Author: pnedonosko
Date: 2010-03-26 11:52:20 -0400 (Fri, 26 Mar 2010)
New Revision: 2175
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/writing/TestNodeReference.java
Log:
EXOJCR-614 check on deleted REFERENCE property's parent added to prevent NPE for
transiently deleted ref properties
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java 2010-03-26
15:18:03 UTC (rev 2174)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/SessionDataManager.java 2010-03-26
15:52:20 UTC (rev 2175)
@@ -594,31 +594,34 @@
for (int i = 0, length = refDatas.size(); i < length; i++)
{
PropertyData data = refDatas.get(i);
- // check for permission for read
NodeData parent = (NodeData)getItemData(data.getParentIdentifier());
- // skip not permitted
- if (accessManager.hasPermission(parent.getACL(), new
String[]{PermissionType.READ}, session.getUserState()
- .getIdentity()))
+ // if parent exists check for read permissions, otherwise the ref property was
deleted in this session but not yet saved.
+ if (parent != null)
{
- PropertyImpl item;
- ItemState state = changesLog.getItemState(data.getIdentifier());
- if (state != null)
+ // skip not permitted
+ if (accessManager.hasPermission(parent.getACL(), new
String[]{PermissionType.READ}, session.getUserState()
+ .getIdentity()))
{
- if (state.isDeleted())
+ PropertyImpl item;
+ ItemState state = changesLog.getItemState(data.getIdentifier());
+ if (state != null)
{
- // skip deleted
- continue;
+ if (state.isDeleted())
+ {
+ // skip deleted
+ continue;
+ }
+
+ item = (PropertyImpl)readItem(state.getData(), null, true, false);
}
+ else
+ {
+ item = (PropertyImpl)readItem(data, null, true, false);
+ }
- item = (PropertyImpl)readItem(state.getData(), null, true, false);
+ refs.add(item);
+ session.getActionHandler().postRead(item);
}
- else
- {
- item = (PropertyImpl)readItem(data, null, true, false);
- }
-
- refs.add(item);
- session.getActionHandler().postRead(item);
}
}
return refs;
@@ -1141,7 +1144,7 @@
// We can't remove this VH now.
return;
} // else -- if we has a references in workspace where the VH is being
- // deleted we can remove VH now.
+ // deleted we can remove VH now.
}
}
finally
Modified:
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/writing/TestNodeReference.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/writing/TestNodeReference.java 2010-03-26
15:18:03 UTC (rev 2174)
+++
jcr/trunk/exo.jcr.component.core/src/test/java/org/exoplatform/services/jcr/api/writing/TestNodeReference.java 2010-03-26
15:52:20 UTC (rev 2175)
@@ -21,12 +21,16 @@
import org.exoplatform.services.jcr.JcrAPIBaseTest;
import org.exoplatform.services.jcr.impl.core.NodeImpl;
+import java.io.ByteArrayInputStream;
+import java.util.Calendar;
+
import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.PropertyIterator;
import javax.jcr.PropertyType;
import javax.jcr.ReferentialIntegrityException;
import javax.jcr.RepositoryException;
+import javax.jcr.Session;
import javax.jcr.Value;
import javax.jcr.ValueFactory;
@@ -342,6 +346,95 @@
PropertyIterator refs = testNode.getReferences();
assertEquals(1, refs.getSize());
+ }
+ public void testGetTransientDeletedReferences() throws Exception
+ {
+ Node file = root.addNode("n", "nt:file");
+ Node content = file.addNode("jcr:content", "nt:resource");
+ content.setProperty("jcr:data", new ByteArrayInputStream(new byte[0]));
+ content.setProperty("jcr:mimeType", "");
+ content.setProperty("jcr:lastModified", Calendar.getInstance());
+ root.save();
+ Node link = root.addNode("link", "nt:linkedFile");
+ link.setProperty("jcr:content", content);
+ root.save();
+
+ // remove linked file but don't save it
+ content.getReferences().nextProperty().getParent().remove();
+
+ try
+ {
+ PropertyIterator it = content.getReferences();
+ assertEquals(0, it.getSize());
+
+ root.refresh(false);
+
+ it = content.getReferences();
+ assertEquals(1, it.getSize());
+ }
+ catch (Exception e)
+ {
+ fail(e.getMessage());
+ }
}
+
+ public void testGetTransientDeletedReferences_AnotherSession() throws Exception
+ {
+ Node file = root.addNode("n", "nt:file");
+ Node content = file.addNode("jcr:content", "nt:resource");
+ content.setProperty("jcr:data", new ByteArrayInputStream(new byte[0]));
+ content.setProperty("jcr:mimeType", "");
+ content.setProperty("jcr:lastModified", Calendar.getInstance());
+ root.save();
+ Node link = root.addNode("link", "nt:linkedFile");
+ link.setProperty("jcr:content", content);
+ root.save();
+
+ // remove linked file but don't save it
+ content.getReferences().nextProperty().getParent().remove();
+
+ Session anotherSession = repository.login(credentials,
root.getSession().getWorkspace().getName());
+ try
+ {
+ // but another session still see the link as a reference
+ PropertyIterator it =
((Node)anotherSession.getItem(content.getPath())).getReferences();
+ assertEquals(1, it.getSize());
+ }
+ catch (Exception e)
+ {
+ fail(e.getMessage());
+ }
+ finally
+ {
+ anotherSession.logout();
+ }
+ }
+
+ public void testGetDeletedReferences() throws Exception
+ {
+ Node file = root.addNode("n", "nt:file");
+ Node content = file.addNode("jcr:content", "nt:resource");
+ content.setProperty("jcr:data", new ByteArrayInputStream(new byte[0]));
+ content.setProperty("jcr:mimeType", "");
+ content.setProperty("jcr:lastModified", Calendar.getInstance());
+ root.save();
+ Node link = root.addNode("link", "nt:linkedFile");
+ link.setProperty("jcr:content", content);
+ root.save();
+
+ // remove linked file but and save it
+ content.getReferences().nextProperty().getParent().remove();
+ root.save();
+
+ try
+ {
+ PropertyIterator it = content.getReferences();
+ assertEquals(0, it.getSize());
+ }
+ catch (Exception e)
+ {
+ fail(e.getMessage());
+ }
+ }
}