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 [1/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
Author: stefan
Date: Mon Feb 21 10:03:31 2005
New Revision: 154700
URL: http://svn.apache.org/viewcvs?view=rev&rev=154700
Log:
reimplementing Session.importXML & friends due to spec changes
Added:
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/LocalNamespaceMappings.java (with props)
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/Importer.java (with props)
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/SessionImporter.java (with props)
Modified:
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NodeImpl.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/QName.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/SessionImpl.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/NodeDefImpl.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/builtin_nodetypes.xml
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/DocViewImportHandler.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/ImportHandler.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/SysViewImportHandler.java
Added: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/LocalNamespaceMappings.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/LocalNamespaceMappings.java?view=auto&rev=154700
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/LocalNamespaceMappings.java (added)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/LocalNamespaceMappings.java Mon Feb 21 10:03:31 2005
@@ -0,0 +1,201 @@
+/*
+ * 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;
+
+import org.apache.xerces.util.XMLChar;
+
+import javax.jcr.NamespaceException;
+import javax.jcr.RepositoryException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * <code>LocalNamespaceMappings</code> ...
+ */
+class LocalNamespaceMappings implements NamespaceResolver {
+
+ // the global persistent namespace registry
+ private final NamespaceRegistryImpl nsReg;
+
+ // local prefix/namespace mappings
+ private final HashMap prefixToURI = new HashMap();
+ private final HashMap uriToPrefix = new HashMap();
+
+ // prefixes in global namespace registry hidden by local mappings
+ private Set hiddenPrefixes = new HashSet();
+
+ /**
+ * Constructor
+ *
+ * @param nsReg
+ */
+ LocalNamespaceMappings(NamespaceRegistryImpl nsReg) {
+ this.nsReg = nsReg;
+ }
+
+ /**
+ * Rename a persistently registered namespace URI to the new prefix.
+ *
+ * @param prefix
+ * @param uri
+ * @throws NamespaceException
+ * @throws RepositoryException
+ */
+ void setNamespacePrefix(String prefix, String uri)
+ throws NamespaceException, RepositoryException {
+ if (prefix == null || uri == null) {
+ throw new IllegalArgumentException("prefix/uri can not be null");
+ }
+ if (Constants.NS_EMPTY_PREFIX.equals(prefix)
+ || Constants.NS_DEFAULT_URI.equals(uri)) {
+ throw new NamespaceException("default namespace is reserved and can not be changed");
+ }
+ // special case: prefixes xml*
+ if (prefix.toLowerCase().startsWith(Constants.NS_XML_PREFIX)) {
+ throw new NamespaceException("reserved prefix: " + prefix);
+ }
+ // check if the prefix is a valid XML prefix
+ if (!XMLChar.isValidNCName(prefix)) {
+ throw new NamespaceException("invalid prefix: " + prefix);
+ }
+
+ // check if namespace exists (the following call will
+ // trigger a NamespaceException if it doesn't)
+ String globalPrefix = nsReg.getPrefix(uri);
+
+ // check new prefix for collision
+ String globalURI = null;
+ try {
+ globalURI = nsReg.getURI(prefix);
+ } catch (NamespaceException nse) {
+ // ignore
+ }
+ if (globalURI != null) {
+ // prefix is already mapped in global namespace registry;
+ // check if it is redundant or if it refers to a namespace
+ // that has been locally remapped, thus hiding it
+ if (!hiddenPrefixes.contains(prefix)) {
+ if (uri.equals(globalURI) && prefix.equals(globalPrefix)) {
+ // redundant mapping, silently ignore
+ return;
+ }
+ // we don't allow to hide a namespace because we can't
+ // guarantee that there are no references to it
+ // (in names of nodes/properties/node types etc.)
+ throw new NamespaceException(prefix + ": prefix is already mapped to the namespace: " + globalURI);
+ }
+ }
+
+ // check if namespace is already locally mapped
+ String oldPrefix = (String) uriToPrefix.get(uri);
+ if (oldPrefix != null) {
+ if (oldPrefix.equals(prefix)) {
+ // redundant mapping, silently ignore
+ return;
+ }
+ // resurrect hidden global prefix
+ hiddenPrefixes.remove(nsReg.getPrefix(uri));
+ // remove old mapping
+ uriToPrefix.remove(uri);
+ prefixToURI.remove(oldPrefix);
+ }
+
+ // check if prefix is already locally mapped
+ String oldURI = (String) prefixToURI.get(prefix);
+ if (oldURI != null) {
+ // resurrect hidden global prefix
+ hiddenPrefixes.remove(nsReg.getPrefix(oldURI));
+ // remove old mapping
+ uriToPrefix.remove(oldURI);
+ prefixToURI.remove(prefix);
+ }
+
+ if (!prefix.equals(globalPrefix)) {
+ // store new mapping
+ prefixToURI.put(prefix, uri);
+ uriToPrefix.put(uri, prefix);
+ hiddenPrefixes.add(globalPrefix);
+ }
+ }
+
+ /**
+ * Returns all prefixes.
+ *
+ * @return
+ * @throws RepositoryException
+ */
+ String[] getPrefixes() throws RepositoryException {
+ if (prefixToURI.isEmpty()) {
+ // shortcut
+ return nsReg.getPrefixes();
+ }
+
+ HashSet prefixes = new HashSet();
+ // global prefixes
+ String[] globalPrefixes = nsReg.getPrefixes();
+ for (int i = 0; i < globalPrefixes.length; i++) {
+ if (!hiddenPrefixes.contains(globalPrefixes[i])) {
+ prefixes.add(globalPrefixes[i]);
+ }
+ }
+ // local prefixes
+ prefixes.addAll(prefixToURI.keySet());
+
+ return (String[]) prefixes.toArray(new String[prefixes.size()]);
+ }
+
+ //----------------------------------------------------< NamespaceResolver >
+ /**
+ * @see NamespaceResolver#getURI
+ */
+ public String getURI(String prefix) throws NamespaceException {
+ if (prefixToURI.isEmpty()) {
+ // shortcut
+ return nsReg.getURI(prefix);
+ }
+ // check local mappings
+ if (prefixToURI.containsKey(prefix)) {
+ return (String) prefixToURI.get(prefix);
+ }
+
+ // check global mappings
+ if (!hiddenPrefixes.contains(prefix)) {
+ return nsReg.getURI(prefix);
+ }
+
+ throw new NamespaceException(prefix + ": unknown prefix");
+ }
+
+ /**
+ * @see NamespaceResolver#getPrefix
+ */
+ public String getPrefix(String uri) throws NamespaceException {
+ if (prefixToURI.isEmpty()) {
+ // shortcut
+ return nsReg.getPrefix(uri);
+ }
+
+ // check local mappings
+ if (uriToPrefix.containsKey(uri)) {
+ return (String) uriToPrefix.get(uri);
+ }
+
+ // check global mappings
+ return nsReg.getPrefix(uri);
+ }
+}
Propchange: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/LocalNamespaceMappings.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NodeImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NodeImpl.java?view=diff&r1=154699&r2=154700
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NodeImpl.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NodeImpl.java Mon Feb 21 10:03:31 2005
@@ -16,24 +16,77 @@
*/
package org.apache.jackrabbit.core;
-import org.apache.jackrabbit.core.nodetype.*;
-import org.apache.jackrabbit.core.state.*;
+import org.apache.jackrabbit.core.nodetype.ChildNodeDef;
+import org.apache.jackrabbit.core.nodetype.EffectiveNodeType;
+import org.apache.jackrabbit.core.nodetype.NodeDefId;
+import org.apache.jackrabbit.core.nodetype.NodeDefImpl;
+import org.apache.jackrabbit.core.nodetype.NodeTypeConflictException;
+import org.apache.jackrabbit.core.nodetype.NodeTypeImpl;
+import org.apache.jackrabbit.core.nodetype.NodeTypeManagerImpl;
+import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
+import org.apache.jackrabbit.core.nodetype.PropDef;
+import org.apache.jackrabbit.core.nodetype.PropDefId;
+import org.apache.jackrabbit.core.nodetype.PropertyDefImpl;
+import org.apache.jackrabbit.core.state.ItemState;
+import org.apache.jackrabbit.core.state.ItemStateException;
+import org.apache.jackrabbit.core.state.NodeReferences;
+import org.apache.jackrabbit.core.state.NodeReferencesId;
+import org.apache.jackrabbit.core.state.NodeState;
+import org.apache.jackrabbit.core.state.PropertyState;
import org.apache.jackrabbit.core.util.ChildrenCollectorFilter;
import org.apache.jackrabbit.core.util.IteratorHelper;
import org.apache.jackrabbit.core.util.uuid.UUID;
-import org.apache.jackrabbit.core.version.*;
+import org.apache.jackrabbit.core.version.GenericVersionSelector;
+import org.apache.jackrabbit.core.version.InternalFreeze;
+import org.apache.jackrabbit.core.version.InternalFrozenNode;
+import org.apache.jackrabbit.core.version.InternalFrozenVersionHistory;
+import org.apache.jackrabbit.core.version.InternalVersion;
+import org.apache.jackrabbit.core.version.VersionHistoryImpl;
+import org.apache.jackrabbit.core.version.VersionImpl;
+import org.apache.jackrabbit.core.version.VersionSelector;
import org.apache.log4j.Logger;
-import javax.jcr.*;
+import javax.jcr.AccessDeniedException;
+import javax.jcr.InvalidItemStateException;
+import javax.jcr.Item;
+import javax.jcr.ItemExistsException;
+import javax.jcr.ItemNotFoundException;
+import javax.jcr.ItemVisitor;
+import javax.jcr.MergeException;
+import javax.jcr.NoSuchWorkspaceException;
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.Property;
+import javax.jcr.PropertyIterator;
+import javax.jcr.PropertyType;
+import javax.jcr.ReferenceValue;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.Value;
+import javax.jcr.ValueFormatException;
import javax.jcr.lock.Lock;
import javax.jcr.lock.LockException;
-import javax.jcr.nodetype.*;
+import javax.jcr.nodetype.ConstraintViolationException;
+import javax.jcr.nodetype.NoSuchNodeTypeException;
+import javax.jcr.nodetype.NodeDef;
+import javax.jcr.nodetype.NodeType;
+import javax.jcr.nodetype.PropertyDef;
import javax.jcr.version.OnParentVersionAction;
import javax.jcr.version.Version;
import javax.jcr.version.VersionException;
import javax.jcr.version.VersionHistory;
import java.io.InputStream;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.BitSet;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
/**
* <code>NodeImpl</code> implements the <code>Node</code> interface.
@@ -359,7 +412,7 @@
String parentUUID = ((NodeState) state).getUUID();
// create a new property state
- PropertyState propState = null;
+ PropertyState propState;
try {
propState = stateMgr.createTransientPropertyState(parentUUID, name, ItemState.STATUS_NEW);
propState.setType(type);
@@ -402,7 +455,7 @@
throws RepositoryException {
String parentUUID = ((NodeState) state).getUUID();
// create a new node state
- NodeState nodeState = null;
+ NodeState nodeState;
try {
if (uuid == null) {
uuid = UUID.randomUUID().toString(); // version 4 uuid
@@ -705,7 +758,7 @@
private void setMixinTypesProperty(Set mixinNames) throws RepositoryException {
NodeState thisState = (NodeState) state;
// get or create jcr:mixinTypes property
- PropertyImpl prop = null;
+ PropertyImpl prop;
if (thisState.hasPropertyEntry(JCR_MIXINTYPES)) {
prop = (PropertyImpl) itemMgr.getItem(new PropertyId(thisState.getUUID(), JCR_MIXINTYPES));
} else {
@@ -838,6 +891,222 @@
}
/**
+ * Same as {@link Node#addMixin(String)}, but takes a <code>QName</code>
+ * instad of a <code>String</code>.
+ *
+ * @see Node#addMixin(String)
+ */
+ public void addMixin(QName mixinName)
+ throws NoSuchNodeTypeException, VersionException,
+ ConstraintViolationException, LockException, RepositoryException {
+ // check state of this instance
+ sanityCheck();
+
+ // make sure this node is checked-out
+ if (!internalIsCheckedOut()) {
+ String msg = safeGetJCRPath() + ": cannot add a mixin node type to a checked-in node";
+ log.debug(msg);
+ throw new VersionException(msg);
+ }
+
+ // check protected flag
+ if (definition.isProtected()) {
+ String msg = safeGetJCRPath() + ": cannot add a mixin node type to a protected node";
+ log.debug(msg);
+ throw new ConstraintViolationException(msg);
+ }
+
+ NodeTypeManagerImpl ntMgr = session.getNodeTypeManager();
+ NodeTypeImpl mixin = ntMgr.getNodeType(mixinName);
+ if (!mixin.isMixin()) {
+ throw new RepositoryException(mixinName + ": not a mixin node type");
+ }
+ if (nodeType.isDerivedFrom(mixinName)) {
+ throw new RepositoryException(mixinName + ": already contained in primary node type");
+ }
+
+ // build effective node type of mixin's & primary type in order to detect conflicts
+ NodeTypeRegistry ntReg = ntMgr.getNodeTypeRegistry();
+ EffectiveNodeType entExisting;
+ try {
+ // existing mixin's
+ HashSet set = new HashSet(((NodeState) state).getMixinTypeNames());
+ // primary type
+ set.add(nodeType.getQName());
+ // build effective node type representing primary type including existing mixin's
+ entExisting = ntReg.getEffectiveNodeType((QName[]) set.toArray(new QName[set.size()]));
+ if (entExisting.includesNodeType(mixinName)) {
+ throw new RepositoryException(mixinName + ": already contained in mixin types");
+ }
+ // add new mixin
+ set.add(mixinName);
+ // try to build new effective node type (will throw in case of conflicts)
+ ntReg.getEffectiveNodeType((QName[]) set.toArray(new QName[set.size()]));
+ } catch (NodeTypeConflictException ntce) {
+ throw new ConstraintViolationException(ntce.getMessage());
+ }
+
+ // do the actual modifications implied by the new mixin;
+ // try to revert the changes in case an excpetion occurs
+ try {
+ // modify the state of this node
+ NodeState thisState = (NodeState) getOrCreateTransientItemState();
+ // add mixin name
+ Set mixins = new HashSet(thisState.getMixinTypeNames());
+ mixins.add(mixinName);
+ thisState.setMixinTypeNames(mixins);
+
+ // set jcr:mixinTypes property
+ setMixinTypesProperty(mixins);
+
+ // add 'auto-create' properties defined in mixin type
+ PropertyDef[] pda = mixin.getAutoCreatePropertyDefs();
+ for (int i = 0; i < pda.length; i++) {
+ PropertyDefImpl pd = (PropertyDefImpl) pda[i];
+ // make sure that the property is not already defined by primary type
+ // or existing mixin's
+ NodeTypeImpl declaringNT = (NodeTypeImpl) pd.getDeclaringNodeType();
+ if (!entExisting.includesNodeType(declaringNT.getQName())) {
+ createChildProperty(pd.getQName(), pd.getRequiredType(), pd);
+ }
+ }
+
+ // recursively add 'auto-create' child nodes defined in mixin type
+ NodeDef[] nda = mixin.getAutoCreateNodeDefs();
+ for (int i = 0; i < nda.length; i++) {
+ NodeDefImpl nd = (NodeDefImpl) nda[i];
+ // make sure that the child node is not already defined by primary type
+ // or existing mixin's
+ NodeTypeImpl declaringNT = (NodeTypeImpl) nd.getDeclaringNodeType();
+ if (!entExisting.includesNodeType(declaringNT.getQName())) {
+ createChildNode(nd.getQName(), nd, (NodeTypeImpl) nd.getDefaultPrimaryType(), null);
+ }
+ }
+ } catch (RepositoryException re) {
+ // try to undo the modifications by removing the mixin
+ try {
+ removeMixin(mixinName);
+ } catch (RepositoryException re1) {
+ // silently ignore & fall through
+ }
+ throw re;
+ }
+ }
+
+ /**
+ * Same as {@link Node#removeMixin(String)}, but takes a <code>QName</code>
+ * instad of a <code>String</code>.
+ *
+ * @see Node#removeMixin(String)
+ */
+ public void removeMixin(QName mixinName)
+ throws NoSuchNodeTypeException, VersionException,
+ ConstraintViolationException, LockException, RepositoryException {
+ // check state of this instance
+ sanityCheck();
+
+ // make sure this node is checked-out
+ if (!internalIsCheckedOut()) {
+ String msg = safeGetJCRPath() + ": cannot remove a mixin node type from a checked-in node";
+ log.debug(msg);
+ throw new VersionException(msg);
+ }
+
+ // check protected flag
+ if (definition.isProtected()) {
+ String msg = safeGetJCRPath() + ": cannot remove a mixin node type from a protected node";
+ log.debug(msg);
+ throw new ConstraintViolationException(msg);
+ }
+
+ // check if mixin is assigned
+ if (!((NodeState) state).getMixinTypeNames().contains(mixinName)) {
+ throw new NoSuchNodeTypeException();
+ }
+
+ if (MIX_REFERENCEABLE.equals(mixinName)) {
+ /**
+ * mix:referenceable needs special handling because it has
+ * special semantics:
+ * it can only be removed if there no more references to this node
+ */
+ PropertyIterator iter = getReferences();
+ if (iter.hasNext()) {
+ throw new ConstraintViolationException(mixinName + " can not be removed: the node is being referenced through at least one property of type REFERENCE");
+ }
+ }
+
+ // modify the state of this node
+ NodeState thisState = (NodeState) getOrCreateTransientItemState();
+ // remove mixin name
+ Set mixins = new HashSet(thisState.getMixinTypeNames());
+ mixins.remove(mixinName);
+ thisState.setMixinTypeNames(mixins);
+
+ // set jcr:mixinTypes property
+ setMixinTypesProperty(mixins);
+
+ // build effective node type of remaining mixin's & primary type
+ NodeTypeManagerImpl ntMgr = session.getNodeTypeManager();
+ NodeTypeRegistry ntReg = ntMgr.getNodeTypeRegistry();
+ EffectiveNodeType entRemaining;
+ try {
+ // remaining mixin's
+ HashSet set = new HashSet(mixins);
+ // primary type
+ set.add(nodeType.getQName());
+ // build effective node type representing primary type including remaining mixin's
+ entRemaining = ntReg.getEffectiveNodeType((QName[]) set.toArray(new QName[set.size()]));
+ } catch (NodeTypeConflictException ntce) {
+ throw new ConstraintViolationException(ntce.getMessage());
+ }
+
+ NodeTypeImpl mixin = session.getNodeTypeManager().getNodeType(mixinName);
+
+ // shortcut
+ if (mixin.getChildNodeDefs().length == 0
+ && mixin.getPropertyDefs().length == 0) {
+ // the node type has neither property nor child node definitions,
+ // i.e. we're done
+ return;
+ }
+
+ // walk through properties and child nodes and remove those that have been
+ // defined by the specified mixin type
+
+ // use temp array to avoid ConcurrentModificationException
+ ArrayList tmp = new ArrayList(thisState.getPropertyEntries());
+ Iterator iter = tmp.iterator();
+ while (iter.hasNext()) {
+ NodeState.PropertyEntry entry = (NodeState.PropertyEntry) iter.next();
+ PropertyImpl prop = (PropertyImpl) itemMgr.getItem(new PropertyId(thisState.getUUID(), entry.getName()));
+ // check if property has been defined by mixin type (or one of its supertypes)
+ NodeTypeImpl declaringNT = (NodeTypeImpl) prop.getDefinition().getDeclaringNodeType();
+ if (!entRemaining.includesNodeType(declaringNT.getQName())) {
+ // the remaining effective node type doesn't include the
+ // node type that declared this property, it is thus safe
+ // to remove it
+ removeChildProperty(entry.getName());
+ }
+ }
+ // use temp array to avoid ConcurrentModificationException
+ tmp = new ArrayList(thisState.getChildNodeEntries());
+ iter = tmp.iterator();
+ while (iter.hasNext()) {
+ NodeState.ChildNodeEntry entry = (NodeState.ChildNodeEntry) iter.next();
+ NodeImpl node = (NodeImpl) itemMgr.getItem(new NodeId(entry.getUUID()));
+ // check if node has been defined by mixin type (or one of its supertypes)
+ NodeTypeImpl declaringNT = (NodeTypeImpl) node.getDefinition().getDeclaringNodeType();
+ if (!entRemaining.includesNodeType(declaringNT.getQName())) {
+ // the remaining effective node type doesn't include the
+ // node type that declared this child node, it is thus safe
+ // to remove it
+ removeChildNode(entry.getName(), entry.getIndex());
+ }
+ }
+ }
+
+ /**
* Same as {@link Node#isNodeType(String)}, but takes a <code>QName</code>
* instad of a <code>String</code>.
*
@@ -1106,20 +1375,30 @@
}
/**
- * Same as <code>{@link Node#addNode(String)}</code> except that
- * this method takes a <code>QName</code> name argument instead of a
- * <code>String</code>.
- *
- * @param nodeName
- * @return
+ * Same as <code>{@link Node#addNode(String, String)}</code> except that
+ * this method takes <code>QName</code> arguments instead of
+ * <code>String</code>s and has an additional <code>uuid</code> argument.
+ * <p/>
+ * <b>Important Notice:</b> This method is for internal use only! Passing
+ * already assigned uuid's might lead to unexpected results and
+ * data corruption in the worst case.
+ *
+ * @param nodeName name of the new node
+ * @param nodeTypeName name of the new node's node type or <code>null</code>
+ * if it should be determined automatically
+ * @param uuid uuid of the new node or <code>null</code> if a new
+ * uuid should be assigned
+ * @return the newly added node
* @throws ItemExistsException
+ * @throws NoSuchNodeTypeException
* @throws VersionException
* @throws ConstraintViolationException
* @throws LockException
* @throws RepositoryException
*/
- public synchronized NodeImpl addNode(QName nodeName)
- throws ItemExistsException, VersionException,
+ public synchronized NodeImpl addNode(QName nodeName, QName nodeTypeName,
+ String uuid)
+ throws ItemExistsException, NoSuchNodeTypeException, VersionException,
ConstraintViolationException, LockException, RepositoryException {
// check state of this instance
sanityCheck();
@@ -1131,55 +1410,51 @@
throw new VersionException(msg);
}
- return internalAddChildNode(nodeName, null);
+ NodeTypeImpl nt = (nodeTypeName == null) ?
+ null : session.getNodeTypeManager().getNodeType(nodeTypeName);
+ return internalAddChildNode(nodeName, nt, uuid);
}
/**
- * Same as <code>{@link Node#addNode(String, String)}</code> except that
- * this method takes a <code>QName</code> arguments instead of a
- * <code>String</code>s.
+ * Same as <code>{@link Node#setProperty(String, Value[])}</code> except that
+ * this method takes a <code>QName</code> name argument instead of a
+ * <code>String</code>.
*
- * @param nodeName
- * @param nodeTypeName
+ * @param name
+ * @param values
* @return
- * @throws ItemExistsException
- * @throws NoSuchNodeTypeException
+ * @throws ValueFormatException
* @throws VersionException
- * @throws ConstraintViolationException
* @throws LockException
* @throws RepositoryException
*/
- public synchronized NodeImpl addNode(QName nodeName, QName nodeTypeName)
- throws ItemExistsException, NoSuchNodeTypeException, VersionException,
- ConstraintViolationException, LockException, RepositoryException {
- // check state of this instance
- sanityCheck();
-
- // make sure this node is checked-out
- if (!internalIsCheckedOut()) {
- String msg = safeGetJCRPath() + ": cannot add node to a checked-in node";
- log.debug(msg);
- throw new VersionException(msg);
+ public PropertyImpl setProperty(QName name, Value[] values)
+ throws ValueFormatException, VersionException, LockException,
+ RepositoryException {
+ int type;
+ if (values == null || values.length == 0) {
+ type = PropertyType.UNDEFINED;
+ } else {
+ type = values[0].getType();
}
-
- NodeTypeImpl nt = session.getNodeTypeManager().getNodeType(nodeTypeName);
- return internalAddChildNode(nodeName, nt);
+ return setProperty(name, values, type);
}
/**
- * Same as <code>{@link Node#setProperty(String, Value[])}</code> except that
- * this method takes a <code>QName</code> name argument instead of a
+ * Same as <code>{@link Node#setProperty(String, Value[], int)}</code> except
+ * that this method takes a <code>QName</code> name argument instead of a
* <code>String</code>.
*
* @param name
* @param values
+ * @param type
* @return
* @throws ValueFormatException
* @throws VersionException
* @throws LockException
* @throws RepositoryException
*/
- public PropertyImpl setProperty(QName name, Value[] values)
+ public PropertyImpl setProperty(QName name, Value[] values, int type)
throws ValueFormatException, VersionException, LockException,
RepositoryException {
// check state of this instance
@@ -1192,12 +1467,6 @@
throw new VersionException(msg);
}
- int type;
- if (values == null || values.length == 0) {
- type = PropertyType.UNDEFINED;
- } else {
- type = values[0].getType();
- }
BitSet status = new BitSet();
PropertyImpl prop = getOrCreateProperty(name, type, true, status);
try {
@@ -2043,23 +2312,6 @@
public void addMixin(String mixinName)
throws NoSuchNodeTypeException, VersionException,
ConstraintViolationException, LockException, RepositoryException {
- // check state of this instance
- sanityCheck();
-
- // make sure this node is checked-out
- if (!internalIsCheckedOut()) {
- String msg = safeGetJCRPath() + ": cannot add a mixin node type to a checked-in node";
- log.debug(msg);
- throw new VersionException(msg);
- }
-
- // check protected flag
- if (definition.isProtected()) {
- String msg = safeGetJCRPath() + ": cannot add a mixin node type to a protected node";
- log.debug(msg);
- throw new ConstraintViolationException(msg);
- }
-
QName ntName;
try {
ntName = QName.fromJCRName(mixinName, session.getNamespaceResolver());
@@ -2069,81 +2321,7 @@
throw new RepositoryException("invalid mixin type name: " + mixinName, upe);
}
- NodeTypeManagerImpl ntMgr = session.getNodeTypeManager();
- NodeTypeImpl mixin = ntMgr.getNodeType(ntName);
- if (!mixin.isMixin()) {
- throw new RepositoryException(mixinName + ": not a mixin node type");
- }
- if (nodeType.isDerivedFrom(ntName)) {
- throw new RepositoryException(mixinName + ": already contained in primary node type");
- }
-
- // build effective node type of mixin's & primary type in order to detect conflicts
- NodeTypeRegistry ntReg = ntMgr.getNodeTypeRegistry();
- EffectiveNodeType entExisting;
- try {
- // existing mixin's
- HashSet set = new HashSet(((NodeState) state).getMixinTypeNames());
- // primary type
- set.add(nodeType.getQName());
- // build effective node type representing primary type including existing mixin's
- entExisting = ntReg.getEffectiveNodeType((QName[]) set.toArray(new QName[set.size()]));
- if (entExisting.includesNodeType(ntName)) {
- throw new RepositoryException(mixinName + ": already contained in mixin types");
- }
- // add new mixin
- set.add(ntName);
- // try to build new effective node type (will throw in case of conflicts)
- ntReg.getEffectiveNodeType((QName[]) set.toArray(new QName[set.size()]));
- } catch (NodeTypeConflictException ntce) {
- throw new ConstraintViolationException(ntce.getMessage());
- }
-
- // do the actual modifications implied by the new mixin;
- // try to revert the changes in case an excpetion occurs
- try {
- // modify the state of this node
- NodeState thisState = (NodeState) getOrCreateTransientItemState();
- // add mixin name
- Set mixins = new HashSet(thisState.getMixinTypeNames());
- mixins.add(ntName);
- thisState.setMixinTypeNames(mixins);
-
- // set jcr:mixinTypes property
- setMixinTypesProperty(mixins);
-
- // add 'auto-create' properties defined in mixin type
- PropertyDef[] pda = mixin.getAutoCreatePropertyDefs();
- for (int i = 0; i < pda.length; i++) {
- PropertyDefImpl pd = (PropertyDefImpl) pda[i];
- // make sure that the property is not already defined by primary type
- // or existing mixin's
- NodeTypeImpl declaringNT = (NodeTypeImpl) pd.getDeclaringNodeType();
- if (!entExisting.includesNodeType(declaringNT.getQName())) {
- createChildProperty(pd.getQName(), pd.getRequiredType(), pd);
- }
- }
-
- // recursively add 'auto-create' child nodes defined in mixin type
- NodeDef[] nda = mixin.getAutoCreateNodeDefs();
- for (int i = 0; i < nda.length; i++) {
- NodeDefImpl nd = (NodeDefImpl) nda[i];
- // make sure that the child node is not already defined by primary type
- // or existing mixin's
- NodeTypeImpl declaringNT = (NodeTypeImpl) nd.getDeclaringNodeType();
- if (!entExisting.includesNodeType(declaringNT.getQName())) {
- createChildNode(nd.getQName(), nd, (NodeTypeImpl) nd.getDefaultPrimaryType(), null);
- }
- }
- } catch (RepositoryException re) {
- // try to undo the modifications by removing the mixin
- try {
- removeMixin(mixinName);
- } catch (RepositoryException re1) {
- // silently ignore & fall through
- }
- throw re;
- }
+ addMixin(ntName);
}
/**
@@ -2152,23 +2330,6 @@
public void removeMixin(String mixinName)
throws NoSuchNodeTypeException, VersionException,
ConstraintViolationException, LockException, RepositoryException {
- // check state of this instance
- sanityCheck();
-
- // make sure this node is checked-out
- if (!internalIsCheckedOut()) {
- String msg = safeGetJCRPath() + ": cannot remove a mixin node type from a checked-in node";
- log.debug(msg);
- throw new VersionException(msg);
- }
-
- // check protected flag
- if (definition.isProtected()) {
- String msg = safeGetJCRPath() + ": cannot remove a mixin node type from a protected node";
- log.debug(msg);
- throw new ConstraintViolationException(msg);
- }
-
QName ntName;
try {
ntName = QName.fromJCRName(mixinName, session.getNamespaceResolver());
@@ -2178,91 +2339,7 @@
throw new RepositoryException("invalid mixin type name: " + mixinName, upe);
}
- // check if mixin is assigned
- if (!((NodeState) state).getMixinTypeNames().contains(ntName)) {
- throw new NoSuchNodeTypeException(mixinName);
- }
-
- if (MIX_REFERENCEABLE.equals(ntName)) {
- /**
- * mix:referenceable needs special handling because it has
- * special semantics:
- * it can only be removed if there no more references to this node
- */
- PropertyIterator iter = getReferences();
- if (iter.hasNext()) {
- throw new ConstraintViolationException(mixinName + " can not be removed: the node is being referenced through at least one property of type REFERENCE");
- }
- }
-
- // modify the state of this node
- NodeState thisState = (NodeState) getOrCreateTransientItemState();
- // remove mixin name
- Set mixins = new HashSet(thisState.getMixinTypeNames());
- mixins.remove(ntName);
- thisState.setMixinTypeNames(mixins);
-
- // set jcr:mixinTypes property
- setMixinTypesProperty(mixins);
-
- // build effective node type of remaining mixin's & primary type
- NodeTypeManagerImpl ntMgr = session.getNodeTypeManager();
- NodeTypeRegistry ntReg = ntMgr.getNodeTypeRegistry();
- EffectiveNodeType entRemaining;
- try {
- // remaining mixin's
- HashSet set = new HashSet(mixins);
- // primary type
- set.add(nodeType.getQName());
- // build effective node type representing primary type including remaining mixin's
- entRemaining = ntReg.getEffectiveNodeType((QName[]) set.toArray(new QName[set.size()]));
- } catch (NodeTypeConflictException ntce) {
- throw new ConstraintViolationException(ntce.getMessage());
- }
-
- NodeTypeImpl mixin = session.getNodeTypeManager().getNodeType(ntName);
-
- // shortcut
- if (mixin.getChildNodeDefs().length == 0
- && mixin.getPropertyDefs().length == 0) {
- // the node type has neither property nor child node definitions,
- // i.e. we're done
- return;
- }
-
- // walk through properties and child nodes and remove those that have been
- // defined by the specified mixin type
-
- // use temp array to avoid ConcurrentModificationException
- ArrayList tmp = new ArrayList(thisState.getPropertyEntries());
- Iterator iter = tmp.iterator();
- while (iter.hasNext()) {
- NodeState.PropertyEntry entry = (NodeState.PropertyEntry) iter.next();
- PropertyImpl prop = (PropertyImpl) itemMgr.getItem(new PropertyId(thisState.getUUID(), entry.getName()));
- // check if property has been defined by mixin type (or one of its supertypes)
- NodeTypeImpl declaringNT = (NodeTypeImpl) prop.getDefinition().getDeclaringNodeType();
- if (!entRemaining.includesNodeType(declaringNT.getQName())) {
- // the remaining effective node type doesn't include the
- // node type that declared this property, it is thus safe
- // to remove it
- removeChildProperty(entry.getName());
- }
- }
- // use temp array to avoid ConcurrentModificationException
- tmp = new ArrayList(thisState.getChildNodeEntries());
- iter = tmp.iterator();
- while (iter.hasNext()) {
- NodeState.ChildNodeEntry entry = (NodeState.ChildNodeEntry) iter.next();
- NodeImpl node = (NodeImpl) itemMgr.getItem(new NodeId(entry.getUUID()));
- // check if node has been defined by mixin type (or one of its supertypes)
- NodeTypeImpl declaringNT = (NodeTypeImpl) node.getDefinition().getDeclaringNodeType();
- if (!entRemaining.includesNodeType(declaringNT.getQName())) {
- // the remaining effective node type doesn't include the
- // node type that declared this child node, it is thus safe
- // to remove it
- removeChildNode(entry.getName(), entry.getIndex());
- }
- }
+ removeMixin(ntName);
}
/**
@@ -3049,11 +3126,7 @@
// todo: also respect mixing types on creation?
QName[] mxNames = frozen.getFrozenMixinTypes();
for (int i = 0; i < mxNames.length; i++) {
- try {
- node.addMixin(mxNames[i].toJCRName(session.getNamespaceResolver()));
- } catch (NoPrefixDeclaredException e) {
- throw new NoSuchNodeTypeException("Unable to resolve mixin: " + e.toString());
- }
+ node.addMixin(mxNames[i]);
}
return node;
}
@@ -3097,11 +3170,7 @@
// todo: also respect mixing types on creation?
QName[] mxNames = frozen.getFrozenMixinTypes();
for (int i = 0; i < mxNames.length; i++) {
- try {
- node.addMixin(mxNames[i].toJCRName(session.getNamespaceResolver()));
- } catch (NoPrefixDeclaredException e) {
- throw new NoSuchNodeTypeException("Unable to resolve mixin: " + e.toString());
- }
+ node.addMixin(mxNames[i]);
}
return node;
}
@@ -3204,13 +3273,7 @@
}
}
if (!found) {
- try {
- addMixin(values[i].toJCRName(session.getNamespaceResolver()));
- } catch (NoPrefixDeclaredException e) {
- String msg = "Unable to add mixin for restored node: " + e.getMessage();
- log.debug(msg);
- throw new RepositoryException(msg);
- }
+ addMixin(values[i]);
}
}
// remove additional mixins
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/QName.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/QName.java?view=diff&r1=154699&r2=154700
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/QName.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/QName.java Mon Feb 21 10:03:31 2005
@@ -95,7 +95,23 @@
if (resolver == null) {
throw new NullPointerException("resolver must not be null");
}
- return internalFromJCRName(rawName, resolver);
+
+ if (rawName == null || rawName.length() == 0) {
+ throw new IllegalNameException("empty name");
+ }
+
+ // parts[0]: prefix
+ // parts[1]: localName
+ String[] parts = parse(rawName);
+
+ String uri;
+ try {
+ uri = resolver.getURI(parts[0]);
+ } catch (NamespaceException nse) {
+ throw new UnknownPrefixException(parts[0]);
+ }
+
+ return new QName(uri, parts[1]);
}
/**
@@ -143,36 +159,29 @@
* JCR-style name.
*/
public static void checkFormat(String jcrName) throws IllegalNameException {
- try {
- internalFromJCRName(jcrName, null);
- } catch (UnknownPrefixException e) {
- // ignore, will never happen
- }
+ parse(jcrName);
}
/**
- * Parses the <code>jcrName</code>, resolves the prefix using the namespace
- * resolver and returns a new QName instance. this method is also used
- * internally just to check the format of the given string by passing a
- * <code>null</code> value as <code>resolver</code>
+ * Parses the <code>jcrName</code> and returns an array of two strings:
+ * the first array element contains the prefix (or empty string),
+ * the second the local name.
*
- * @param rawName the jcr name to parse
- * @param resolver the namespace resolver or <code>null</code>
- * @return a new resolved QName
- * @throws IllegalNameException
- * @throws UnknownPrefixException
+ * @param jcrName the name to be parsed
+ * @return An array holding two strings: the first array element contains
+ * the prefix (or empty string), the second the local name.
+ * @throws IllegalNameException If <code>jcrName</code> is not a valid
+ * JCR-style name.
*/
- public static QName internalFromJCRName(String rawName, NamespaceResolver resolver)
- throws IllegalNameException, UnknownPrefixException {
-
- if (rawName == null || rawName.length() == 0) {
+ public static String[] parse(String jcrName) throws IllegalNameException {
+ if (jcrName == null || jcrName.length() == 0) {
throw new IllegalNameException("empty name");
}
- String prefix = null;
- String localName = null;
+ String prefix;
+ String localName;
- Matcher matcher = NAME_PATTERN.matcher(rawName);
+ Matcher matcher = NAME_PATTERN.matcher(jcrName);
if (matcher.matches()) {
// check for prefix (group 1)
if (matcher.group(1) != null) {
@@ -188,23 +197,11 @@
localName = matcher.group(3);
} else {
// illegal syntax for name
- throw new IllegalNameException("'" + rawName + "' is not a valid name");
+ throw new IllegalNameException("'" + jcrName + "' is not a valid name");
}
- if (resolver == null) {
- return null;
- } else {
- String uri;
- try {
- uri = resolver.getURI(prefix);
- } catch (NamespaceException nse) {
- throw new UnknownPrefixException(prefix);
- }
-
- return new QName(uri, localName);
- }
+ return new String[]{prefix, localName};
}
-
//-------------------------------------------------------< public methods >
/**
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/SessionImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/SessionImpl.java?view=diff&r1=154699&r2=154700
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/SessionImpl.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/SessionImpl.java Mon Feb 21 10:03:31 2005
@@ -30,8 +30,9 @@
import org.apache.jackrabbit.core.xml.DocViewSAXEventGenerator;
import org.apache.jackrabbit.core.xml.ImportHandler;
import org.apache.jackrabbit.core.xml.SysViewSAXEventGenerator;
+import org.apache.jackrabbit.core.xml.SessionImporter;
+import org.apache.jackrabbit.core.xml.Importer;
import org.apache.log4j.Logger;
-import org.apache.xerces.util.XMLChar;
import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;
import org.xml.sax.ContentHandler;
@@ -40,7 +41,23 @@
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;
-import javax.jcr.*;
+import javax.jcr.AccessDeniedException;
+import javax.jcr.Credentials;
+import javax.jcr.InvalidItemStateException;
+import javax.jcr.InvalidSerializedDataException;
+import javax.jcr.Item;
+import javax.jcr.ItemExistsException;
+import javax.jcr.ItemNotFoundException;
+import javax.jcr.LoginException;
+import javax.jcr.NamespaceException;
+import javax.jcr.NoSuchWorkspaceException;
+import javax.jcr.Node;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+import javax.jcr.Workspace;
import javax.jcr.lock.LockException;
import javax.jcr.nodetype.ConstraintViolationException;
import javax.jcr.version.VersionException;
@@ -49,7 +66,10 @@
import java.io.OutputStream;
import java.io.PrintStream;
import java.security.AccessControlException;
-import java.util.*;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
/**
* A <code>SessionImpl</code> ...
@@ -119,7 +139,7 @@
/**
* the transient prefix/namespace mappings with session scope
*/
- protected final TransientNamespaceMappings nsMappings;
+ protected final LocalNamespaceMappings nsMappings;
/**
* The version manager for this session
@@ -160,7 +180,7 @@
} else {
userId = null;
}
- nsMappings = new TransientNamespaceMappings(rep.getNamespaceRegistry());
+ nsMappings = new LocalNamespaceMappings(rep.getNamespaceRegistry());
ntMgr = new NodeTypeManagerImpl(rep.getNodeTypeRegistry(), getNamespaceResolver());
String wspName = wspConfig.getName();
wsp = new WorkspaceImpl(wspConfig, rep.getWorkspaceStateManager(wspName),
@@ -193,7 +213,7 @@
alive = true;
this.rep = rep;
this.userId = userId;
- nsMappings = new TransientNamespaceMappings(rep.getNamespaceRegistry());
+ nsMappings = new LocalNamespaceMappings(rep.getNamespaceRegistry());
ntMgr = new NodeTypeManagerImpl(rep.getNodeTypeRegistry(), getNamespaceResolver());
String wspName = wspConfig.getName();
wsp = new WorkspaceImpl(wspConfig, rep.getWorkspaceStateManager(wspName),
@@ -874,7 +894,8 @@
throw new ConstraintViolationException(msg);
}
- return new ImportHandler(parent, rep.getNamespaceRegistry(), this);
+ SessionImporter importer = new SessionImporter(parent, this, Importer.IMPORT_UUID_CREATE_NEW);
+ return new ImportHandler(importer, getNamespaceResolver(), rep.getNamespaceRegistry());
}
/**
@@ -932,7 +953,8 @@
boolean skipBinary, boolean noRecurse)
throws InvalidSerializedDataException, IOException,
PathNotFoundException, RepositoryException {
- OutputFormat format = new OutputFormat("xml", "UTF-8", true);
+ boolean indenting = true;
+ OutputFormat format = new OutputFormat("xml", "UTF-8", indenting);
XMLSerializer serializer = new XMLSerializer(out, format);
try {
exportDocView(absPath, serializer.asContentHandler(), skipBinary, noRecurse);
@@ -965,7 +987,8 @@
public void exportSysView(String absPath, OutputStream out,
boolean skipBinary, boolean noRecurse)
throws IOException, PathNotFoundException, RepositoryException {
- OutputFormat format = new OutputFormat("xml", "UTF-8", true);
+ boolean indenting = true;
+ OutputFormat format = new OutputFormat("xml", "UTF-8", indenting);
XMLSerializer serializer = new XMLSerializer(out, format);
try {
exportSysView(absPath, serializer.asContentHandler(), skipBinary, noRecurse);
@@ -1082,160 +1105,5 @@
public void removeLockToken(String lt) {
// @todo implement locking support
throw new UnsupportedOperationException("Locking not implemented yet.");
- }
-
- //--------------------------------------------------------< inner classes >
- class TransientNamespaceMappings implements NamespaceResolver {
-
- // the global persistent namespace registry
- private NamespaceRegistryImpl nsReg;
-
- // local prefix/namespace mappings
- private HashMap prefixToURI = new HashMap();
- private HashMap uriToPrefix = new HashMap();
-
- // prefixes in global namespace registry hidden by local mappings
- private Set hiddenPrefixes = new HashSet();
-
- TransientNamespaceMappings(NamespaceRegistryImpl nsReg) {
- this.nsReg = nsReg;
- }
-
- void setNamespacePrefix(String prefix, String uri)
- throws NamespaceException, RepositoryException {
- if (prefix == null || uri == null) {
- throw new IllegalArgumentException("prefix/uri can not be null");
- }
- if (NS_EMPTY_PREFIX.equals(prefix)
- || NS_DEFAULT_URI.equals(uri)) {
- throw new NamespaceException("default namespace is reserved and can not be changed");
- }
- // special case: prefixes xml*
- if (prefix.toLowerCase().startsWith(NS_XML_PREFIX)) {
- throw new NamespaceException("reserved prefix: " + prefix);
- }
- // check if the prefix is a valid XML prefix
- if (!XMLChar.isValidNCName(prefix)) {
- throw new NamespaceException("invalid prefix: " + prefix);
- }
-
- // check if namespace exists (the following call will
- // trigger a NamespaceException if it doesn't)
- String globalPrefix = nsReg.getPrefix(uri);
-
- // check new prefix for collision
- String globalURI = null;
- try {
- globalURI = nsReg.getURI(prefix);
- } catch (NamespaceException nse) {
- // ignore
- }
- if (globalURI != null) {
- // prefix is already mapped in global namespace registry;
- // check if it is redundant or if it refers to a namespace
- // that has been locally remapped, thus hiding it
- if (!hiddenPrefixes.contains(prefix)) {
- if (uri.equals(globalURI) && prefix.equals(globalPrefix)) {
- // redundant mapping, silently ignore
- return;
- }
- // we don't allow to hide a namespace because we can't
- // guarantee that there are no references to it
- // (in names of nodes/properties/node types etc.)
- throw new NamespaceException(prefix + ": prefix is already mapped to the namespace: " + globalURI);
- }
- }
-
- // check if namespace is already locally mapped
- String oldPrefix = (String) uriToPrefix.get(uri);
- if (oldPrefix != null) {
- if (oldPrefix.equals(prefix)) {
- // redundant mapping, silently ignore
- return;
- }
- // resurrect hidden global prefix
- hiddenPrefixes.remove(nsReg.getPrefix(uri));
- // remove old mapping
- uriToPrefix.remove(uri);
- prefixToURI.remove(oldPrefix);
- }
-
- // check if prefix is already locally mapped
- String oldURI = (String) prefixToURI.get(prefix);
- if (oldURI != null) {
- // resurrect hidden global prefix
- hiddenPrefixes.remove(nsReg.getPrefix(oldURI));
- // remove old mapping
- uriToPrefix.remove(oldURI);
- prefixToURI.remove(prefix);
- }
-
- if (!prefix.equals(globalPrefix)) {
- // store new mapping
- prefixToURI.put(prefix, uri);
- uriToPrefix.put(uri, prefix);
- hiddenPrefixes.add(globalPrefix);
- }
- }
-
- String[] getPrefixes() throws RepositoryException {
- if (prefixToURI.isEmpty()) {
- // shortcut
- return nsReg.getPrefixes();
- }
-
- HashSet prefixes = new HashSet();
- // global prefixes
- String[] globalPrefixes = nsReg.getPrefixes();
- for (int i = 0; i < globalPrefixes.length; i++) {
- if (!hiddenPrefixes.contains(globalPrefixes[i])) {
- prefixes.add(globalPrefixes[i]);
- }
- }
- // local prefixes
- prefixes.addAll(prefixToURI.keySet());
-
- return (String[]) prefixes.toArray(new String[prefixes.size()]);
- }
-
- //------------------------------------------------< NamespaceResolver >
- /**
- * @see NamespaceResolver#getURI
- */
- public String getURI(String prefix) throws NamespaceException {
- if (prefixToURI.isEmpty()) {
- // shortcut
- return nsReg.getURI(prefix);
- }
- // check local mappings
- if (prefixToURI.containsKey(prefix)) {
- return (String) prefixToURI.get(prefix);
- }
-
- // check global mappings
- if (!hiddenPrefixes.contains(prefix)) {
- return nsReg.getURI(prefix);
- }
-
- throw new NamespaceException(prefix + ": unknown prefix");
- }
-
- /**
- * @see NamespaceResolver#getPrefix
- */
- public String getPrefix(String uri) throws NamespaceException {
- if (prefixToURI.isEmpty()) {
- // shortcut
- return nsReg.getPrefix(uri);
- }
-
- // check local mappings
- if (uriToPrefix.containsKey(uri)) {
- return (String) uriToPrefix.get(uri);
- }
-
- // check global mappings
- return nsReg.getPrefix(uri);
- }
}
}
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/NodeDefImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/NodeDefImpl.java?view=diff&r1=154699&r2=154700
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/NodeDefImpl.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/NodeDefImpl.java Mon Feb 21 10:03:31 2005
@@ -57,16 +57,14 @@
*/
public NodeType getDefaultPrimaryType() {
QName ntName = nodeDef.getDefaultPrimaryType();
+ if (ntName == null) {
+ return null;
+ }
try {
- if (ntName == null) {
- // return "nt:unstructured"
- return ntMgr.getNodeType(Constants.NT_UNSTRUCTURED);
- } else {
- return ntMgr.getNodeType(ntName);
- }
+ return ntMgr.getNodeType(ntName);
} catch (NoSuchNodeTypeException e) {
// should never get here
- log.error("default node type does not exist", e);
+ log.error("invalid default node type " + ntName, e);
return null;
}
}
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/builtin_nodetypes.xml
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/builtin_nodetypes.xml?view=diff&r1=154699&r2=154700
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/builtin_nodetypes.xml (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/builtin_nodetypes.xml Mon Feb 21 10:03:31 2005
@@ -336,7 +336,7 @@
</requiredPrimaryTypes>
</childNodeDef>
</nodeType>
- <!-- internal nodetypes for persistent version manager -->
+ <!-- internal node types for persistent version manager -->
<nodeType name="rep:versionHistory" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
<supertypes>
<supertype>nt:unstructured</supertype>
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/DocViewImportHandler.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/DocViewImportHandler.java?view=diff&r1=154699&r2=154700
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/DocViewImportHandler.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/DocViewImportHandler.java Mon Feb 21 10:03:31 2005
@@ -16,53 +16,80 @@
*/
package org.apache.jackrabbit.core.xml;
-import org.apache.jackrabbit.core.*;
+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.ISO9075;
import org.apache.log4j.Logger;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
+import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import javax.jcr.StringValue;
+import javax.jcr.Value;
+import java.util.ArrayList;
import java.util.Stack;
/**
- * <code>DocViewImportHandler</code> ...
+ * <code>DocViewImportHandler</code> processes Document View XML SAX events
+ * and 'translates' them into <code>{@link Importer}</code> method calls.
*/
-class DocViewImportHandler extends DefaultHandler {
+class DocViewImportHandler extends DefaultHandler implements Constants {
private static Logger log = Logger.getLogger(DocViewImportHandler.class);
- private Stack parents;
- private SessionImpl session;
- // buffer used to merge adjacent character data
- private StringBuffer text;
-
- DocViewImportHandler(NodeImpl importTargetNode, SessionImpl session) {
- this.session = session;
- parents = new Stack();
+ private final Importer importer;
+ private final NamespaceResolver nsContext;
- parents.push(importTargetNode);
+ /**
+ * stack of NodeInfo instances; an instance is pushed onto the stack
+ * in the startElement method and is popped from the stack in the
+ * endElement method.
+ */
+ private final Stack stack = new Stack();
+ // buffer used to merge adjacent character data
+ private final StringBuffer text = new StringBuffer();
- text = new StringBuffer();
+ DocViewImportHandler(Importer importer, NamespaceResolver nsContext) {
+ this.importer = importer;
+ this.nsContext = nsContext;
}
/**
- * Stores character data encountered in <code>{@link #characters(char[], int, int)}</code>
- * as <code>jcr:xmlcharacters</code> property of <code>jcr:xmltext</code>
- * child node.
+ * Translates character data encountered in
+ * <code>{@link #characters(char[], int, int)}</code> into a
+ * <code>jcr:xmltext</code> child node with a <code>jcr:xmlcharacters</code>
+ * property.
*
- * @param parent
* @param text
* @throws SAXException
*/
- protected void addTextNode(NodeImpl parent, String text) throws SAXException {
+ private void onTextNode(String text)
+ throws SAXException {
+ if (text.trim().length() == 0) {
+ // ignore whitespace-only character data
+ log.debug("ignoring withespace character data: " + text);
+ return;
+ }
if (text.length() > 0) {
try {
- NodeImpl txtNode = (NodeImpl) parent.addNode(Constants.JCR_XMLTEXT);
- StringValue val = new StringValue(text.toString());
- txtNode.setProperty(Constants.JCR_XMLCHARACTERS, val);
+ Importer.NodeInfo node =
+ new Importer.NodeInfo(JCR_XMLTEXT, null, null, null);
+ Value[] values =
+ new Value[]{new StringValue(text.toString())};
+ ArrayList props = new ArrayList();
+ Importer.PropInfo prop =
+ new Importer.PropInfo(JCR_XMLCHARACTERS, PropertyType.STRING, values);
+ props.add(prop);
+ // call Importer
+ importer.startNode(node, props, nsContext);
+ importer.endNode(node);
} catch (RepositoryException re) {
throw new SAXException(re);
}
@@ -71,12 +98,25 @@
//-------------------------------------------------------< 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 {
+ public void startElement(String namespaceURI, String localName,
+ String qName, Attributes atts)
+ throws SAXException {
if (text.length() > 0) {
// there is character data that needs to be added to the current node
- addTextNode((NodeImpl) parents.peek(), text.toString());
+ onTextNode(text.toString());
// reset buffer
text.setLength(0);
}
@@ -87,20 +127,22 @@
nodeName = new QName(namespaceURI, localName);
} else {
try {
- nodeName = QName.fromJCRName(qName, session.getNamespaceResolver());
+ nodeName = QName.fromJCRName(qName, nsContext);
} catch (IllegalNameException ine) {
throw new SAXException("illegal node name: " + qName, ine);
} catch (UnknownPrefixException upe) {
throw new SAXException("illegal node name: " + qName, upe);
}
}
-
- // @todo how should 'system' properties be handled in document view (e.g. jcr:primaryType,jcr:mixinTypes, jcr:uuid)?
- NodeImpl currentParent = (NodeImpl) parents.peek();
- currentParent = (NodeImpl) currentParent.addNode(nodeName, Constants.NT_UNSTRUCTURED);
- parents.push(currentParent);
+ // decode node name
+ nodeName = ISO9075.decode(nodeName);
// properties
+ String uuid = null;
+ QName nodeTypeName = null;
+ QName[] mixinTypes = null;
+
+ ArrayList props = new ArrayList(atts.getLength());
for (int i = 0; i < atts.getLength(); i++) {
if (atts.getQName(i).startsWith("xml:")) {
// skipping xml:space, xml:lang, etc.
@@ -112,16 +154,58 @@
propName = new QName(atts.getURI(i), atts.getLocalName(i));
} else {
try {
- propName = QName.fromJCRName(atts.getQName(i), session.getNamespaceResolver());
+ propName = QName.fromJCRName(atts.getQName(i), nsContext);
} catch (IllegalNameException ine) {
throw new SAXException("illegal property name: " + atts.getQName(i), ine);
} catch (UnknownPrefixException upe) {
throw new SAXException("illegal property name: " + atts.getQName(i), upe);
}
}
- StringValue val = new StringValue(atts.getValue(i));
- currentParent.setProperty(propName, val);
+ // decode property name
+ propName = ISO9075.decode(propName);
+
+ // value(s)
+ String attrValue = atts.getValue(i);
+ Value[] 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] = new StringValue(strings[j]);
+ }
+*/
+ if (propName.equals(JCR_PRIMARYTYPE)) {
+ // jcr:primaryType
+ try {
+ nodeTypeName = QName.fromJCRName(attrValue, nsContext);
+ } catch (BaseException be) {
+ throw new SAXException("illegal jcr:primaryType value: " + attrValue, be);
+ }
+ } else if (propName.equals(JCR_MIXINTYPES)) {
+ // jcr:mixinTypes
+ try {
+ mixinTypes = new QName[]{QName.fromJCRName(attrValue, nsContext)};
+ } catch (BaseException be) {
+ throw new SAXException("illegal jcr:mixinTypes value: " + attrValue, be);
+ }
+ } else if (propName.equals(JCR_UUID)) {
+ // jcr:uuid
+ uuid = attrValue;
+ } else {
+ propValues = new Value[]{new StringValue(atts.getValue(i))};
+ props.add(new Importer.PropInfo(propName, PropertyType.STRING, propValues));
+ }
}
+
+ Importer.NodeInfo nodeInfo =
+ new Importer.NodeInfo(nodeName, nodeTypeName, mixinTypes, uuid);
+ // all information has been collected, now delegate to importer
+ importer.startNode(nodeInfo, props, nsContext);
+ // push current node data onto stack
+ stack.push(nodeInfo);
} catch (RepositoryException re) {
throw new SAXException(re);
}
@@ -144,10 +228,29 @@
public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
if (text.length() > 0) {
// there is character data that needs to be added to the current node
- addTextNode((NodeImpl) parents.peek(), text.toString());
+ onTextNode(text.toString());
// reset buffer
text.setLength(0);
}
- parents.pop();
+ Importer.NodeInfo node = (Importer.NodeInfo) stack.peek();
+ try {
+ // call Importer
+ importer.endNode(node);
+ } catch (RepositoryException re) {
+ throw new SAXException(re);
+ }
+ // we're done with this node, pop it from stack
+ stack.pop();
+ }
+
+ /**
+ * @see ContentHandler#endDocument()
+ */
+ public void endDocument() throws SAXException {
+ try {
+ importer.end();
+ } catch (RepositoryException re) {
+ throw new SAXException(re);
+ }
}
}
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/ImportHandler.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/ImportHandler.java?view=diff&r1=154699&r2=154700
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/ImportHandler.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/ImportHandler.java Mon Feb 21 10:03:31 2005
@@ -16,39 +16,64 @@
*/
package org.apache.jackrabbit.core.xml;
-import org.apache.jackrabbit.core.*;
+import org.apache.jackrabbit.core.BaseException;
+import org.apache.jackrabbit.core.Constants;
+import org.apache.jackrabbit.core.NamespaceRegistryImpl;
+import org.apache.jackrabbit.core.NamespaceResolver;
+import org.apache.jackrabbit.core.QName;
import org.apache.log4j.Logger;
-import org.xml.sax.*;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
+import org.xml.sax.helpers.NamespaceSupport;
import javax.jcr.NamespaceException;
import javax.jcr.RepositoryException;
/**
* An <code>ImportHandler</code> instance can be used to import serialized
- * data in System View XML or Document View XML. The actual task of importing
- * is delegated to specialized <code>ContentHandler</code>s (i.e.
- * <code>SysViewImportHandler</code> and <code>DocViewImportHandler</code>).
+ * data in System View XML or Document View XML. Processing of the XML is handled
+ * by specialized <code>ContentHandler</code>s (i.e. <code>SysViewImportHandler</code>
+ * and <code>DocViewImportHandler</code>).
+ * <p/>
+ * The actual task of importing though is delegated to the implementation of
+ * the <code>{@link Importer}</code> interface.
*/
public class ImportHandler extends DefaultHandler {
private static Logger log = Logger.getLogger(ImportHandler.class);
+ protected final Importer importer;
+ protected final NamespaceRegistryImpl nsReg;
+ protected final NamespaceResolver nsResolver;
+
protected Locator locator;
protected ContentHandler targetHandler;
-
- protected SessionImpl session;
- protected NodeImpl importTargetNode;
- protected NamespaceRegistryImpl nsReg;
protected boolean systemViewXML;
protected boolean initialized;
- public ImportHandler(NodeImpl importTargetNode,
- NamespaceRegistryImpl nsReg,
- SessionImpl session) {
- this.importTargetNode = importTargetNode;
- this.session = session;
+ protected final NamespaceContext nsContext;
+
+ /**
+ * this flag is used to determine whether a namespace context needs to be
+ * started in the startElement event or if the namespace context has already
+ * been started in a preceeding startPrefixMapping event;
+ * the flag is set per element in the first startPrefixMapping event and is
+ * cleared again in the following startElement event;
+ */
+ protected boolean nsContextStarted;
+
+ public ImportHandler(Importer importer, NamespaceResolver nsResolver,
+ NamespaceRegistryImpl nsReg) {
+ this.importer = importer;
+ this.nsResolver = nsResolver;
this.nsReg = nsReg;
+
+ nsContext = new NamespaceContext();
}
//---------------------------------------------------------< ErrorHandler >
@@ -91,6 +116,24 @@
systemViewXML = false;
initialized = false;
targetHandler = null;
+
+ /**
+ * start initial context containing existing mappings reflected
+ * by nsResolver
+ */
+ nsContext.reset();
+ nsContext.pushContext();
+ try {
+ String[] uris = nsReg.getURIs();
+ for (int i = 0; i < uris.length; i++) {
+ nsContext.declarePrefix(nsResolver.getPrefix(uris[i]), uris[i]);
+ }
+ } catch (RepositoryException re) {
+ throw new SAXException(re);
+ }
+
+ // initialize flag
+ nsContextStarted = false;
}
/**
@@ -99,6 +142,8 @@
public void endDocument() throws SAXException {
// delegate to target handler
targetHandler.endDocument();
+ // cleanup
+ nsContext.reset();
}
/**
@@ -106,39 +151,49 @@
*/
public void startPrefixMapping(String prefix, String uri)
throws SAXException {
+ // check if new context needs to be started
+ if (!nsContextStarted) {
+ // entering new namespace context
+ nsContext.pushContext();
+ nsContextStarted = true;
+ }
+
try {
- String oldPrefix = session.getNamespacePrefix(uri);
- // namespace is already registered; check prefix
- if (!"".equals(prefix) && !oldPrefix.equals(prefix)) {
- /**
- * namespace is mapped to different prefix;
- * try to remap it to given prefix
- */
- try {
- session.setNamespacePrefix(prefix, uri);
- } catch (RepositoryException re) {
- throw new SAXException("failed to remap namespace " + uri
- + " to prefix " + prefix, re);
- }
- }
+ // this will trigger NamespaceException if namespace is unknown
+ nsContext.getPrefix(uri);
} catch (NamespaceException nse) {
- // namespace is not yet registered, try to register it
+ // namespace is not yet registered ...
+ String newPrefix;
if ("".equals(prefix)) {
/**
- * the xml document specifies a default namespace (i.e. an empty prefix);
- * we need to create a random prefix as the empty prefix is reserved
- * according to the JCR spec.
+ * the xml document specifies a default namespace
+ * (i.e. an empty prefix); we need to create a random
+ * prefix as the empty prefix is reserved according
+ * to the JCR spec.
*/
- prefix = nsReg.getUniquePrefix(uri);
+ newPrefix = nsReg.getUniquePrefix(uri);
+ } else {
+ newPrefix = prefix;
}
+ // register new namespace
try {
- nsReg.registerNamespace(prefix, uri);
+ nsReg.registerNamespace(newPrefix, uri);
} catch (RepositoryException re) {
- throw new SAXException("failed to register namespace " + uri + " with prefix " + prefix, re);
+ throw new SAXException(re);
}
- } catch (RepositoryException re) {
- throw new SAXException("failed to check prefix for namespace " + uri, re);
}
+ // map namespace in this context to given prefix
+ nsContext.declarePrefix(prefix, uri);
+ }
+
+ /**
+ * @see ContentHandler#endPrefixMapping(String)
+ */
+ public void endPrefixMapping(String prefix) throws SAXException {
+ /**
+ * nothing to do here as namespace context has already been popped
+ * in endElement event
+ */
}
/**
@@ -146,6 +201,16 @@
*/
public void startElement(String namespaceURI, String localName, String qName,
Attributes atts) throws SAXException {
+ // check if new context needs to be started
+ if (!nsContextStarted) {
+ // there hasn't been a preceeding startPrefixMapping event
+ // so enter new namespace context
+ nsContext.pushContext();
+ } else {
+ // reset flag
+ nsContextStarted = false;
+ }
+
if (!initialized) {
// the namespace of the first element determines the type of XML
// (system view/document view)
@@ -154,7 +219,7 @@
nsURI = namespaceURI;
} else {
try {
- nsURI = QName.fromJCRName(qName, session.getNamespaceResolver()).getNamespaceURI();
+ nsURI = QName.fromJCRName(qName, nsResolver).getNamespaceURI();
} catch (BaseException e) {
// should never happen...
String msg = "internal error: failed to parse/resolve element name " + qName;
@@ -165,9 +230,9 @@
systemViewXML = Constants.NS_SV_URI.equals(nsURI);
if (systemViewXML) {
- targetHandler = new SysViewImportHandler(importTargetNode, session);
+ targetHandler = new SysViewImportHandler(importer, nsContext);
} else {
- targetHandler = new DocViewImportHandler(importTargetNode, session);
+ targetHandler = new DocViewImportHandler(importer, nsContext);
}
targetHandler.startDocument();
initialized = true;
@@ -190,6 +255,9 @@
*/
public void endElement(String namespaceURI, String localName, String qName)
throws SAXException {
+ // leaving element, pop namespace context
+ nsContext.popContext();
+
// delegate to target handler
targetHandler.endElement(namespaceURI, localName, qName);
}
@@ -199,5 +267,86 @@
*/
public void setDocumentLocator(Locator locator) {
this.locator = locator;
+ }
+
+ //--------------------------------------------------------< inner classes >
+ class NamespaceContext implements NamespaceResolver {
+
+ private final NamespaceSupport nsContext;
+
+ /**
+ * NamespaceSupport doesn't accept "" as default uri;
+ * internally we're using " " instead
+ */
+ private static final String DUMMY_DEFAULT_URI = " ";
+ private static final String DEFAULT_URI = Constants.NS_DEFAULT_URI;
+
+ private static final String EMPTY_PREFIX = "";
+
+ NamespaceContext() {
+ nsContext = new NamespaceSupport();
+ }
+
+ /**
+ * @see NamespaceSupport#popContext()
+ */
+ void popContext() {
+ nsContext.popContext();
+ }
+
+ /**
+ * @see NamespaceSupport#pushContext()
+ */
+ void pushContext() {
+ nsContext.pushContext();
+ }
+
+ /**
+ * @see NamespaceSupport#reset()
+ */
+ void reset() {
+ nsContext.reset();
+ }
+
+ /**
+ * @see NamespaceSupport#declarePrefix(String, String)
+ */
+ boolean declarePrefix(String prefix, String uri) {
+ uri = DEFAULT_URI.equals(uri) ? DUMMY_DEFAULT_URI : uri;
+ return nsContext.declarePrefix(prefix, uri);
+ }
+
+ //------------------------------------------------< NamespaceResolver >
+ /**
+ * @see NamespaceResolver#getURI(String)
+ */
+ public String getURI(String prefix) throws NamespaceException {
+ String uri = nsContext.getURI(prefix);
+ if (uri == null) {
+ throw new NamespaceException("unknown prefix");
+ }
+ return DUMMY_DEFAULT_URI.equals(uri) ? DEFAULT_URI : uri;
+ }
+
+ /**
+ * @see NamespaceResolver#getPrefix(String)
+ */
+ public String getPrefix(String uri) throws NamespaceException {
+ uri = DEFAULT_URI.equals(uri) ? DUMMY_DEFAULT_URI : uri;
+ String prefix = nsContext.getPrefix(uri);
+ if (prefix == null) {
+ /**
+ * NamespaceSupport#getPrefix will never return the empty
+ * (default) prefix; we have to do a reverse-lookup to check
+ * whether it's the current default namespace
+ */
+ if (uri.equals(nsContext.getURI(EMPTY_PREFIX))) {
+ return EMPTY_PREFIX;
+ }
+ throw new NamespaceException("unknown uri");
+ }
+ return prefix;
+ }
+
}
}
Added: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/Importer.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/Importer.java?view=auto&rev=154700
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/Importer.java (added)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/Importer.java Mon Feb 21 10:03:31 2005
@@ -0,0 +1,151 @@
+/*
+ * 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.NamespaceResolver;
+import org.apache.jackrabbit.core.QName;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+import javax.jcr.Workspace;
+import java.util.List;
+
+/**
+ * The <code>Importer</code> interface ...
+ */
+public interface Importer {
+
+ public static final int IMPORT_UUID_CREATE_NEW = Workspace.IMPORT_UUID_CREATE_NEW;
+ public static final int IMPORT_UUID_COLLISION_REMOVE_EXISTING = Workspace.IMPORT_UUID_COLLISION_REMOVE_EXISTING;
+ public static final int IMPORT_UUID_COLLISION_REPLACE_EXISTING = Workspace.IMPORT_UUID_COLLISION_REPLACE_EXISTING;
+ public static final int IMPORT_UUID_COLLISION_THROW = Workspace.IMPORT_UUID_COLLISION_THROW;
+
+ /**
+ * @throws RepositoryException
+ */
+ public void start() throws RepositoryException;
+
+ /**
+ * @param nodeInfo
+ * @param propInfos list of <code>PropInfo</code> instances
+ * @param nsContext prefix mappings of current context
+ * @throws RepositoryException
+ */
+ public void startNode(NodeInfo nodeInfo, List propInfos,
+ NamespaceResolver nsContext) throws RepositoryException;
+
+ /**
+ * @param nodeInfo
+ * @throws RepositoryException
+ */
+ public void endNode(NodeInfo nodeInfo) throws RepositoryException;
+
+ /**
+ * @throws RepositoryException
+ */
+ public void end() throws RepositoryException;
+
+ //--------------------------------------------------------< inner classes >
+ public static class NodeInfo {
+ private QName name;
+ private QName nodeTypeName;
+ private QName[] mixinNames;
+ private String uuid;
+
+ public NodeInfo() {
+ }
+
+ public NodeInfo(QName name, QName nodeTypeName, QName[] mixinNames,
+ String uuid) {
+ this.name = name;
+ this.nodeTypeName = nodeTypeName;
+ this.mixinNames = mixinNames;
+ this.uuid = uuid;
+ }
+
+ public void setName(QName name) {
+ this.name = name;
+ }
+
+ public QName getName() {
+ return name;
+ }
+
+ public void setNodeTypeName(QName nodeTypeName) {
+ this.nodeTypeName = nodeTypeName;
+ }
+
+ public QName getNodeTypeName() {
+ return nodeTypeName;
+ }
+
+ public void setMixinNames(QName[] mixinNames) {
+ this.mixinNames = mixinNames;
+ }
+
+ public QName[] getMixinNames() {
+ return mixinNames;
+ }
+
+ public void setUUID(String uuid) {
+ this.uuid = uuid;
+ }
+
+ public String getUUID() {
+ return uuid;
+ }
+ }
+
+ public static class PropInfo {
+ private QName name;
+ private int type;
+ private Value[] values;
+
+ public PropInfo() {
+ }
+
+ public PropInfo(QName name, int type, Value[] values) {
+ this.name = name;
+ this.type = type;
+ this.values = values;
+ }
+
+ public void setName(QName name) {
+ this.name = name;
+ }
+
+ public QName getName() {
+ return name;
+ }
+
+ public void setType(int type) {
+ this.type = type;
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public void setValues(Value[] values) {
+ this.values = values;
+ }
+
+ public Value[] getValues() {
+ return values;
+ }
+ }
+}
Propchange: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/Importer.java
------------------------------------------------------------------------------
svn:eol-style = native