You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by ju...@apache.org on 2009/04/22 16:00:15 UTC
svn commit: r767525 - in /jackrabbit/branches/1.5: ./
jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/
jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/
jackrabbit-core/src/test/java/org/apache/jackrabbit/cor...
Author: jukka
Date: Wed Apr 22 14:00:14 2009
New Revision: 767525
URL: http://svn.apache.org/viewvc?rev=767525&view=rev
Log:
1.5: Merged revisions 752457 and 752458 (JCR-2017 and JCR-2007)
Modified:
jackrabbit/branches/1.5/ (props changed)
jackrabbit/branches/1.5/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeRegistry.java
jackrabbit/branches/1.5/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/BufferedStringValue.java
jackrabbit/branches/1.5/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/SysViewImportHandler.java
jackrabbit/branches/1.5/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/ExportImportTest.java
jackrabbit/branches/1.5/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/xml/SystemViewExporter.java
Propchange: jackrabbit/branches/1.5/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Apr 22 14:00:14 2009
@@ -1,2 +1,2 @@
/jackrabbit/branches/1.3:631261
-/jackrabbit/trunk:703899-704158,704165,704167,704324,704358,704361,704864,704933,704939,705010,705033,705243,705496,705522,705579,705925,705932,705934,705937-705938,705961,706242,706273,706285-706286,706562,706606,706649,706655,706660,706697,706918,707303-707304,707307,707310,707630,708206,708598,708609,708613,708619,708634,708840,708863,708909,708929,708943,709115,709142,709207,709211,710047,711238,711566-711567,711595,711841-711843,712984-712985,713037,713059,713065,713072,713076,713162,713214,713956,713958,713964,713971,713975,714034,718218,718249-718250,718371,718376,718566,718632,718981,719225,719282,719575-719577,719579,719585-719586,719588,719592,720455,720484,720492,720524,720533,720540,720673,720679,720687,720784,720940,720969,721186,721191,721194,721235,721387-721389,721470,721495,722068-722069,722463,722465,722467,722470,722825,723281,723346,723728,723784,724300,724387,725292,727376,727388,727390,727395,727397,727402,727492,727701,728022,731896,731934,731941,73234
7,732678,732686,732689,732693,732703,732715-732716,732719,732728,732730,732734-732738,732740,732742-732743,732745,732867,732883,733057-733059,733061,733080,734092,734366,734375,734400,734709,735401,736021,736030,736274,736276,736650-736651,736653-736656,736658,736680,737695,738087,738119,738121,738419,738422,738474,738512,739210,739212,739226,740262,740734,740736-740738,740747,740749-740750,741052,741100,741121,741206,741208-741210,741213,741509,741524,741652,741803,742382,742538,743295,743713,743718,743726,743734,743738,744883-744884,744889,744895,744911,744935,744940,744954,744956,745041,745051,745053,745056,745060,745120,745500,745534,745824,745849,746301-746302,746486,746602-746603,746609,746666,746747-746748,746932,746946,747096,747325,747347,747358-747360,747362,747365,747368,747372,747785,747839,748065,748232-748233,748247,748486,749237,749448,749622,749953,749965,750011,750437,752036-752039,752044,752046-752051,752053-752054,752056,752058-752060,752063-752067,752115,
752131,752414-752415,752478,752543-752545,752809,752831,752840-752841,753225-753228,753232,753244,755582,756378,756403,756405,756409,756429,756432,756442,756444-756445,757364,757698,757775-757776,757814,757854,757856,757862,758193,758263,758265,758349,758354,758629,758632,758634-758636,758639-758642,758646,758649,758653-758654,759880,759889,760386,760479,760945,761267,761279-761280,761282-761283,761292,761634,761645,761690-761691,761715,762671,762675,762700,762702,762731,762737,762755,762780-762781,762789,762793,762797,762802,762804,762808,762813-762814,762817-762818,762821-762823,763146,763160,763188,763205,763215,763242,763244,763248,763617,765322,765328,765337,765532,765551,765554,765556,765585
+/jackrabbit/trunk:703899-704158,704165,704167,704324,704358,704361,704864,704933,704939,705010,705033,705243,705496,705522,705579,705925,705932,705934,705937-705938,705961,706242,706273,706285-706286,706562,706606,706649,706655,706660,706697,706918,707303-707304,707307,707310,707630,708206,708598,708609,708613,708619,708634,708840,708863,708909,708929,708943,709115,709142,709207,709211,710047,711238,711566-711567,711595,711841-711843,712984-712985,713037,713059,713065,713072,713076,713162,713214,713956,713958,713964,713971,713975,714034,718218,718249-718250,718371,718376,718566,718632,718981,719225,719282,719575-719577,719579,719585-719586,719588,719592,720455,720484,720492,720524,720533,720540,720673,720679,720687,720784,720940,720969,721186,721191,721194,721235,721387-721389,721470,721495,722068-722069,722463,722465,722467,722470,722825,723281,723346,723728,723784,724300,724387,725292,727376,727388,727390,727395,727397,727402,727492,727701,728022,731896,731934,731941,73234
7,732678,732686,732689,732693,732703,732715-732716,732719,732728,732730,732734-732738,732740,732742-732743,732745,732867,732883,733057-733059,733061,733080,734092,734366,734375,734400,734709,735401,736021,736030,736274,736276,736650-736651,736653-736656,736658,736680,737695,738087,738119,738121,738419,738422,738474,738512,739210,739212,739226,740262,740734,740736-740738,740747,740749-740750,741052,741100,741121,741206,741208-741210,741213,741509,741524,741652,741803,742382,742538,743295,743713,743718,743726,743734,743738,744883-744884,744889,744895,744911,744935,744940,744954,744956,745041,745051,745053,745056,745060,745120,745500,745534,745824,745849,746301-746302,746486,746602-746603,746609,746666,746747-746748,746932,746946,747096,747325,747347,747358-747360,747362,747365,747368,747372,747785,747839,748065-748066,748232-748233,748243,748247,748486,749237,749448,749622,749953,749965,750008,750011,750437,750536,752036-752039,752044,752046-752051,752053-752054,752056,752058-
752060,752063-752067,752115,752131,752414-752415,752457-752458,752478,752543-752545,752809,752831,752840-752841,753225-753228,753232,753244,755582,756378,756403,756405,756409,756429,756432,756442,756444-756445,757364,757698,757775-757776,757814,757854,757856,757862,758193,758263,758265,758349,758354,758629,758632,758634-758636,758639-758642,758646,758649,758653-758654,759880,759889,760386,760479,760945,761267,761279-761280,761282-761283,761292,761634,761645,761690-761691,761715,762671,762675,762700,762702,762731,762737,762755,762780-762781,762789,762793,762797,762802,762804,762808,762813-762814,762817-762818,762821-762823,763146,763160,763188,763205,763215,763242,763244,763248,763617,765322,765328,765337,765532,765551,765554,765556,765585
Modified: jackrabbit/branches/1.5/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeRegistry.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.5/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeRegistry.java?rev=767525&r1=767524&r2=767525&view=diff
==============================================================================
--- jackrabbit/branches/1.5/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeRegistry.java (original)
+++ jackrabbit/branches/1.5/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeRegistry.java Wed Apr 22 14:00:14 2009
@@ -165,7 +165,7 @@
*/
public static int getBits(Privilege[] privileges) throws AccessControlException {
if (privileges == null || privileges.length == 0) {
- throw new AccessControlException();
+ throw new AccessControlException("Privilege array is empty or null.");
}
int bits = NO_PRIVILEGE;
for (int i = 0; i < privileges.length; i++) {
Modified: jackrabbit/branches/1.5/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/BufferedStringValue.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.5/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/BufferedStringValue.java?rev=767525&r1=767524&r2=767525&view=diff
==============================================================================
--- jackrabbit/branches/1.5/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/BufferedStringValue.java (original)
+++ jackrabbit/branches/1.5/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/BufferedStringValue.java Wed Apr 22 14:00:14 2009
@@ -29,15 +29,20 @@
import javax.jcr.RepositoryException;
import javax.jcr.Value;
import javax.jcr.ValueFormatException;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
+import java.io.FileInputStream;
import java.io.FileOutputStream;
-import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
+import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.StringReader;
+import java.io.StringWriter;
import java.io.Writer;
/**
@@ -54,42 +59,46 @@
private static Logger log = LoggerFactory.getLogger(BufferedStringValue.class);
/**
- * max size for buffering data in memory
+ * The maximum size for buffering data in memory.
*/
private static final int MAX_BUFFER_SIZE = 0x10000;
+
/**
- * size of increment if capacity buffer needs to be enlarged
- */
- private static final int BUFFER_INCREMENT = 0x2000;
- /**
- * in-memory buffer
+ * The in-memory buffer.
*/
- private char[] buffer;
+ private StringWriter buffer;
+
/**
- * current position within buffer (size of actual data in buffer)
+ * The number of characters written so far.
+ * If the in-memory buffer is used, this is position within buffer (size of actual data in buffer)
*/
- private int bufferPos;
+ private long length;
/**
- * backing temporary file created when size of data exceeds
- * MAX_BUFFER_SIZE
+ * Backing temporary file created when size of data exceeds
+ * MAX_BUFFER_SIZE.
*/
private File tmpFile;
+
/**
- * writer used to write to tmpFile; writer & tmpFile are always
- * instantiated together, i.e. they are either both null or both not null.
+ * Writer used to write to tmpFile.
*/
private Writer writer;
private final NamePathResolver nsContext;
+
+ /**
+ * Whether the value is base64 encoded.
+ */
+ private boolean base64;
/**
* Constructs a new empty <code>BufferedStringValue</code>.
* @param nsContext
*/
protected BufferedStringValue(NamePathResolver nsContext) {
- buffer = new char[0x2000];
- bufferPos = 0;
+ buffer = new StringWriter();
+ length = 0;
tmpFile = null;
writer = null;
this.nsContext = nsContext;
@@ -102,15 +111,17 @@
* @throws IOException if an I/O error occurs
*/
public long length() throws IOException {
- if (buffer != null) {
- return bufferPos;
- } else if (tmpFile != null) {
- // flush writer first
- writer.flush();
- return tmpFile.length();
- } else {
- throw new IOException("this instance has already been disposed");
+ return length;
+ }
+
+ private String retrieveString() throws IOException {
+ String value = retrieve();
+ if (base64) {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ Base64.decode(value, out);
+ value = new String(out.toByteArray(), "UTF-8");
}
+ return value;
}
/**
@@ -121,18 +132,18 @@
*/
public String retrieve() throws IOException {
if (buffer != null) {
- return new String(buffer, 0, bufferPos);
+ return buffer.toString();
} else if (tmpFile != null) {
- // flush writer first
- writer.flush();
+ // close writer first
+ writer.close();
if (tmpFile.length() > Integer.MAX_VALUE) {
throw new IOException("size of value is too big, use reader()");
}
- StringBuffer sb = new StringBuffer((int) tmpFile.length());
+ StringBuffer sb = new StringBuffer((int) length);
char[] chunk = new char[0x2000];
- int read;
- Reader reader = new FileReader(tmpFile);
+ Reader reader = openReader();
try {
+ int read;
while ((read = reader.read(chunk)) > -1) {
sb.append(chunk, 0, read);
}
@@ -144,6 +155,11 @@
throw new IOException("this instance has already been disposed");
}
}
+
+ private Reader openReader() throws IOException {
+ return new InputStreamReader(
+ new BufferedInputStream(new FileInputStream(tmpFile)), "UTF-8");
+ }
/**
* Returns a <code>Reader</code> for reading the serialized value.
@@ -153,11 +169,11 @@
*/
public Reader reader() throws IOException {
if (buffer != null) {
- return new StringReader(new String(buffer, 0, bufferPos));
+ return new StringReader(retrieve());
} else if (tmpFile != null) {
- // flush writer first
- writer.flush();
- return new FileReader(tmpFile);
+ // close writer first
+ writer.close();
+ return openReader();
} else {
throw new IOException("this instance has already been disposed");
}
@@ -168,48 +184,32 @@
*
* @param chars the characters to be appended
* @param start the index of the first character to append
- * @param length the number of characters to append
+ * @param len the number of characters to append
* @throws IOException if an I/O error occurs
*/
- public void append(char[] chars, int start, int length)
+ public void append(char[] chars, int start, int len)
throws IOException {
if (buffer != null) {
- if (bufferPos + length > MAX_BUFFER_SIZE) {
+ if (this.length + len > MAX_BUFFER_SIZE) {
// threshold for keeping data in memory exceeded;
// create temp file and spool buffer contents
TransientFileFactory fileFactory = TransientFileFactory.getInstance();
tmpFile = fileFactory.createTransientFile("txt", null, null);
- final FileOutputStream fout = new FileOutputStream(tmpFile);
- writer = new OutputStreamWriter(fout) {
- public void flush() throws IOException {
- // flush this writer
- super.flush();
- // force synchronization with underlying file
- fout.getFD().sync();
- }
- };
- writer.write(buffer, 0, bufferPos);
- writer.write(chars, start, length);
- // reset fields
+ BufferedOutputStream fout = new BufferedOutputStream(new FileOutputStream(tmpFile));
+ writer = new OutputStreamWriter(fout, "UTF-8");
+ writer.write(buffer.toString());
+ writer.write(chars, start, len);
+ // reset the in-memory buffer
buffer = null;
- bufferPos = 0;
} else {
- if (bufferPos + length > buffer.length) {
- // reallocate new buffer and spool old buffer contents
- int bufferSize =
- BUFFER_INCREMENT * (((bufferPos + length) / BUFFER_INCREMENT) + 1);
- char[] newBuffer = new char[bufferSize];
- System.arraycopy(buffer, 0, newBuffer, 0, bufferPos);
- buffer = newBuffer;
- }
- System.arraycopy(chars, start, buffer, bufferPos, length);
- bufferPos += length;
+ buffer.write(chars, start, len);
}
} else if (tmpFile != null) {
- writer.write(chars, start, length);
+ writer.write(chars, start, len);
} else {
throw new IOException("this instance has already been disposed");
}
+ length += len;
}
/**
@@ -262,7 +262,7 @@
}
} else {
// all other types
- return ValueHelper.deserialize(retrieve(), targetType, false, ValueFactoryImpl.getInstance());
+ return ValueHelper.deserialize(retrieveString(), targetType, false, ValueFactoryImpl.getInstance());
}
} catch (IOException e) {
String msg = "failed to retrieve serialized value";
@@ -286,7 +286,7 @@
return InternalValue.create(baos.toByteArray());
} else {
// >= 65kb: deserialize BINARY type
- // using Reader and temporay file
+ // using Reader and temporary file
if (InternalValue.USE_DATA_STORE) {
Base64ReaderInputStream in = new Base64ReaderInputStream(reader());
return InternalValue.createTemporary(in);
@@ -307,13 +307,16 @@
// convert serialized value to InternalValue using
// current namespace context of xml document
return InternalValue.create(ValueHelper.convert(
- retrieve(), type, ValueFactoryImpl.getInstance()), nsContext);
+ retrieveString(), type, ValueFactoryImpl.getInstance()), nsContext);
}
} catch (IOException e) {
throw new RepositoryException("Error accessing property value", e);
}
}
+ /**
+ * This class converts the text read Converts a base64 reader to an input stream.
+ */
private static class Base64ReaderInputStream extends InputStream {
private static final int BUFFER_SIZE = 1024;
@@ -361,7 +364,6 @@
public void dispose() {
if (buffer != null) {
buffer = null;
- bufferPos = 0;
} else if (tmpFile != null) {
try {
writer.close();
@@ -375,4 +377,14 @@
log.warn("this instance has already been disposed");
}
}
+
+ /**
+ * Whether this value is base64 encoded
+ *
+ * @param base64 the flag
+ */
+ public void setBase64(boolean base64) {
+ this.base64 = base64;
+ }
+
}
Modified: jackrabbit/branches/1.5/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/SysViewImportHandler.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.5/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/SysViewImportHandler.java?rev=767525&r1=767524&r2=767525&view=diff
==============================================================================
--- jackrabbit/branches/1.5/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/SysViewImportHandler.java (original)
+++ jackrabbit/branches/1.5/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/SysViewImportHandler.java Wed Apr 22 14:00:14 2009
@@ -172,9 +172,9 @@
}
} else if (name.equals(NameConstants.SV_VALUE)) {
// sv:value element
-
- // reset temp fields
currentPropValue = new BufferedStringValue(resolver);
+ String xsiType = atts.getValue("xsi:type");
+ currentPropValue.setBase64("xs:base64Binary".equals(xsiType));
} else {
throw new SAXException(new InvalidSerializedDataException(
"Unexpected element in system view xml document: " + name));
@@ -301,6 +301,9 @@
}
//--------------------------------------------------------< inner classes >
+ /**
+ * The state of parsing the XML stream.
+ */
class ImportState {
/**
* name of current node
@@ -327,7 +330,7 @@
/**
* flag indicating whether startNode() has been called for current node
*/
- boolean started = false;
+ boolean started;
}
//-------------------------------------------------------------< private >
Modified: jackrabbit/branches/1.5/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/ExportImportTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.5/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/ExportImportTest.java?rev=767525&r1=767524&r2=767525&view=diff
==============================================================================
--- jackrabbit/branches/1.5/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/ExportImportTest.java (original)
+++ jackrabbit/branches/1.5/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/ExportImportTest.java Wed Apr 22 14:00:14 2009
@@ -29,9 +29,75 @@
import javax.jcr.RepositoryException;
import javax.jcr.Session;
+/**
+ * Test importing and exporting large binary and text objects.
+ */
public class ExportImportTest extends AbstractJCRTest {
/**
+ * Test importing a large text property with Unicode characters larger than 255.
+ */
+ public void testExportImportText() throws RepositoryException {
+ doTestExportImportLargeText("Hello \t\r\n!".toCharArray());
+ doTestExportImportLargeText("World\f\f\f.".toCharArray());
+ doTestExportImportLargeText("Hello\t\n\n.\n".toCharArray());
+ doTestExportImportLargeRandomText(100);
+ doTestExportImportLargeRandomText(10000);
+ doTestExportImportLargeRandomText(100000);
+ }
+
+ private void doTestExportImportLargeRandomText(int len) throws RepositoryException {
+ char[] chars = new char[len];
+ Random random = new Random(1);
+ // The UCS code values 0xd800-0xdfff (UTF-16 surrogates)
+ // as well as 0xfffe and 0xffff (UCS non-characters)
+ // should not appear in conforming UTF-8 streams.
+ // (String.getBytes("UTF-8") only returns 1 byte for 0xd800-0xdfff)
+ for (int i = 0; i < chars.length; i++) {
+ chars[i] = (char) random.nextInt(0xd000);
+ }
+ doTestExportImportLargeText(chars);
+ }
+
+ private void doTestExportImportLargeText(char[] chars) throws RepositoryException {
+ try {
+ Session session = helper.getReadWriteSession();
+ Node root = session.getRootNode();
+ clean(root);
+ Node test = root.addNode("testText");
+ session.save();
+ String s = new String(chars);
+ test.setProperty("text", s);
+ test.save();
+ session.save();
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ session.exportSystemView("/testText", out, false, false);
+ byte[] output = out.toByteArray();
+ Node test2 = root.addNode("testText2");
+ Node test3 = root.addNode("testText3");
+ session.save();
+ session.importXML("/testText2", new ByteArrayInputStream(output), ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
+ session.save();
+ session.getWorkspace().importXML("/testText3", new ByteArrayInputStream(output), ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
+ test2 = root.getNode("testText2");
+ test2 = test2.getNode("testText");
+ test3 = root.getNode("testText3");
+ test3 = test3.getNode("testText");
+ String s2 = test2.getProperty("text").getString();
+ String s3 = test3.getProperty("text").getString();
+ assertEquals(s.length(), s2.length());
+ assertEquals(s.length(), s3.length());
+ assertEquals(s, s2);
+ assertEquals(s, s3);
+ clean(root);
+ } catch (Exception e) {
+ e.printStackTrace();
+ assertFalse(e.getMessage(), true);
+ }
+ }
+
+
+ /**
* Test a node type with a binary default value
* @throws RepositoryException
*/
@@ -105,6 +171,15 @@
while (root.hasNode("testBinary3")) {
root.getNode("testBinary3").remove();
}
+ while (root.hasNode("testText")) {
+ root.getNode("testText").remove();
+ }
+ while (root.hasNode("testText2")) {
+ root.getNode("testText2").remove();
+ }
+ while (root.hasNode("testText3")) {
+ root.getNode("testText3").remove();
+ }
root.getSession().save();
}
}
Modified: jackrabbit/branches/1.5/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/xml/SystemViewExporter.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.5/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/xml/SystemViewExporter.java?rev=767525&r1=767524&r2=767525&view=diff
==============================================================================
--- jackrabbit/branches/1.5/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/xml/SystemViewExporter.java (original)
+++ jackrabbit/branches/1.5/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/xml/SystemViewExporter.java Wed Apr 22 14:00:14 2009
@@ -161,7 +161,7 @@
String string = value.getString();
for (int i = 0; i < string.length(); i++) {
char c = string.charAt(i);
- if (c >= 0 && c < 32 && c != '\r' && c != '\n' && c != '\t') {
+ if (c >= 0 && c < 32 && c != '\n' && c != '\t') {
return true;
}
}