You are viewing a plain text version of this content. The canonical link for it is here.
Posted to graffito-commits@incubator.apache.org by ap...@apache.org on 2006/02/15 01:45:56 UTC
svn commit: r377917 - in /incubator/graffito/trunk/jcr/jcr-mapping: ./
src/java/org/apache/portals/graffito/jcr/mapper/impl/
src/java/org/apache/portals/graffito/jcr/mapper/model/
src/java/org/apache/portals/graffito/jcr/persistence/objectconverter/impl/
Author: apopescu
Date: Tue Feb 14 17:45:54 2006
New Revision: 377917
URL: http://svn.apache.org/viewcvs?rev=377917&view=rev
Log:
+ inheritance persistence/fetching
+ node type verification against updates/fetching
Modified:
incubator/graffito/trunk/jcr/jcr-mapping/CHANGES
incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/mapper/impl/DigesterDescriptorReader.java
incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/mapper/impl/DigesterMapperImpl.java
incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/mapper/model/ClassDescriptor.java
incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/mapper/model/MappingDescriptor.java
incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/persistence/objectconverter/impl/ObjectConverterImpl.java
Modified: incubator/graffito/trunk/jcr/jcr-mapping/CHANGES
URL: http://svn.apache.org/viewcvs/incubator/graffito/trunk/jcr/jcr-mapping/CHANGES?rev=377917&r1=377916&r2=377917&view=diff
==============================================================================
--- incubator/graffito/trunk/jcr/jcr-mapping/CHANGES (original)
+++ incubator/graffito/trunk/jcr/jcr-mapping/CHANGES Tue Feb 14 17:45:54 2006
@@ -1,7 +1,11 @@
+20060215
+support for persisting/fetching inheritance
+
20060214
basic support for inheritance
= TODO =
++ Add tests for persistence/fetching of inheritting objects
+ Add exception tests
+ Review query/filters
Modified: incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/mapper/impl/DigesterDescriptorReader.java
URL: http://svn.apache.org/viewcvs/incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/mapper/impl/DigesterDescriptorReader.java?rev=377917&r1=377916&r2=377917&view=diff
==============================================================================
--- incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/mapper/impl/DigesterDescriptorReader.java (original)
+++ incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/mapper/impl/DigesterDescriptorReader.java Tue Feb 14 17:45:54 2006
@@ -70,7 +70,7 @@
digester.addSetProperties("graffito-jcr/class-descriptor", "className", "className");
digester.addSetProperties("graffito-jcr/class-descriptor", "jcrNodeType", "jcrNodeType");
digester.addSetProperties("graffito-jcr/class-descriptor", "jcrSuperTypes", "jcrSuperTypes");
- digester.addSetProperties("graffito-jcr/class-descriptor", "jcrMixinTypes", "jcrMixinTypesList");
+ digester.addSetProperties("graffito-jcr/class-descriptor", "jcrMixinTypes", "jcrMixinTypes");
digester.addSetProperties("graffito-jcr/class-descriptor", "extends", "superClass");
digester.addSetProperties("graffito-jcr/class-descriptor", "abstract", "abstract");
digester.addSetProperties("graffito-jcr/class-descriptor", "discriminatorValue", "discriminatorValue");
Modified: incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/mapper/impl/DigesterMapperImpl.java
URL: http://svn.apache.org/viewcvs/incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/mapper/impl/DigesterMapperImpl.java?rev=377917&r1=377916&r2=377917&view=diff
==============================================================================
--- incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/mapper/impl/DigesterMapperImpl.java (original)
+++ incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/mapper/impl/DigesterMapperImpl.java Tue Feb 14 17:45:54 2006
@@ -18,9 +18,10 @@
import java.io.InputStream;
+import java.util.ArrayList;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
-
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.portals.graffito.jcr.exception.InitMapperException;
@@ -146,7 +147,14 @@
}
}
if (null != this.mappingDescriptor) {
- solveReferences();
+ List errors = new ArrayList();
+ solveReferences(errors);
+ validateDescriptors(errors);
+
+ if (!errors.isEmpty()) {
+ throw new InitMapperException("Mapping files contain errors."
+ + getErrorMessage(errors));
+ }
}
else {
throw new InitMapperException("No mappings were provided");
@@ -155,17 +163,43 @@
return this;
}
- private void solveReferences() {
- for(Iterator it = this.mappingDescriptor.getClassDescriptors().keySet().iterator(); it.hasNext(); ) {
+ private String getErrorMessage(List errors) {
+ final String lineSep = System.getProperty("line.separator");
+ StringBuffer buf = new StringBuffer();
+ for(Iterator it = errors.iterator(); it.hasNext();) {
+ buf.append(lineSep).append(it.next());
+ }
+
+ return buf.toString();
+ }
+
+ private void validateDescriptors(List errors) {
+ for(Iterator it = this.mappingDescriptor.getClassDescriptors().entrySet().iterator(); it.hasNext(); ) {
Map.Entry entry = (Map.Entry) it.next();
ClassDescriptor cd = (ClassDescriptor) entry.getValue();
-
+
+ try {
+ cd.afterPropertiesSet();
+ }
+ catch(JcrMappingException jme) {
+ log.warn("Mapping of class " + cd.getClassName() + " is invalid", jme);
+ errors.add(jme.getMessage());
+ }
+ }
+ }
+
+ private List solveReferences(List errors) {
+ for(Iterator it = this.mappingDescriptor.getClassDescriptors().entrySet().iterator(); it.hasNext(); ) {
+ Map.Entry entry = (Map.Entry) it.next();
+ ClassDescriptor cd = (ClassDescriptor) entry.getValue();
+
if (null != cd.getSuperClass() && !"".equals(cd.getSuperClass())) {
ClassDescriptor superClassDescriptor = this.mappingDescriptor.getClassDescriptor(cd.getSuperClass());
-
+
if (null == superClassDescriptor) {
- throw new JcrMappingException("Cannot find mapping for class "
- + cd.getSuperClass() + " references as extends from "
+ errors.add("Cannot find mapping for class "
+ + cd.getSuperClass()
+ + " referenced as extends from "
+ cd.getClassName());
}
else {
@@ -173,6 +207,8 @@
}
}
}
+
+ return errors;
}
/**
Modified: incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/mapper/model/ClassDescriptor.java
URL: http://svn.apache.org/viewcvs/incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/mapper/model/ClassDescriptor.java?rev=377917&r1=377916&r2=377917&view=diff
==============================================================================
--- incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/mapper/model/ClassDescriptor.java (original)
+++ incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/mapper/model/ClassDescriptor.java Tue Feb 14 17:45:54 2006
@@ -20,6 +20,7 @@
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
+import org.apache.portals.graffito.jcr.exception.JcrMappingException;
/**
*
@@ -29,8 +30,8 @@
* @author <a href='mailto:the_mindstorm[at]evolva[dot]ro'>Alexandru Popescu</a>
*/
public class ClassDescriptor {
- public static final String NODETYPE_PER_HIERARCHY = "nodetypeperhierarchy";
- public static final String NODETYPE_PER_CONCRETECLASS = "nodetypeperconcreteclass";
+ private static final String NODETYPE_PER_HIERARCHY = "nodetypeperhierarchy";
+ private static final String NODETYPE_PER_CONCRETECLASS = "nodetypeperconcreteclass";
private MappingDescriptor mappingDescriptor;
private ClassDescriptor superClassDescriptor;
@@ -71,7 +72,7 @@
/**
* @return Returns the descriminatorValue.
*/
- public String getDescriminatorValue() {
+ public String getDiscriminatorValue() {
return descriminatorValue;
}
@@ -83,7 +84,7 @@
*
* @param descriminatorValue The descriminatorValue to set.
*/
- public void setDescriminatorValue(String descriminatorValue) {
+ public void setDiscriminatorValue(String descriminatorValue) {
this.descriminatorValue= descriminatorValue;
}
@@ -95,10 +96,19 @@
* @return Returns {@link #NODETYPE_PER_HIERARCHY} or {@link #NODETYPE_PER_CONCRETECLASS} or
* <tt>null</tt>
*/
+/*
public String getExtendsStrategy() {
return extendsStrategy;
}
+*/
+ public boolean usesNodeTypePerHierarchyStrategy() {
+ return NODETYPE_PER_HIERARCHY.equals(this.extendsStrategy);
+ }
+
+ public boolean usesNodeTypePerConcreteClassStrategy() {
+ return NODETYPE_PER_CONCRETECLASS.equals(this.extendsStrategy);
+ }
/**
* @return Returns the className.
*/
@@ -162,7 +172,7 @@
* @return all {@link FieldDescriptor} defined in this ClassDescriptor
*/
public Collection getFieldDescriptors() {
- return this.fieldDescriptors.values();
+ return this.allFields.values();
}
/**
@@ -242,7 +252,7 @@
public boolean hasDiscriminatorField() {
return this.discriminatorFieldDescriptor != null;
}
-
+
/**
* Check if this class has an ID
* @return true if the class has an ID
@@ -290,14 +300,16 @@
*
* @param mixinTypes command separated list of mixins
*/
- public void setJcrMixinTypesList(String mixinTypes) {
- if (null != mixinTypes) {
- setJcrMixinTypes(mixinTypes.split(","));
- }
- }
+// public void setJcrMixinTypesList(String[] mixinTypes) {
+// if (null != mixinTypes) {
+// setJcrMixinTypes(mixinTypes[0].split(","));
+// }
+// }
public void setJcrMixinTypes(String[] mixinTypes) {
- jcrMixinTypes = mixinTypes;
+ if (null != mixinTypes && mixinTypes.length == 1) {
+ jcrMixinTypes = mixinTypes[0].split(" *, *");
+ }
}
/**
@@ -315,33 +327,67 @@
}
/**
- * @return <tt>true</tt> if the class descriptor is correct;
- * <tt>false</tt> otherwise
+ * Revisit information in this descriptor and fills in more.
*/
- public boolean validate() {
- if (null == this.superClassDescriptor) {
- this.allFields = this.fieldDescriptors;
- this.allBeans = this.beanDescriptors;
- this.allCollections = this.collectionDescriptors;
+ public void afterPropertiesSet() {
+ lookupSuperDescriptor();
+
+ lookupInheritanceSettings();
+
+ validateInheritanceSettings();
+ }
+
+ private void validateInheritanceSettings() {
+ if (NODETYPE_PER_CONCRETECLASS.equals(this.extendsStrategy)) {
+ this.discriminatorFieldDescriptor = findDiscriminatorField();
+
+ if (null != this.discriminatorFieldDescriptor) {
+ throw new JcrMappingException("");
+ }
}
- else {
- this.allFields = merge(this.fieldDescriptors, this.superClassDescriptor.getFieldDescriptors());
- this.allBeans = merge(this.beanDescriptors, this.superClassDescriptor.getBeanDescriptors());
- this.allCollections = merge(this.collectionDescriptors, this.superClassDescriptor.getCollectionDescriptors());
+ else if (NODETYPE_PER_HIERARCHY.equals(this.extendsStrategy)) {
+ this.discriminatorFieldDescriptor = findDiscriminatorField();
if (null == this.discriminatorFieldDescriptor) {
- this.discriminatorFieldDescriptor = this.superClassDescriptor.getDiscriminatorFieldDescriptor();
+ throw new JcrMappingException("");
}
+ }
+ }
- if (null == this.discriminatorFieldDescriptor) {
+ private FieldDescriptor findDiscriminatorField() {
+ if (null != this.discriminatorFieldDescriptor) {
+ return this.discriminatorFieldDescriptor;
+ }
+
+ if (null != this.superClassDescriptor) {
+ return this.superClassDescriptor.findDiscriminatorField();
+ }
+
+ return null;
+ }
+
+ private void lookupInheritanceSettings() {
+ if (null != this.superClassDescriptor) {
+ if (this.jcrNodeType.equals(this.superClassDescriptor.jcrNodeType)) {
this.extendsStrategy = NODETYPE_PER_HIERARCHY;
}
else {
this.extendsStrategy = NODETYPE_PER_CONCRETECLASS;
}
}
+ }
- return true;
+ private void lookupSuperDescriptor() {
+ if (null == this.superClassDescriptor) {
+ this.allFields = this.fieldDescriptors;
+ this.allBeans = this.beanDescriptors;
+ this.allCollections = this.collectionDescriptors;
+ }
+ else {
+ this.allFields = merge(this.fieldDescriptors, this.superClassDescriptor.getFieldDescriptors());
+ this.allBeans = merge(this.beanDescriptors, this.superClassDescriptor.getBeanDescriptors());
+ this.allCollections = merge(this.collectionDescriptors, this.superClassDescriptor.getCollectionDescriptors());
+ }
}
/**
Modified: incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/mapper/model/MappingDescriptor.java
URL: http://svn.apache.org/viewcvs/incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/mapper/model/MappingDescriptor.java?rev=377917&r1=377916&r2=377917&view=diff
==============================================================================
--- incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/mapper/model/MappingDescriptor.java (original)
+++ incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/mapper/model/MappingDescriptor.java Tue Feb 14 17:45:54 2006
@@ -53,10 +53,6 @@
}
}
- if (!classDescriptor.validate()) {
- return;
- }
-
classDescriptors.put(classDescriptor.getClassName(), classDescriptor);
classDescriptor.setMappingDescriptor(this);
}
Modified: incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/persistence/objectconverter/impl/ObjectConverterImpl.java
URL: http://svn.apache.org/viewcvs/incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/persistence/objectconverter/impl/ObjectConverterImpl.java?rev=377917&r1=377916&r2=377917&view=diff
==============================================================================
--- incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/persistence/objectconverter/impl/ObjectConverterImpl.java (original)
+++ incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/persistence/objectconverter/impl/ObjectConverterImpl.java Tue Feb 14 17:45:54 2006
@@ -159,6 +159,10 @@
}
}
+ if (classDescriptor.usesNodeTypePerHierarchyStrategy()) {
+
+ }
+
storeSimpleFields(session, object, classDescriptor, objectNode);
insertBeanFields(session, object, classDescriptor, objectNode);
insertCollectionFields(session, object, classDescriptor, objectNode);
@@ -195,7 +199,17 @@
try {
ClassDescriptor classDescriptor = getClassDescriptor(object.getClass());
Node objectNode = parentNode.getNode(nodeName);
-
+
+ if (!objectNode.getPrimaryNodeType().getName().equals(classDescriptor.getJcrNodeType())) {
+ throw new PersistenceException("Cannot update object of type "
+ + object.getClass().getName()
+ + ". Node type '"
+ + objectNode.getPrimaryNodeType().getName()
+ + "' doesn't match mapping node type '"
+ + classDescriptor.getJcrNodeType()
+ + "'.");
+ }
+
storeSimpleFields(session, object, classDescriptor, objectNode);
updateBeanFields(session, object, classDescriptor, objectNode);
updateCollectionFields(session, object, classDescriptor, objectNode);
@@ -222,7 +236,35 @@
}
ClassDescriptor classDescriptor = getClassDescriptor(clazz);
+
+ if (classDescriptor.isAbstract()) {
+ throw new PersistenceException("Cannot fetch declared abstract object of type "
+ + clazz.getName());
+ }
+
Node node = (Node) session.getItem(path);
+
+ if (!node.getPrimaryNodeType().getName().equals(classDescriptor.getJcrNodeType())
+ &&
+ !("nt:frozenNode".equals(node.getPrimaryNodeType().getName())
+ && node.getProperty("jcr:frozenPrimaryType").getString().equals(classDescriptor.getJcrNodeType()))) {
+ throw new PersistenceException("Cannot fetch object of type '"
+ + clazz.getName()
+ + "'. Node type '"
+ + node.getPrimaryNodeType().getName()
+ + "' does not match descriptor node type '"
+ + classDescriptor.getJcrNodeType()
+ + "'");
+ }
+ if (classDescriptor.usesNodeTypePerHierarchyStrategy()) {
+ String discriminatorProperty = classDescriptor.getDiscriminatorFieldDescriptor().getJcrName();
+
+ if (!node.hasProperty(discriminatorProperty)) {
+ throw new PersistenceException("Cannot fetch object of type '"
+ + clazz.getName()
+ + "' using NODETYPE_PER_HIERARCHY. Discriminator property is not present.");
+ }
+ }
Object object = ReflectionUtils.newInstance(clazz);
retrieveSimpleFields(session, classDescriptor, node, object);
@@ -286,7 +328,20 @@
}
ReflectionUtils.setNestedProperty(initializedBean, fieldName, node.getPath());
- } else {
+ }
+ else if (classDescriptor.usesNodeTypePerHierarchyStrategy() && fieldDescriptor.isDiscriminator()) {
+ if (null != classDescriptor.getDiscriminatorValue()) {
+ if (null == initializedBean) {
+ initializedBean = ReflectionUtils.newInstance(classDescriptor.getClassName());
+ }
+
+ ReflectionUtils.setNestedProperty(initializedBean, fieldName, classDescriptor.getDiscriminatorValue());
+ }
+ else {
+ throw new PersistenceException("Class '" + classDescriptor.getClassName() + "' does not declare a valid discriminator value.");
+ }
+ }
+ else {
if (node.hasProperty(propertyName)) {
Value propValue = node.getProperty(propertyName).getValue();
if (null != propValue && null == initializedBean) { // HINT: lazy initialize target bean
@@ -531,6 +586,19 @@
if (fieldDescriptor.isPath()) {
continue;
}
+
+ // Discriminator is already written
+ if (classDescriptor.usesNodeTypePerHierarchyStrategy() && fieldDescriptor.isDiscriminator()) {
+ if (null != classDescriptor.getDiscriminatorValue() && !"".equals(classDescriptor.getDiscriminatorValue())) {
+ objectNode.setProperty(fieldDescriptor.getJcrName(), classDescriptor.getDiscriminatorValue());
+ }
+ else {
+ throw new PersistenceException("Cannot persist object of type " + object.getClass().getName()
+ + " Missing discriminator value from class descriptor.");
+ }
+
+ continue;
+ }
String fieldName = fieldDescriptor.getFieldName();
String jcrName = fieldDescriptor.getJcrName();
@@ -651,7 +719,11 @@
throw new JcrMappingException("Class of type: " + beanClass.getName()
+ " is not JCR persistable. Maybe element 'class-descriptor' for this type in mapping file is missing");
}
-
+
+ if(classDescriptor.isAbstract()) {
+ throw new PersistenceException("Cannot persist/retrieve abstract class " + beanClass.getName());
+ }
+
return classDescriptor;
}
}