You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by cl...@apache.org on 2007/08/17 00:06:05 UTC
svn commit: r566872 - in
/jackrabbit/trunk/contrib/jackrabbit-jcr-mapping/jcr-mapping/src:
main/java/org/apache/jackrabbit/ocm/manager/collectionconverter/impl/
test/java/org/apache/jackrabbit/ocm/manager/proxy/
test/java/org/apache/jackrabbit/ocm/test...
Author: clombart
Date: Thu Aug 16 15:06:04 2007
New Revision: 566872
URL: http://svn.apache.org/viewvc?view=rev&rev=566872
Log:
Apply and modify patch for JCR-1053. Thanks to André Bierwolf.
I added more unit tests on collection & proxy.
Added:
jackrabbit/trunk/contrib/jackrabbit-jcr-mapping/jcr-mapping/src/test/java/org/apache/jackrabbit/ocm/testmodel/proxy/NTDetail.java
jackrabbit/trunk/contrib/jackrabbit-jcr-mapping/jcr-mapping/src/test/java/org/apache/jackrabbit/ocm/testmodel/proxy/NTMain.java
Modified:
jackrabbit/trunk/contrib/jackrabbit-jcr-mapping/jcr-mapping/src/main/java/org/apache/jackrabbit/ocm/manager/collectionconverter/impl/NTCollectionConverterImpl.java
jackrabbit/trunk/contrib/jackrabbit-jcr-mapping/jcr-mapping/src/test/java/org/apache/jackrabbit/ocm/manager/proxy/ProxyTest.java
jackrabbit/trunk/contrib/jackrabbit-jcr-mapping/jcr-mapping/src/test/test-config/jcrmapping-proxy.xml
jackrabbit/trunk/contrib/jackrabbit-jcr-mapping/jcr-mapping/src/test/test-config/nodetypes/custom_nodetypes.xml
Modified: jackrabbit/trunk/contrib/jackrabbit-jcr-mapping/jcr-mapping/src/main/java/org/apache/jackrabbit/ocm/manager/collectionconverter/impl/NTCollectionConverterImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/jackrabbit-jcr-mapping/jcr-mapping/src/main/java/org/apache/jackrabbit/ocm/manager/collectionconverter/impl/NTCollectionConverterImpl.java?view=diff&rev=566872&r1=566871&r2=566872
==============================================================================
--- jackrabbit/trunk/contrib/jackrabbit-jcr-mapping/jcr-mapping/src/main/java/org/apache/jackrabbit/ocm/manager/collectionconverter/impl/NTCollectionConverterImpl.java (original)
+++ jackrabbit/trunk/contrib/jackrabbit-jcr-mapping/jcr-mapping/src/main/java/org/apache/jackrabbit/ocm/manager/collectionconverter/impl/NTCollectionConverterImpl.java Thu Aug 16 15:06:04 2007
@@ -33,6 +33,9 @@
import javax.jcr.ValueFormatException;
import javax.jcr.lock.LockException;
import javax.jcr.nodetype.ConstraintViolationException;
+import javax.jcr.query.InvalidQueryException;
+import javax.jcr.query.Query;
+import javax.jcr.query.QueryResult;
import javax.jcr.version.VersionException;
import org.apache.commons.logging.Log;
@@ -44,14 +47,19 @@
import org.apache.jackrabbit.ocm.mapper.model.ClassDescriptor;
import org.apache.jackrabbit.ocm.mapper.model.CollectionDescriptor;
import org.apache.jackrabbit.ocm.reflection.ReflectionUtils;
+import org.apache.jackrabbit.util.ISO9075;
/**
* Collection Mapping/convertion based on node type.
*
- * This collection mapping strategy maps a collection into several nodes based on specific node type.
+ * This collection mapping strategy maps the collection elements into subnodes based on the same node types.
+ *
+ * There are 2 constraints in this collection converter :
+ * 1/ this is not possible to have 2 different collections in the main object which are used the same jcr node type for their elements.
+ * 2/ this is not possible to make a distinction between an empty collection and an null collection.
*
*
- * If the collection element class contains an id (see the FieldDescriptor definition), this id value is used to build the collection element node.
+ * If the collection element class contains an id (see the FieldDescriptor definition), this id value is used to build the collection element node name.
* Otherwise, the element node name is a simple constant (collection-element)
*
* Example - without an id attribute:
@@ -61,6 +69,8 @@
* ....
* /collection-element (node used to store the second collection element)
* ...
+ *
+ * Each "collection-element" nodes have the same jcr node type
*
* Example - with an id attribute:
* /test (Main object containing the collection field )
@@ -69,6 +79,8 @@
* ....
* /anotherValue (id value assigned to the first element)
* ...
+ *
+ * Each collection element nodes have the same jcr node type
*
* @author <a href="mailto:christophe.lombart@gmail.com">Christophe Lombart</a>
*
@@ -174,13 +186,13 @@
}
// Delete JCR nodes that are not present in the collection
- Collection collectionNodes = this.getCollectionNodes(session, parentNode,
+ NodeIterator nodes = this.getCollectionNodes(session, parentNode,
elementClassDescriptor.getJcrType());
- if (collectionNodes != null && elementClassDescriptor.hasIdField()) {
- Iterator nodeIterator = collectionNodes.iterator();
+ if (nodes != null && elementClassDescriptor.hasIdField()) {
+
- while (nodeIterator.hasNext()) {
- Node child = (Node) nodeIterator.next();
+ while (nodes.hasNext()) {
+ Node child = (Node) nodes.next();
if (!updatedItems.containsKey(child.getName())) {
child.remove();
@@ -198,17 +210,16 @@
Class collectionFieldClass) throws RepositoryException {
ClassDescriptor elementClassDescriptor = mapper.getClassDescriptorByClass( ReflectionUtils.forName(collectionDescriptor.getElementClassName()));
ManageableCollection collection = ManageableCollectionUtil.getManageableCollection(collectionFieldClass);
- //Class elementClass = ReflectionUtils.forName(collectionDescriptor.getElementClassName());
- Collection nodes = this.getCollectionNodes(session, parentNode, elementClassDescriptor.getJcrType());
+
+ NodeIterator nodes = this.getCollectionNodes(session, parentNode, elementClassDescriptor.getJcrType());
- if (nodes == null)
+ if (nodes == null || nodes.getSize() == 0)
{
return null;
}
-
- Iterator children = nodes.iterator();
- while (children.hasNext()) {
- Node itemNode = (Node) children.next();
+
+ while (nodes.hasNext()) {
+ Node itemNode = (Node) nodes.next();
log.debug("Collection node found : " + itemNode.getPath());
Object item = objectConverter.getObject(session, itemNode.getPath());
collection.addObject(item);
@@ -219,54 +230,29 @@
/**
* @see AbstractCollectionConverterImpl#doIsNull(Session, Node, CollectionDescriptor, Class)
+ *
+ * return true If the parent node doesn't contains node based on the node type associated to the collection elements
+ *
*/
protected boolean doIsNull(Session session,
Node parentNode,
CollectionDescriptor collectionDescriptor,
Class collectionFieldClass) throws RepositoryException {
- // This collection converter returns at least a empty collection (see in doGetCollection)
- return false;
- }
-
- private Collection getCollectionNodes(Session session, Node parentNode, String itemNodeType)
+ String elementClassName = collectionDescriptor.getElementClassName();
+ ClassDescriptor elementClassDescriptor = mapper.getClassDescriptorByClass(ReflectionUtils.forName(elementClassName));
+ QueryResult queryResult = getQuery(session, parentNode, elementClassDescriptor.getJcrType());
+ return queryResult.getNodes().getSize() == 0;
+ }
+
+ private NodeIterator getCollectionNodes(Session session, Node parentNode, String itemNodeType)
throws PathNotFoundException, ValueFormatException, RepositoryException {
- List collectionNodes = new ArrayList();
-
- // TODO : review this workaround used to support version nodes
- // Searching on the version storage has some bugs => loop on all child noded and check the property jcr:frozenPrimaryType
- // I have to investigate in more detail what's happen exactly
- if (!parentNode.getPath().startsWith("/jcr:system/jcr:versionStorage")) {
- NodeIterator nodeIterator = parentNode.getNodes();
- while (nodeIterator.hasNext()) {
- Node child = nodeIterator.nextNode();
-
- if (child.isNodeType(itemNodeType)) {
- collectionNodes.add(child);
- }
- }
- }
- else {
- NodeIterator nodeIterator = parentNode.getNodes();
- while (nodeIterator.hasNext()) {
- Node child = nodeIterator.nextNode();
-
- if (child.getProperty("jcr:frozenPrimaryType").getString().equals(itemNodeType)) {
- collectionNodes.add(child);
- }
- }
-
- }
-
- if (collectionNodes.size() == 0)
- {
- return null;
- }
- else
- {
- return collectionNodes;
- }
+ List collectionNodes = null;
+
+ QueryResult queryResult = getQuery(session, parentNode, itemNodeType);
+ return queryResult.getNodes();
+
}
private void deleteCollectionItems(Session session, Node parentNode, String itemNodeType)
@@ -277,13 +263,35 @@
ValueFormatException,
RepositoryException
{
- Collection nodes = this.getCollectionNodes(session, parentNode, itemNodeType);
- if (nodes == null) return;
-
- Iterator nodeIterator = nodes.iterator();
- while (nodeIterator.hasNext()) {
- Node node = (Node) nodeIterator.next();
+ NodeIterator nodes = this.getCollectionNodes(session, parentNode, itemNodeType);
+ if (nodes == null || nodes.getSize()==0) return;
+
+ while (nodes.hasNext()) {
+ Node node = (Node) nodes.next();
node.remove();
}
}
+
+
+
+ private QueryResult getQuery(Session session, Node parentNode, String jcrNodeType) throws RepositoryException, InvalidQueryException {
+ String jcrExpression= "";
+ if (!parentNode.getPath().startsWith("/jcr:system/jcr:versionStorage"))
+ {
+ jcrExpression = "SELECT * FROM " + jcrNodeType + " WHERE jcr:path LIKE '" + parentNode.getPath()
+ + "/%' AND NOT jcr:path LIKE '" + parentNode.getPath() + "/%/%'";
+ }
+ else
+ {
+
+ jcrExpression = "SELECT * FROM nt:frozenNode" + " WHERE jcr:path LIKE '" + parentNode.getPath() + "/%'"
+ + " AND NOT jcr:path LIKE '" + parentNode.getPath() + "/%/%'"
+ + " AND jcr:frozenPrimaryType = '" + jcrNodeType + "'";
+
+
+ }
+ Query jcrQuery = session.getWorkspace().getQueryManager().createQuery(jcrExpression, javax.jcr.query.Query.SQL);
+ QueryResult queryResult = jcrQuery.execute();
+ return queryResult;
+ }
}
Modified: jackrabbit/trunk/contrib/jackrabbit-jcr-mapping/jcr-mapping/src/test/java/org/apache/jackrabbit/ocm/manager/proxy/ProxyTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/jackrabbit-jcr-mapping/jcr-mapping/src/test/java/org/apache/jackrabbit/ocm/manager/proxy/ProxyTest.java?view=diff&rev=566872&r1=566871&r2=566872
==============================================================================
--- jackrabbit/trunk/contrib/jackrabbit-jcr-mapping/jcr-mapping/src/test/java/org/apache/jackrabbit/ocm/manager/proxy/ProxyTest.java (original)
+++ jackrabbit/trunk/contrib/jackrabbit-jcr-mapping/jcr-mapping/src/test/java/org/apache/jackrabbit/ocm/manager/proxy/ProxyTest.java Thu Aug 16 15:06:04 2007
@@ -29,6 +29,7 @@
import org.apache.jackrabbit.ocm.manager.ObjectContentManager;
import org.apache.jackrabbit.ocm.testmodel.proxy.Detail;
import org.apache.jackrabbit.ocm.testmodel.proxy.Main;
+import org.apache.jackrabbit.ocm.testmodel.proxy.NTMain;
/**
* Test inheritance with node type per concrete class (without discreminator field)
@@ -114,7 +115,6 @@
//---------------------------------------------------------------------------------------------------------
// Retrieve the main object
//---------------------------------------------------------------------------------------------------------
-
main = (Main) ocm.getObject( "/test");
assertNotNull("detail is null", main.getDetail());
assertTrue("Invalid detail bean", main.getDetail().getField().equals("AnotherFieldValue"));
@@ -126,6 +126,11 @@
assertNull("nulldetail is not null",main.getNullDetail());
+ //---------------------------------------------------------------------------------------------------------
+ // Delete the main object
+ //---------------------------------------------------------------------------------------------------------
+ ocm.remove("/test");
+ ocm.save();
} catch (Exception e) {
e.printStackTrace();
@@ -135,7 +140,7 @@
}
- public void testCollectionProxy() {
+ public void testDefaultCollectionConverterWithProxy() {
try {
ObjectContentManager ocm = this.getObjectContentManager();
@@ -183,7 +188,12 @@
assertNotNull("main is null", main);
assertEquals("Invalide size",main.getProxyCollection().size(), 101);
assertNull("nullcollectionproxy is not null", main.getNullProxyCollection());
-
+
+ //---------------------------------------------------------------------------------------------------------
+ // Delete the main object
+ //---------------------------------------------------------------------------------------------------------
+ ocm.remove("/test");
+ ocm.save();
} catch (Exception e) {
e.printStackTrace();
@@ -193,6 +203,82 @@
}
+ public void testNTCollectionconverterWithProxy() {
+
+ try {
+
+ ObjectContentManager ocm = this.getObjectContentManager();
+
+ NTMain main = new NTMain();
+ main.setPath("/test");
+ ocm.insert(main);
+ ocm.save();
+
+ //---------------------------------------------------------------------------------------------------------
+ // Retrieve the main object
+ //---------------------------------------------------------------------------------------------------------
+ main = (NTMain) ocm.getObject( "/test");
+ assertNotNull("main is null", main);
+
+ Collection result = main.getProxyCollection();
+ assertNull("Collection is not null", result);
+
+/*
+ //---------------------------------------------------------------------------------------------------------
+ // Update
+ //---------------------------------------------------------------------------------------------------------
+ ArrayList details= new ArrayList();
+ for(int i=1; i<=100;i++)
+ {
+ Detail detail = new Detail();
+ detail.setField("field" + i);
+ details.add(detail);
+ }
+ main.setProxyCollection(details);
+ ocm.update(main);
+ ocm.save();
+
+ //---------------------------------------------------------------------------------------------------------
+ // Retrieve the main object
+ //---------------------------------------------------------------------------------------------------------
+ main = (NtMain) ocm.getObject( "/test");
+ assertNotNull("main is null", main);
+
+ result = main.getProxyCollection();
+ assertEquals("Invalide size", result.size(), 100);
+
+
+ //---------------------------------------------------------------------------------------------------------
+ // Update
+ //---------------------------------------------------------------------------------------------------------
+ Detail detail = new Detail();
+ detail.setField("newFieldValue");
+ result.add(detail);
+ main.setProxyCollection(result);
+ ocm.update(main);
+ ocm.save();
+
+ //---------------------------------------------------------------------------------------------------------
+ // Retrieve the main object
+ //---------------------------------------------------------------------------------------------------------
+ main = (NtMain) ocm.getObject("/test");
+ assertNotNull("main is null", main);
+ assertEquals("Invalide size",main.getProxyCollection().size(), 101);
+
+*/
+ //---------------------------------------------------------------------------------------------------------
+ // Delete the main object
+ //---------------------------------------------------------------------------------------------------------
+ ocm.remove("/test");
+ ocm.save();
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail();
+ }
+
+
+ }
Added: jackrabbit/trunk/contrib/jackrabbit-jcr-mapping/jcr-mapping/src/test/java/org/apache/jackrabbit/ocm/testmodel/proxy/NTDetail.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/jackrabbit-jcr-mapping/jcr-mapping/src/test/java/org/apache/jackrabbit/ocm/testmodel/proxy/NTDetail.java?view=auto&rev=566872
==============================================================================
--- jackrabbit/trunk/contrib/jackrabbit-jcr-mapping/jcr-mapping/src/test/java/org/apache/jackrabbit/ocm/testmodel/proxy/NTDetail.java (added)
+++ jackrabbit/trunk/contrib/jackrabbit-jcr-mapping/jcr-mapping/src/test/java/org/apache/jackrabbit/ocm/testmodel/proxy/NTDetail.java Thu Aug 16 15:06:04 2007
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.ocm.testmodel.proxy;
+
+public class NTDetail
+{
+ private String path;
+ private String field;
+
+
+ public String getPath() {
+ return path;
+ }
+
+ public void setPath(String path) {
+ this.path = path;
+ }
+
+ public String getField() {
+ return field;
+ }
+
+ public void setField(String field) {
+ this.field = field;
+ }
+
+
+}
Added: jackrabbit/trunk/contrib/jackrabbit-jcr-mapping/jcr-mapping/src/test/java/org/apache/jackrabbit/ocm/testmodel/proxy/NTMain.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/jackrabbit-jcr-mapping/jcr-mapping/src/test/java/org/apache/jackrabbit/ocm/testmodel/proxy/NTMain.java?view=auto&rev=566872
==============================================================================
--- jackrabbit/trunk/contrib/jackrabbit-jcr-mapping/jcr-mapping/src/test/java/org/apache/jackrabbit/ocm/testmodel/proxy/NTMain.java (added)
+++ jackrabbit/trunk/contrib/jackrabbit-jcr-mapping/jcr-mapping/src/test/java/org/apache/jackrabbit/ocm/testmodel/proxy/NTMain.java Thu Aug 16 15:06:04 2007
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.ocm.testmodel.proxy;
+
+import java.util.Collection;
+
+public class NTMain
+{
+
+ private String path;
+ //private Detail proxyDetail;
+ private Collection proxyCollection;
+
+
+
+ public String getPath() {
+ return path;
+ }
+
+ public void setPath(String path) {
+ this.path = path;
+ }
+
+ public Collection getProxyCollection() {
+ return proxyCollection;
+ }
+
+ public void setProxyCollection(Collection proxyCollection) {
+ this.proxyCollection = proxyCollection;
+ }
+
+
+}
Modified: jackrabbit/trunk/contrib/jackrabbit-jcr-mapping/jcr-mapping/src/test/test-config/jcrmapping-proxy.xml
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/jackrabbit-jcr-mapping/jcr-mapping/src/test/test-config/jcrmapping-proxy.xml?view=diff&rev=566872&r1=566871&r2=566872
==============================================================================
--- jackrabbit/trunk/contrib/jackrabbit-jcr-mapping/jcr-mapping/src/test/test-config/jcrmapping-proxy.xml (original)
+++ jackrabbit/trunk/contrib/jackrabbit-jcr-mapping/jcr-mapping/src/test/test-config/jcrmapping-proxy.xml Thu Aug 16 15:06:04 2007
@@ -20,6 +20,21 @@
<field-descriptor fieldName="path" path="true" />
<field-descriptor fieldName="field" jcrName="field" />
</class-descriptor>
+
+ <class-descriptor className="org.apache.jackrabbit.ocm.testmodel.proxy.NTDetail" jcrType="ocm:ntdetail" >
+ <field-descriptor fieldName="path" path="true" />
+ <field-descriptor fieldName="field" jcrName="ocm:field" />
+ </class-descriptor>
+
+ <class-descriptor className="org.apache.jackrabbit.ocm.testmodel.proxy.NTMain" jcrType="ocm:ntmain" >
+ <field-descriptor fieldName="path" path="true" />
+ <!-- bean-descriptor fieldName="nullDetail" jcrName="nulldetail" proxy="true" jcrType="ocm:ntdetail" / -->
+
+ <collection-descriptor fieldName="proxyCollection" proxy="true"
+ elementClassName="org.apache.jackrabbit.ocm.testmodel.proxy.NTDetail"
+ collectionConverter="org.apache.jackrabbit.ocm.manager.collectionconverter.impl.NTCollectionConverterImpl" />
+ </class-descriptor>
+
+
-</jackrabbit-ocm>
-
+</jackrabbit-ocm>
Modified: jackrabbit/trunk/contrib/jackrabbit-jcr-mapping/jcr-mapping/src/test/test-config/nodetypes/custom_nodetypes.xml
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/jackrabbit-jcr-mapping/jcr-mapping/src/test/test-config/nodetypes/custom_nodetypes.xml?view=diff&rev=566872&r1=566871&r2=566872
==============================================================================
--- jackrabbit/trunk/contrib/jackrabbit-jcr-mapping/jcr-mapping/src/test/test-config/nodetypes/custom_nodetypes.xml (original)
+++ jackrabbit/trunk/contrib/jackrabbit-jcr-mapping/jcr-mapping/src/test/test-config/nodetypes/custom_nodetypes.xml Thu Aug 16 15:06:04 2007
@@ -221,5 +221,26 @@
</defaultValues>
</propertyDefinition>
</nodeType>
+
+ <nodeType name="ocm:ntdetail" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
+ <supertypes>
+ <supertype>nt:base</supertype>
+ </supertypes>
+ <propertyDefinition name="*" requiredType="undefined" autoCreated="false" mandatory="false" onParentVersion="COPY" protected="false" multiple="false" />
+ <propertyDefinition name="ocm:field" requiredType="String" autoCreated="false" mandatory="true" onParentVersion="COPY" protected="false" multiple="false" />
+ </nodeType>
+
+ <nodeType name="ocm:ntmain" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
+ <supertypes>
+ <supertype>nt:base</supertype>
+ </supertypes>
+ <propertyDefinition name="*" requiredType="undefined" autoCreated="false" mandatory="false" onParentVersion="COPY" protected="false" multiple="false" />
+ <childNodeDefinition name="*" defaultPrimaryType="ocm:ntdetail" autoCreated="false" mandatory="false" onParentVersion="COPY" protected="false" sameNameSiblings="true">
+ <requiredPrimaryTypes>
+ <requiredPrimaryType>ocm:ntdetail</requiredPrimaryType>
+ </requiredPrimaryTypes>
+ </childNodeDefinition>
+ </nodeType>
+
</nodeTypes>