You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by kw...@apache.org on 2020/02/13 11:36:09 UTC
svn commit: r1873974 - in
/jackrabbit/commons/filevault/trunk/vault-validation/src:
main/java/org/apache/jackrabbit/vault/validation/impl/util/
main/java/org/apache/jackrabbit/vault/validation/spi/
test/java/org/apache/jackrabbit/vault/validation/ test...
Author: kwin
Date: Thu Feb 13 11:36:09 2020
New Revision: 1873974
URL: http://svn.apache.org/viewvc?rev=1873974&view=rev
Log:
JCRVLT-409 emit node names in expanded form
Modified:
jackrabbit/commons/filevault/trunk/vault-validation/src/main/java/org/apache/jackrabbit/vault/validation/impl/util/DocumentViewXmlContentHandler.java
jackrabbit/commons/filevault/trunk/vault-validation/src/main/java/org/apache/jackrabbit/vault/validation/spi/DocumentViewXmlValidator.java
jackrabbit/commons/filevault/trunk/vault-validation/src/test/java/org/apache/jackrabbit/vault/validation/DocumentViewParserValidatorTest.java
jackrabbit/commons/filevault/trunk/vault-validation/src/test/resources/simple-package/jcr_root/apps/.content.xml
Modified: jackrabbit/commons/filevault/trunk/vault-validation/src/main/java/org/apache/jackrabbit/vault/validation/impl/util/DocumentViewXmlContentHandler.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-validation/src/main/java/org/apache/jackrabbit/vault/validation/impl/util/DocumentViewXmlContentHandler.java?rev=1873974&r1=1873973&r2=1873974&view=diff
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-validation/src/main/java/org/apache/jackrabbit/vault/validation/impl/util/DocumentViewXmlContentHandler.java (original)
+++ jackrabbit/commons/filevault/trunk/vault-validation/src/main/java/org/apache/jackrabbit/vault/validation/impl/util/DocumentViewXmlContentHandler.java Thu Feb 13 11:36:09 2020
@@ -25,9 +25,15 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import javax.jcr.NamespaceException;
+import javax.xml.namespace.QName;
+
import org.apache.jackrabbit.spi.Name;
+import org.apache.jackrabbit.spi.commons.conversion.IllegalNameException;
+import org.apache.jackrabbit.spi.commons.conversion.NameParser;
import org.apache.jackrabbit.spi.commons.name.NameConstants;
import org.apache.jackrabbit.spi.commons.name.NameFactoryImpl;
+import org.apache.jackrabbit.spi.commons.namespace.NamespaceResolver;
import org.apache.jackrabbit.util.ISO9075;
import org.apache.jackrabbit.util.Text;
import org.apache.jackrabbit.vault.util.DocViewNode;
@@ -43,7 +49,7 @@ import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/** TODO: reuse more logic from DocViewSAXImporter (https://issues.apache.org/jira/browse/JCRVLT-357) */
-public class DocumentViewXmlContentHandler extends DefaultHandler {
+public class DocumentViewXmlContentHandler extends DefaultHandler implements NamespaceResolver {
private final @NotNull Map<String, Integer> nodePathsAndLineNumbers;
private String rootNodeName;
@@ -54,6 +60,7 @@ public class DocumentViewXmlContentHandl
private Deque<DocViewNode> nodeStack;
private Deque<String> nodePathStack;
private final Map<String, DocumentViewXmlValidator> validators;
+ private final Map<String, String> namespaceRegistry;
private @NotNull List<ValidationViolation> violations;
@@ -96,31 +103,76 @@ public class DocumentViewXmlContentHandl
nodePathStack = new LinkedList<>();
this.validators = documentViewXmlValidators;
violations = new LinkedList<>();
+ namespaceRegistry = new HashMap<>();
}
+
@Override
- public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
- // convert to DocViewNode (mostly taken over from DocViewSAXImporter#startElement)
- String label = ISO9075.decode(qName);
- if (elementNameStack.isEmpty()) {
- if (localName.equals(NameConstants.JCR_ROOT.getLocalName())
- && uri.equals(NameConstants.JCR_ROOT.getNamespaceURI())) {
- // take over node name from file name
- label = rootNodeName;
- } else {
- // element name takes precedence over file name
- rootNodeName = label;
- }
+ public void startPrefixMapping(String prefix, String uri) throws SAXException {
+ namespaceRegistry.put(prefix, uri);
+ }
+
+
+ @Override
+ public void endPrefixMapping(String prefix) throws SAXException {
+ namespaceRegistry.remove(prefix);
+ }
+
+
+ @Override
+ public String getPrefix(String uri) throws NamespaceException {
+ throw new UnsupportedOperationException("Only resolving from prefix to URI is supported, but not vice-versa");
+ }
+
+
+ @Override
+ public String getURI(String prefix) throws NamespaceException {
+ if (prefix.isEmpty()) {
+ return Name.NS_DEFAULT_URI;
}
+ return namespaceRegistry.get(prefix);
+ }
- String name = label; // name is usually the same except for SNS nodes
+ private Name getExpandedName(String name) throws IllegalNameException, NamespaceException {
+ return NameParser.parse(name, this, NameFactoryImpl.getInstance());
+ }
+
+ /**
+ * Resolves the ISO-9075 encoding and removes a same-name sibling suffix from the name which is either a localName or qualified name
+ * @param name
+ * @return the normalized name
+ */
+ private String getNormalizedName(String name) {
// in the case of SNS nodes the name contains an index in brackets as suffix
+ name = ISO9075.decode(name);
int idx = name.lastIndexOf('[');
if (idx > 0) {
name = name.substring(0, idx);
}
- elementNameStack.push(name);
+ return name;
+ }
+
+ @Override
+ public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
+ // convert to DocViewNode (mostly taken over from DocViewSAXImporter#startElement)
+ String label = qName;
+ Name name;
+ if (elementNameStack.isEmpty() && localName.equals(NameConstants.JCR_ROOT.getLocalName())
+ && uri.equals(NameConstants.JCR_ROOT.getNamespaceURI())) {
+ // take over node name from file name
+ label = rootNodeName;
+ try {
+ name = getExpandedName(rootNodeName);
+ } catch (IllegalNameException|NamespaceException e) {
+ throw new SAXException("Given root node name (implicitly given via filename) cannot be resolved. The prefix used in the filename must be defined in the XML as well!", e);
+ }
+ } else {
+ name = NameFactoryImpl.getInstance().create(uri, getNormalizedName(localName));
+ }
+
+ // the path is being given via the qualified (prefixed) names
+ elementNameStack.push(label);
// add fully qualified name
StringBuilder nodePath = new StringBuilder(rootNodeParentPath);
@@ -129,8 +181,9 @@ public class DocumentViewXmlContentHandl
nodePath.append("/").append(iterator.next());
}
nodePathStack.push(nodePath.toString());
+
try {
- DocViewNode node = getDocViewNode(name, label, attributes);
+ DocViewNode node = getDocViewNode(name, qName, attributes);
nodeStack.push(node);
violations.add(new ValidationViolation(ValidationMessageSeverity.DEBUG, "Validate node '" + node + "' start"));
for (Map.Entry<String, DocumentViewXmlValidator> entry : validators.entrySet()) {
@@ -153,7 +206,7 @@ public class DocumentViewXmlContentHandl
}
}
- private DocViewNode getDocViewNode(String name, String label, Attributes attributes) {
+ private DocViewNode getDocViewNode(Name name, String label, Attributes attributes) {
Map<String, DocViewProperty> propertyMap = new HashMap<>();
String uuid = null;
@@ -173,8 +226,7 @@ public class DocumentViewXmlContentHandl
mixins = property.values;
}
}
-
- return new DocViewNode(name, label, uuid, propertyMap, mixins, primary);
+ return new DocViewNode(name.toString(), label, uuid, propertyMap, mixins, primary);
}
/** @return a Collection of absolute node paths (i.e. starting with "/") with "/" as path delimiter. */
Modified: jackrabbit/commons/filevault/trunk/vault-validation/src/main/java/org/apache/jackrabbit/vault/validation/spi/DocumentViewXmlValidator.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-validation/src/main/java/org/apache/jackrabbit/vault/validation/spi/DocumentViewXmlValidator.java?rev=1873974&r1=1873973&r2=1873974&view=diff
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-validation/src/main/java/org/apache/jackrabbit/vault/validation/spi/DocumentViewXmlValidator.java (original)
+++ jackrabbit/commons/filevault/trunk/vault-validation/src/main/java/org/apache/jackrabbit/vault/validation/spi/DocumentViewXmlValidator.java Thu Feb 13 11:36:09 2020
@@ -20,7 +20,9 @@ import java.nio.file.Path;
import java.util.Collection;
import org.apache.jackrabbit.spi.Name;
+import org.apache.jackrabbit.spi.commons.name.NameConstants;
import org.apache.jackrabbit.vault.util.DocViewNode;
+import org.apache.jackrabbit.vault.validation.spi.util.NameUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.osgi.annotation.versioning.ProviderType;
@@ -37,10 +39,11 @@ public interface DocumentViewXmlValidato
/**
* Called for the beginning of each new JCR document view node.
* Deserialization of the node information was already done when this method is called!
- * The attribute names have the string representation outlined in {@link Name} (i.e. including the expanded namespace uri in the format <code>{namespaceURI}localPart</code>).
+ * The node and attribute names have the string representation outlined in {@link Name} (i.e. including the namespace uri in the format <code>{namespaceURI}localPart</code>).
* This is also referred to as <a href="https://docs.adobe.com/docs/en/spec/jcr/2.0/3_Repository_Model.html#3.2.5.1%20Expanded%20Form">JCR name expanded form</a>.
* To construct such names either use {@link NameUtil} or use the constants from {@link NameConstants}.
*
+ * The node's label refers to the XML element name specifying the node. There shouldn't be any checks derived from it, but only from the expanded name.
* @param node the node which should be validated
* @param nodePath the absolute repository path of the given node
* @param filePath the relative file path of the docview file containing this node
Modified: jackrabbit/commons/filevault/trunk/vault-validation/src/test/java/org/apache/jackrabbit/vault/validation/DocumentViewParserValidatorTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-validation/src/test/java/org/apache/jackrabbit/vault/validation/DocumentViewParserValidatorTest.java?rev=1873974&r1=1873973&r2=1873974&view=diff
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-validation/src/test/java/org/apache/jackrabbit/vault/validation/DocumentViewParserValidatorTest.java (original)
+++ jackrabbit/commons/filevault/trunk/vault-validation/src/test/java/org/apache/jackrabbit/vault/validation/DocumentViewParserValidatorTest.java Thu Feb 13 11:36:09 2020
@@ -83,21 +83,24 @@ public class DocumentViewParserValidator
Collection<ValidationMessage> messages = validator.validateJcrData(input, Paths.get("apps", ".content.xml"), nodePathsAndLineNumbers);
// filter
ValidationExecutorTest.assertViolation(messages,
- new ValidationViolation("docviewid", ValidationMessageSeverity.ERROR, "startDocView", Paths.get("apps/.content.xml"), Paths.get(""), "/apps", 19, 36, null
+ new ValidationViolation("docviewid", ValidationMessageSeverity.ERROR, "startDocView", Paths.get("apps/.content.xml"), Paths.get(""), "/apps", 19, 35, null
),
new ValidationViolation("docviewid", ValidationMessageSeverity.ERROR,
- "startDocView", Paths.get("apps/.content.xml"), Paths.get(""), "/apps/somepath", 22, 6, null));
+ "startDocView", Paths.get("apps/.content.xml"), Paths.get(""), "/apps/somepath", 21, 29, null),
+ new ValidationViolation("docviewid", ValidationMessageSeverity.ERROR,
+ "startDocView", Paths.get("apps/.content.xml"), Paths.get(""), "/apps/somepath/jc:content", 22, 54, null));
// verify node names
Map<String, Integer> expectedNodePathsAndLineNumber = new HashMap<>();
expectedNodePathsAndLineNumber.put("/apps", 19);
- expectedNodePathsAndLineNumber.put("/apps/somepath", 22);
+ expectedNodePathsAndLineNumber.put("/apps/somepath", 21);
+ expectedNodePathsAndLineNumber.put("/apps/somepath/jc:content", 22);
Assert.assertEquals(expectedNodePathsAndLineNumber, nodePathsAndLineNumbers);
Map<String, DocViewProperty> properties = new HashMap<>();
properties.put(NameConstants.JCR_PRIMARYTYPE.toString(),
new DocViewProperty(NameConstants.JCR_PRIMARYTYPE.toString(), new String[] { "sling:Folder" }, false,
PropertyType.UNDEFINED));
- DocViewNode node = new DocViewNode("apps", "apps", null, properties, null, "sling:Folder");
+ DocViewNode node = new DocViewNode("{}apps", "jc:root", null, properties, null, "sling:Folder");
Mockito.verify(docViewXmlValidator).validate(node, "/apps", Paths.get("apps", ".content.xml"), true);
properties = new HashMap<>();
@@ -105,8 +108,15 @@ public class DocumentViewParserValidator
new DocViewProperty(NameConstants.JCR_PRIMARYTYPE.toString(), new String[] { JcrConstants.NT_UNSTRUCTURED }, false,
PropertyType.UNDEFINED));
properties.put("{}attribute1", new DocViewProperty("{}attribute1", new String[] { "value1" }, false, PropertyType.UNDEFINED));
- node = new DocViewNode("somepath", "somepath", null, properties, null, JcrConstants.NT_UNSTRUCTURED);
+ node = new DocViewNode("{}somepath", "somepath", null, properties, null, JcrConstants.NT_UNSTRUCTURED);
Mockito.verify(docViewXmlValidator).validate(node, "/apps/somepath", Paths.get("apps", ".content.xml"), false);
+
+ properties = new HashMap<>();
+ properties.put(NameConstants.JCR_PRIMARYTYPE.toString(),
+ new DocViewProperty(NameConstants.JCR_PRIMARYTYPE.toString(), new String[] { JcrConstants.NT_UNSTRUCTURED }, false,
+ PropertyType.UNDEFINED));
+ node = new DocViewNode("{http://www.jcp.org/jcr/1.0}content", "jc:content", null, properties, null, JcrConstants.NT_UNSTRUCTURED);
+ Mockito.verify(docViewXmlValidator).validate(node, "/apps/somepath/jc:content", Paths.get("apps", ".content.xml"), false);
}
}
@@ -136,7 +146,7 @@ public class DocumentViewParserValidator
properties.put(NameConstants.JCR_PRIMARYTYPE.toString(),
new DocViewProperty(NameConstants.JCR_PRIMARYTYPE.toString(), new String[] { "sling:Folder" }, false,
PropertyType.UNDEFINED));
- DocViewNode node = new DocViewNode("child1", "child1", null, properties, null, "sling:Folder");
+ DocViewNode node = new DocViewNode("{}child1", "jcr:root", null, properties, null, "sling:Folder");
Mockito.verify(docViewXmlValidator).validate(node, "/apps/child1", Paths.get("apps", "child1.xml"), true);
properties = new HashMap<>();
@@ -144,7 +154,7 @@ public class DocumentViewParserValidator
new DocViewProperty(NameConstants.JCR_PRIMARYTYPE.toString(), new String[] { JcrConstants.NT_UNSTRUCTURED }, false,
PropertyType.UNDEFINED));
properties.put("{}attribute1", new DocViewProperty("{}attribute1", new String[] { "value1" }, false, PropertyType.UNDEFINED));
- node = new DocViewNode("somepath", "somepath", null, properties, null, JcrConstants.NT_UNSTRUCTURED);
+ node = new DocViewNode("{}somepath", "somepath", null, properties, null, JcrConstants.NT_UNSTRUCTURED);
Mockito.verify(docViewXmlValidator).validate(node, "/apps/child1/somepath", Paths.get("apps", "child1.xml"), false);
// verify node names
@@ -166,7 +176,7 @@ public class DocumentViewParserValidator
properties.put(NameConstants.JCR_PRIMARYTYPE.toString(),
new DocViewProperty(NameConstants.JCR_PRIMARYTYPE.toString(), new String[] { "sling:Folder" }, false,
PropertyType.UNDEFINED));
- DocViewNode node = new DocViewNode("child3", "child3", null, properties, null, "sling:Folder");
+ DocViewNode node = new DocViewNode("{}child3", "child3", null, properties, null, "sling:Folder");
Mockito.verify(docViewXmlValidator).validate(node, "/apps/child3", Paths.get("apps", "child2", ".content.xml"), true);
properties = new HashMap<>();
@@ -174,7 +184,7 @@ public class DocumentViewParserValidator
new DocViewProperty(NameConstants.JCR_PRIMARYTYPE.toString(), new String[] { JcrConstants.NT_UNSTRUCTURED }, false,
PropertyType.UNDEFINED));
properties.put("{}attribute1", new DocViewProperty("{}attribute1", new String[] { "value1" }, false, PropertyType.UNDEFINED));
- node = new DocViewNode("somepath", "somepath", null, properties, null, JcrConstants.NT_UNSTRUCTURED);
+ node = new DocViewNode("{}somepath", "somepath", null, properties, null, JcrConstants.NT_UNSTRUCTURED);
Mockito.verify(docViewXmlValidator).validate(node, "/apps/child3/somepath", Paths.get("apps", "child2", ".content.xml"), false);
// verify node names
Modified: jackrabbit/commons/filevault/trunk/vault-validation/src/test/resources/simple-package/jcr_root/apps/.content.xml
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-validation/src/test/resources/simple-package/jcr_root/apps/.content.xml?rev=1873974&r1=1873973&r2=1873974&view=diff
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-validation/src/test/resources/simple-package/jcr_root/apps/.content.xml (original)
+++ jackrabbit/commons/filevault/trunk/vault-validation/src/test/resources/simple-package/jcr_root/apps/.content.xml Thu Feb 13 11:36:09 2020
@@ -15,9 +15,11 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
- jcr:primaryType="sling:Folder">
- <somepath jcr:primaryType="nt:unstructured"
- attribute1="value1"
- ></somepath>
-</jcr:root>
+<jc:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jc="http://www.jcp.org/jcr/1.0"
+ jc:primaryType="sling:Folder">
+ <somepath jc:primaryType="nt:unstructured"
+ attribute1="value1">
+ <jc:content jc:primaryType="nt:unstructured">
+ </jc:content>
+ </somepath>
+</jc:root>