You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by tr...@apache.org on 2014/10/28 01:28:32 UTC
svn commit: r1634753 - in /jackrabbit/commons/filevault/trunk/vault-core/src:
main/java/org/apache/jackrabbit/vault/fs/impl/io/
main/java/org/apache/jackrabbit/vault/util/
test/java/org/apache/jackrabbit/vault/packaging/integration/
Author: tripod
Date: Tue Oct 28 00:28:32 2014
New Revision: 1634753
URL: http://svn.apache.org/r1634753
Log:
JCRVLT-66 Updating an exiting authorizable does not work if on different path (mode=merge)
JCRVLT-67 rep:authorizableId might be removed on package install causing error in oak
Modified:
jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewSAXImporter.java
jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/JcrSysViewTransformer.java
jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/DocViewNode.java
jackrabbit/commons/filevault/trunk/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/integration/TestUserContentPackage.java
Modified: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewSAXImporter.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewSAXImporter.java?rev=1634753&r1=1634752&r2=1634753&view=diff
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewSAXImporter.java (original)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewSAXImporter.java Tue Oct 28 00:28:32 2014
@@ -635,37 +635,7 @@ public class DocViewSAXImporter extends
stack = stack.push();
}
} else if (userManagement != null && userManagement.isAuthorizableNodeType(ni.primary)) {
- boolean skip = false;
- String id = userManagement.getAuthorizableId(ni);
- String oldPath = node.getPath() + "/" + ni.name;
- if (wspFilter.getImportMode(oldPath) == ImportMode.MERGE) {
- String existingPath = userManagement.getAuthorizablePath(this.session, id);
- if (existingPath != null) {
- // if existing path is not the same as this, we need to register this so that further
- // nodes down the line (i.e. profiles, policies) are imported at the correct location
- if (!oldPath.equals(existingPath)) {
- importInfo.onRemapped(oldPath, existingPath);
- }
- skip = true;
-
- // remember desired memberships. todo: how to deal with multi-node memberships?
- DocViewProperty prop = ni.props.get("rep:members");
- if (prop != null) {
- importInfo.registerMemberships(id, prop.values);
- }
- }
- }
- if (skip) {
- log.info("Skipping import of existing authorizable '{}' due to MERGE import mode.", id);
- stack = stack.push();
- importInfo.onNop(node.getPath() + "/" + ni.name);
- } else {
- log.debug("Authorizable element detected. starting sysview transformation {}/{}", node.getPath(), name);
- stack = stack.push();
- stack.adapter = new JcrSysViewTransformer(node);
- stack.adapter.startNode(ni);
- importInfo.onCreated(node.getPath() + "/" + ni.name);
- }
+ handleAuthorizable(node, ni);
} else {
stack = stack.push(addNode(ni));
}
@@ -686,6 +656,90 @@ public class DocViewSAXImporter extends
}
}
+ /**
+ * Handle an authorizable node
+ * @param node the parent node
+ * @param ni doc view node of the authorizable
+ * @throws RepositoryException
+ * @throws SAXException
+ */
+ private void handleAuthorizable(Node node, DocViewNode ni) throws RepositoryException, SAXException {
+ String id = userManagement.getAuthorizableId(ni);
+ String newPath = node.getPath() + "/" + ni.name;
+ String oldPath = userManagement.getAuthorizablePath(this.session, id);
+ if (oldPath == null) {
+ // just import the authorizable node
+ log.debug("Authorizable element detected. starting sysview transformation {}", newPath);
+ stack = stack.push();
+ stack.adapter = new JcrSysViewTransformer(node);
+ stack.adapter.startNode(ni);
+ importInfo.onCreated(newPath);
+ return;
+ }
+
+ Node authNode = session.getNode(oldPath);
+ ImportMode mode = wspFilter.getImportMode(oldPath);
+ // if existing path is not the same as this, we need to register this so that further
+ // nodes down the line (i.e. profiles, policies) are imported at the correct location
+ // todo: check if this also works cross-aggregates
+ if (mode != ImportMode.REPLACE && !oldPath.equals(newPath)) {
+ importInfo.onRemapped(oldPath, newPath);
+ }
+
+ switch (mode) {
+ case MERGE:
+ // remember desired memberships.
+ // todo: how to deal with multi-node memberships? see JCRVLT-69
+ DocViewProperty prop = ni.props.get("rep:members");
+ if (prop != null) {
+ importInfo.registerMemberships(id, prop.values);
+ }
+
+ log.info("Skipping import of existing authorizable '{}' due to MERGE import mode.", id);
+ stack = stack.push(new StackElement(authNode, false));
+ importInfo.onNop(oldPath);
+ break;
+
+ case REPLACE:
+ // just replace the entire subtree for now.
+ log.debug("Authorizable element detected. starting sysview transformation {}", newPath);
+ stack = stack.push();
+ stack.adapter = new JcrSysViewTransformer(node);
+ stack.adapter.startNode(ni);
+ importInfo.onReplaced(newPath);
+ break;
+
+ case UPDATE:
+ log.debug("Authorizable element detected. starting sysview transformation {}", newPath);
+ stack = stack.push();
+ stack.adapter = new JcrSysViewTransformer(node, oldPath);
+ // we need to tweak the ni.name so that the sysview import does not
+ // rename the authorizable node name
+ String newName = Text.getName(oldPath);
+ DocViewNode mapped = new DocViewNode(
+ newName,
+ newName,
+ ni.uuid,
+ ni.props,
+ ni.mixins,
+ ni.primary
+ );
+ // but we need to be augment with a potential rep:authorizableId
+ if (authNode.hasProperty("rep:authorizableId")) {
+ DocViewProperty authId = new DocViewProperty(
+ "rep:authorizableId",
+ new String[]{authNode.getProperty("rep:authorizableId").getString()},
+ false,
+ PropertyType.STRING
+ );
+ mapped.props.put(authId.name, authId);
+ }
+ stack.adapter.startNode(mapped);
+ importInfo.onReplaced(newPath);
+ break;
+ }
+ }
+
private StackElement addNode(DocViewNode ni) throws RepositoryException, IOException {
final Node currentNode = stack.getNode();
Modified: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/JcrSysViewTransformer.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/JcrSysViewTransformer.java?rev=1634753&r1=1634752&r2=1634753&view=diff
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/JcrSysViewTransformer.java (original)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/JcrSysViewTransformer.java Tue Oct 28 00:28:32 2014
@@ -18,6 +18,7 @@ package org.apache.jackrabbit.vault.fs.i
import javax.jcr.ImportUUIDBehavior;
import javax.jcr.Node;
+import javax.jcr.NodeIterator;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
@@ -25,6 +26,9 @@ import javax.jcr.Session;
import org.apache.jackrabbit.spi.Name;
import org.apache.jackrabbit.vault.util.DocViewNode;
import org.apache.jackrabbit.vault.util.DocViewProperty;
+import org.apache.jackrabbit.vault.util.JcrConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
@@ -38,25 +42,91 @@ import org.xml.sax.helpers.AttributesImp
public class JcrSysViewTransformer implements DocViewAdapter {
/**
+ * default logger
+ */
+ private static final Logger log = LoggerFactory.getLogger(JcrSysViewTransformer.class);
+
+ /**
* sysview handler for special content
*/
private ContentHandler handler;
- JcrSysViewTransformer(Node node) throws RepositoryException, SAXException {
+ /**
+ * temporary node when 'rescuing' the child nodes
+ */
+ private Node tmpNode;
+
+ private final String existingPath;
+
+ public JcrSysViewTransformer(Node node) throws SAXException, RepositoryException {
+ this(node, null);
+ }
+
+ JcrSysViewTransformer(Node node, String existingPath) throws RepositoryException, SAXException {
Session session = node.getSession();
handler = session.getImportContentHandler(
node.getPath(),
- ImportUUIDBehavior.IMPORT_UUID_COLLISION_REMOVE_EXISTING);
+ existingPath != null
+ ? ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING
+ : ImportUUIDBehavior.IMPORT_UUID_COLLISION_REMOVE_EXISTING
+ );
// first define the current namespaces
String[] prefixes = session.getNamespacePrefixes();
handler.startDocument();
for (String prefix: prefixes) {
handler.startPrefixMapping(prefix, session.getNamespaceURI(prefix));
}
+
+ this.existingPath = existingPath;
+ if (existingPath != null) {
+ Node existingNode = session.getNode(existingPath);
+ // check if there is an existing node with the name
+ try {
+ // if old node exist, try to 'save' the child nodes
+ NodeIterator iter = existingNode.getNodes();
+ while (iter.hasNext()) {
+ Node child = iter.nextNode();
+ if (tmpNode == null) {
+ tmpNode = session.getRootNode().addNode("tmp" + System.currentTimeMillis(), JcrConstants.NT_UNSTRUCTURED);
+ }
+ try {
+ session.move(child.getPath(), tmpNode.getPath() + "/" + child.getName());
+ } catch (RepositoryException e) {
+ log.error("Error while moving child node to temporary location. Child will be removed.", e);
+ }
+ }
+ } catch (RepositoryException e) {
+ log.warn("error while moving child nodes (ignored)", e);
+ }
+ }
}
public void close() throws SAXException {
handler.endDocument();
+
+ // check for rescued child nodes
+ // move the old child nodes back
+ if (tmpNode != null) {
+ try {
+ Session session = tmpNode.getSession();
+ Node node = session.getNode(existingPath);
+ NodeIterator iter = tmpNode.getNodes();
+ while (iter.hasNext()) {
+ Node child = iter.nextNode();
+ String newPath = node.getPath() + "/" + child.getName();
+ try {
+ session.move(child.getPath(), newPath);
+ } catch (RepositoryException e) {
+ log.warn("Unable to move child back to new location at {} due to: {}. Node will remain in temporary location: {}",
+ new Object[]{newPath, e.getMessage(), child.getPath()});
+ }
+ }
+ tmpNode.remove();
+ } catch (RepositoryException e) {
+ log.error("Error while processing rescued child nodes");
+ }
+ }
+
}
public void startNode(DocViewNode ni) throws SAXException {
Modified: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/DocViewNode.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/DocViewNode.java?rev=1634753&r1=1634752&r2=1634753&view=diff
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/DocViewNode.java (original)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/DocViewNode.java Tue Oct 28 00:28:32 2014
@@ -42,6 +42,15 @@ public class DocViewNode {
public final String[] mixins;
public final String primary;
+ public DocViewNode(String name, String label, String uuid, Map<String, DocViewProperty> props, String[] mixins, String primary) {
+ this.name = name;
+ this.label = label;
+ this.uuid = uuid;
+ this.mixins = mixins;
+ this.primary = primary;
+ this.props.putAll(props);
+ }
+
public DocViewNode(String name, String label, Attributes attributes, NamePathResolver npResolver)
throws NamespaceException {
this.name = name;
Modified: jackrabbit/commons/filevault/trunk/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/integration/TestUserContentPackage.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/integration/TestUserContentPackage.java?rev=1634753&r1=1634752&r2=1634753&view=diff
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/integration/TestUserContentPackage.java (original)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/integration/TestUserContentPackage.java Tue Oct 28 00:28:32 2014
@@ -78,25 +78,21 @@ public class TestUserContentPackage exte
}
@Test
- @Ignore("JCRVLT-66")
public void installUserA_Merge() throws RepositoryException, IOException, PackageException {
installUserA(ImportMode.MERGE, false, false);
}
@Test
- @Ignore("JCRVLT-66")
public void installUserA_Merge_PkgPath() throws RepositoryException, IOException, PackageException {
installUserA(ImportMode.MERGE, true, true);
}
@Test
- @Ignore("JCRVLT-66")
public void installUserA_Update() throws RepositoryException, IOException, PackageException {
installUserA(ImportMode.UPDATE, false, false);
}
@Test
- @Ignore("JCRVLT-66")
public void installUserA_Update_PkgPath() throws RepositoryException, IOException, PackageException {
installUserA(ImportMode.UPDATE, true, true);
}