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 2005/02/21 19:03:35 UTC
svn commit: r154700 [2/2] - in
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core:
LocalNamespaceMappings.java NodeImpl.java QName.java SessionImpl.java
nodetype/NodeDefImpl.java nodetype/builtin_nodetypes.xml
xml/DocViewImportHandler.java xml/ImportHandler.java xml/Importer.java
xml/SessionImporter.java xml/SysViewImportHandler.java
Added: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/SessionImporter.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/SessionImporter.java?view=auto&rev=154700
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/SessionImporter.java (added)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/SessionImporter.java Mon Feb 21 10:03:31 2005
@@ -0,0 +1,274 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.xml;
+
+import org.apache.jackrabbit.core.Constants;
+import org.apache.jackrabbit.core.NamespaceResolver;
+import org.apache.jackrabbit.core.NodeImpl;
+import org.apache.jackrabbit.core.QName;
+import org.apache.jackrabbit.core.SessionImpl;
+import org.apache.log4j.Logger;
+
+import javax.jcr.ItemExistsException;
+import javax.jcr.ItemNotFoundException;
+import javax.jcr.Property;
+import javax.jcr.PropertyType;
+import javax.jcr.ReferenceValue;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+import javax.jcr.ValueFormatException;
+import javax.jcr.nodetype.ConstraintViolationException;
+import javax.jcr.nodetype.PropertyDef;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Stack;
+
+/**
+ * <code>SessionImporter</code> ...
+ */
+public class SessionImporter implements Importer {
+
+ private static Logger log = Logger.getLogger(SessionImporter.class);
+
+ private final SessionImpl session;
+ private final NodeImpl importTargetNode;
+ private final int uuidBehavior;
+
+ private Stack parents;
+
+ /**
+ * mapping <original uuid> to <new uuid> of mix:referenceable nodes
+ */
+ private final HashMap uuidMap;
+ /**
+ * list of imported reference properties that might need correcting
+ */
+ private final ArrayList references;
+
+ public SessionImporter(NodeImpl importTargetNode,
+ SessionImpl session,
+ int uuidBehavior) {
+ this.importTargetNode = importTargetNode;
+ this.session = session;
+ this.uuidBehavior = uuidBehavior;
+
+ uuidMap = new HashMap();
+ references = new ArrayList();
+
+ parents = new Stack();
+ parents.push(importTargetNode);
+ }
+
+ protected NodeImpl createNode(NodeImpl parent,
+ QName nodeName,
+ QName nodeTypeName,
+ QName[] mixinNames,
+ String uuid)
+ throws RepositoryException {
+ NodeImpl node;
+ // add node
+ node = (NodeImpl) parent.addNode(nodeName, nodeTypeName, uuid);
+ // add mixins
+ if (mixinNames != null) {
+ for (int i = 0; i < mixinNames.length; i++) {
+ node.addMixin(mixinNames[i]);
+ }
+ }
+ return node;
+ }
+
+ protected NodeImpl resolveUUIDConflict(NodeImpl parent,
+ NodeImpl conflicting,
+ NodeInfo nodeInfo)
+ throws RepositoryException {
+ NodeImpl node;
+ if (uuidBehavior == IMPORT_UUID_CREATE_NEW) {
+ // create new with new uuid
+ node = createNode(parent, nodeInfo.getName(),
+ nodeInfo.getNodeTypeName(), nodeInfo.getMixinNames(), null);
+ // remember uuid mapping
+ if (node.isNodeType(Constants.MIX_REFERENCEABLE)) {
+ uuidMap.put(nodeInfo.getUUID(), node.getUUID());
+ }
+ } else if (uuidBehavior == IMPORT_UUID_COLLISION_THROW) {
+ String msg = "a node with uuid " + nodeInfo.getUUID() + " already exists!";
+ log.debug(msg);
+ throw new ItemExistsException(msg);
+ } else if (uuidBehavior == IMPORT_UUID_COLLISION_REMOVE_EXISTING) {
+ // make sure conflicting node is not importTargetNode or an ancestor thereof
+ if (importTargetNode.getPath().startsWith(conflicting.getPath())) {
+ String msg = "cannot remove ancestor node";
+ log.debug(msg);
+ throw new RepositoryException(msg);
+ }
+ // remove conflicting
+ conflicting.remove();
+ // create new with given uuid
+ node = createNode(parent, nodeInfo.getName(),
+ nodeInfo.getNodeTypeName(), nodeInfo.getMixinNames(),
+ nodeInfo.getUUID());
+ } else if (uuidBehavior == IMPORT_UUID_COLLISION_REPLACE_EXISTING) {
+ if (conflicting.isRepositoryRoot()) {
+ String msg = "root node cannot be replaced";
+ log.debug(msg);
+ throw new RepositoryException(msg);
+ }
+ // @todo implement IMPORT_UUID_COLLISION_REPLACE_EXISTING behavior
+ throw new RepositoryException("uuidBehavior IMPORT_UUID_COLLISION_REPLACE_EXISTING is not yet implemented");
+ } else {
+ String msg = "unknown uuidBehavior: " + uuidBehavior;
+ log.debug(msg);
+ throw new RepositoryException(msg);
+ }
+ return node;
+ }
+
+ //-------------------------------------------------------------< Importer >
+ /**
+ * @see Importer#start()
+ */
+ public void start() throws RepositoryException {
+ // nop
+ }
+
+ /**
+ * @see Importer#startNode(NodeInfo, List, NamespaceResolver)
+ */
+ public void startNode(NodeInfo nodeInfo, List propInfos,
+ NamespaceResolver nsContext)
+ throws RepositoryException {
+ NodeImpl parent = (NodeImpl) parents.peek();
+
+ // process node
+
+ NodeImpl node;
+ String uuid = nodeInfo.getUUID();
+ QName nodeName = nodeInfo.getName();
+ QName ntName = nodeInfo.getNodeTypeName();
+ QName[] mixins = nodeInfo.getMixinNames();
+ if (uuid == null) {
+ // no potential uuid conflict, always add new node
+ node = createNode(parent, nodeName, ntName, mixins, null);
+ } else {
+ // potential uuid conflict
+ NodeImpl conflicting;
+ try {
+ conflicting = (NodeImpl) session.getNodeByUUID(uuid);
+ } catch (ItemNotFoundException infe) {
+ conflicting = null;
+ }
+ if (conflicting != null) {
+ // resolve uuid conflict
+ node = resolveUUIDConflict(parent, conflicting, nodeInfo);
+ } else {
+ // create new with given uuid
+ node = createNode(parent, nodeName, ntName, mixins, uuid);
+ }
+ }
+
+ // process properties
+
+ Iterator iter = propInfos.iterator();
+ while (iter.hasNext()) {
+ PropInfo pi = (PropInfo) iter.next();
+ QName propName = pi.getName();
+ Value[] vals = pi.getValues();
+ int type = pi.getType();
+ if (node.hasProperty(propName)) {
+ PropertyDef def = node.getProperty(propName).getDefinition();
+ if (def.isProtected()) {
+ // skip protected property
+ log.debug("skipping protected property " + propName);
+ continue;
+ }
+ }
+ // multi- or single-valued property?
+ if (vals.length == 1) {
+ // could be single- or multi-valued (n == 1)
+ try {
+ // try setting single-value
+ node.setProperty(propName, vals[0]);
+ } catch (ValueFormatException vfe) {
+ // try setting value array
+ node.setProperty(propName, vals, type);
+ } catch (ConstraintViolationException vfe) {
+ // try setting value array
+ node.setProperty(propName, vals, type);
+ }
+ } else {
+ // can only be multi-valued (n == 0 || n > 1)
+ node.setProperty(propName, vals, type);
+ }
+ if (type == PropertyType.REFERENCE) {
+ // store reference for later resolution
+ references.add(node.getProperty(propName));
+ }
+ }
+
+ parents.push(node);
+ }
+
+ /**
+ * @see Importer#endNode(NodeInfo)
+ */
+ public void endNode(NodeInfo node) throws RepositoryException {
+ parents.pop();
+ }
+
+ /**
+ * @see Importer#end()
+ */
+ public void end() throws RepositoryException {
+ /**
+ * adjust references that refer to uuid's which have been mapped to
+ * newly gererated uuid's on import
+ */
+ Iterator iter = references.iterator();
+ while (iter.hasNext()) {
+ Property prop = (Property) iter.next();
+ // being paranoid...
+ if (prop.getType() != PropertyType.REFERENCE) {
+ continue;
+ }
+ if (prop.getDefinition().isMultiple()) {
+ Value[] values = prop.getValues();
+ Value[] newVals = new Value[values.length];
+ for (int i = 0; i < values.length; i++) {
+ Value val = values[i];
+ String original = val.getString();
+ String adjusted = (String) uuidMap.get(original);
+ if (adjusted != null) {
+ newVals[i] = new ReferenceValue(session.getNodeByUUID(adjusted));
+ } else {
+ // reference doesn't need adjusting, just copy old value
+ newVals[i] = val;
+ }
+ }
+ prop.setValue(newVals);
+ } else {
+ Value val = prop.getValue();
+ String original = val.getString();
+ String adjusted = (String) uuidMap.get(original);
+ if (adjusted != null) {
+ prop.setValue(session.getNodeByUUID(adjusted));
+ }
+ }
+ }
+ }
+}
Propchange: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/SessionImporter.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/SysViewImportHandler.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/SysViewImportHandler.java?view=diff&r1=154699&r2=154700
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/SysViewImportHandler.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/SysViewImportHandler.java Mon Feb 21 10:03:31 2005
@@ -16,8 +16,12 @@
*/
package org.apache.jackrabbit.core.xml;
-import org.apache.jackrabbit.core.*;
-import org.apache.jackrabbit.core.nodetype.NodeTypeImpl;
+import org.apache.jackrabbit.core.BaseException;
+import org.apache.jackrabbit.core.Constants;
+import org.apache.jackrabbit.core.IllegalNameException;
+import org.apache.jackrabbit.core.NamespaceResolver;
+import org.apache.jackrabbit.core.QName;
+import org.apache.jackrabbit.core.UnknownPrefixException;
import org.apache.jackrabbit.core.util.Base64;
import org.apache.jackrabbit.core.util.ValueHelper;
import org.apache.log4j.Logger;
@@ -26,21 +30,25 @@
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
-import javax.jcr.*;
-import javax.jcr.nodetype.ConstraintViolationException;
-import javax.jcr.nodetype.NodeDef;
-import javax.jcr.nodetype.PropertyDef;
+import javax.jcr.BinaryValue;
+import javax.jcr.InvalidSerializedDataException;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Stack;
/**
* <code>SysViewImportHandler</code> ...
*/
class SysViewImportHandler extends DefaultHandler implements Constants {
+
private static Logger log = Logger.getLogger(SysViewImportHandler.class);
- private SessionImpl session;
+ private final Importer importer;
+ private final NamespaceResolver nsContext;
/**
* stack of ImportState instances; an instance is pushed onto the stack
@@ -48,134 +56,156 @@
* the same instance is popped from the stack in the endElement method
* when the corresponding sv:node element is encountered.
*/
- private Stack stateStack = new Stack();
-
- /**
- * list of all reference properties that need to be adjusted
- */
- private LinkedList references = new LinkedList();
-
- /**
- * mapping <original uuid> to <new uuid> of mix:referenceable nodes
- */
- private HashMap referees = new HashMap();
+ private final Stack stack = new Stack();
/**
* fields used temporarily while processing sv:property and sv:value elements
*/
private QName currentPropName;
private int currentPropType = PropertyType.UNDEFINED;
- private ArrayList currentPropValues;
+ private ArrayList currentPropValues = new ArrayList();
private StringBuffer currentPropValue;
- SysViewImportHandler(NodeImpl importTargetNode, SessionImpl session) {
- ImportState state = new ImportState();
- state.node = importTargetNode;
- this.session = session;
- stateStack.push(state);
+ SysViewImportHandler(Importer importer, NamespaceResolver nsContext) {
+ this.importer = importer;
+ this.nsContext = nsContext;
+ }
+
+ private void processNode(ImportState state, boolean start, boolean end)
+ throws SAXException {
+ if (!start && !end) {
+ return;
+ }
+ Importer.NodeInfo node = new Importer.NodeInfo();
+ node.setName(state.nodeName);
+ node.setNodeTypeName(state.nodeTypeName);
+ if (state.mixinNames != null) {
+ QName[] mixins = (QName[]) state.mixinNames.toArray(new QName[state.mixinNames.size()]);
+ node.setMixinNames(mixins);
+ }
+ node.setUUID(state.uuid);
+ // call Importer
+ try {
+ if (start) {
+ importer.startNode(node, state.props, nsContext);
+ }
+ if (end) {
+ importer.endNode(node);
+ }
+ } catch (RepositoryException re) {
+ throw new SAXException(re);
+ }
}
//-------------------------------------------------------< ContentHandler >
/**
+ * @see ContentHandler#startDocument()
+ */
+ public void startDocument() throws SAXException {
+ try {
+ importer.start();
+ } catch (RepositoryException re) {
+ throw new SAXException(re);
+ }
+ }
+
+ /**
* @see ContentHandler#startElement(String, String, String, Attributes)
*/
public void startElement(String namespaceURI, String localName,
String qName, Attributes atts)
throws SAXException {
- try {
- String elemName;
- String nsURI;
- if (namespaceURI != null && !"".equals(namespaceURI)) {
- nsURI = namespaceURI;
- elemName = localName;
- } else {
- try {
- nsURI = QName.fromJCRName(qName, session.getNamespaceResolver()).getNamespaceURI();
- elemName = QName.fromJCRName(qName, session.getNamespaceResolver()).getLocalName();
- } catch (BaseException e) {
- // should never happen...
- String msg = "internal error: failed to parse/resolve element name " + qName;
- log.debug(msg);
- throw new SAXException(msg, e);
- }
+ String elemName;
+ String nsURI;
+ if (namespaceURI != null && !"".equals(namespaceURI)) {
+ nsURI = namespaceURI;
+ elemName = localName;
+ } else {
+ try {
+ nsURI = QName.fromJCRName(qName, nsContext).getNamespaceURI();
+ elemName = QName.fromJCRName(qName, nsContext).getLocalName();
+ } catch (BaseException e) {
+ // should never happen...
+ String msg = "internal error: failed to parse/resolve element name " + qName;
+ log.debug(msg);
+ throw new SAXException(msg, e);
}
- // check namespace
- if (!NS_SV_URI.equals(nsURI)) {
- throw new SAXException(new InvalidSerializedDataException("invalid namespace for element in system view xml document: " + nsURI));
+ }
+ // check namespace
+ if (!NS_SV_URI.equals(nsURI)) {
+ throw new SAXException(new InvalidSerializedDataException("invalid namespace for element in system view xml document: " + nsURI));
+ }
+ // check element name
+ if (SysViewSAXEventGenerator.NODE_ELEMENT.equals(elemName)) {
+ // sv:node element
+
+ // node name (value of sv:name attribute)
+ String name = atts.getValue(SysViewSAXEventGenerator.NS_SV_URI, SysViewSAXEventGenerator.NAME_ATTRIBUTE);
+ if (name == null) {
+ // try qualified name
+ name = atts.getValue(SysViewSAXEventGenerator.NS_SV_PREFIX + ":" + SysViewSAXEventGenerator.NAME_ATTRIBUTE);
+ }
+ if (name == null) {
+ throw new SAXException(new InvalidSerializedDataException("missing mandatory sv:name attributeof element sv:node"));
}
- // check element name
- if (SysViewSAXEventGenerator.NODE_ELEMENT.equals(elemName)) {
- // sv:node element
-
- // node name (value of sv:name attribute)
- String name = atts.getValue(SysViewSAXEventGenerator.NS_SV_URI, SysViewSAXEventGenerator.NAME_ATTRIBUTE);
- if (name == null) {
- // try qualified name
- name = atts.getValue(SysViewSAXEventGenerator.NS_SV_PREFIX + ":" + SysViewSAXEventGenerator.NAME_ATTRIBUTE);
- }
- if (name == null) {
- throw new SAXException(new InvalidSerializedDataException("missing mandatory sv:name attributeof element sv:node"));
- }
-
- ImportState current = (ImportState) stateStack.peek();
- if (current.node == null) {
- // need to create current node first
- createNode(current);
- }
-
- // push new ImportState instance onto the stack
- ImportState state = new ImportState();
- state.parent = current.node;
- try {
- state.nodeName = QName.fromJCRName(name, session.getNamespaceResolver());
- } catch (IllegalNameException ine) {
- throw new SAXException(new InvalidSerializedDataException("illegal node name: " + name, ine));
- } catch (UnknownPrefixException upe) {
- throw new SAXException(new InvalidSerializedDataException("illegal node name: " + name, upe));
- }
- stateStack.push(state);
- } else if (SysViewSAXEventGenerator.PROPERTY_ELEMENT.equals(elemName)) {
- // sv:property element
-
- // reset temp fields
- currentPropValues = new ArrayList();
- // property name (value of sv:name attribute)
- String name = atts.getValue(SysViewSAXEventGenerator.NS_SV_URI, SysViewSAXEventGenerator.NAME_ATTRIBUTE);
- if (name == null) {
- // try qualified name
- name = atts.getValue(SysViewSAXEventGenerator.NS_SV_PREFIX + ":" + SysViewSAXEventGenerator.NAME_ATTRIBUTE);
- }
- if (name == null) {
- throw new SAXException(new InvalidSerializedDataException("missing mandatory sv:name attributeof element sv:property"));
- }
- try {
- currentPropName = QName.fromJCRName(name, session.getNamespaceResolver());
- } catch (IllegalNameException ine) {
- throw new SAXException(new InvalidSerializedDataException("illegal property name: " + name, ine));
- } catch (UnknownPrefixException upe) {
- throw new SAXException(new InvalidSerializedDataException("illegal property name: " + name, upe));
- }
- // property type (sv:type attribute)
- String type = atts.getValue(SysViewSAXEventGenerator.NS_SV_URI, SysViewSAXEventGenerator.TYPE_ATTRIBUTE);
- if (type == null) {
- // try qualified name
- type = atts.getValue(SysViewSAXEventGenerator.NS_SV_PREFIX + ":" + SysViewSAXEventGenerator.TYPE_ATTRIBUTE);
- }
- if (type == null) {
- throw new SAXException(new InvalidSerializedDataException("missing mandatory sv:type attributeof element sv:property"));
- }
- currentPropType = PropertyType.valueFromName(type);
- } else if (SysViewSAXEventGenerator.VALUE_ELEMENT.equals(elemName)) {
- // sv:value element
+ if (!stack.isEmpty()) {
+ // process current node first
+ ImportState current = (ImportState) stack.peek();
+ // need to start current node
+ processNode(current, true, false);
+ current.started = true;
+ }
- // reset temp fields
- currentPropValue = new StringBuffer();
- } else {
- throw new SAXException(new InvalidSerializedDataException("unexpected element found in system view xml document: " + elemName));
+ // push new ImportState instance onto the stack
+ ImportState state = new ImportState();
+ try {
+ state.nodeName = QName.fromJCRName(name, nsContext);
+ } catch (IllegalNameException ine) {
+ throw new SAXException(new InvalidSerializedDataException("illegal node name: " + name, ine));
+ } catch (UnknownPrefixException upe) {
+ throw new SAXException(new InvalidSerializedDataException("illegal node name: " + name, upe));
}
- } catch (RepositoryException re) {
- throw new SAXException(re);
+ stack.push(state);
+ } else if (SysViewSAXEventGenerator.PROPERTY_ELEMENT.equals(elemName)) {
+ // sv:property element
+
+ // reset temp fields
+ currentPropValues.clear();
+
+ // property name (value of sv:name attribute)
+ String name = atts.getValue(SysViewSAXEventGenerator.NS_SV_URI, SysViewSAXEventGenerator.NAME_ATTRIBUTE);
+ if (name == null) {
+ // try qualified name
+ name = atts.getValue(SysViewSAXEventGenerator.NS_SV_PREFIX + ":" + SysViewSAXEventGenerator.NAME_ATTRIBUTE);
+ }
+ if (name == null) {
+ throw new SAXException(new InvalidSerializedDataException("missing mandatory sv:name attributeof element sv:property"));
+ }
+ try {
+ currentPropName = QName.fromJCRName(name, nsContext);
+ } catch (IllegalNameException ine) {
+ throw new SAXException(new InvalidSerializedDataException("illegal property name: " + name, ine));
+ } catch (UnknownPrefixException upe) {
+ throw new SAXException(new InvalidSerializedDataException("illegal property name: " + name, upe));
+ }
+ // property type (sv:type attribute)
+ String type = atts.getValue(SysViewSAXEventGenerator.NS_SV_URI, SysViewSAXEventGenerator.TYPE_ATTRIBUTE);
+ if (type == null) {
+ // try qualified name
+ type = atts.getValue(SysViewSAXEventGenerator.NS_SV_PREFIX + ":" + SysViewSAXEventGenerator.TYPE_ATTRIBUTE);
+ }
+ if (type == null) {
+ throw new SAXException(new InvalidSerializedDataException("missing mandatory sv:type attributeof element sv:property"));
+ }
+ currentPropType = PropertyType.valueFromName(type);
+ } else if (SysViewSAXEventGenerator.VALUE_ELEMENT.equals(elemName)) {
+ // sv:value element
+
+ // reset temp fields
+ currentPropValue = new StringBuffer();
+ } else {
+ throw new SAXException(new InvalidSerializedDataException("unexpected element found in system view xml document: " + elemName));
}
}
@@ -199,7 +229,7 @@
elemName = localName;
} else {
try {
- elemName = QName.fromJCRName(qName, session.getNamespaceResolver()).getLocalName();
+ elemName = QName.fromJCRName(qName, nsContext).getLocalName();
} catch (BaseException e) {
// should never happen...
String msg = "internal error: failed to parse/resolve element name " + qName;
@@ -208,15 +238,19 @@
}
}
// check element name
- ImportState current = (ImportState) stateStack.peek();
+ ImportState state = (ImportState) stack.peek();
if (SysViewSAXEventGenerator.NODE_ELEMENT.equals(elemName)) {
// sv:node element
- if (current.node == null) {
- // need to create current node first
- createNode(current);
+ if (!state.started) {
+ // need to start & end current node
+ processNode(state, true, true);
+ state.started = true;
+ } else {
+ // need to end current node
+ processNode(state, false, true);
}
// pop current state from stack
- stateStack.pop();
+ stack.pop();
} else if (SysViewSAXEventGenerator.PROPERTY_ELEMENT.equals(elemName)) {
// sv:property element
@@ -224,20 +258,20 @@
// have been collected and create node as necessary
if (currentPropName.equals(JCR_PRIMARYTYPE)) {
try {
- current.primaryType = QName.fromJCRName((String) currentPropValues.get(0), session.getNamespaceResolver());
+ state.nodeTypeName = QName.fromJCRName((String) currentPropValues.get(0), nsContext);
} catch (IllegalNameException ine) {
throw new SAXException(new InvalidSerializedDataException("illegal node type name: " + currentPropValues.get(0), ine));
} catch (UnknownPrefixException upe) {
throw new SAXException(new InvalidSerializedDataException("illegal node type name: " + currentPropValues.get(0), upe));
}
} else if (currentPropName.equals(JCR_MIXINTYPES)) {
- if (current.mixinTypes == null) {
- current.mixinTypes = new ArrayList(currentPropValues.size());
+ if (state.mixinNames == null) {
+ state.mixinNames = new ArrayList(currentPropValues.size());
}
for (int i = 0; i < currentPropValues.size(); i++) {
try {
- QName mixin = QName.fromJCRName((String) currentPropValues.get(i), session.getNamespaceResolver());
- current.mixinTypes.add(mixin);
+ QName mixin = QName.fromJCRName((String) currentPropValues.get(i), nsContext);
+ state.mixinNames.add(mixin);
} catch (IllegalNameException ine) {
throw new SAXException(new InvalidSerializedDataException("illegal mixin type name: " + currentPropValues.get(i), ine));
} catch (UnknownPrefixException upe) {
@@ -245,31 +279,8 @@
}
}
} else if (currentPropName.equals(JCR_UUID)) {
- current.uuid = (String) currentPropValues.get(0);
- // jcr:uuid is the last system property; we can assume that all
- // required system properties have been collected by now
- if (current.node == null) {
- // now that we've collected all required system properties
- // we're ready to create the node
- createNode(current);
- }
- } else if (currentPropName.equals(JCR_BASEVERSION)) {
- // ignore so far
- } else if (currentPropName.equals(JCR_VERSIONHISTORY)) {
- // ignore so far
- } else if (currentPropName.equals(JCR_PREDECESSORS)) {
- // ignore so far
- } else if (currentPropName.equals(JCR_ISCHECKEDOUT)) {
- // ignore so far
+ state.uuid = (String) currentPropValues.get(0);
} else {
- // non-system property encountered; we can assume that all
- // required system properties have been collected by now
- if (current.node == null) {
- // now that we've collected all required system properties
- // we're ready to create the node
- createNode(current);
- }
-
// convert values to native type and set property
Value[] vals = new Value[currentPropValues.size()];
for (int i = 0; i < currentPropValues.size(); i++) {
@@ -288,40 +299,16 @@
vals[i] = ValueHelper.convert(value, currentPropType);
}
}
- if (current.node.hasProperty(currentPropName)) {
- PropertyDef def = current.node.getProperty(currentPropName).getDefinition();
- if (def.isProtected()) {
- // ignore protected property
- // reset temp fields and get outta here
- currentPropValues = null;
- return;
- }
- }
- // multi- or single-valued property?
- if (vals.length == 1) {
- // could be single- or multi-valued (n == 1)
- try {
- // try setting single-value
- current.node.setProperty(currentPropName, vals[0]);
- } catch (ValueFormatException vfe) {
- // try setting value array
- current.node.setProperty(currentPropName, vals);
- } catch (ConstraintViolationException vfe) {
- // try setting value array
- current.node.setProperty(currentPropName, vals);
- }
- } else {
- // can only be multi-valued (n == 0 || n > 1)
- current.node.setProperty(currentPropName, vals);
- }
- if (currentPropType == PropertyType.REFERENCE) {
- // store reference for later resolution
- references.add(current.node.getProperty(currentPropName));
- }
+ Importer.PropInfo prop = new Importer.PropInfo();
+ prop.setName(currentPropName);
+ prop.setType(currentPropType);
+ prop.setValues(vals);
+
+ state.props.add(prop);
}
// reset temp fields
- currentPropValues = null;
+ currentPropValues.clear();
} else if (SysViewSAXEventGenerator.VALUE_ELEMENT.equals(elemName)) {
// sv:value element
currentPropValues.add(currentPropValue.toString());
@@ -340,91 +327,39 @@
*/
public void endDocument() throws SAXException {
try {
- // adjust all reference properties
- Iterator iter = references.iterator();
- while (iter.hasNext()) {
- Property prop = (Property) iter.next();
- if (prop.getDefinition().isMultiple()) {
- Value[] values = prop.getValues();
- Value[] newVals = new Value[values.length];
- for (int i = 0; i < values.length; i++) {
- Value val = values[i];
- if (val.getType() == PropertyType.REFERENCE) {
- String original = val.getString();
- String adjusted = (String) referees.get(original);
- if (adjusted == null) {
- log.warn("Reference " + original + " of property can not be adjusted! " + prop.getPath());
- newVals[i] = val;
- } else {
- newVals[i] = new ReferenceValue(session.getNodeByUUID(adjusted));
- }
- } else {
- newVals[i] = val;
- }
- }
- prop.setValue(newVals);
- } else {
- Value val = prop.getValue();
- if (val.getType() == PropertyType.REFERENCE) {
- String original = val.getString();
- String adjusted = (String) referees.get(original);
- if (adjusted == null) {
- log.warn("Reference " + original + " of property can not be adjusted! " + prop.getPath());
- } else {
- prop.setValue(session.getNodeByUUID(adjusted));
- }
- }
- }
- }
+ importer.end();
} catch (RepositoryException re) {
- throw new SAXException("failed to adjust REFERENCE properties", re);
- }
- }
-
- private void createNode(ImportState state) throws RepositoryException {
- if (state.primaryType == null) {
- throw new InvalidSerializedDataException("missing mandatory jcr:primaryType property");
- }
- if (state.uuid != null) {
- // @todo what are the semantics of the uuid with respect to import?
- // move existing node with given uuid to current position?
- // create with new uuid? what about reference values refering to given uuid?
- }
- if (state.parent.hasNode(state.nodeName)) {
- state.node = state.parent.getNode(state.nodeName);
- NodeDef def = state.node.getDefinition();
- if (def.isProtected() || def.isAutoCreate()) {
- // @todo how to handle protected/auto-created child node?
- state.node = (NodeImpl) state.parent.getNode(state.nodeName);
- } else if (!def.allowSameNameSibs()) {
- throw new ItemExistsException(state.parent.safeGetJCRPath() + "/" + state.nodeName);
- }
- }
- if (state.node == null) {
- state.node = (NodeImpl) state.parent.addNode(state.nodeName, state.primaryType);
- if (state.mixinTypes != null) {
- for (int i = 0; i < state.mixinTypes.size(); i++) {
- NodeTypeImpl mixin = session.getNodeTypeManager().getNodeType((QName) state.mixinTypes.get(i));
- state.node.addMixin(mixin.getName());
- }
- }
- }
-
- // check for mix:referenceable
- if (state.node.isNodeType(MIX_REFERENCEABLE)) {
- log.info("adding refereee: ori=" + state.uuid + " new=" + state.node.getUUID());
- referees.put(state.uuid, state.node.getUUID());
+ throw new SAXException(re);
}
}
//--------------------------------------------------------< inner classes >
class ImportState {
- QName primaryType = null;
- ArrayList mixinTypes = null;
- String uuid = null;
-
- QName nodeName = null;
- NodeImpl parent = null;
- NodeImpl node = null;
+ /**
+ * name of current node
+ */
+ QName nodeName;
+ /**
+ * primary type of current node
+ */
+ QName nodeTypeName;
+ /**
+ * list of mixin types of current node
+ */
+ ArrayList mixinNames;
+ /**
+ * uuid of current node
+ */
+ String uuid;
+
+ /**
+ * list of PropInfo instances representing properties of current node
+ */
+ ArrayList props = new ArrayList();
+
+ /**
+ * flag indicating whether startNode() has been called for current node
+ */
+ boolean started = false;
}
}