You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by st...@apache.org on 2006/03/08 13:20:38 UTC
svn commit: r384197 - in
/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core:
jndi/provider/DummyContext.java xml/DocViewImportHandler.java
xml/DocViewSAXEventGenerator.java
Author: stefan
Date: Wed Mar 8 04:20:37 2006
New Revision: 384197
URL: http://svn.apache.org/viewcvs?rev=384197&view=rev
Log:
JCR-325: docview roundtripping does not work with multivalue non-string properties
Modified:
incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/jndi/provider/DummyContext.java
incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/DocViewImportHandler.java
incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/DocViewSAXEventGenerator.java
Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/jndi/provider/DummyContext.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/jndi/provider/DummyContext.java?rev=384197&r1=384196&r2=384197&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/jndi/provider/DummyContext.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/jndi/provider/DummyContext.java Wed Mar 8 04:20:37 2006
@@ -35,7 +35,7 @@
import java.util.Properties;
/**
- * <code>DummyContext</code> is a simple service provider that
+ * <code>DummyContext</code> is a simple service provider that
* implements a flat namespace in memory. It is intended to be used for
* testing purposes only.
*/
Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/DocViewImportHandler.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/DocViewImportHandler.java?rev=384197&r1=384196&r2=384197&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/DocViewImportHandler.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/DocViewImportHandler.java Wed Mar 8 04:20:37 2006
@@ -20,6 +20,7 @@
import org.apache.jackrabbit.name.NamespaceResolver;
import org.apache.jackrabbit.name.QName;
import org.apache.jackrabbit.util.ISO9075;
+import org.apache.jackrabbit.util.Text;
import org.apache.jackrabbit.core.NodeId;
import org.apache.log4j.Logger;
import org.xml.sax.Attributes;
@@ -162,6 +163,9 @@
/**
* {@inheritDoc}
+ * <p/>
+ * See also {@link DocViewSAXEventGenerator#leaving(javax.jcr.Node, int)}
+ * regarding special handling of multi-valued properties on export.
*/
public void startElement(String namespaceURI, String localName,
String qName, Attributes atts)
@@ -188,35 +192,49 @@
// value(s)
String attrValue = atts.getValue(i);
Importer.TextValue[] propValues;
-/*
- // @todo should attribute value be interpreted as LIST type (i.e. multi-valued property)?
- String[] strings = Text.explode(attrValue, ' ', true);
- propValues = new Value[strings.length];
- for (int j = 0; j < strings.length; j++) {
- // decode encoded blanks in value
- strings[j] = Text.replace(strings[j], "_x0020_", " ");
- propValues[j] = InternalValue.create(strings[j]);
+
+ if (attrValue.startsWith("\n")) {
+ // assume multi-valued property:
+ // a leading line-feed (a valid whitespace NMTOKENS delimiter)
+ // is interpreted as a hint that this attribute value is of
+ // type NMTOKENS.
+ // see DocViewSAXEventGenerator#leaving(Node, int)
+ attrValue = attrValue.substring(1);
+ String[] strings = Text.explode(attrValue, ' ', true);
+ propValues = new Importer.TextValue[strings.length];
+ for (int j = 0; j < strings.length; j++) {
+ // decode encoded blanks in value
+ strings[j] = Text.replace(strings[j], "_x0020_", " ");
+ propValues[j] = new StringValue(strings[j]);
+ }
+ } else {
+ // assume single-valued property
+ propValues = new Importer.TextValue[1];
+ propValues[0] = new StringValue(attrValue);
}
-*/
+
if (propName.equals(QName.JCR_PRIMARYTYPE)) {
// jcr:primaryType
if (attrValue.length() > 0) {
try {
nodeTypeName = QName.fromJCRName(attrValue, nsContext);
- } catch (NameException be) {
+ } catch (NameException ne) {
throw new SAXException("illegal jcr:primaryType value: "
- + attrValue, be);
+ + attrValue, ne);
}
}
} else if (propName.equals(QName.JCR_MIXINTYPES)) {
// jcr:mixinTypes
- if (attrValue.length() > 0) {
- try {
- mixinTypes =
- new QName[]{QName.fromJCRName(attrValue, nsContext)};
- } catch (NameException be) {
- throw new SAXException("illegal jcr:mixinTypes value: "
- + attrValue, be);
+ if (propValues.length > 0) {
+ mixinTypes = new QName[propValues.length];
+ for (int j = 0; j < propValues.length; j++) {
+ String val = ((StringValue) propValues[j]).retrieve();
+ try {
+ mixinTypes[j] = QName.fromJCRName(val, nsContext);
+ } catch (NameException ne) {
+ throw new SAXException("illegal jcr:mixinTypes value: "
+ + val, ne);
+ }
}
}
} else if (propName.equals(QName.JCR_UUID)) {
@@ -225,8 +243,6 @@
id = NodeId.valueOf(attrValue);
}
} else {
- propValues = new Importer.TextValue[1];
- propValues[0] = new StringValue(atts.getValue(i));
props.add(new Importer.PropInfo(propName,
PropertyType.UNDEFINED, propValues));
}
Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/DocViewSAXEventGenerator.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/DocViewSAXEventGenerator.java?rev=384197&r1=384196&r2=384197&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/DocViewSAXEventGenerator.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/DocViewSAXEventGenerator.java Wed Mar 8 04:20:37 2006
@@ -98,6 +98,9 @@
/**
* {@inheritDoc}
+ * <p/>
+ * See also {@link DocViewImportHandler#startElement(String, String, String, org.xml.sax.Attributes)}
+ * regarding special handling of multi-valued properties on import.
*/
protected void leavingProperties(Node node, int level)
throws RepositoryException, SAXException {
@@ -146,18 +149,44 @@
StringBuffer attrValue = new StringBuffer();
// process property value(s)
boolean multiValued = prop.getDefinition().isMultiple();
- Value[] vals;
+
if (multiValued) {
- vals = prop.getValues();
- } else {
- vals = new Value[]{prop.getValue()};
- }
- for (int i = 0; i < vals.length; i++) {
- if (i > 0) {
- // use space as delimiter for multi-valued properties
- attrValue.append(" ");
+ // multi-valued property:
+ // according to "6.4.2.5 Multi-value Properties" of the
+ // jsr-170 specification a multi-valued property can be
+ // either skipped or it must be exported as NMTOKENS
+ // type where "a mechanism must be adopted whereby upon
+ // re-import the distinction between multi- and single-
+ // value properties is not lost"...
+
+ // the following implementation is a pragmatic approach
+ // in the interest of improved useability:
+ // the attribute value is constructed by concatenating
+ // the serialized and escaped values, separated by a
+ // space character each, into a single string and
+ // prepending a new-line to help distinguish multi-
+ // from single-valued properties on re-import.
+
+ // use a leading line-feed (a valid whitespace
+ // delimiter) as a hint on re-import that this attribute
+ // value is of type NMTOKENS; note that line-feed rather
+ // than space has been chosen as leading line-feeds are
+ // not affected by attribute-value normalization
+ // (http://www.w3.org/TR/REC-xml/#AVNormalize)
+ attrValue.append("\n");
+ Value[] vals = prop.getValues();
+ for (int i = 0; i < vals.length; i++) {
+ if (i > 0) {
+ // use space as delimiter for separate values
+ attrValue.append(" ");
+ }
+ // serialize value (with encoded embedded spaces)
+ attrValue.append(ValueHelper.serialize(vals[i], true));
}
- attrValue.append(ValueHelper.serialize(vals[i], true));
+ } else {
+ // single-valued property:
+ // serialize value without encoding embedded spaces
+ attrValue.append(ValueHelper.serialize(prop.getValue(), false));
}
attrs.addAttribute(qName.getNamespaceURI(),
qName.getLocalName(), attrName, CDATA_TYPE,