Author: tolusha
Date: 2010-09-23 03:59:35 -0400 (Thu, 23 Sep 2010)
New Revision: 3180
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/version/ItemDataRestoreVisitor.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/ItemDataRemoveVisitor.java
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/version/TestVersionable.java
Log:
EXOJCR-961: During restore some nodes will remain and not be deleted.
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/version/ItemDataRestoreVisitor.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/version/ItemDataRestoreVisitor.java 2010-09-23
07:26:44 UTC (rev 3179)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/version/ItemDataRestoreVisitor.java 2010-09-23
07:59:35 UTC (rev 3180)
@@ -34,6 +34,7 @@
import org.exoplatform.services.jcr.impl.dataflow.AbstractItemDataCopyVisitor;
import org.exoplatform.services.jcr.impl.dataflow.ItemDataCopyVisitor;
import org.exoplatform.services.jcr.impl.dataflow.ItemDataRemoveVisitor;
+import org.exoplatform.services.jcr.impl.dataflow.TransientItemData;
import org.exoplatform.services.jcr.impl.dataflow.TransientNodeData;
import org.exoplatform.services.jcr.impl.dataflow.TransientPropertyData;
import org.exoplatform.services.jcr.impl.dataflow.TransientValueData;
@@ -45,7 +46,9 @@
import java.io.IOException;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import java.util.Stack;
import javax.jcr.ItemExistsException;
@@ -83,6 +86,11 @@
protected final SessionChangesLog changes;
/**
+ * Node paths for updating instead of deleting.
+ */
+ protected final Set<QPath> updatingPath = new HashSet<QPath>();
+
+ /**
* Usecase of Workspace.restore(Version[], boolean), for not existing
* versionable nodes in the target workspace.
*/
@@ -120,19 +128,146 @@
}
}
+ /**
+ * Prepare item states for removing subtree before restoring. Accordingly to JCR
specification
+ * some nodes will remain and not be deleted. For this case visitor skips such nodes
and stores
+ * its paths. For nodes with OnParentVersion attribute IGNORE
ItemDataCopyIgnoredVisitor will be used
+ * to copy children/properties to the restored node.
+ */
protected class RemoveVisitor extends ItemDataRemoveVisitor
{
+ /**
+ * The stack. In the top it contains a parent node.
+ */
+ protected Stack<NodeData> parents = new Stack<NodeData>();
+
+ /**
+ * Last met node path during traversing which will remain during restore and not be
deleted.
+ */
+ private QPath remainedNode;
+
+ /**
+ * Node path for updating instead of deleting. All ancestors of remained nodes
+ * not be deleted since updating will be applied later.
+ */
+ private final Set<QPath> updatingPath = new HashSet<QPath>();
+
+ /**
+ * RemoveVisitor constructor.
+ *
+ * @throws RepositoryException
+ */
RemoveVisitor() throws RepositoryException
{
super(userSession.getTransientNodesManager(), null, nodeTypeDataManager,
userSession.getAccessManager(),
userSession.getUserState());
}
+ /**
+ * {@inheritDoc}
+ */
@Override
protected void validateReferential(NodeData node) throws RepositoryException
{
// no REFERENCE validation here
}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void entering(NodeData node, int level) throws RepositoryException
+ {
+ if (level == 0)
+ {
+ removedRoot = node;
+ }
+
+ parents.push(node);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void visit(NodeData node) throws RepositoryException
+ {
+ if (currentLevel > 0)
+ {
+ NodeData parent = parents.peek();
+ int onParentVersion =
+ nodeTypeDataManager.getChildNodeDefinition(node.getQPath().getName(),
parent.getPrimaryTypeName(),
+ parent.getMixinTypeNames()).getOnParentVersion();
+
+ // ItemDataCopyIgnoredVisitory
+ if (onParentVersion != OnParentVersionAction.COPY
+ && onParentVersion != OnParentVersionAction.VERSION
+ && onParentVersion != OnParentVersionAction.IGNORE
+ || onParentVersion == OnParentVersionAction.VERSION
+ && nodeTypeDataManager.isNodeType(Constants.MIX_VERSIONABLE,
node.getPrimaryTypeName(),
+ node.getMixinTypeNames()))
+ {
+ remainedNode = node.getQPath();
+
+ // node and its children will remain and not be removed
+ return;
+ }
+ }
+
+ super.visit(node);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void leaving(NodeData node, int level) throws RepositoryException
+ {
+ if (validate)
+ {
+ validate(node);
+ }
+
+ if (remainedNode != null &&
remainedNode.isDescendantOf(node.getQPath()))
+ {
+ updatingPath.add(node.getQPath());
+ }
+ else
+ {
+ if (!(node instanceof TransientItemData))
+ {
+ node = (NodeData)copyItemDataDelete(node);
+ }
+
+ ItemState state =
+ new ItemState(node, ItemState.DELETED, true, ancestorToSave != null ?
ancestorToSave
+ : removedRoot.getQPath());
+
+ itemRemovedStates.add(state);
+ }
+
+ parents.pop();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List<ItemState> getRemovedStates()
+ {
+ return itemRemovedStates;
+ }
+
+ /**
+ * Return nodes paths for updating.
+ *
+ * @return Set
+ */
+ public Set<QPath> getUpdatingPath()
+ {
+ return updatingPath;
+ }
+
};
ItemDataRestoreVisitor(NodeData context, InternalQName restoringName, NodeData
history, SessionImpl userSession,
@@ -248,7 +383,7 @@
// parent
sameIdentifierPath.getName().equals(nodePath.getName()))
{ // same
- // name
+ // name
if (sameIdentifierPath.getIndex() != nodePath.getIndex())
// but different index, see below... fix it
@@ -258,10 +393,11 @@
existing = sameIdentifierNode;
// remove existed node, with validation
- ItemDataRemoveVisitor removeVisitor = new RemoveVisitor();
+ RemoveVisitor removeVisitor = new RemoveVisitor();
removeVisitor.visit(existing);
changes.addAll(removeVisitor.getRemovedStates());
+ updatingPath.addAll(removeVisitor.getUpdatingPath());
}
else if (!sameIdentifierPath.isDescendantOf(nodePath))
{
@@ -376,7 +512,14 @@
new TransientNodeData(nodePath, fidentifier, (existing != null ?
existing.getPersistedVersion() : -1), ptName,
mixins == null ? new InternalQName[0] : mixins, 0,
parentData.getIdentifier(), parentData.getACL());
- changes.add(ItemState.createAddedState(restoredData));
+ if (updatingPath.contains(nodePath))
+ {
+ changes.add(ItemState.createUpdatedState(restoredData));
+ }
+ else
+ {
+ changes.add(ItemState.createAddedState(restoredData));
+ }
pushCurrent(restoredData);
}
@@ -519,8 +662,8 @@
// jcr:uuid
String jcrUuid = null;
NodeData existing = null;
- if (nodeTypeDataManager.isNodeType(Constants.MIX_REFERENCEABLE,
frozen.getPrimaryTypeName(), frozen
- .getMixinTypeNames()))
+ if (nodeTypeDataManager.isNodeType(Constants.MIX_REFERENCEABLE,
frozen.getPrimaryTypeName(),
+ frozen.getMixinTypeNames()))
{
// copy uuid from frozen state of mix:referenceable,
// NOTE: mix:referenceable stored in frozen state with genereted ID
@@ -573,10 +716,11 @@
{
// remove existed node, with validation (same as for restored
// root)
- ItemDataRemoveVisitor removeVisitor = new RemoveVisitor();
+ RemoveVisitor removeVisitor = new RemoveVisitor();
removeVisitor.visit(existing);
changes.addAll(removeVisitor.getRemovedStates());
+ updatingPath.addAll(removeVisitor.getUpdatingPath());
}
else
{
@@ -594,7 +738,15 @@
frozen.getMixinTypeNames(), frozen.getOrderNumber(),
currentNode().getIdentifier(), // parent
frozen.getACL());
- changes.add(ItemState.createAddedState(restoredData));
+ if (updatingPath.contains(restoredPath))
+ {
+ changes.add(ItemState.createUpdatedState(restoredData));
+ }
+ else
+ {
+ changes.add(ItemState.createAddedState(restoredData));
+ }
+
pushCurrent(restoredData);
}
else if (action == OnParentVersionAction.INITIALIZE || action ==
OnParentVersionAction.COMPUTE)
@@ -651,8 +803,9 @@
}
int action =
- nodeTypeDataManager.getPropertyDefinitions(qname,
currentNode().getPrimaryTypeName(),
-
currentNode().getMixinTypeNames()).getAnyDefinition().getOnParentVersion();
+ nodeTypeDataManager
+ .getPropertyDefinitions(qname, currentNode().getPrimaryTypeName(),
currentNode().getMixinTypeNames())
+ .getAnyDefinition().getOnParentVersion();
if (log.isDebugEnabled())
{
@@ -669,14 +822,14 @@
if (qname.equals(Constants.JCR_PREDECESSORS))
{
tagetProperty =
- TransientPropertyData.createPropertyData(currentNode(), qname,
property.getType(), property
- .isMultiValued(), new ArrayList<ValueData>());
+ TransientPropertyData.createPropertyData(currentNode(), qname,
property.getType(),
+ property.isMultiValued(), new ArrayList<ValueData>());
}
else
{
tagetProperty =
- TransientPropertyData.createPropertyData(currentNode(), qname,
property.getType(), property
- .isMultiValued(), copyValues(property));
+ TransientPropertyData.createPropertyData(currentNode(), qname,
property.getType(),
+ property.isMultiValued(), copyValues(property));
}
changes.add(ItemState.createAddedState(tagetProperty));
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/ItemDataRemoveVisitor.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/ItemDataRemoveVisitor.java 2010-09-23
07:26:44 UTC (rev 3179)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/ItemDataRemoveVisitor.java 2010-09-23
07:59:35 UTC (rev 3180)
@@ -234,8 +234,8 @@
}
property = (PropertyData)copyItemDataDelete(property);
ItemState state =
- new ItemState(property, ItemState.DELETED, true, ancestorToSave != null ?
ancestorToSave : removedRoot
- .getQPath());
+ new ItemState(property, ItemState.DELETED, true, ancestorToSave != null ?
ancestorToSave
+ : removedRoot.getQPath());
if (!itemRemovedStates.contains(state))
{
@@ -306,7 +306,7 @@
* @throws RepositoryException
* if error occurs
*/
- private TransientItemData copyItemDataDelete(final ItemData item) throws
RepositoryException
+ protected TransientItemData copyItemDataDelete(final ItemData item) throws
RepositoryException
{
if (item == null)
@@ -327,8 +327,8 @@
+ node.getIdentifier());
}
- return new TransientNodeData(node.getQPath(), node.getIdentifier(),
node.getPersistedVersion(), node
- .getPrimaryTypeName(), node.getMixinTypeNames(), node.getOrderNumber(),
node.getParentIdentifier(), acl);
+ return new TransientNodeData(node.getQPath(), node.getIdentifier(),
node.getPersistedVersion(),
+ node.getPrimaryTypeName(), node.getMixinTypeNames(), node.getOrderNumber(),
node.getParentIdentifier(), acl);
}
// else - property
Modified:
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/version/TestVersionable.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/version/TestVersionable.java 2010-09-23
07:26:44 UTC (rev 3179)
+++
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/version/TestVersionable.java 2010-09-23
07:59:35 UTC (rev 3180)
@@ -29,6 +29,7 @@
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.nodetype.NoSuchNodeTypeException;
+import javax.jcr.version.Version;
import javax.jcr.version.VersionHistory;
/**
@@ -216,4 +217,385 @@
}
}
+ public void testJCR1438() throws Exception
+ {
+ // node content
+ Node testRoot = root.addNode("testRoot");
+ root.save();
+
+ Node web = testRoot.addNode("web", "exo:webContent");
+
+ web.addMixin("exo:datetime");
+ web.addMixin("exo:owneable");
+ web.addMixin("exo:modify");
+ web.addMixin("mix:votable");
+ web.addMixin("mix:commentable");
+ web.addMixin("publication:stateAndVersionBasedPublication");
+ web.addMixin("mix:versionable");
+
+ web.setProperty("exo:dateCreated", Calendar.getInstance());
+ web.setProperty("exo:dateModified", Calendar.getInstance());
+ web.setProperty("exo:lastModifiedDate", Calendar.getInstance());
+ web.setProperty("exo:lastModifier", "root");
+ web.setProperty("exo:summary", "text summary");
+ web.setProperty("exo:title", "web title");
+ web.setProperty("exo:voteTotal", "1");
+ web.setProperty("exo:voteTotalOfLang", "1");
+ web.setProperty("exo:votingRate", "1");
+ web.setProperty("publication:currentState", "draft");
+ web.setProperty("publication:history", new String[]{"13",
"12", "14"});
+ web.setProperty("publication:lifecycleName", "lf_name");
+ web.setProperty("publication:revisionData", new
String[]{"r_data_1", "r_data_2"});
+
+ Node defHtml = web.addNode("default.html", "nt:file");
+ defHtml.addMixin("exo:datetime");
+ defHtml.addMixin("exo:owneable");
+ defHtml.addMixin("exo:modify");
+ defHtml.addMixin("exo:htmlFile");
+
+ defHtml.setProperty("exo:dateCreated", Calendar.getInstance());
+ defHtml.setProperty("exo:dateModified", Calendar.getInstance());
+ defHtml.setProperty("exo:lastModifiedDate", Calendar.getInstance());
+ defHtml.setProperty("exo:lastModifier", "root");
+
+ Node contentDefHtml = defHtml.addNode("jcr:content",
"nt:resource");
+ contentDefHtml.addMixin("exo:datetime");
+ contentDefHtml.addMixin("exo:owneable");
+ contentDefHtml.addMixin("dc:elementSet");
+
+ contentDefHtml.setProperty("exo:dateCreated", Calendar.getInstance());
+ contentDefHtml.setProperty("exo:dateModified", Calendar.getInstance());
+ contentDefHtml.setProperty("jcr:data", "def_html_data");
+ contentDefHtml.setProperty("jcr:encoding", "UTF-8");
+ contentDefHtml.setProperty("jcr:lastModified", Calendar.getInstance());
+ contentDefHtml.setProperty("jcr:mimeType", "text/html");
+
+ Node css = web.addNode("css", "exo:cssFolder");
+ css.addMixin("exo:datetime");
+ css.addMixin("exo:owneable");
+ css.addMixin("exo:modify");
+
+ css.setProperty("exo:dateCreated", Calendar.getInstance());
+ css.setProperty("exo:dateModified", Calendar.getInstance());
+ css.setProperty("exo:lastModifiedDate", Calendar.getInstance());
+ css.setProperty("exo:lastModifier", "root");
+
+ Node defCss = css.addNode("default.css", "nt:file");
+
+ defCss.addMixin("exo:datetime");
+ defCss.addMixin("exo:owneable");
+ defCss.addMixin("exo:modify");
+
+ defCss.setProperty("exo:dateCreated", Calendar.getInstance());
+ defCss.setProperty("exo:dateModified", Calendar.getInstance());
+ defCss.setProperty("exo:lastModifiedDate", Calendar.getInstance());
+ defCss.setProperty("exo:lastModifier", "root");
+
+ Node contentDefCss = defCss.addNode("jcr:content",
"nt:resource");
+ contentDefCss.addMixin("exo:datetime");
+ contentDefCss.addMixin("exo:owneable");
+ contentDefCss.addMixin("dc:elementSet");
+
+ contentDefCss.setProperty("exo:dateCreated", Calendar.getInstance());
+ contentDefCss.setProperty("exo:dateModified", Calendar.getInstance());
+ contentDefCss.setProperty("jcr:data", "def_css_data");
+ contentDefCss.setProperty("jcr:encoding", "UTF-8");
+ contentDefCss.setProperty("jcr:lastModified", Calendar.getInstance());
+ contentDefCss.setProperty("jcr:mimeType", "text/css");
+
+ Node medias = web.addNode("medias", "exo:multimediaFolder");
+ medias.addMixin("exo:datetime");
+ medias.addMixin("exo:owneable");
+ medias.addMixin("exo:modify");
+
+ medias.setProperty("exo:dateCreated", Calendar.getInstance());
+ medias.setProperty("exo:dateModified", Calendar.getInstance());
+ medias.setProperty("exo:lastModifiedDate", Calendar.getInstance());
+ medias.setProperty("exo:lastModifier", "root");
+
+ Node videos = medias.addNode("videos", "nt:folder");
+ videos.addMixin("exo:datetime");
+ videos.addMixin("exo:owneable");
+ videos.addMixin("exo:modify");
+
+ videos.setProperty("exo:dateCreated", Calendar.getInstance());
+ videos.setProperty("exo:dateModified", Calendar.getInstance());
+ videos.setProperty("exo:lastModifiedDate", Calendar.getInstance());
+ videos.setProperty("exo:lastModifier", "root");
+
+ Node images = medias.addNode("images", "nt:folder");
+ images.addMixin("exo:datetime");
+ images.addMixin("exo:owneable");
+ images.addMixin("exo:modify");
+
+ images.setProperty("exo:dateCreated", Calendar.getInstance());
+ images.setProperty("exo:dateModified", Calendar.getInstance());
+ images.setProperty("exo:lastModifiedDate", Calendar.getInstance());
+ images.setProperty("exo:lastModifier", "root");
+
+ Node illustration = images.addNode("illustration", "nt:file");
+ illustration.addMixin("exo:datetime");
+ illustration.addMixin("exo:owneable");
+ illustration.addMixin("exo:modify");
+ illustration.addMixin("mix:referenceable");
+
+ illustration.setProperty("exo:dateCreated", Calendar.getInstance());
+ illustration.setProperty("exo:dateModified", Calendar.getInstance());
+ illustration.setProperty("exo:lastModifiedDate",
Calendar.getInstance());
+ illustration.setProperty("exo:lastModifier", "root");
+
+ Node contentIllustration = illustration.addNode("jcr:content",
"nt:resource");
+ contentIllustration.addMixin("exo:datetime");
+ contentIllustration.addMixin("exo:owneable");
+ contentIllustration.addMixin("dc:elementSet");
+
+ contentIllustration.setProperty("exo:dateCreated",
Calendar.getInstance());
+ contentIllustration.setProperty("exo:dateModified",
Calendar.getInstance());
+ contentIllustration.setProperty("jcr:data",
"illustration_data");
+ contentIllustration.setProperty("jcr:encoding", "UTF-8");
+ contentIllustration.setProperty("jcr:lastModified",
Calendar.getInstance());
+ contentIllustration.setProperty("jcr:mimeType", "text/jpeg");
+
+ Node documents = web.addNode("documents", "nt:unstructured");
+ documents.addMixin("exo:datetime");
+ documents.addMixin("exo:owneable");
+ documents.addMixin("exo:modify");
+ documents.addMixin("exo:documentFolder");
+
+ documents.setProperty("exo:dateCreated", Calendar.getInstance());
+ documents.setProperty("exo:dateModified", Calendar.getInstance());
+ documents.setProperty("exo:lastModifiedDate", Calendar.getInstance());
+ documents.setProperty("exo:lastModifier", "root");
+
+ Node js = web.addNode("js", "exo:jsFolder");
+ js.addMixin("exo:datetime");
+ js.addMixin("exo:owneable");
+ js.addMixin("exo:modify");
+
+ js.setProperty("exo:dateCreated", Calendar.getInstance());
+ js.setProperty("exo:dateModified", Calendar.getInstance());
+ js.setProperty("exo:lastModifiedDate", Calendar.getInstance());
+ js.setProperty("exo:lastModifier", "root");
+
+ Node defJs = js.addNode("default.js", "nt:file");
+ defJs.addMixin("exo:datetime");
+ defJs.addMixin("exo:owneable");
+ defJs.addMixin("exo:modify");
+
+ defJs.setProperty("exo:dateCreated", Calendar.getInstance());
+ defJs.setProperty("exo:dateModified", Calendar.getInstance());
+ defJs.setProperty("exo:lastModifiedDate", Calendar.getInstance());
+ defJs.setProperty("exo:lastModifier", "root");
+
+ Node contentDefJs = defJs.addNode("jcr:content",
"nt:resource");
+ contentDefJs.addMixin("exo:datetime");
+ contentDefJs.addMixin("exo:owneable");
+ contentDefJs.addMixin("dc:elementSet");
+
+ contentDefJs.setProperty("exo:dateCreated", Calendar.getInstance());
+ contentDefJs.setProperty("exo:dateModified", Calendar.getInstance());
+ contentDefJs.setProperty("jcr:data", "def_js_data");
+ contentDefJs.setProperty("jcr:encoding", "UTF-8");
+ contentDefJs.setProperty("jcr:lastModified", Calendar.getInstance());
+ contentDefJs.setProperty("jcr:mimeType", "text/js");
+
+ root.save();
+
+ web.checkin();
+ web.checkout();
+ root.save();
+
+ Node testImage = images.addNode("test_image", "nt:file");
+ testImage.addMixin("exo:datetime");
+ testImage.addMixin("exo:owneable");
+ testImage.addMixin("exo:modify");
+ testImage.addMixin("mix:referenceable");
+ testImage.addMixin("mix:versionable");
+
+ testImage.setProperty("exo:dateCreated", Calendar.getInstance());
+ testImage.setProperty("exo:dateModified", Calendar.getInstance());
+ testImage.setProperty("exo:lastModifiedDate", Calendar.getInstance());
+ testImage.setProperty("exo:lastModifier", "root");
+
+ Node contentTestImage = testImage.addNode("jcr:content",
"nt:resource");
+ contentTestImage.addMixin("exo:datetime");
+ contentTestImage.addMixin("exo:owneable");
+ contentTestImage.addMixin("dc:elementSet");
+
+ contentTestImage.setProperty("exo:dateCreated", Calendar.getInstance());
+ contentTestImage.setProperty("exo:dateModified",
Calendar.getInstance());
+ contentTestImage.setProperty("jcr:data",
"content_test_image_data");
+ contentTestImage.setProperty("jcr:encoding", "UTF-8");
+ contentTestImage.setProperty("jcr:lastModified",
Calendar.getInstance());
+ contentTestImage.setProperty("jcr:mimeType", "text/jpeg");
+ root.save();
+
+ testImage.checkin();
+ testImage.checkout();
+ testImage.save();
+
+ web.checkin();
+ web.checkout();
+ root.save();
+
+ Node rTestImage =
web.getNode("medias").getNode("images").getNode("test_image");
+ assertNotNull(rTestImage);
+ Node rTestImageContent = rTestImage.getNode("jcr:content");
+ assertNotNull(rTestImageContent);
+ assertNotNull(rTestImageContent.getProperty("jcr:data"));
+ assertEquals("content_test_image_data",
rTestImageContent.getProperty("jcr:data").getString());
+
+ web.restore("2", true);
+ root.save();
+
+ rTestImage =
web.getNode("medias").getNode("images").getNode("test_image");
+ assertNotNull(rTestImage);
+ rTestImageContent = rTestImage.getNode("jcr:content");
+ assertNotNull(rTestImageContent);
+ assertNotNull(rTestImageContent.getProperty("jcr:data"));
+ assertEquals("content_test_image_data",
rTestImageContent.getProperty("jcr:data").getString());
+
+ }
+
+ public void testJCR1438_Simple() throws Exception
+ {
+ Node testRoot = root.addNode("testRoot");
+ root.save();
+
+ Node l1Node = testRoot.addNode("l1");
+ l1Node.addMixin("mix:versionable");
+ Node folder = l1Node.addNode("folder", "nt:folder");
+ root.save();
+
+ l1Node.checkin();
+ l1Node.checkout();
+ root.save();
+
+ Node testImage = folder.addNode("test_image", "nt:file");
+ testImage.addMixin("mix:versionable");
+
+ Node contentTestImage = testImage.addNode("jcr:content",
"nt:resource");
+ contentTestImage.setProperty("jcr:data",
"content_test_image_data");
+ contentTestImage.setProperty("jcr:encoding", "UTF-8");
+ contentTestImage.setProperty("jcr:lastModified",
Calendar.getInstance());
+ contentTestImage.setProperty("jcr:mimeType", "text/jpeg");
+ root.save();
+
+ Version tImageV1 = testImage.checkin();
+ testImage.checkout();
+ testImage.save();
+
+ Version v2 = l1Node.checkin();
+ l1Node.checkout();
+ root.save();
+
+ Node rTestImage =
testRoot.getNode("l1").getNode("folder").getNode("test_image");
+ assertNotNull(rTestImage);
+ Node rTestImageContent = rTestImage.getNode("jcr:content");
+ assertNotNull(rTestImageContent);
+ assertNotNull(rTestImageContent.getProperty("jcr:data"));
+ assertEquals("content_test_image_data",
rTestImageContent.getProperty("jcr:data").getString());
+
+ /*testImage.remove();
+ root.save();*/
+
+ l1Node.restore("2", true);
+
+ rTestImage =
testRoot.getNode("l1").getNode("folder").getNode("test_image");
+ assertNotNull(rTestImage);
+ rTestImageContent = rTestImage.getNode("jcr:content");
+ assertNotNull(rTestImageContent);
+ assertNotNull(rTestImageContent.getProperty("jcr:data"));
+ assertEquals("content_test_image_data",
rTestImageContent.getProperty("jcr:data").getString());
+ }
+
+ public void testJCR1438_Simple2() throws Exception
+ {
+ Node testRoot = root.addNode("testRoot");
+ root.save();
+
+ Node l1Node = testRoot.addNode("l1");
+ l1Node.addMixin("mix:versionable");
+ Node folder = l1Node.addNode("folder", "nt:folder");
+ root.save();
+
+ l1Node.checkin();
+ l1Node.checkout();
+ root.save();
+
+ Node folderL2 = folder.addNode("folder_l2", "nt:folder");
+ folderL2.addMixin("mix:versionable");
+
+ Node testImage = folderL2.addNode("test_image", "nt:file");
+
+ Node contentTestImage = testImage.addNode("jcr:content",
"nt:resource");
+ contentTestImage.setProperty("jcr:data",
"content_test_image_data");
+ contentTestImage.setProperty("jcr:encoding", "UTF-8");
+ contentTestImage.setProperty("jcr:lastModified",
Calendar.getInstance());
+ contentTestImage.setProperty("jcr:mimeType", "text/jpeg");
+ root.save();
+
+ folderL2.checkin();
+ folderL2.checkout();
+ folderL2.save();
+
+ // sub version node l2
+ Node folderL3 = folderL2.addNode("folder_l3", "nt:folder");
+ folderL3.addMixin("mix:versionable");
+
+ testImage = folderL3.addNode("test_image", "nt:file");
+
+ contentTestImage = testImage.addNode("jcr:content",
"nt:resource");
+ contentTestImage.setProperty("jcr:data",
"content_test_image_data");
+ contentTestImage.setProperty("jcr:encoding", "UTF-8");
+ contentTestImage.setProperty("jcr:lastModified",
Calendar.getInstance());
+ contentTestImage.setProperty("jcr:mimeType", "text/jpeg");
+ root.save();
+
+ folderL3.checkin();
+ folderL3.checkout();
+ folderL3.save();
+ //
+
+ folderL2.checkin();
+ folderL2.checkout();
+ folderL2.save();
+
+ l1Node.checkin();
+ l1Node.checkout();
+ root.save();
+
+ Node rTestImage =
testRoot.getNode("l1").getNode("folder").getNode("folder_l2").getNode("test_image");
+ assertNotNull(rTestImage);
+ Node rTestImageContent = rTestImage.getNode("jcr:content");
+ assertNotNull(rTestImageContent);
+ assertNotNull(rTestImageContent.getProperty("jcr:data"));
+ assertEquals("content_test_image_data",
rTestImageContent.getProperty("jcr:data").getString());
+
+ rTestImage =
+
testRoot.getNode("l1").getNode("folder").getNode("folder_l2").getNode("folder_l3").getNode("test_image");
+ assertNotNull(rTestImage);
+ rTestImageContent = rTestImage.getNode("jcr:content");
+ assertNotNull(rTestImageContent);
+ assertNotNull(rTestImageContent.getProperty("jcr:data"));
+ assertEquals("content_test_image_data",
rTestImageContent.getProperty("jcr:data").getString());
+
+ l1Node.restore("2", true);
+
+ rTestImage =
testRoot.getNode("l1").getNode("folder").getNode("folder_l2").getNode("test_image");
+ assertNotNull(rTestImage);
+ rTestImageContent = rTestImage.getNode("jcr:content");
+ assertNotNull(rTestImageContent);
+ assertNotNull(rTestImageContent.getProperty("jcr:data"));
+ assertEquals("content_test_image_data",
rTestImageContent.getProperty("jcr:data").getString());
+
+ rTestImage =
+
testRoot.getNode("l1").getNode("folder").getNode("folder_l2").getNode("folder_l3").getNode("test_image");
+ assertNotNull(rTestImage);
+ rTestImageContent = rTestImage.getNode("jcr:content");
+ assertNotNull(rTestImageContent);
+ assertNotNull(rTestImageContent.getProperty("jcr:data"));
+ assertEquals("content_test_image_data",
rTestImageContent.getProperty("jcr:data").getString());
+ }
+
}