You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by zo...@apache.org on 2011/01/27 09:17:22 UTC
svn commit: r1064021 - in /aries/branches/0.3-RCx/jpa/jpa-container/src:
main/java/org/apache/aries/jpa/container/parsing/impl/
test/java/org/apache/aries/jpa/container/parsing/ test/resources/file24/
test/resources/file24/META-INF/
Author: zoe
Date: Thu Jan 27 08:17:22 2011
New Revision: 1064021
URL: http://svn.apache.org/viewvc?rev=1064021&view=rev
Log:
ARIES-556 Merge changes into release branch for 0.3
Added:
aries/branches/0.3-RCx/jpa/jpa-container/src/test/resources/file24/
- copied from r1063278, aries/trunk/jpa/jpa-container/src/test/resources/file24/
aries/branches/0.3-RCx/jpa/jpa-container/src/test/resources/file24/META-INF/
- copied from r1063278, aries/trunk/jpa/jpa-container/src/test/resources/file24/META-INF/
aries/branches/0.3-RCx/jpa/jpa-container/src/test/resources/file24/META-INF/persistence.xml
- copied unchanged from r1063278, aries/trunk/jpa/jpa-container/src/test/resources/file24/META-INF/persistence.xml
Modified:
aries/branches/0.3-RCx/jpa/jpa-container/src/main/java/org/apache/aries/jpa/container/parsing/impl/PersistenceDescriptorParserImpl.java
aries/branches/0.3-RCx/jpa/jpa-container/src/test/java/org/apache/aries/jpa/container/parsing/PersistenceXMLParsingTest.java
Modified: aries/branches/0.3-RCx/jpa/jpa-container/src/main/java/org/apache/aries/jpa/container/parsing/impl/PersistenceDescriptorParserImpl.java
URL: http://svn.apache.org/viewvc/aries/branches/0.3-RCx/jpa/jpa-container/src/main/java/org/apache/aries/jpa/container/parsing/impl/PersistenceDescriptorParserImpl.java?rev=1064021&r1=1064020&r2=1064021&view=diff
==============================================================================
--- aries/branches/0.3-RCx/jpa/jpa-container/src/main/java/org/apache/aries/jpa/container/parsing/impl/PersistenceDescriptorParserImpl.java (original)
+++ aries/branches/0.3-RCx/jpa/jpa-container/src/main/java/org/apache/aries/jpa/container/parsing/impl/PersistenceDescriptorParserImpl.java Thu Jan 27 08:17:22 2011
@@ -20,7 +20,6 @@
package org.apache.aries.jpa.container.parsing.impl;
import java.io.BufferedInputStream;
-import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
@@ -46,10 +45,133 @@ public class PersistenceDescriptorParser
* This class is used internally to prevent the first pass parse from
* closing the InputStream when it exits.
*/
- private static class UnclosableInputStream extends FilterInputStream {
+ private static class RememberingInputStream extends InputStream {
- public UnclosableInputStream(InputStream in) {
- super(in);
+ /** The size by which to grow our array */
+ private static final int bufferGrowthSize = 0x4000;
+ /** The bytes that have been read so far */
+ private byte[] bytes = new byte[bufferGrowthSize];
+ /** Index of the next empty entry in the array */
+ private int pos = 0;
+ /** The input stream that actually holds the data */
+ private final InputStream stream;
+ /** Index of the last valid byte in the byte array */
+ private int maxRead = -1;
+ /** The point to reset to */
+ private int markPoint = -1;
+
+
+ public RememberingInputStream(InputStream in) throws IOException{
+ stream = in;
+ // Pre fill with data that we know we're going to need - it's
+ // more efficient than the single byte reads are - hopefully
+ // someone reading a lot of data will do reads in bulk
+
+ maxRead = stream.read(bytes) - 1;
+ }
+
+ @Override
+ public int read() throws IOException {
+
+ if(pos <= maxRead)
+ {
+ //We can't return the byte directly, because it is signed
+ //We can pretend this is an unsigned byte by using boolean
+ //& to set the low end byte of an int.
+ return bytes[pos++] & 0xFF;
+ } else {
+ int i = stream.read();
+ if(i<0)
+ return i;
+
+ ensureCapacity(0);
+ bytes[pos++] = (byte) i;
+ return i;
+ }
+ }
+
+ /**
+ * Ensure our internal byte array can hold enough data
+ * @param i one less than the number of bytes that need
+ * to be held.
+ */
+ private void ensureCapacity(int i) {
+ if((pos + i) >= bytes.length) {
+ byte[] tmp = bytes;
+ int newLength = bytes.length + bufferGrowthSize;
+ while(newLength < pos + i) {
+ newLength += bufferGrowthSize;
+ }
+ bytes = new byte[newLength];
+ System.arraycopy(tmp, 0, bytes, 0, (maxRead >= pos) ? maxRead + 1 : pos);
+ }
+ }
+
+ @Override
+ public int read(byte[] b) throws IOException {
+ return read(b, 0, b.length);
+ }
+
+ @Override
+ public int read(byte[] b, int off, int len) throws IOException {
+ if(pos <= maxRead) {
+ if(pos + len <= maxRead)
+ {
+ System.arraycopy(bytes, pos, b, off, len);
+ pos += len;
+ return len;
+ } else {
+ int lengthLeftOfBuffer = (maxRead - pos) + 1;
+ System.arraycopy(bytes, pos, b, off, lengthLeftOfBuffer);
+ int read = stream.read(b, off + lengthLeftOfBuffer, len - lengthLeftOfBuffer);
+ if(read < 0) {
+ pos += lengthLeftOfBuffer;
+ return lengthLeftOfBuffer;
+ }
+ ensureCapacity(lengthLeftOfBuffer + read - 1);
+ System.arraycopy(b, off + lengthLeftOfBuffer, bytes, maxRead + 1, read);
+ pos += (lengthLeftOfBuffer + read);
+ return lengthLeftOfBuffer + read;
+ }
+ } else {
+ int i = stream.read(b, off, len);
+ if(i<0)
+ return i;
+ ensureCapacity(i - 1);
+ System.arraycopy(b, off, bytes, pos, i);
+ pos += i;
+ return i;
+ }
+ }
+
+ @Override
+ public long skip(long n) throws IOException {
+ throw new IOException("Skip is unsupported");
+ }
+
+ @Override
+ public int available() throws IOException {
+ if(pos <= maxRead)
+ return (maxRead - pos) + 1;
+ else
+ return stream.available();
+ }
+
+ @Override
+ public synchronized void mark(int readlimit) {
+ markPoint = pos;
+ }
+
+ @Override
+ public synchronized void reset() throws IOException {
+ if(maxRead < pos)
+ maxRead = pos - 1;
+ pos = markPoint;
+ }
+
+ @Override
+ public boolean markSupported() {
+ return true;
}
@Override
@@ -64,17 +186,17 @@ public class PersistenceDescriptorParser
public Collection<ParsedPersistenceUnit> parse(Bundle b, PersistenceDescriptor descriptor) throws PersistenceDescriptorParserException {
Collection<ParsedPersistenceUnit> persistenceUnits = new ArrayList<ParsedPersistenceUnit>();
SAXParserFactory parserFactory = SAXParserFactory.newInstance();
- BufferedInputStream is = null;
+ InputStream is = null;
boolean schemaFound = false;
try {
//Buffer the InputStream so we can mark it, though we'll be in
//trouble if we have to read more than 8192 characters before finding
//the schema!
- is = new BufferedInputStream(descriptor.getInputStream(), 8192);
- is.mark(8192);
+ is = new RememberingInputStream(descriptor.getInputStream());
+ is.mark(Integer.MAX_VALUE);
SAXParser parser = parserFactory.newSAXParser();
try{
- parser.parse(new UnclosableInputStream(is), new SchemaLocatingHandler());
+ parser.parse(is, new SchemaLocatingHandler());
} catch (EarlyParserReturn epr) {
//This is not really an exception, but a way to work out which
//version of the persistence schema to use in validation
Modified: aries/branches/0.3-RCx/jpa/jpa-container/src/test/java/org/apache/aries/jpa/container/parsing/PersistenceXMLParsingTest.java
URL: http://svn.apache.org/viewvc/aries/branches/0.3-RCx/jpa/jpa-container/src/test/java/org/apache/aries/jpa/container/parsing/PersistenceXMLParsingTest.java?rev=1064021&r1=1064020&r2=1064021&view=diff
==============================================================================
--- aries/branches/0.3-RCx/jpa/jpa-container/src/test/java/org/apache/aries/jpa/container/parsing/PersistenceXMLParsingTest.java (original)
+++ aries/branches/0.3-RCx/jpa/jpa-container/src/test/java/org/apache/aries/jpa/container/parsing/PersistenceXMLParsingTest.java Thu Jan 27 08:17:22 2011
@@ -266,6 +266,87 @@ public class PersistenceXMLParsingTest
is.close();
}
}
+
+
+ /**
+ * Test parsing a persistence descriptor with several entries
+ * @throws Exception
+ */
+ @Test
+ public void testReallyBigFile() throws Exception
+ {
+ InputStream is = null;
+ try {
+ String location = "file24/META-INF/persistence.xml";
+ is = getClass().getClassLoader().getResourceAsStream(location);
+ PersistenceDescriptor descriptor = new PersistenceDescriptorImpl(location, is);
+
+ Bundle b = Skeleton.newMock(Bundle.class);
+
+ Collection<ParsedPersistenceUnit> parsedUnits = new PersistenceDescriptorParserImpl().parse(b, descriptor);
+ assertEquals("An incorrect number of persistence units has been returned.", 33, parsedUnits.size());
+
+ List<ParsedPersistenceUnit> units = getList(parsedUnits);
+
+ Collections.sort(units, new Comparator<ParsedPersistenceUnit>() {
+
+ public int compare(ParsedPersistenceUnit p1,
+ ParsedPersistenceUnit p2) {
+
+ return Integer.valueOf((String)p1.getPersistenceXmlMetadata().
+ get(ParsedPersistenceUnit.UNIT_NAME)).compareTo(
+ Integer.valueOf((String)p2.getPersistenceXmlMetadata().
+ get(ParsedPersistenceUnit.UNIT_NAME)));
+ }
+ });
+
+ for(int i = 0; i < units.size() ; i++)
+ checkParsedUnit(b, units.get(i), Integer.valueOf(i + 1).toString());
+
+ } finally {
+ if(is != null)
+ is.close();
+ }
+ }
+
+ private void checkParsedUnit(Bundle b, ParsedPersistenceUnit unit, String number) {
+ assertEquals("The schema version was incorrect", "1.0",
+ unit.getPersistenceXmlMetadata().get(ParsedPersistenceUnit.SCHEMA_VERSION));
+ assertEquals("The unit name was incorrect", number,
+ unit.getPersistenceXmlMetadata().get(ParsedPersistenceUnit.UNIT_NAME));
+ assertEquals("The transaction type was incorrect", "JTA",
+ unit.getPersistenceXmlMetadata().get(ParsedPersistenceUnit.TRANSACTION_TYPE));
+ assertEquals("The provider class name was incorrect", "provider." + number,
+ unit.getPersistenceXmlMetadata().get(ParsedPersistenceUnit.PROVIDER_CLASSNAME));
+ assertEquals("The jta datasource jndi name was wrong", "jtaDS." + number,
+ unit.getPersistenceXmlMetadata().get(ParsedPersistenceUnit.JTA_DATASOURCE));
+ assertEquals("The non jta datasource jndi name was wrong", "nonJtaDS." + number,
+ unit.getPersistenceXmlMetadata().get(ParsedPersistenceUnit.NON_JTA_DATASOURCE));
+ assertEquals("An incorrect number of mapping files were specified", 1,
+ ((Collection)unit.getPersistenceXmlMetadata().get(ParsedPersistenceUnit.MAPPING_FILES)).size());
+ assertTrue("Incorrect mapping files were listed",
+ ((Collection)unit.getPersistenceXmlMetadata().get(ParsedPersistenceUnit.MAPPING_FILES)).contains("mappingFile." + number));
+ assertEquals("An incorrect number of jar files were specified", 1,
+ ((Collection)unit.getPersistenceXmlMetadata().get(ParsedPersistenceUnit.JAR_FILES)).size());
+ assertTrue("Incorrect jar URLs were listed", ((Collection<String>)unit.getPersistenceXmlMetadata().get(ParsedPersistenceUnit.JAR_FILES)).contains("jarFile." + number));
+
+ assertEquals("An incorrect number of managed classes were specified", 1,
+ ((Collection)unit.getPersistenceXmlMetadata().get(ParsedPersistenceUnit.MANAGED_CLASSES)).size());
+ assertTrue("Incorrect managed classes were listed",
+ ((Collection)unit.getPersistenceXmlMetadata().get(ParsedPersistenceUnit.MANAGED_CLASSES)).contains("class." + number));
+
+ //In the schema this defaults to false. There is a separate test (testFile1b)
+ //for the spec behaviour, which defaults to true
+ assertFalse("We should exclude any classes not listed",
+ (Boolean)unit.getPersistenceXmlMetadata().get(ParsedPersistenceUnit.EXCLUDE_UNLISTED_CLASSES));
+ assertNotNull("The properties should never be null",
+ unit.getPersistenceXmlMetadata().get(ParsedPersistenceUnit.PROPERTIES));
+ assertEquals("The wrong number of properties were specified", 1,
+ ((Properties)unit.getPersistenceXmlMetadata().get(ParsedPersistenceUnit.PROPERTIES)).size());
+ assertEquals("The property had the wrong value", "prop.value." + number,
+ ((Properties)unit.getPersistenceXmlMetadata().get(ParsedPersistenceUnit.PROPERTIES)).getProperty("some.prop." + number));
+ assertSame("The persistence unit was associated with the wrong bundle", b, unit.getDefiningBundle());
+ }
/**
* Sort a Collection of ParsedPersistenceUnit into alphabetical order (by unit name)