Author: rhauch
Date: 2008-10-29 13:48:23 -0400 (Wed, 29 Oct 2008)
New Revision: 597
Added:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/GraphImporter.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/JcrLexicon.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/JcrNtLexicon.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/GraphImporterTest.java
Removed:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/util/
trunk/dna-graph/src/test/java/org/jboss/dna/graph/util/
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/Graph.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/NameFactory.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/xml/XmlHandler.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/xml/XmlSequencer.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/xml/XmlHandlerTest.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/xml/XmlSequencerTest.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrLexicon.java
trunk/dna-repository/src/main/java/org/jboss/dna/repository/sequencers/SequencerOutputMap.java
trunk/dna-repository/src/test/java/org/jboss/dna/repository/sequencers/SequencerNodeContextTest.java
trunk/docs/examples/gettingstarted/repositories/src/main/java/org/jboss/example/dna/repository/RepositoryClient.java
Log:
DNA-242 - Change the XML importer code to no longer use XmlSequencer
http://jira.jboss.com/jira/browse/DNA-242
Changed the GraphImporter and Graph.importXmlFrom(...) methods to use the new XmlHandler
(rather than the XmlSequencer).
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/Graph.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/Graph.java 2008-10-29 15:16:23 UTC
(rev 596)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/Graph.java 2008-10-29 17:48:23 UTC
(rev 597)
@@ -61,7 +61,7 @@
import org.jboss.dna.graph.requests.RemovePropertiesRequest;
import org.jboss.dna.graph.requests.Request;
import org.jboss.dna.graph.requests.UpdatePropertiesRequest;
-import org.jboss.dna.graph.util.GraphImporter;
+import org.xml.sax.SAXException;
/**
* A graph representation of the content within a {@link RepositorySource}, including
mechanisms to interact and manipulate that
@@ -993,31 +993,38 @@
*/
public ImportInto<Conjunction<Graph>> importXmlFrom( final URI uri ) {
return new ImportInto<Conjunction<Graph>>() {
- public Conjunction<Graph> into( String path ) throws IOException {
+ private boolean skipRootElement = false;
+
+ public ImportInto<Conjunction<Graph>> skippingRootElement(
boolean skipRootElement ) {
+ this.skipRootElement = skipRootElement;
+ return this;
+ }
+
+ public Conjunction<Graph> into( String path ) throws IOException,
SAXException {
return into(new Location(createPath(path)));
}
- public Conjunction<Graph> into( Path path ) throws IOException {
+ public Conjunction<Graph> into( Path path ) throws IOException,
SAXException {
return into(new Location(path));
}
- public Conjunction<Graph> into( Property idProperty ) throws
IOException {
+ public Conjunction<Graph> into( Property idProperty ) throws
IOException, SAXException {
return into(new Location(idProperty));
}
public Conjunction<Graph> into( Property firstIdProperty,
- Property... additionalIdProperties ) throws
IOException {
+ Property... additionalIdProperties ) throws
IOException, SAXException {
return into(new Location(firstIdProperty, additionalIdProperties));
}
- public Conjunction<Graph> into( UUID uuid ) throws IOException {
+ public Conjunction<Graph> into( UUID uuid ) throws IOException,
SAXException {
return into(new Location(uuid));
}
@SuppressWarnings( "synthetic-access" )
- public Conjunction<Graph> into( Location at ) throws IOException {
+ public Conjunction<Graph> into( Location at ) throws IOException,
SAXException {
GraphImporter importer = new GraphImporter(Graph.this);
- importer.importXml(uri, at).execute(); // 'importXml' creates and
uses a new batch
+ importer.importXml(uri, at, skipRootElement).execute(); //
'importXml' creates and uses a new batch
return Graph.this.nextGraph;
}
};
@@ -2482,13 +2489,23 @@
*/
public interface ImportInto<Next> {
/**
+ * Specify whether the root element in the XML document should be skipped (that
is, not be represented by a node). By
+ * default, the root element is not skipped.
+ *
+ * @param skip true if the root element should be skipped, or false if a node
should be created for the root XML element
+ * @return the interface used to specify the location where the content should be
placed
+ */
+ ImportInto<Next> skippingRootElement( boolean skip );
+
+ /**
* Finish the import by specifying the new location into which the node should be
copied/moved.
*
* @param to the location of the new parent
* @return the interface for additional requests or actions
* @throws IOException if there is a problem reading the content being imported
+ * @throws SAXException if there is a problem with the SAX Parser
*/
- Next into( Location to ) throws IOException;
+ Next into( Location to ) throws IOException, SAXException;
/**
* Finish the import by specifying the new location into which the node should be
copied/moved.
@@ -2496,8 +2513,9 @@
* @param toPath the path of the new parent
* @return the interface for additional requests or actions
* @throws IOException if there is a problem reading the content being imported
+ * @throws SAXException if there is a problem with the SAX Parser
*/
- Next into( String toPath ) throws IOException;
+ Next into( String toPath ) throws IOException, SAXException;
/**
* Finish the import by specifying the new location into which the node should be
copied/moved.
@@ -2505,8 +2523,9 @@
* @param to the path of the new parent
* @return the interface for additional requests or actions
* @throws IOException if there is a problem reading the content being imported
+ * @throws SAXException if there is a problem with the SAX Parser
*/
- Next into( Path to ) throws IOException;
+ Next into( Path to ) throws IOException, SAXException;
/**
* Finish the import by specifying the new location into which the node should be
copied/moved.
@@ -2514,8 +2533,9 @@
* @param to the UUID of the new parent
* @return the interface for additional requests or actions
* @throws IOException if there is a problem reading the content being imported
+ * @throws SAXException if there is a problem with the SAX Parser
*/
- Next into( UUID to ) throws IOException;
+ Next into( UUID to ) throws IOException, SAXException;
/**
* Finish the import by specifying the new location into which the node should be
copied/moved.
@@ -2523,8 +2543,9 @@
* @param idProperty the property that uniquely identifies the new parent
* @return the interface for additional requests or actions
* @throws IOException if there is a problem reading the content being imported
+ * @throws SAXException if there is a problem with the SAX Parser
*/
- Next into( Property idProperty ) throws IOException;
+ Next into( Property idProperty ) throws IOException, SAXException;
/**
* Finish the import by specifying the new location into which the node should be
copied/moved.
@@ -2535,9 +2556,10 @@
* identifies the new parent
* @return the interface for additional requests or actions
* @throws IOException if there is a problem reading the content being imported
+ * @throws SAXException if there is a problem with the SAX Parser
*/
Next into( Property firstIdProperty,
- Property... additionalIdProperties ) throws IOException;
+ Property... additionalIdProperties ) throws IOException,
SAXException;
}
public interface BatchConjunction extends Conjunction<Batch>, Executable {
@@ -2616,9 +2638,11 @@
}
public Results execute() {
- // Execute the requests ...
- Request request = CompositeRequest.with(requests);
- Graph.this.execute(request);
+ if (!requests.isEmpty()) {
+ // Execute the requests ...
+ Request request = CompositeRequest.with(requests);
+ Graph.this.execute(request);
+ }
return new BatchResults(requests);
}
}
Copied: trunk/dna-graph/src/main/java/org/jboss/dna/graph/GraphImporter.java (from rev
593, trunk/dna-graph/src/main/java/org/jboss/dna/graph/util/GraphImporter.java)
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/GraphImporter.java
(rev 0)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/GraphImporter.java 2008-10-29
17:48:23 UTC (rev 597)
@@ -0,0 +1,173 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.dna.graph;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.util.List;
+import net.jcip.annotations.NotThreadSafe;
+import org.jboss.dna.common.text.TextDecoder;
+import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.graph.connectors.RepositorySource;
+import org.jboss.dna.graph.connectors.RepositorySourceException;
+import org.jboss.dna.graph.properties.Name;
+import org.jboss.dna.graph.properties.NamespaceRegistry;
+import org.jboss.dna.graph.properties.Path;
+import org.jboss.dna.graph.properties.Property;
+import org.jboss.dna.graph.xml.XmlHandler;
+import org.jboss.dna.graph.xml.XmlHandler.Destination;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.XMLReaderFactory;
+
+/**
+ * @author Randall Hauch
+ * @author John Verhaeg
+ */
+public class GraphImporter {
+
+ private final Graph graph;
+
+ public GraphImporter( Graph graph ) {
+ CheckArg.isNotNull(graph, "graph");
+ this.graph = graph;
+ }
+
+ /**
+ * Get the context in which the importer will be executed.
+ *
+ * @return the execution context; never null
+ */
+ public ExecutionContext getContext() {
+ return this.graph.getContext();
+ }
+
+ /**
+ * The graph that this importer uses.
+ *
+ * @return the graph; never null
+ */
+ public Graph getGraph() {
+ return graph;
+ }
+
+ /**
+ * Read the content from the supplied URI and import into the repository at the
supplied location.
+ *
+ * @param uri the URI where the importer can read the content that is to be imported
+ * @param location the location in the {@link RepositorySource repository source}
where the content is to be written; may not
+ * be null
+ * @return the batch of requests for creating the graph content that represents the
imported content
+ * @throws IllegalArgumentException if the <code>uri</code> or
destination path are null
+ * @throws IOException if there is a problem reading the content
+ * @throws SAXException if there is a problem with the SAX Parser
+ * @throws RepositorySourceException if there is a problem while writing the content
to the {@link RepositorySource repository
+ * source}
+ */
+ public Graph.Batch importXml( URI uri,
+ Location location ) throws IOException, SAXException,
RepositorySourceException {
+ return importXml(uri, location, false);
+ }
+
+ /**
+ * Read the content from the supplied URI and import into the repository at the
supplied location.
+ *
+ * @param uri the URI where the importer can read the content that is to be imported
+ * @param location the location in the {@link RepositorySource repository source}
where the content is to be written; may not
+ * be null
+ * @param skip true if the root element should be skipped, or false if a node should
be created for the root XML element
+ * @return the batch of requests for creating the graph content that represents the
imported content
+ * @throws IllegalArgumentException if the <code>uri</code> or
destination path are null
+ * @throws IOException if there is a problem reading the content
+ * @throws SAXException if there is a problem with the SAX Parser
+ * @throws RepositorySourceException if there is a problem while writing the content
to the {@link RepositorySource repository
+ * source}
+ */
+ public Graph.Batch importXml( URI uri,
+ Location location,
+ boolean skip ) throws IOException, SAXException,
RepositorySourceException {
+ CheckArg.isNotNull(uri, "uri");
+ CheckArg.isNotNull(location, "location");
+ CheckArg.isNotNull(location.getPath(), "location.getPath()");
+
+ // Create the destination for the XmlHandler ...
+ Graph.Batch batch = graph.batch();
+ XmlHandler.Destination destination = new CreateOnGraphInBatch(batch);
+
+ // Determine where the content is to be placed ...
+ Path parentPath = location.getPath();
+ InputStream stream = null;
+ Name nameAttribute = JcrLexicon.NAME;
+ Name typeAttribute = JcrLexicon.PRIMARY_TYPE;
+ Name typeAttributeValue = null;
+ NamespaceRegistry reg = graph.getContext().getNamespaceRegistry();
+ if (reg.isRegisteredNamespaceUri(JcrNtLexicon.Namespace.URI)) {
+ typeAttributeValue = JcrNtLexicon.UNSTRUCTURED;
+ }
+
+ TextDecoder decoder = null;
+ XmlHandler.AttributeScoping scoping =
XmlHandler.AttributeScoping.USE_DEFAULT_NAMESPACE;
+ XmlHandler handler = new XmlHandler(destination, skip, parentPath, decoder,
nameAttribute, typeAttribute,
+ typeAttributeValue, scoping);
+ try {
+ stream = uri.toURL().openStream();
+ XMLReader reader = XMLReaderFactory.createXMLReader();
+ reader.setContentHandler(handler);
+ reader.setErrorHandler(handler);
+ reader.parse(new InputSource(stream));
+ } finally {
+ if (stream != null) stream.close();
+ }
+ return batch;
+ }
+
+ @NotThreadSafe
+ protected final static class CreateOnGraphInBatch implements Destination {
+ private final Graph.Batch batch;
+
+ protected CreateOnGraphInBatch( Graph.Batch batch ) {
+ assert batch != null;
+ this.batch = batch;
+ }
+
+ public ExecutionContext getExecutionContext() {
+ return batch.getGraph().getContext();
+ }
+
+ public void create( Path path,
+ List<Property> properties,
+ Name elementName ) {
+ assert properties != null;
+ if (properties.isEmpty()) {
+ batch.create(path).and();
+ } else {
+ batch.create(path, properties).and();
+ }
+ }
+
+ public void submit() {
+ }
+ }
+
+}
Property changes on: trunk/dna-graph/src/main/java/org/jboss/dna/graph/GraphImporter.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/dna-graph/src/main/java/org/jboss/dna/graph/JcrLexicon.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/JcrLexicon.java
(rev 0)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/JcrLexicon.java 2008-10-29 17:48:23
UTC (rev 597)
@@ -0,0 +1,40 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.dna.graph;
+
+import org.jboss.dna.graph.properties.Name;
+import org.jboss.dna.graph.properties.basic.BasicName;
+
+/**
+ * @author Randall Hauch
+ */
+public class JcrLexicon {
+
+ public static class Namespace {
+ public static final String URI = "http://www.jcp.org/jcr/1.0";
+ public static final String PREFIX = "jcr";
+ }
+
+ public static final Name UUID = new BasicName(Namespace.URI, "uuid");
+ public static final Name NAME = new BasicName(Namespace.URI, "name");
+ public static final Name PRIMARY_TYPE = new BasicName(Namespace.URI,
"primaryType");
+}
Property changes on: trunk/dna-graph/src/main/java/org/jboss/dna/graph/JcrLexicon.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/dna-graph/src/main/java/org/jboss/dna/graph/JcrNtLexicon.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/JcrNtLexicon.java
(rev 0)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/JcrNtLexicon.java 2008-10-29
17:48:23 UTC (rev 597)
@@ -0,0 +1,38 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.dna.graph;
+
+import org.jboss.dna.graph.properties.Name;
+import org.jboss.dna.graph.properties.basic.BasicName;
+
+/**
+ * @author Randall Hauch
+ */
+public class JcrNtLexicon {
+
+ public static class Namespace {
+ public static final String URI = "http://www.jcp.org/jcr/nt/1.0";
+ public static final String PREFIX = "nt";
+ }
+
+ public static final Name UNSTRUCTURED = new BasicName(Namespace.URI,
"unstructured");
+}
Property changes on: trunk/dna-graph/src/main/java/org/jboss/dna/graph/JcrNtLexicon.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/NameFactory.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/NameFactory.java 2008-10-29
15:16:23 UTC (rev 596)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/NameFactory.java 2008-10-29
17:48:23 UTC (rev 597)
@@ -30,8 +30,6 @@
*/
public interface NameFactory extends ValueFactory<Name> {
- String JCR_PRIMARY_TYPE = "jcr:primaryType";
-
/**
* Create a name from the given namespace URI and local name.
* <p>
@@ -43,7 +41,8 @@
* @return the new name
* @throws IllegalArgumentException if the local name is
<code>null</code> or empty
*/
- Name create( String namespaceUri, String localName );
+ Name create( String namespaceUri,
+ String localName );
/**
* Create a name from the given namespace URI and local name.
@@ -54,7 +53,9 @@
* @return the new name
* @throws IllegalArgumentException if the local name is
<code>null</code> or empty
*/
- Name create( String namespaceUri, String localName, TextDecoder decoder );
+ Name create( String namespaceUri,
+ String localName,
+ TextDecoder decoder );
/**
* Get the namespace registry.
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/xml/XmlHandler.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/xml/XmlHandler.java 2008-10-29
15:16:23 UTC (rev 596)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/xml/XmlHandler.java 2008-10-29
17:48:23 UTC (rev 597)
@@ -31,7 +31,6 @@
import org.jboss.dna.common.text.XmlNameEncoder;
import org.jboss.dna.common.util.CheckArg;
import org.jboss.dna.graph.ExecutionContext;
-import org.jboss.dna.graph.Graph;
import org.jboss.dna.graph.properties.Name;
import org.jboss.dna.graph.properties.NameFactory;
import org.jboss.dna.graph.properties.NamespaceRegistry;
@@ -91,6 +90,16 @@
protected final Name nameAttribute;
/**
+ * The name of the property that is to be set with the type of the XML element. For
example, "jcr:name".
+ */
+ protected final Name typeAttribute;
+
+ /**
+ * The value of the node type property, if the node's name is set with the {@link
#nameAttribute}.
+ */
+ protected final Name typeAttributeValue;
+
+ /**
* The cached reference to the graph's path factory.
*/
protected final PathFactory pathFactory;
@@ -154,8 +163,12 @@
* @param parent the path to the node in the graph under which the content should be
placed; if null, the root node is assumed
* @param textDecoder the text decoder that should be used to decode the XML element
names and XML attribute names, prior to
* using those values to create names; or null if the default encoder should
be used
- * @param nameAttribute the name of the XML attribute whose value should be used for
the names of the nodes (typically, this
- * is "jcr:name" or something equivalent); or null if the XML
element name should always be used as the node name
+ * @param nameAttribute the name of the property whose value should be used for the
names of the nodes (typically, this is
+ * "jcr:name" or something equivalent); or null if the XML element
name should always be used as the node name
+ * @param typeAttribute the name of the property that should be set with the type of
the XML element, or null if there is no
+ * such property
+ * @param typeAttributeValue the value of the type property that should be used if
the node has no <code>nameAttribute</code>,
+ * or null if the value should be set to the type of the XML element
* @param scoping defines how to choose the namespace of attributes that do not have
a namespace prefix; if null, the
* {@link #DEFAULT_ATTRIBUTE_SCOPING} value is used
* @throws IllegalArgumentException if the destination reference is null
@@ -165,11 +178,15 @@
Path parent,
TextDecoder textDecoder,
Name nameAttribute,
+ Name typeAttribute,
+ Name typeAttributeValue,
AttributeScoping scoping ) {
CheckArg.isNotNull(destination, "destination");
assert destination != null;
this.destination = destination;
this.nameAttribute = nameAttribute;
+ this.typeAttribute = typeAttribute;
+ this.typeAttributeValue = typeAttributeValue;
this.decoder = textDecoder != null ? textDecoder : DEFAULT_DECODER;
this.skipFirstElement = skipRootElement;
this.attributeScoping = scoping != null ? scoping : DEFAULT_ATTRIBUTE_SCOPING;
@@ -192,39 +209,6 @@
}
/**
- * Create a handler that creates content in the supplied graph
- *
- * @param graph the graph in which the content should be placed
- * @param useBatch true if all of the actions to create the content in the graph
should be submitted to the graph in a single
- * batch, or false if they should be submitted immediately after each is
identified
- * @param skipRootElement true if the root element of the document should be skipped,
or false if the root element should be
- * converted to the top-level node of the content
- * @param parent the path to the node in the graph under which the content should be
placed; if null, the root node is assumed
- * @param textDecoder the text decoder that should be used to decode the XML element
names and XML attribute names, prior to
- * using those values to create names; or null if the default encoder should
be used
- * @param nameAttribute the name of the XML attribute whose value should be used for
the names of the nodes (typically, this
- * is "jcr:name" or something equivalent); or null if the XML
element name should always be used as the node name
- * @param scoping defines how to choose the namespace of attributes that do not have
a namespace prefix; if null, the
- * {@link #DEFAULT_ATTRIBUTE_SCOPING} value is used
- * @throws IllegalArgumentException if the graph reference is null
- */
- public XmlHandler( Graph graph,
- boolean useBatch,
- boolean skipRootElement,
- Path parent,
- TextDecoder textDecoder,
- Name nameAttribute,
- AttributeScoping scoping ) {
- this(createDestination(graph, useBatch), skipRootElement, parent, textDecoder,
nameAttribute, scoping);
- }
-
- protected static Destination createDestination( Graph graph,
- boolean useBatch ) {
- CheckArg.isNotNull(graph, "graph");
- return useBatch ? new CreateOnGraphInBatches(graph.batch()) : new
CreateOnGraph(graph);
- }
-
- /**
* {@inheritDoc}
* <p>
* This method ensures that the namespace is registered with the {@link
NamespaceRegistry registry}, using the supplied prefix
@@ -267,6 +251,7 @@
Name nodeName = null;
properties.clear();
+ Object typePropertyValue = null;
// Convert each of the attributes to a property ...
for (int i = 0; i != attributes.getLength(); ++i) {
String attributeLocalName = attributes.getLocalName(i);
@@ -290,16 +275,34 @@
nodeName = nameFactory.create(attributes.getValue(i)); // don't use a
decoder
continue;
}
+ if (attributeName.equals(typeAttribute)) {
+ typePropertyValue = nameFactory.create(attributes.getValue(i)); //
don't use a decoder
+ continue;
+ }
// Create a property for this attribute ...
Property property = createProperty(attributeName, attributes.getValue(i));
properties.add(property);
}
// Create the node name if required ...
- if (nodeName == null) nodeName = nameFactory.create(uri, localName, decoder);
+ Name elementName = nameFactory.create(uri, localName, decoder);
+ if (nodeName == null) {
+ // No attribute defines the node name ...
+ nodeName = elementName;
+ } else {
+ // A attribute defines the node name ...
+ typePropertyValue = elementName;
+ }
+ // Set the type property, if required
+ if (typeAttribute != null) {
+ if (typePropertyValue == null) typePropertyValue = typeAttributeValue;
+ propertyValues[0] = typePropertyValue;
+ Property property = propertyFactory.create(typeAttribute, propertyValues);
+ properties.add(property);
+ }
// Update the current path ...
currentPath = pathFactory.create(currentPath, nodeName);
// Create the node, and note that we don't care about same-name siblings (as
the graph will correct them) ...
- destination.create(currentPath, properties);
+ destination.create(currentPath, properties, elementName);
}
/**
@@ -363,9 +366,12 @@
*
* @param path the absolute path of the node
* @param properties the properties for the node; never null, but may be empty if
there are no properties
+ * @param elementName the name of the XML element from which the node should be
created; never null, and may or may not be
+ * the same name as the last segment of the path
*/
public void create( Path path,
- List<Property> properties );
+ List<Property> properties,
+ Name elementName );
/**
* Signal to this destination that any enqueued create requests should be
submitted. Usually this happens at the end of
@@ -373,61 +379,4 @@
*/
public void submit();
}
-
- @NotThreadSafe
- protected final static class CreateOnGraph implements Destination {
- private final Graph graph;
-
- protected CreateOnGraph( final Graph graph ) {
- assert graph != null;
- this.graph = graph;
- }
-
- public ExecutionContext getExecutionContext() {
- return graph.getContext();
- }
-
- public final void create( Path path,
- List<Property> properties ) {
- assert properties != null;
- if (properties.isEmpty()) {
- graph.create(path);
- } else {
- graph.create(path, properties);
- }
- }
-
- public void submit() {
- // Nothing to do, since each call to 'create' immediate executes on
the graph
- }
- }
-
- @NotThreadSafe
- protected final static class CreateOnGraphInBatches implements Destination {
- private final Graph.Batch batch;
-
- protected CreateOnGraphInBatches( Graph.Batch batch ) {
- assert batch != null;
- this.batch = batch;
- }
-
- public ExecutionContext getExecutionContext() {
- return batch.getGraph().getContext();
- }
-
- public void create( Path path,
- List<Property> properties ) {
- assert properties != null;
- if (properties.isEmpty()) {
- batch.create(path);
- } else {
- batch.create(path, properties);
- }
- }
-
- public void submit() {
- batch.execute();
- }
- }
-
}
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/xml/XmlSequencer.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/xml/XmlSequencer.java 2008-10-29
15:16:23 UTC (rev 596)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/xml/XmlSequencer.java 2008-10-29
17:48:23 UTC (rev 597)
@@ -30,6 +30,7 @@
import org.jboss.dna.common.monitor.ProgressMonitor;
import org.jboss.dna.common.util.StringUtil;
import org.jboss.dna.graph.GraphI18n;
+import org.jboss.dna.graph.JcrLexicon;
import org.jboss.dna.graph.properties.Name;
import org.jboss.dna.graph.properties.NameFactory;
import org.jboss.dna.graph.properties.NamespaceRegistry;
@@ -128,7 +129,6 @@
// Cached instances of the name factory and commonly referenced names
private final NameFactory nameFactory;
- private Name primaryTypeName;
private Name defaultPrimaryType;
// Recursive map used to track the number of occurrences of names for elements
under a particular path
@@ -233,7 +233,7 @@
stopIfCancelled();
// Output separate nodes for each comment since multiple are allowed
startElement(DnaXmlLexicon.COMMENT);
- output.setProperty(path, getPrimaryTypeName(), DnaXmlLexicon.COMMENT);
+ output.setProperty(path, JcrLexicon.PRIMARY_TYPE, DnaXmlLexicon.COMMENT);
output.setProperty(path, DnaXmlLexicon.COMMENT_CONTENT, String.valueOf(ch,
start, length));
endElement();
updateProgress();
@@ -281,7 +281,7 @@
if (content.length() > 0) {
// Create separate node for each content entry since entries can be
interspersed amongst child elements
startElement(DnaXmlLexicon.ELEMENT_CONTENT);
- output.setProperty(path, getPrimaryTypeName(),
DnaXmlLexicon.ELEMENT_CONTENT);
+ output.setProperty(path, JcrLexicon.PRIMARY_TYPE,
DnaXmlLexicon.ELEMENT_CONTENT);
output.setProperty(path, DnaXmlLexicon.ELEMENT_CONTENT, content);
endElement();
}
@@ -380,7 +380,7 @@
// Add "synthetic" entity container to path to help prevent name
collisions with XML elements
Name entityName = DnaDtdLexicon.ENTITY;
startElement(entityName);
- output.setProperty(path, getPrimaryTypeName(), entityName);
+ output.setProperty(path, JcrLexicon.PRIMARY_TYPE, entityName);
output.setProperty(path, nameFactory.create(DnaDtdLexicon.NAME), name);
output.setProperty(path, nameFactory.create(DnaDtdLexicon.PUBLIC_ID),
publicId);
output.setProperty(path, nameFactory.create(DnaDtdLexicon.SYSTEM_ID),
systemId);
@@ -401,13 +401,6 @@
monitor.getProblems().addError(error,
GraphI18n.fatalErrorSequencingXmlDocument, error);
}
- private Name getPrimaryTypeName() {
- if (primaryTypeName == null) {
- primaryTypeName = nameFactory.create(NameFactory.JCR_PRIMARY_TYPE);
- }
- return primaryTypeName;
- }
-
private Name getDefaultPrimaryType() {
if (defaultPrimaryType == null) {
defaultPrimaryType = nameFactory.create(DEFAULT_PRIMARY_TYPE);
@@ -443,7 +436,7 @@
// Add "synthetic" entity container to path to help prevent name
collisions with XML elements
Name entityName = DnaDtdLexicon.ENTITY;
startElement(entityName);
- output.setProperty(path, getPrimaryTypeName(), entityName);
+ output.setProperty(path, JcrLexicon.PRIMARY_TYPE, entityName);
output.setProperty(path, DnaDtdLexicon.NAME, name);
output.setProperty(path, DnaDtdLexicon.VALUE, value);
endElement();
@@ -478,7 +471,7 @@
// Output separate nodes for each instruction since multiple are allowed
Name name = DnaXmlLexicon.PROCESSING_INSTRUCTION;
startElement(name);
- output.setProperty(path, getPrimaryTypeName(), name);
+ output.setProperty(path, JcrLexicon.PRIMARY_TYPE, name);
output.setProperty(path, DnaXmlLexicon.TARGET, target);
output.setProperty(path, DnaXmlLexicon.PROCESSING_INSTRUCTION_CONTENT,
data);
endElement();
@@ -524,7 +517,7 @@
@Override
public void startDocument() throws SAXException {
stopIfCancelled();
- output.setProperty(path, getPrimaryTypeName(), DnaXmlLexicon.DOCUMENT);
+ output.setProperty(path, JcrLexicon.PRIMARY_TYPE, DnaXmlLexicon.DOCUMENT);
updateProgress();
}
@@ -603,7 +596,7 @@
}
}
startElement(nameObj);
- output.setProperty(path, getPrimaryTypeName(), type);
+ output.setProperty(path, JcrLexicon.PRIMARY_TYPE, type);
// Output this element's attributes using the attribute's namespace,
if supplied, or the current namespace in scope.
String inheritedNs = nsStack.getFirst();
for (int ndx = 0, len = attributes.getLength(); ndx < len; ++ndx) {
Copied: trunk/dna-graph/src/test/java/org/jboss/dna/graph/GraphImporterTest.java (from rev
593, trunk/dna-graph/src/test/java/org/jboss/dna/graph/util/GraphImporterTest.java)
===================================================================
--- trunk/dna-graph/src/test/java/org/jboss/dna/graph/GraphImporterTest.java
(rev 0)
+++ trunk/dna-graph/src/test/java/org/jboss/dna/graph/GraphImporterTest.java 2008-10-29
17:48:23 UTC (rev 597)
@@ -0,0 +1,182 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.dna.graph;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsInstanceOf.instanceOf;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.stub;
+import java.io.File;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javax.transaction.xa.XAResource;
+import org.jboss.dna.common.util.StringUtil;
+import org.jboss.dna.graph.cache.CachePolicy;
+import org.jboss.dna.graph.connectors.BasicExecutionContext;
+import org.jboss.dna.graph.connectors.RepositoryConnection;
+import org.jboss.dna.graph.connectors.RepositoryConnectionFactory;
+import org.jboss.dna.graph.connectors.RepositorySourceException;
+import org.jboss.dna.graph.connectors.RepositorySourceListener;
+import org.jboss.dna.graph.properties.Name;
+import org.jboss.dna.graph.properties.Path;
+import org.jboss.dna.graph.properties.Property;
+import org.jboss.dna.graph.requests.CompositeRequest;
+import org.jboss.dna.graph.requests.CreateNodeRequest;
+import org.jboss.dna.graph.requests.Request;
+import org.jboss.dna.graph.xml.DnaDtdLexicon;
+import org.jboss.dna.graph.xml.DnaXmlLexicon;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.MockitoAnnotations;
+import org.mockito.MockitoAnnotations.Mock;
+
+/**
+ * @author Randall Hauch
+ */
+public class GraphImporterTest {
+
+ private Graph graph;
+ private GraphImporter importer;
+ private String sourceName;
+ private ExecutionContext context;
+ private URI xmlContent;
+ private MockRepositoryConnection connection;
+ private Request lastExecutedRequest;
+ private Path destinationPath;
+ @Mock
+ private RepositoryConnectionFactory sources;
+
+ @Before
+ public void beforeEach() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ xmlContent = new
File("src/test/resources/repositoryImporterTestData1.xml").toURI();
+ context = new BasicExecutionContext();
+ context.getNamespaceRegistry().register(DnaLexicon.Namespace.PREFIX,
DnaLexicon.Namespace.URI);
+ context.getNamespaceRegistry().register(DnaXmlLexicon.Namespace.PREFIX,
DnaXmlLexicon.Namespace.URI);
+ context.getNamespaceRegistry().register(DnaDtdLexicon.Namespace.PREFIX,
DnaDtdLexicon.Namespace.URI);
+ context.getNamespaceRegistry().register("jcr",
"http://www.jcp.org/jcr/1.0");
+ context.getNamespaceRegistry().register("nt",
"http://www.jcp.org/jcr/nt/1.0");
+ sourceName = "sourceA";
+ destinationPath =
context.getValueFactories().getPathFactory().create("/a/b");
+ graph = Graph.create(sourceName, sources, context);
+ importer = new GraphImporter(graph);
+ connection = new MockRepositoryConnection();
+ stub(sources.createConnection(sourceName)).toReturn(connection);
+ }
+
+ @Test
+ public void shouldImportXmlContentAndGenerateTheCorrectCommands() throws Exception {
+ System.out.println(xmlContent);
+ Graph.Batch batch = importer.importXml(xmlContent, new
Location(destinationPath));
+ batch.execute();
+ // 'lastExecutedCommand'
+ assertThat(lastExecutedRequest, is(instanceOf(CompositeRequest.class)));
+ Iterator<Request> iter =
((CompositeRequest)lastExecutedRequest).iterator();
+ // assertCreateNode(iter, "/a/b/",
"jcr:primaryType={http://www.jboss.org/dna/xml/1.0}document");
+ assertCreateNode(iter, "/a/b/dna:system[1]",
"jcr:primaryType={http://www.jcp.org/jcr/nt/1.0}unstructured");
+ assertCreateNode(iter, "/a/b/dna:system[1]/dna:sources[1]",
"jcr:primaryType={http://www.jcp.org/jcr/nt/1.0}unstructured");
+ assertCreateNode(iter,
+ "/a/b/dna:system[1]/dna:sources[1]/sourceA[1]",
+ "repositoryName=repositoryA",
+ "retryLimit=3",
+ "jcr:primaryType={http://www.jboss.org/dna}xyz",
+
"dna:classname=org.jboss.dna.connector.inmemory.InMemoryRepositorySource");
+ assertCreateNode(iter,
+ "/a/b/dna:system[1]/dna:sources[1]/sourceB[1]",
+ "repositoryName=repositoryB",
+
"jcr:primaryType={http://www.jcp.org/jcr/nt/1.0}unstructured",
+
"dna:classname=org.jboss.dna.connector.inmemory.InMemoryRepositorySource");
+ assertThat(iter.hasNext(), is(false));
+ }
+
+ public void assertCreateNode( Iterator<Request> iterator,
+ String path,
+ String... properties ) {
+ Request nextCommand = iterator.next();
+ assertThat(nextCommand, is(instanceOf(CreateNodeRequest.class)));
+ CreateNodeRequest createNode = (CreateNodeRequest)nextCommand;
+ Path expectedPath = context.getValueFactories().getPathFactory().create(path);
+ assertThat(createNode.at().getPath(), is(expectedPath));
+ Map<Name, Property> propertiesByName = new HashMap<Name,
Property>();
+ for (Property prop : createNode.properties()) {
+ propertiesByName.put(prop.getName(), prop);
+ }
+ for (String propertyStr : properties) {
+ if (propertyStr == "any properties") {
+ propertiesByName.clear();
+ break;
+ }
+ Matcher matcher =
Pattern.compile("([^=]+)=(.*)").matcher(propertyStr);
+ if (!matcher.matches()) continue;
+ System.out.println("Property: " + propertyStr + " ==>
" + matcher);
+ Name propertyName =
context.getValueFactories().getNameFactory().create(matcher.group(1));
+ System.out.println("Property name: " + matcher.group(1));
+ String value = matcher.group(2); // doesn't handle multiple values!!
+ if (value.trim().length() == 0) value = null;
+ Property actual = propertiesByName.remove(propertyName);
+ Property expectedProperty = context.getPropertyFactory().create(propertyName,
value);
+ assertThat("missing property " + propertyName, actual,
is(expectedProperty));
+ }
+ if (!propertiesByName.isEmpty()) {
+ System.out.println("Properties for " + path + "\n" +
StringUtil.readableString(propertiesByName));
+ }
+ assertThat(propertiesByName.isEmpty(), is(true));
+ }
+
+ protected class MockRepositoryConnection implements RepositoryConnection {
+ public void close() {
+ }
+
+ @SuppressWarnings( "synthetic-access" )
+ public void execute( ExecutionContext context,
+ Request request ) throws RepositorySourceException {
+ lastExecutedRequest = request;
+ }
+
+ public CachePolicy getDefaultCachePolicy() {
+ return null;
+ }
+
+ @SuppressWarnings( "synthetic-access" )
+ public String getSourceName() {
+ return sourceName;
+ }
+
+ public XAResource getXAResource() {
+ return null;
+ }
+
+ public boolean ping( long time,
+ TimeUnit unit ) {
+ return true;
+ }
+
+ public void setListener( RepositorySourceListener listener ) {
+ }
+ }
+
+}
Property changes on:
trunk/dna-graph/src/test/java/org/jboss/dna/graph/GraphImporterTest.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: trunk/dna-graph/src/test/java/org/jboss/dna/graph/xml/XmlHandlerTest.java
===================================================================
--- trunk/dna-graph/src/test/java/org/jboss/dna/graph/xml/XmlHandlerTest.java 2008-10-29
15:16:23 UTC (rev 596)
+++ trunk/dna-graph/src/test/java/org/jboss/dna/graph/xml/XmlHandlerTest.java 2008-10-29
17:48:23 UTC (rev 597)
@@ -35,7 +35,7 @@
import org.jboss.dna.common.text.Jsr283Encoder;
import org.jboss.dna.common.text.TextDecoder;
import org.jboss.dna.graph.ExecutionContext;
-import org.jboss.dna.graph.Graph;
+import org.jboss.dna.graph.JcrLexicon;
import org.jboss.dna.graph.Location;
import org.jboss.dna.graph.connectors.BasicExecutionContext;
import org.jboss.dna.graph.properties.Name;
@@ -56,7 +56,7 @@
*/
public class XmlHandlerTest {
- private static final String JCR_NAMESPACE_URI =
"http://www.jcp.org/jcr/1.0";
+ private static final String NT_NAMESPACE_URI =
"http://www.jcp.org/jcr/nt/1.0";
private XmlHandler handler;
private ExecutionContext context;
@@ -65,37 +65,39 @@
private Path parentPath;
private TextDecoder decoder;
private Name nameAttribute;
+ private Name typeAttribute;
+ private Name typeAttributeValue;
private XmlHandler.AttributeScoping scoping;
private LinkedList<CreateNodeRequest> requests;
@Before
public void beforeEach() {
context = new BasicExecutionContext();
- context.getNamespaceRegistry().register("jcr", JCR_NAMESPACE_URI);
+ context.getNamespaceRegistry().register(JcrLexicon.Namespace.PREFIX,
JcrLexicon.Namespace.URI);
+ context.getNamespaceRegistry().register("nt", NT_NAMESPACE_URI);
destination = new RecordingDestination();
parentPath =
context.getValueFactories().getPathFactory().create("/a/b");
decoder = null;
- nameAttribute =
context.getValueFactories().getNameFactory().create("jcr:name");
+ nameAttribute = JcrLexicon.NAME;
+ typeAttribute = null;
+ typeAttributeValue = null;
scoping = XmlHandler.AttributeScoping.USE_DEFAULT_NAMESPACE;
- handler = new XmlHandler(destination, skipRootElement, parentPath, decoder,
nameAttribute, scoping);
+ handler = new XmlHandler(destination, skipRootElement, parentPath, decoder,
nameAttribute, typeAttribute,
+ typeAttributeValue, scoping);
}
@Test( expected = IllegalArgumentException.class )
public void shouldNotConstructInstanceWhenGivenNullDestination() {
destination = null;
- new XmlHandler(destination, skipRootElement, parentPath, decoder, nameAttribute,
scoping);
+ new XmlHandler(destination, skipRootElement, parentPath, decoder, nameAttribute,
typeAttribute, typeAttributeValue,
+ scoping);
}
- @Test( expected = IllegalArgumentException.class )
- public void shouldNotConstructInstanceWhenGivenNullGraph() {
- Graph graph = null;
- new XmlHandler(graph, true, skipRootElement, parentPath, decoder, nameAttribute,
scoping);
- }
-
@Test
public void shouldUseDefaultDecoderIfNoneIsProvidedInConstructor() {
decoder = null;
- handler = new XmlHandler(destination, skipRootElement, parentPath, decoder,
nameAttribute, scoping);
+ handler = new XmlHandler(destination, skipRootElement, parentPath, decoder,
nameAttribute, typeAttribute,
+ typeAttributeValue, scoping);
assertThat(handler.destination, is(sameInstance(destination)));
assertThat(handler.currentPath, is(sameInstance(parentPath)));
assertThat(handler.skipFirstElement, is(skipRootElement));
@@ -106,7 +108,8 @@
@Test
public void shouldUseDecoderProvidedInConstructor() {
decoder = new Jsr283Encoder();
- handler = new XmlHandler(destination, skipRootElement, parentPath, decoder,
nameAttribute, scoping);
+ handler = new XmlHandler(destination, skipRootElement, parentPath, decoder,
nameAttribute, typeAttribute,
+ typeAttributeValue, scoping);
assertThat(handler.destination, is(sameInstance(destination)));
assertThat(handler.currentPath, is(sameInstance(parentPath)));
assertThat(handler.skipFirstElement, is(skipRootElement));
@@ -117,7 +120,8 @@
@Test
public void shouldPlaceContentUnderRootIfNoPathIsProvidedInConstructor() {
parentPath = null;
- handler = new XmlHandler(destination, skipRootElement, parentPath, decoder,
nameAttribute, scoping);
+ handler = new XmlHandler(destination, skipRootElement, parentPath, decoder,
nameAttribute, typeAttribute,
+ typeAttributeValue, scoping);
assertThat(handler.destination, is(sameInstance(destination)));
assertThat(handler.currentPath.isRoot(), is(true));
assertThat(handler.skipFirstElement, is(skipRootElement));
@@ -128,7 +132,8 @@
@Test
public void shouldNotLookForNameAttributeIfNoneIsProvidedInConstructor() {
nameAttribute = null;
- handler = new XmlHandler(destination, skipRootElement, parentPath, decoder,
nameAttribute, scoping);
+ handler = new XmlHandler(destination, skipRootElement, parentPath, decoder,
nameAttribute, typeAttribute,
+ typeAttributeValue, scoping);
assertThat(handler.destination, is(sameInstance(destination)));
assertThat(handler.currentPath, is(sameInstance(parentPath)));
assertThat(handler.skipFirstElement, is(skipRootElement));
@@ -199,9 +204,11 @@
@Test
public void shouldParseXmlDocumentWithNamespacesThatAreNotYetInRegistry() throws
IOException, SAXException {
NamespaceRegistry reg = context.getNamespaceRegistry();
- reg.unregister(JCR_NAMESPACE_URI);
+ reg.unregister(JcrLexicon.Namespace.URI);
+ reg.unregister(NT_NAMESPACE_URI);
// Verify the prefixes don't exist ...
- assertThat(reg.getPrefixForNamespaceUri(JCR_NAMESPACE_URI, false),
is(nullValue()));
+ assertThat(reg.getPrefixForNamespaceUri(JcrLexicon.Namespace.URI, false),
is(nullValue()));
+ assertThat(reg.getPrefixForNamespaceUri(NT_NAMESPACE_URI, false),
is(nullValue()));
assertThat(reg.getPrefixForNamespaceUri("http://default.namespace.com",
false), is(nullValue()));
// Parse the XML file ...
parse("xmlHandler/docWithNestedNamespaces.xml");
@@ -249,7 +256,8 @@
context.getNamespaceRegistry().register("c",
"http://default.namespace.com");
parentPath = null;
skipRootElement = true;
- handler = new XmlHandler(destination, skipRootElement, parentPath, decoder,
nameAttribute, scoping);
+ handler = new XmlHandler(destination, skipRootElement, parentPath, decoder,
nameAttribute, typeAttribute,
+ typeAttributeValue, scoping);
parse("xmlHandler/docWithNamespaces.xml");
// Check the generated content; note that the attribute name DOES match, so the
nodes names come from "jcr:name" attribute
assertNode("c:Hybrid");
@@ -264,7 +272,8 @@
@Test
public void shouldParseXmlDocumentAndShouldPlaceContentUnderNonRootNode() throws
IOException, SAXException {
parentPath =
context.getValueFactories().getPathFactory().create("/a/b");
- handler = new XmlHandler(destination, skipRootElement, parentPath, decoder,
nameAttribute, scoping);
+ handler = new XmlHandler(destination, skipRootElement, parentPath, decoder,
nameAttribute, typeAttribute,
+ typeAttributeValue, scoping);
context.getNamespaceRegistry().register("c",
"http://default.namespace.com");
parse("xmlHandler/docWithNamespaces.xml");
// Check the generated content; note that the attribute name DOES match, so the
nodes names come from "jcr:name" attribute
@@ -281,7 +290,8 @@
@Test
public void shouldParseXmlDocumentAndShouldPlaceContentUnderRootNode() throws
IOException, SAXException {
parentPath = null;
- handler = new XmlHandler(destination, skipRootElement, parentPath, decoder,
nameAttribute, scoping);
+ handler = new XmlHandler(destination, skipRootElement, parentPath, decoder,
nameAttribute, typeAttribute,
+ typeAttributeValue, scoping);
context.getNamespaceRegistry().register("c",
"http://default.namespace.com");
parse("xmlHandler/docWithNamespaces.xml");
// Check the generated content; note that the attribute name DOES match, so the
nodes names come from "jcr:name" attribute
@@ -309,6 +319,46 @@
assertNode("c:Cars/c:Sports/Infiniti G37", "maker=Infiniti",
"model=G37");
}
+ @Test
+ public void shouldParseXmlDocumentWithoutNamespacesUsingTypeAttributeValue() throws
IOException, SAXException {
+ typeAttribute = JcrLexicon.PRIMARY_TYPE;
+ typeAttributeValue =
context.getValueFactories().getNameFactory().create("nt:unstructured");
+ handler = new XmlHandler(destination, skipRootElement, parentPath, decoder,
nameAttribute, typeAttribute,
+ typeAttributeValue, scoping);
+ parse("xmlHandler/docWithoutNamespaces.xml");
+ // Check the generated content; note that the attribute name doesn't match,
so the nodes don't get special names
+ String unstructPrimaryType =
"jcr:primaryType={http://www.jcp.org/jcr/nt/1.0}unstructured";
+ assertNode("Cars", unstructPrimaryType);
+ assertNode("Cars/Hybrid", unstructPrimaryType);
+ assertNode("Cars/Hybrid/car", unstructPrimaryType, "name=Toyota
Prius", "maker=Toyota", "model=Prius");
+ assertNode("Cars/Hybrid/car", unstructPrimaryType, "name=Toyota
Highlander", "maker=Toyota", "model=Highlander");
+ assertNode("Cars/Hybrid/car", unstructPrimaryType, "name=Nissan
Altima", "maker=Nissan", "model=Altima");
+ assertNode("Cars/Sports", unstructPrimaryType);
+ assertNode("Cars/Sports/car", unstructPrimaryType, "name=Aston
Martin DB9", "maker=Aston Martin", "model=DB9");
+ assertNode("Cars/Sports/car", unstructPrimaryType, "name=Infiniti
G37", "maker=Infiniti", "model=G37");
+ }
+
+ @Test
+ public void shouldParseXmlDocumentWithNamespacesUsingTypeAttributeValue() throws
IOException, SAXException {
+ context.getNamespaceRegistry().register("c",
"http://default.namespace.com");
+ typeAttribute = JcrLexicon.PRIMARY_TYPE;
+ typeAttributeValue =
context.getValueFactories().getNameFactory().create("nt:unstructured");
+ handler = new XmlHandler(destination, skipRootElement, parentPath, decoder,
nameAttribute, typeAttribute,
+ typeAttributeValue, scoping);
+ parse("xmlHandler/docWithNamespaces.xml");
+ // Check the generated content; note that the attribute name doesn't match,
so the nodes don't get special names
+ String unstructPrimaryType =
"jcr:primaryType={http://www.jcp.org/jcr/nt/1.0}unstructured";
+ String carPrimaryType =
"jcr:primaryType={http://default.namespace.com}car";
+ assertNode("c:Cars", unstructPrimaryType);
+ assertNode("c:Cars/c:Hybrid", unstructPrimaryType);
+ assertNode("c:Cars/c:Hybrid/Toyota Prius", carPrimaryType,
"maker=Toyota", "model=Prius");
+ assertNode("c:Cars/c:Hybrid/Toyota Highlander", carPrimaryType,
"maker=Toyota", "model=Highlander");
+ assertNode("c:Cars/c:Hybrid/Nissan Altima", carPrimaryType,
"maker=Nissan", "model=Altima");
+ assertNode("c:Cars/c:Sports", unstructPrimaryType);
+ assertNode("c:Cars/c:Sports/Aston Martin DB9", carPrimaryType,
"maker=Aston Martin", "model=DB9");
+ assertNode("c:Cars/c:Sports/Infiniti G37", carPrimaryType,
"maker=Infiniti", "model=G37");
+ }
+
protected void assertNode( String path,
String... properties ) {
// Create the expected path ...
@@ -335,7 +385,16 @@
assertThat(expected, is(notNullValue()));
assertThat(actual, is(expected));
}
- assertThat(expectedProperties.isEmpty(), is(true));
+ if (!expectedProperties.isEmpty()) {
+ StringBuilder msg = new StringBuilder("missing actual properties:
");
+ boolean isFirst = true;
+ for (Property expected : expectedProperties.values()) {
+ if (!isFirst) msg.append(", ");
+ else isFirst = false;
+ msg.append(expected.getName());
+ }
+ assertThat(msg.toString(), expectedProperties.isEmpty(), is(true));
+ }
}
protected void parse( String relativePathToXmlFile ) throws IOException, SAXException
{
@@ -354,7 +413,8 @@
private final LinkedList<CreateNodeRequest> requests = new
LinkedList<CreateNodeRequest>();
public void create( Path path,
- List<Property> properties ) {
+ List<Property> properties,
+ Name elementName ) {
requests.add(new CreateNodeRequest(new Location(path), properties));
}
Modified: trunk/dna-graph/src/test/java/org/jboss/dna/graph/xml/XmlSequencerTest.java
===================================================================
--- trunk/dna-graph/src/test/java/org/jboss/dna/graph/xml/XmlSequencerTest.java 2008-10-29
15:16:23 UTC (rev 596)
+++ trunk/dna-graph/src/test/java/org/jboss/dna/graph/xml/XmlSequencerTest.java 2008-10-29
17:48:23 UTC (rev 597)
@@ -31,7 +31,6 @@
import org.jboss.dna.common.monitor.ProgressMonitor;
import org.jboss.dna.common.monitor.SimpleProgressMonitor;
import org.jboss.dna.graph.properties.Name;
-import org.jboss.dna.graph.properties.NameFactory;
import org.jboss.dna.graph.sequencers.MockSequencerContext;
import org.jboss.dna.graph.sequencers.MockSequencerOutput;
import org.jboss.dna.graph.sequencers.SequencerContext;
@@ -102,38 +101,38 @@
@Test
public void shouldSequenceXml() throws IOException {
verifyDocument(xml1);
- verifyName(COMMENT + "[1]", NameFactory.JCR_PRIMARY_TYPE, COMMENT);
+ verifyName(COMMENT + "[1]", "jcr:primaryType", COMMENT);
String text = verify(COMMENT + "[1]", COMMENT_CONTENT, String.class);
assertThat(text.startsWith("\n Licensed to the Apache Software Foundation
(ASF)"), is(true));
assertThat(text.endsWith(" limitations under the License.\n"),
is(true));
verifyString("/", DTD_NAME, "Repository");
verifyString("/", DTD_PUBLIC_ID, "-//The Apache Software
Foundation//DTD Jackrabbit 1.2//EN");
verifyString("/", DTD_SYSTEM_ID,
"http://jackrabbit.apache.org/dtd/repository-1.2.dtd");
- verifyName(COMMENT + "[2]", NameFactory.JCR_PRIMARY_TYPE, COMMENT);
+ verifyName(COMMENT + "[2]", "jcr:primaryType", COMMENT);
verifyString(COMMENT + "[2]", COMMENT_CONTENT, " Example
Repository Configuration File ");
- verifyName("Repository[1]", NameFactory.JCR_PRIMARY_TYPE,
"nt:unstructured");
- verifyName("Repository[1]/" + COMMENT + "[1]",
NameFactory.JCR_PRIMARY_TYPE, COMMENT);
+ verifyName("Repository[1]", "jcr:primaryType",
"nt:unstructured");
+ verifyName("Repository[1]/" + COMMENT + "[1]",
"jcr:primaryType", COMMENT);
}
@Test
public void shouldHandleNamespaces() throws IOException {
verifyDocument(xml2);
- verifyName("book[1]/bookinfo[1]/xi:include[1]",
NameFactory.JCR_PRIMARY_TYPE, "nt:unstructured");
+ verifyName("book[1]/bookinfo[1]/xi:include[1]",
"jcr:primaryType", "nt:unstructured");
verifyString("book[1]/bookinfo[1]/xi:include[1]", "xi:href",
"Author_Group.xml");
- verifyName("book[1]/bookinfo[1]/xi:include[2]",
NameFactory.JCR_PRIMARY_TYPE, "nt:unstructured");
+ verifyName("book[1]/bookinfo[1]/xi:include[2]",
"jcr:primaryType", "nt:unstructured");
verifyString("book[1]/bookinfo[1]/xi:include[2]", "xi:href",
"Legal_Notice.xml");
}
@Test
public void shouldSequenceEntityDeclarations() throws IOException {
verifyDocument(xml2);
- verifyName(ENTITY + "[1]", NameFactory.JCR_PRIMARY_TYPE, ENTITY);
+ verifyName(ENTITY + "[1]", "jcr:primaryType", ENTITY);
verifyString(ENTITY + "[1]", DTD_NAME, "%RH-ENTITIES");
verifyString(ENTITY + "[1]", DTD_SYSTEM_ID,
"Common_Config/rh-entities.ent");
- verifyName(ENTITY + "[2]", NameFactory.JCR_PRIMARY_TYPE, ENTITY);
+ verifyName(ENTITY + "[2]", "jcr:primaryType", ENTITY);
verifyString(ENTITY + "[2]", DTD_NAME, "versionNumber");
verifyString(ENTITY + "[2]", DTD_VALUE, "0.1");
- verifyName(ENTITY + "[3]", NameFactory.JCR_PRIMARY_TYPE, ENTITY);
+ verifyName(ENTITY + "[3]", "jcr:primaryType", ENTITY);
verifyString(ENTITY + "[3]", DTD_NAME, "copyrightYear");
verifyString(ENTITY + "[3]", DTD_VALUE, "2008");
}
@@ -173,7 +172,7 @@
@Test
public void shouldSequenceProcessingInstructions() throws IOException {
verifyDocument(xml4);
- verifyName(PI + "[1]", NameFactory.JCR_PRIMARY_TYPE, PI);
+ verifyName(PI + "[1]", "jcr:primaryType", PI);
verifyString(PI + "[1]", TARGET, "eclipse");
verifyString(PI + "[1]", PI_CONTENT,
"version=\"3.0\"");
}
@@ -181,10 +180,10 @@
@Test
public void shouldSequenceXsds() throws IOException {
verifyDocument(xsd);
- verifyName("xs:schema[1]", NameFactory.JCR_PRIMARY_TYPE,
"nt:unstructured");
+ verifyName("xs:schema[1]", "jcr:primaryType",
"nt:unstructured");
verifyString("xs:schema[1]", "xs:targetNamespace",
"http://ns.adobe.com/air/application/1.0");
verifyString("xs:schema[1]", "xs:elementFormDefault",
"qualified");
- verifyName("xs:schema[1]/xs:element[1]", NameFactory.JCR_PRIMARY_TYPE,
"nt:unstructured");
+ verifyName("xs:schema[1]/xs:element[1]", "jcr:primaryType",
"nt:unstructured");
verifyString("xs:schema[1]/xs:element[1]", "xs:name",
"application");
}
@@ -203,7 +202,7 @@
stream = url.openStream();
assertThat(stream, is(notNullValue()));
sequencer.sequence(stream, output, context, monitor);
- verifyName("", NameFactory.JCR_PRIMARY_TYPE, DOCUMENT);
+ verifyName("", "jcr:primaryType", DOCUMENT);
}
private void verifyName( String nodePath,
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrLexicon.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrLexicon.java 2008-10-29 15:16:23 UTC
(rev 596)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrLexicon.java 2008-10-29 17:48:23 UTC
(rev 597)
@@ -21,18 +21,10 @@
*/
package org.jboss.dna.jcr;
-import org.jboss.dna.graph.properties.Name;
-import org.jboss.dna.graph.properties.basic.BasicName;
/**
* @author Randall Hauch
*/
-class JcrLexicon {
+class JcrLexicon extends org.jboss.dna.graph.JcrLexicon {
- public static class Namespace {
- public static final String URI = "http://www.jcp.org/jcr/1.0";
- public static final String PREFIX = "jcr";
- }
-
- public static final Name UUID = new BasicName(Namespace.URI, "uuid");
}
Modified:
trunk/dna-repository/src/main/java/org/jboss/dna/repository/sequencers/SequencerOutputMap.java
===================================================================
---
trunk/dna-repository/src/main/java/org/jboss/dna/repository/sequencers/SequencerOutputMap.java 2008-10-29
15:16:23 UTC (rev 596)
+++
trunk/dna-repository/src/main/java/org/jboss/dna/repository/sequencers/SequencerOutputMap.java 2008-10-29
17:48:23 UTC (rev 597)
@@ -32,8 +32,8 @@
import net.jcip.annotations.NotThreadSafe;
import org.jboss.dna.common.util.CheckArg;
import org.jboss.dna.common.util.StringUtil;
+import org.jboss.dna.graph.JcrLexicon;
import org.jboss.dna.graph.properties.Name;
-import org.jboss.dna.graph.properties.NameFactory;
import org.jboss.dna.graph.properties.Path;
import org.jboss.dna.graph.properties.PathFactory;
import org.jboss.dna.graph.properties.ValueFactories;
@@ -230,8 +230,8 @@
*/
public int compareTo( PropertyValue that ) {
if (this == that) return 0;
- if (this.name.equals(NameFactory.JCR_PRIMARY_TYPE)) return -1;
- if (that.name.equals(NameFactory.JCR_PRIMARY_TYPE)) return 1;
+ if (this.name.equals(JcrLexicon.PRIMARY_TYPE)) return -1;
+ if (that.name.equals(JcrLexicon.PRIMARY_TYPE)) return 1;
return this.name.compareTo(that.name);
}
Modified:
trunk/dna-repository/src/test/java/org/jboss/dna/repository/sequencers/SequencerNodeContextTest.java
===================================================================
---
trunk/dna-repository/src/test/java/org/jboss/dna/repository/sequencers/SequencerNodeContextTest.java 2008-10-29
15:16:23 UTC (rev 596)
+++
trunk/dna-repository/src/test/java/org/jboss/dna/repository/sequencers/SequencerNodeContextTest.java 2008-10-29
17:48:23 UTC (rev 597)
@@ -30,7 +30,6 @@
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import org.jboss.dna.common.jcr.AbstractJcrRepositoryTest;
-import org.jboss.dna.graph.properties.NameFactory;
import org.jboss.dna.graph.properties.NamespaceRegistry;
import org.jboss.dna.graph.properties.Property;
import org.jboss.dna.graph.sequencers.SequencerContext;
@@ -160,7 +159,7 @@
assertThat(sequencerContext.getInputProperties().isEmpty(), is(false));
assertThat(sequencerContext.getInputProperties().size(), is(3));
verifyProperty(sequencerContext,
- NameFactory.JCR_PRIMARY_TYPE,
+ "jcr:primaryType",
execContext.getValueFactories().getNameFactory().create("{http://www...);
verifyProperty(sequencerContext, "x", true);
verifyProperty(sequencerContext, "y", "asdf",
"xyzzy");
Modified:
trunk/docs/examples/gettingstarted/repositories/src/main/java/org/jboss/example/dna/repository/RepositoryClient.java
===================================================================
---
trunk/docs/examples/gettingstarted/repositories/src/main/java/org/jboss/example/dna/repository/RepositoryClient.java 2008-10-29
15:16:23 UTC (rev 596)
+++
trunk/docs/examples/gettingstarted/repositories/src/main/java/org/jboss/example/dna/repository/RepositoryClient.java 2008-10-29
17:48:23 UTC (rev 597)
@@ -54,6 +54,7 @@
import org.jboss.dna.jcr.JcrRepository;
import org.jboss.dna.repository.RepositoryLibrary;
import org.jboss.dna.repository.RepositoryService;
+import org.xml.sax.SAXException;
/**
* @author Randall Hauch
@@ -122,9 +123,10 @@
* repositories.
*
* @throws IOException if there is a problem initializing the repositories from the
files.
+ * @throws SAXException if there is a problem with the SAX Parser
* @throws NamingException if there is a problem registering or looking up objects in
JNDI
*/
- public void startRepositories() throws IOException, NamingException {
+ public void startRepositories() throws IOException, SAXException, NamingException {
if (repositoryService != null) return; // already started
// Create the factory for execution contexts.