Index: trunk/jackrabbit/project.xml
===================================================================
--- trunk/jackrabbit/project.xml (revision 394970)
+++ trunk/jackrabbit/project.xml (working copy)
@@ -542,6 +542,7 @@
**/*.xml
**/*.txt
+ **/*.cnd
Index: trunk/jackrabbit/src/test/java/org/apache/jackrabbit/core/nodetype/xml/test_ns_cnd_nodetypes.cnd
===================================================================
--- trunk/jackrabbit/src/test/java/org/apache/jackrabbit/core/nodetype/xml/test_ns_cnd_nodetypes.cnd (revision 0)
+++ trunk/jackrabbit/src/test/java/org/apache/jackrabbit/core/nodetype/xml/test_ns_cnd_nodetypes.cnd (revision 0)
@@ -0,0 +1,14 @@
+
+
+
+[testns3:emptyNodeType] > nt:base
+
+[testns4:mixinNodeType]
+ mixin
+
+[testns3:orderableNodeType] > nt:base
+ orderable
+
+[testns4:itemNodeType] > nt:base
+ - testns4:myDouble (double) ignore
+ - testns4:myBool (boolean) protected
Index: trunk/jackrabbit/src/test/java/org/apache/jackrabbit/core/nodetype/xml/TestAll.java
===================================================================
--- trunk/jackrabbit/src/test/java/org/apache/jackrabbit/core/nodetype/xml/TestAll.java (revision 394970)
+++ trunk/jackrabbit/src/test/java/org/apache/jackrabbit/core/nodetype/xml/TestAll.java (working copy)
@@ -15,26 +15,36 @@
*/
package org.apache.jackrabbit.core.nodetype.xml;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+
+import javax.jcr.NamespaceRegistry;
+import javax.jcr.PropertyType;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+import javax.jcr.Workspace;
+import javax.jcr.nodetype.NodeTypeManager;
+import javax.jcr.version.OnParentVersionAction;
+
import junit.framework.AssertionFailedError;
import junit.framework.TestCase;
+
+import org.apache.jackrabbit.api.JackrabbitNodeTypeManager;
+import org.apache.jackrabbit.core.TransientRepository;
import org.apache.jackrabbit.core.nodetype.InvalidNodeTypeDefException;
import org.apache.jackrabbit.core.nodetype.NodeDef;
import org.apache.jackrabbit.core.nodetype.NodeTypeDef;
+import org.apache.jackrabbit.core.nodetype.NodeTypeManagerImpl;
import org.apache.jackrabbit.core.nodetype.PropDef;
import org.apache.jackrabbit.core.value.InternalValue;
import org.apache.jackrabbit.name.NamespaceResolver;
import org.apache.jackrabbit.name.QName;
-import javax.jcr.NamespaceRegistry;
-import javax.jcr.PropertyType;
-import javax.jcr.RepositoryException;
-import javax.jcr.version.OnParentVersionAction;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Arrays;
-
/**
* Test cases for reading and writing node type definition files.
*/
@@ -47,6 +57,14 @@
private static final String TEST_NODETYPES =
"org/apache/jackrabbit/core/nodetype/xml/test_nodetypes.xml";
+ /** Name of the xml nodetype file for import and namespace registration. */
+ private static final String TEST_NS_XML_NODETYPES =
+ "org/apache/jackrabbit/core/nodetype/xml/test_ns_xml_nodetypes.xml";
+
+ /** Name of the cnd nodetype file for import and namespace registration. */
+ private static final String TEST_NS_CND_NODETYPES =
+ "org/apache/jackrabbit/core/nodetype/xml/test_ns_cnd_nodetypes.cnd";
+
/** Test node types definitions. */
private NodeTypeDef[] types;
@@ -209,6 +227,35 @@
assertTrue("itemNodeType wildcard property", pdef.definesResidual());
}
+ /** Test for namespace registration on node type import. */
+ public void testImportXMLNodeTypes() throws Exception {
+ Repository rep = new TransientRepository();
+ Session session = rep.login(new SimpleCredentials("user", "password".toCharArray()));
+ try {
+ Workspace workspace = session.getWorkspace();
+ NodeTypeManager ntm = workspace.getNodeTypeManager();
+ ((NodeTypeManagerImpl)ntm).registerNodeTypes(getClass().getClassLoader().getResourceAsStream(TEST_NS_XML_NODETYPES), JackrabbitNodeTypeManager.TEXT_XML);
+ assertTrue("xml test2 namespace registered", session.getNamespaceURI("testns2") != null);
+ } finally {
+ session.logout();
+ }
+ }
+
+ /** Test for namespace registration on node type import. */
+ public void testImportCNDNodeTypes() throws Exception {
+
+ Repository rep = new TransientRepository();
+ Session session = rep.login(new SimpleCredentials("user", "password".toCharArray()));
+ Workspace workspace = session.getWorkspace();
+ try {
+ NodeTypeManager ntm = workspace.getNodeTypeManager();
+ ((NodeTypeManagerImpl)ntm).registerNodeTypes(getClass().getClassLoader().getResourceAsStream(TEST_NS_CND_NODETYPES), JackrabbitNodeTypeManager.TEXT_X_JCR_CND);
+ assertTrue("cnd test3 namespace registered", session.getNamespaceURI("testns3") != null);
+ } finally {
+ session.logout();
+ }
+ }
+
/** Test for the empty item definition. */
public void testEmptyItem() {
PropDef def = getProperty("itemNodeType", "emptyItem");
Index: trunk/jackrabbit/src/test/java/org/apache/jackrabbit/core/nodetype/xml/test_ns_xml_nodetypes.xml
===================================================================
--- trunk/jackrabbit/src/test/java/org/apache/jackrabbit/core/nodetype/xml/test_ns_xml_nodetypes.xml (revision 0)
+++ trunk/jackrabbit/src/test/java/org/apache/jackrabbit/core/nodetype/xml/test_ns_xml_nodetypes.xml (revision 0)
@@ -0,0 +1,193 @@
+
+
+
+
+
+
+ nt:base
+
+
+
+
+
+
+
+ nt:base
+
+
+
+
+
+
+ nt:base
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ nt:base
+
+
+
+
+ [0,)
+
+
+
+
+ true
+ false
+
+
+ true
+
+
+
+
+
+ [2005-01-01T00:00:00.000Z,2006-01-01T00:00:00.000Z)
+
+
+
+ 2005-01-01T00:00:00.000Z
+
+
+
+
+ [,0.0)
+ (1.0,2.0)
+ (3.0,]
+
+
+ 1.5
+
+
+
+
+ (-10,0]
+ [1,2]
+ [10,100)
+
+
+ 25
+
+
+
+
+ testns1:testName
+
+
+ testns1:testName
+
+
+
+
+ /testns1:testPath
+
+
+
+
+ bananas?
+
+
+ banana
+ bananas
+
+
+
+
+
+
+
+ nt:base
+
+
+
+
+
+
+
Index: trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/SessionImpl.java
===================================================================
--- trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/SessionImpl.java (revision 394970)
+++ trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/SessionImpl.java (working copy)
@@ -236,7 +236,7 @@
}
this.subject = subject;
nsMappings = new LocalNamespaceMappings(rep.getNamespaceRegistry());
- ntMgr = new NodeTypeManagerImpl(rep.getNodeTypeRegistry(), getNamespaceResolver());
+ ntMgr = new NodeTypeManagerImpl(rep.getNodeTypeRegistry(), rep.getNamespaceRegistry(), getNamespaceResolver());
String wspName = wspConfig.getName();
wsp = createWorkspaceInstance(wspConfig,
rep.getWorkspaceStateManager(wspName), rep, this);
Index: trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeManagerImpl.java
===================================================================
--- trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeManagerImpl.java (revision 394970)
+++ trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeManagerImpl.java (working copy)
@@ -15,28 +15,6 @@
*/
package org.apache.jackrabbit.core.nodetype;
-import org.apache.commons.collections.map.ReferenceMap;
-import org.apache.jackrabbit.name.IllegalNameException;
-import org.apache.jackrabbit.name.NamespaceResolver;
-import org.apache.jackrabbit.name.QName;
-import org.apache.jackrabbit.name.UnknownPrefixException;
-import org.apache.jackrabbit.util.IteratorHelper;
-import org.apache.jackrabbit.util.name.NamespaceMapping;
-import org.apache.jackrabbit.api.JackrabbitNodeTypeManager;
-import org.apache.jackrabbit.core.nodetype.compact.CompactNodeTypeDefReader;
-import org.apache.jackrabbit.core.nodetype.compact.ParseException;
-import org.apache.jackrabbit.core.nodetype.xml.NodeTypeReader;
-import org.apache.jackrabbit.core.util.Dumpable;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-
-import javax.jcr.RepositoryException;
-import javax.jcr.nodetype.NoSuchNodeTypeException;
-import javax.jcr.nodetype.NodeType;
-import javax.jcr.nodetype.NodeTypeIterator;
-
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -44,12 +22,38 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Properties;
import java.util.Set;
+import javax.jcr.NamespaceException;
+import javax.jcr.NamespaceRegistry;
+import javax.jcr.RepositoryException;
+import javax.jcr.nodetype.NoSuchNodeTypeException;
+import javax.jcr.nodetype.NodeType;
+import javax.jcr.nodetype.NodeTypeIterator;
+
+import org.apache.commons.collections.map.ReferenceMap;
+import org.apache.jackrabbit.api.JackrabbitNodeTypeManager;
+import org.apache.jackrabbit.core.nodetype.compact.CompactNodeTypeDefReader;
+import org.apache.jackrabbit.core.nodetype.compact.ParseException;
+import org.apache.jackrabbit.core.nodetype.xml.NodeTypeReader;
+import org.apache.jackrabbit.core.util.Dumpable;
+import org.apache.jackrabbit.name.IllegalNameException;
+import org.apache.jackrabbit.name.NamespaceResolver;
+import org.apache.jackrabbit.name.QName;
+import org.apache.jackrabbit.name.UnknownPrefixException;
+import org.apache.jackrabbit.util.IteratorHelper;
+import org.apache.jackrabbit.util.name.NamespaceMapping;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
/**
* A NodeTypeManagerImpl implements a session dependant
* NodeTypeManager.
@@ -68,6 +72,11 @@
private final NodeTypeRegistry ntReg;
/**
+ * The wrapped node type registry.
+ */
+ private final NamespaceRegistry nsReg;
+
+ /**
* The root node definition.
*/
private final NodeDefinitionImpl rootNodeDef;
@@ -102,7 +111,9 @@
* @param nsResolver namespace resolver
*/
public NodeTypeManagerImpl(NodeTypeRegistry ntReg,
+ NamespaceRegistry nsReg,
NamespaceResolver nsResolver) {
+ this.nsReg = nsReg;
this.nsResolver = nsResolver;
this.ntReg = ntReg;
this.ntReg.addListener(this);
@@ -327,18 +338,59 @@
}
/**
+ * Registers a single namespace bypassing registration if it is already registered.
+ *
+ * @param - The identifier for the namespace
+ * @param - The unique identifier of the collection in the space
+ */
+ protected void registerNamespace(String prefix, String uri) throws RepositoryException
+ {
+ //Check if the uri is already registered
+ String regPrefix = null;
+ try {
+ regPrefix = nsReg.getPrefix(uri);
+ } catch (NamespaceException ne){
+ //The uri was not in the registry so attempt to map the prefix to it.
+ }
+
+ //The uri is not in the registry. The prefix may be with another uri
+ // or it may not be (the ideal scenario). In either case, attempt to register it
+ // and let the registry decide whether what to do in the case of an already existing prefix.
+ if ((regPrefix == null) || !regPrefix.equals(prefix))
+ //Attempt to register the prefix and uri...if the prefix is already registered
+ //an exception will be thrown due to an attempt to remap.
+ nsReg.registerNamespace(prefix, uri);
+ }
+
+ /**
* Registers the node types defined in the given XML stream. This
* is a trivial implementation that just invokes the existing
* {@link NodeTypeReader} and {@link NodeTypeRegistry} methods and
- * heuristically creates the returned node type array.
+ * heuristically creates the returned node type array. It will also register
+ * any namespaces defined in the input source that have not already been registered.
*
* {@inheritDoc}
*/
public NodeType[] registerNodeTypes(InputSource in)
throws SAXException, RepositoryException {
try {
- NodeTypeDef[] defs = NodeTypeReader.read(in.getByteStream());
- return registerNodeTypes(Arrays.asList(defs));
+ NodeTypeReader ntr = new NodeTypeReader(in.getByteStream());
+ Properties namespaces = ntr.getNamespaces();
+ if (namespaces != null){
+ Enumeration prefixes = namespaces.propertyNames();
+ while (prefixes.hasMoreElements()){
+ String prefix = (String) prefixes.nextElement();
+ registerNamespace(prefix, namespaces.getProperty(prefix));
+ }
+ }
+ try {
+ NodeTypeDef[] defs = ntr.getNodeTypeDefs();
+ return registerNodeTypes(Arrays.asList(defs));
+ } catch (IllegalNameException ine){
+ throw new RepositoryException(ine.getMessage(), ine);
+ } catch (UnknownPrefixException upe){
+ throw new RepositoryException(upe.getMessage(), upe);
+ }
} catch (InvalidNodeTypeDefException e) {
throw new RepositoryException("Invalid node type definition", e);
} catch (IOException e) {
@@ -348,32 +400,44 @@
private static final String APPLICATION_XML = "application/xml";
- /** {@inheritDoc} */
+ /**
+ * Registers the node types defined in the given input stream depending on the
+ * content type specified for the stream. This will also register any namespaces
+ * identified in the input stream if they have not already been registered.
+ *
+ * {@inheritDoc}
+ */
public NodeType[] registerNodeTypes(InputStream in, String contentType)
- throws IOException, RepositoryException {
- try {
- if (contentType.equalsIgnoreCase(JackrabbitNodeTypeManager.TEXT_XML)
- || contentType.equalsIgnoreCase(APPLICATION_XML)) {
- return registerNodeTypes(new InputSource(in));
- } else if (contentType.equalsIgnoreCase(
- JackrabbitNodeTypeManager.TEXT_X_JCR_CND)) {
- NamespaceMapping mapping = new NamespaceMapping(nsResolver);
- CompactNodeTypeDefReader reader = new CompactNodeTypeDefReader(
- new InputStreamReader(in), "cnd input stream", mapping);
- return registerNodeTypes(reader.getNodeTypeDefs());
- } else {
- throw new UnsupportedOperationException(
- "Unsupported content type: " + contentType);
- }
- } catch (InvalidNodeTypeDefException e) {
- throw new RepositoryException("Invalid node type definition", e);
- } catch (SAXException e) {
- throw new IOException(e.getMessage());
- } catch (ParseException e) {
- throw new IOException(e.getMessage());
+ throws IOException, RepositoryException {
+ try {
+ if (contentType.equalsIgnoreCase(JackrabbitNodeTypeManager.TEXT_XML)
+ || contentType.equalsIgnoreCase(APPLICATION_XML)) {
+ return registerNodeTypes(new InputSource(in));
+ } else if (contentType.equalsIgnoreCase(
+ JackrabbitNodeTypeManager.TEXT_X_JCR_CND)) {
+ NamespaceMapping mapping = new NamespaceMapping(nsResolver);
+ CompactNodeTypeDefReader reader = new CompactNodeTypeDefReader(
+ new InputStreamReader(in), "cnd input stream", mapping);
+ Map nsMap = mapping.getPrefixToURIMapping();
+ Iterator it = nsMap.keySet().iterator();
+ while (it.hasNext()){
+ String prefix = (String)it.next();
+ registerNamespace(prefix, (String)nsMap.get(prefix));
+ }
+ return registerNodeTypes(reader.getNodeTypeDefs());
+ } else {
+ throw new UnsupportedOperationException(
+ "Unsupported content type: " + contentType);
}
- }
-
+ } catch (InvalidNodeTypeDefException e) {
+ throw new RepositoryException("Invalid node type definition", e);
+ } catch (SAXException e) {
+ throw new IOException(e.getMessage());
+ } catch (ParseException e) {
+ throw new IOException(e.getMessage());
+ }
+ }
+
//-------------------------------------------------------------< Dumpable >
/**
* {@inheritDoc}