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/07 10:41:30 UTC
svn commit: r375573 [2/2] - in
/incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/persistence:
impl/PersistenceManagerImpl.java
objectconverter/impl/ObjectConverterImpl.java
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=375573&r1=375572&r2=375573&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 7 02:41:28 2006
@@ -1,506 +1,575 @@
-/*
- * Copyright 2000-2005 The Apache Software Foundation.
- *
- * Licensed 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.portals.graffito.jcr.persistence.objectconverter.impl;
-
-import java.lang.reflect.InvocationTargetException;
-import java.util.Iterator;
-import java.util.Map;
-
-import javax.jcr.Node;
-import javax.jcr.PathNotFoundException;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.Value;
-import javax.jcr.ValueFactory;
-import javax.jcr.ValueFormatException;
-import javax.jcr.lock.LockException;
-import javax.jcr.nodetype.ConstraintViolationException;
-import javax.jcr.nodetype.PropertyDefinition;
-import javax.jcr.version.VersionException;
-
-import org.apache.commons.beanutils.ConstructorUtils;
-import org.apache.commons.beanutils.PropertyUtils;
-import org.apache.portals.graffito.jcr.exception.JcrMappingException;
-import org.apache.portals.graffito.jcr.exception.PersistenceException;
-import org.apache.portals.graffito.jcr.mapper.Mapper;
-import org.apache.portals.graffito.jcr.mapper.model.BeanDescriptor;
-import org.apache.portals.graffito.jcr.mapper.model.ClassDescriptor;
-import org.apache.portals.graffito.jcr.mapper.model.CollectionDescriptor;
-import org.apache.portals.graffito.jcr.mapper.model.FieldDescriptor;
-import org.apache.portals.graffito.jcr.persistence.atomictypeconverter.AtomicTypeConverter;
-import org.apache.portals.graffito.jcr.persistence.collectionconverter.CollectionConverter;
-import org.apache.portals.graffito.jcr.persistence.collectionconverter.ManageableCollection;
-import org.apache.portals.graffito.jcr.persistence.collectionconverter.ManageableCollectionUtil;
-import org.apache.portals.graffito.jcr.persistence.collectionconverter.impl.DefaultCollectionConverterImpl;
-import org.apache.portals.graffito.jcr.persistence.objectconverter.ObjectConverter;
-import org.apache.portals.graffito.jcr.repository.RepositoryUtil;
-
-/**
- * Default implementation for {@link ObjectConverterImpl}
- *
- * @author <a href="mailto:christophe.lombart@sword-technologies.com">Lombart Christophe </a>
- *
- */
-public class ObjectConverterImpl implements ObjectConverter
-{
- private Mapper mapper;
-
- private Map atomicTypeConverters;
-
- /**
- * Constructor
- *
- * @param mapper The mapper to used
- * @param atomicTypeConverters The atomic type converters to used
- *
- */
- public ObjectConverterImpl(Mapper mapper, Map atomicTypeConverters)
- {
- this.mapper = mapper;
- this.atomicTypeConverters = atomicTypeConverters;
- }
-
- /**
- * @see org.apache.portals.graffito.jcr.persistence.objectconverter.ObjectConverter#insert(javax.jcr.Session, java.lang.Object)
- */
- public void insert(Session session, Object object)
- {
- String path = this.getPath(session, object);
- try
- {
- String parentPath = RepositoryUtil.getParentPath(path);
- String nodeName = RepositoryUtil.getNodeName(path);
- Node parentNode = (Node) session.getItem(parentPath);
- this.insert(session, parentNode, nodeName, object);
-
- }
- catch (Exception e)
- {
- throw new PersistenceException("Impossible to insert the object at " + path, e);
- }
-
- }
-
- /**
- *
- * @see org.apache.portals.graffito.jcr.persistence.objectconverter.ObjectConverter#insert(javax.jcr.Session, javax.jcr.Node, java.lang.String, java.lang.Object)
- */
- public void insert(Session session, Node parentNode, String nodeName, Object object)
- {
- try
- {
- ClassDescriptor classDescriptor = mapper.getClassDescriptor(object.getClass());
- if (classDescriptor == null)
- {
- throw new PersistenceException("Class of type: " + object.getClass().getName() + " is not JCR persistable. Maybe element 'class-descriptor' for this type in mapping file is missing");
- }
-
- String jcrNodeType = classDescriptor.getJcrNodeType();
- if (jcrNodeType == null || jcrNodeType.equals(""))
- {
- throw new PersistenceException("Undefined node type for " + parentNode);
- }
-
- Node objectNode = null;
- objectNode = parentNode.addNode(nodeName, jcrNodeType);
-
- storeSimpleFields(session, object, classDescriptor, objectNode);
- insertBeanFields(session, object, classDescriptor, objectNode);
- insertCollectionFields(session, object, classDescriptor, objectNode);
-
- }
- catch (Exception e)
- {
- throw new PersistenceException("Impossible to insert the object at " + parentNode, e);
- }
-
- }
-
- /**
- * @see org.apache.portals.graffito.jcr.persistence.objectconverter.ObjectConverter#update(javax.jcr.Session, java.lang.Object)
- */
- public void update(Session session, Object object)
- {
- String path = this.getPath(session, object);
- try
- {
- String parentPath = RepositoryUtil.getParentPath(path);
- String nodeName = RepositoryUtil.getNodeName(path);
- Node parentNode = (Node) session.getItem(parentPath);
- this.update(session, parentNode, nodeName, object);
-
- }
- catch (Exception e)
- {
- throw new PersistenceException("Impossible to update the object at " + path, e);
- }
- }
-
- /**
- *
- * @see org.apache.portals.graffito.jcr.persistence.objectconverter.ObjectConverter#update(javax.jcr.Session, javax.jcr.Node, java.lang.String, java.lang.Object)
- */
- public void update(Session session, Node parentNode, String nodeName, Object object)
- {
- try
- {
- ClassDescriptor classDescriptor = mapper.getClassDescriptor(object.getClass());
- if (classDescriptor == null)
- {
- throw new PersistenceException("Class of type: " + object.getClass().getName() + " is not JCR persistable. Maybe element 'class-descriptor' for this type in mapping file is missing");
- }
-
- String jcrNodeType = classDescriptor.getJcrNodeType();
- if (jcrNodeType == null || jcrNodeType.equals(""))
- {
- throw new PersistenceException("Undefined node type for " + parentNode);
- }
-
- Node objectNode = null;
- objectNode = parentNode.getNode(nodeName);
-
- storeSimpleFields(session, object, classDescriptor, objectNode);
- updateBeanFields(session, object, classDescriptor, objectNode);
- updateCollectionFields(session, object, classDescriptor, objectNode);
-
- }
- catch (Exception e)
- {
- throw new PersistenceException("Impossible to update the node : " + parentNode, e);
- }
-
- }
-
- /**
- * @see org.apache.portals.graffito.jcr.persistence.objectconverter.ObjectConverter#getObject(javax.jcr.Session, java.lang.Class, java.lang.String)
- */
- public Object getObject(Session session, Class clazz, String path)
- {
- try
- {
-
- if (!session.itemExists(path))
- {
- return null;
- }
-
- ClassDescriptor classDescriptor = mapper.getClassDescriptor(clazz);
- if (classDescriptor == null)
- {
- throw new PersistenceException("Class of type: " + clazz.getName() + " is not JCR persistable. Maybe element 'class-descriptor' for this type in mapping file is missing");
- }
-
- Node node = (Node) session.getItem(path);
- Object object = clazz.newInstance();
-
- retrieveSimpleFields(classDescriptor, node, object);
- retrieveBeanFields(session, path, classDescriptor, object);
- retrieveCollectionFields(session, classDescriptor, node, object);
-
- return object;
-
- }
- catch (Exception e)
- {
- throw new PersistenceException("Impossible to get the object at " + path, e);
- }
- }
-
-
- public String getPath(Session session, Object object)
- {
- try
- {
- ClassDescriptor classDescriptor = mapper.getClassDescriptor(object.getClass());
- if (classDescriptor == null)
- {
- throw new PersistenceException("Class of type: " + object.getClass().getName() + " is not JCR persistable. Maybe element 'class-descriptor' for this type in mapping file is missing");
- }
-
- final FieldDescriptor pathFieldDescriptor = classDescriptor.getPathFieldDescriptor();
- if (pathFieldDescriptor == null)
- {
- throw new PersistenceException("Class of type: " + object.getClass().getName() + " has no path mapping. Maybe attribute path=\"true\" for a field element of this class in jcrmapping.xml is missing?");
- }
- String pathField = pathFieldDescriptor.getFieldName();
- return (String) PropertyUtils.getNestedProperty(object, pathField);
-
-
- }
- catch (Exception e)
- {
- throw new PersistenceException("Impossible to get the path", e);
- }
-
- }
-
- /**
- * Retrieve simple fields (atomic fields)
- */
- private void retrieveSimpleFields(ClassDescriptor classDescriptor, Node node, Object object) throws PathNotFoundException, RepositoryException, ValueFormatException, IllegalAccessException,
- InvocationTargetException, NoSuchMethodException
- {
- Iterator fieldDescriptorIterator = classDescriptor.getFieldDescriptors().iterator();
-
- while (fieldDescriptorIterator.hasNext())
- {
- FieldDescriptor fieldDescriptor = (FieldDescriptor) fieldDescriptorIterator.next();
-
- String fieldName = fieldDescriptor.getFieldName();
- String propertyName = fieldDescriptor.getJcrName();
-
- if (fieldDescriptor.isPath())
- {
- PropertyUtils.setNestedProperty(object, fieldName, node.getPath());
- }
- else
- {
- Class fieldTypeClass = fieldDescriptor.getFieldTypeClass() != null
- ? fieldDescriptor.getFieldTypeClass()
- : PropertyUtils.getPropertyType(object, fieldName);
-
- AtomicTypeConverter converter = (AtomicTypeConverter) atomicTypeConverters
- .get(fieldTypeClass);
- if (node.hasProperty(propertyName))
- {
- Object fieldValue = converter.getObject(node.getProperty(propertyName).getValue());
- PropertyUtils.setNestedProperty(object, fieldName, fieldValue);
- }
- }
- }
- }
-
- /**
- * Retrieve bean fields
- */
- private void retrieveBeanFields(Session session, String path, ClassDescriptor classDescriptor, Object object) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException
- {
- Iterator beanDescriptorIterator = classDescriptor.getBeanDescriptors().iterator();
- while (beanDescriptorIterator.hasNext())
- {
- BeanDescriptor beanDescriptor = (BeanDescriptor) beanDescriptorIterator.next();
- String beanName = beanDescriptor.getFieldName();
- Class beanClass = PropertyUtils.getPropertyDescriptor(object, beanName).getPropertyType();
- Object bean = this.getObject(session, beanClass, path + "/" + beanDescriptor.getJcrName());
- PropertyUtils.setNestedProperty(object, beanName, bean);
- }
- }
-
- /**
- * Retrieve Collection fields
- */
- private void retrieveCollectionFields(Session session, ClassDescriptor classDescriptor, Node node, Object object) throws PathNotFoundException, RepositoryException, JcrMappingException,
- ClassNotFoundException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException
- {
- Iterator collectionDescriptorIterator = classDescriptor.getCollectionDescriptors().iterator();
- while (collectionDescriptorIterator.hasNext())
- {
- CollectionDescriptor collectionDescriptor = (CollectionDescriptor) collectionDescriptorIterator.next();
- CollectionConverter collectionConverter = this.getCollectionConverter(collectionDescriptor);
- Class collectionFieldClass = PropertyUtils.getPropertyDescriptor(object, collectionDescriptor.getFieldName()).getPropertyType();
- ManageableCollection collection = collectionConverter.getCollection(session, node, collectionDescriptor, collectionFieldClass);
- PropertyUtils.setNestedProperty(object, collectionDescriptor.getFieldName(), collection);
- }
- }
-
- /**
- * Insert Bean fields
- */
- private void insertBeanFields(Session session, Object object, ClassDescriptor classDescriptor, Node objectNode)
- {
- try
- {
- Iterator beanDescriptorIterator = classDescriptor.getBeanDescriptors().iterator();
- while (beanDescriptorIterator.hasNext())
- {
- BeanDescriptor beanDescriptor = (BeanDescriptor) beanDescriptorIterator.next();
- String jcrName = beanDescriptor.getJcrName();
- Object bean = PropertyUtils.getNestedProperty(object, beanDescriptor.getFieldName());
- if (bean != null)
- {
- this.insert(session, objectNode, jcrName, bean);
- }
-
- }
- }
- catch (Exception e)
- {
- throw new PersistenceException("Impossible to insert the bean fields", e);
- }
-
- }
-
- /**
- * Update Bean fields
- */
- private void updateBeanFields(Session session, Object object, ClassDescriptor classDescriptor, Node objectNode)
- {
- try
- {
- Iterator beanDescriptorIterator = classDescriptor.getBeanDescriptors().iterator();
- while (beanDescriptorIterator.hasNext())
- {
- BeanDescriptor beanDescriptor = (BeanDescriptor) beanDescriptorIterator.next();
- String jcrName = beanDescriptor.getJcrName();
- Object bean = PropertyUtils.getNestedProperty(object, beanDescriptor.getFieldName());
-
- // if the bean is null, remove existing node
- if ((bean == null))
- {
- if (objectNode.hasNode(jcrName))
- {
- objectNode.getNode(jcrName).remove();
- }
- }
- else
- {
- this.update(session, objectNode, jcrName, bean);
- }
-
- }
- }
- catch (Exception e)
- {
- throw new PersistenceException("Impossible to update the bean fields", e);
- }
-
- }
-
- private void insertCollectionFields(Session session, Object object, ClassDescriptor classDescriptor, Node objectNode)
- {
- try
- {
- Iterator collectionDescriptorIterator = classDescriptor.getCollectionDescriptors().iterator();
- while (collectionDescriptorIterator.hasNext())
- {
- CollectionDescriptor collectionDescriptor = (CollectionDescriptor) collectionDescriptorIterator.next();
- CollectionConverter collectionConverter = this.getCollectionConverter(collectionDescriptor);
- Object collection = PropertyUtils.getNestedProperty(object, collectionDescriptor.getFieldName());
- ManageableCollection manageableCollection = ManageableCollectionUtil.getManageableCollection(collection);
- collectionConverter.insertCollection(session, objectNode, collectionDescriptor, manageableCollection);
- }
- }
- catch (Exception e)
- {
- throw new PersistenceException("Impossible to insert the collection fields", e);
- }
-
- }
-
- private void updateCollectionFields(Session session, Object object, ClassDescriptor classDescriptor, Node objectNode)
- {
- try
- {
- Iterator collectionDescriptorIterator = classDescriptor.getCollectionDescriptors().iterator();
- while (collectionDescriptorIterator.hasNext())
- {
- CollectionDescriptor collectionDescriptor = (CollectionDescriptor) collectionDescriptorIterator.next();
- CollectionConverter collectionConverter = this.getCollectionConverter(collectionDescriptor);
- Object collection = PropertyUtils.getNestedProperty(object, collectionDescriptor.getFieldName());
- ManageableCollection manageableCollection = ManageableCollectionUtil.getManageableCollection(collection);
- collectionConverter.updateCollection(session, objectNode, collectionDescriptor, manageableCollection);
- }
- }
- catch (Exception e)
- {
- throw new PersistenceException("Impossible to store the bean fields", e);
- }
-
- }
-
- private void storeSimpleFields(Session session,
- Object object,
- ClassDescriptor classDescriptor,
- Node objectNode)
- throws PathNotFoundException, ValueFormatException, VersionException, LockException, ConstraintViolationException,
- RepositoryException, IllegalAccessException, InvocationTargetException, NoSuchMethodException
- {
- ValueFactory valueFactory = session.getValueFactory();
-
- Iterator fieldDescriptorIterator = classDescriptor.getFieldDescriptors().iterator();
- while (fieldDescriptorIterator.hasNext())
- {
- FieldDescriptor fieldDescriptor = (FieldDescriptor) fieldDescriptorIterator.next();
-
- //Of course, Path field is not updated as property
- if (fieldDescriptor.isPath())
- {
- continue;
- }
-
- String fieldName = fieldDescriptor.getFieldName();
- String jcrName = fieldDescriptor.getJcrName();
-
- // Check the node properties
- boolean autoCreated = false;
-
- if (objectNode.hasProperty(jcrName))
- {
- autoCreated = objectNode.getProperty(jcrName).getDefinition().isAutoCreated();
- }
-
- // All auto created JCR properties are ignored
- if (!autoCreated)
- {
-
- Object fieldValue = PropertyUtils.getNestedProperty(object, fieldName);
- Class fieldTypeClass = fieldDescriptor.getFieldTypeClass() != null
- ? fieldDescriptor.getFieldTypeClass()
- : PropertyUtils.getPropertyType(object, fieldName);
- AtomicTypeConverter converter = (AtomicTypeConverter) atomicTypeConverters.get(fieldTypeClass);
- Value value = converter.getValue(valueFactory, fieldValue);
- // Check if mandatory property are not null
- this.checkMandatoryProperty(objectNode, fieldDescriptor, value);
-
- objectNode.setProperty(jcrName, value);
- }
-
- }
- }
-
- private CollectionConverter getCollectionConverter(CollectionDescriptor collectionDescriptor)
- throws ClassNotFoundException, NoSuchMethodException, InstantiationException, InvocationTargetException, IllegalAccessException
- {
-
- String className = collectionDescriptor.getCollectionConverterClassName();
- if (className == null)
- {
- return new DefaultCollectionConverterImpl(this.atomicTypeConverters, this, this.mapper);
- }
- else
- {
- Class converterClass = Class.forName(className);
- Object[] param =
- { this.atomicTypeConverters, this, this.mapper };
- return (CollectionConverter) ConstructorUtils.invokeConstructor(converterClass, param);
- }
-
- }
-
- private void checkMandatoryProperty(Node objectNode, FieldDescriptor fieldDescriptor, Value value) throws RepositoryException
- {
- PropertyDefinition[] propertyDefinitions = objectNode.getPrimaryNodeType().getDeclaredPropertyDefinitions();
- for (int i = 0; i < propertyDefinitions.length; i++)
- {
- PropertyDefinition definition = propertyDefinitions[i];
- if (definition.getName().equals(fieldDescriptor.getJcrName()) && definition.isMandatory() && definition.isAutoCreated() == false && value == null)
- {
- throw new PersistenceException("Class of type:" + fieldDescriptor.getClassDescriptor().getClassName() + " has property: " + fieldDescriptor.getFieldName()
- + " declared as JCR property: " + fieldDescriptor.getJcrName() + " This property is mandatory but property in bean has value null");
- }
- }
- }
-}
+/*
+ * Copyright 2000-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.portals.graffito.jcr.persistence.objectconverter.impl;
+
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.jcr.Node;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.Value;
+import javax.jcr.ValueFactory;
+import javax.jcr.ValueFormatException;
+import javax.jcr.lock.LockException;
+import javax.jcr.nodetype.ConstraintViolationException;
+import javax.jcr.nodetype.NoSuchNodeTypeException;
+import javax.jcr.nodetype.PropertyDefinition;
+import javax.jcr.version.VersionException;
+
+import org.apache.commons.beanutils.ConstructorUtils;
+import org.apache.commons.beanutils.PropertyUtils;
+import org.apache.portals.graffito.jcr.exception.JcrMappingException;
+import org.apache.portals.graffito.jcr.exception.PersistenceException;
+import org.apache.portals.graffito.jcr.mapper.Mapper;
+import org.apache.portals.graffito.jcr.mapper.model.BeanDescriptor;
+import org.apache.portals.graffito.jcr.mapper.model.ClassDescriptor;
+import org.apache.portals.graffito.jcr.mapper.model.CollectionDescriptor;
+import org.apache.portals.graffito.jcr.mapper.model.FieldDescriptor;
+import org.apache.portals.graffito.jcr.persistence.atomictypeconverter.AtomicTypeConverter;
+import org.apache.portals.graffito.jcr.persistence.atomictypeconverter.AtomicTypeConverterProvider;
+import org.apache.portals.graffito.jcr.persistence.collectionconverter.CollectionConverter;
+import org.apache.portals.graffito.jcr.persistence.collectionconverter.ManageableCollection;
+import org.apache.portals.graffito.jcr.persistence.collectionconverter.ManageableCollectionUtil;
+import org.apache.portals.graffito.jcr.persistence.collectionconverter.impl.DefaultCollectionConverterImpl;
+import org.apache.portals.graffito.jcr.persistence.objectconverter.ObjectConverter;
+import org.apache.portals.graffito.jcr.reflection.ReflectionUtils;
+import org.apache.portals.graffito.jcr.repository.RepositoryUtil;
+
+/**
+ * Default implementation for {@link ObjectConverterImpl}
+ *
+ * @author <a href="mailto:christophe.lombart@sword-technologies.com">Lombart Christophe </a>
+ * @author <a href='mailto:the_mindstorm[at]evolva[dot]ro'>Alexandru Popescu</a>
+ */
+public class ObjectConverterImpl implements ObjectConverter {
+ private Mapper mapper;
+
+ private AtomicTypeConverterProvider atomicTypeConverterProvider;
+
+ /**
+ * No-arg constructor.
+ */
+ public ObjectConverterImpl() {
+ }
+
+ /**
+ * Constructor
+ *
+ * @param mapper The mapper to used
+ * @param converterProvider The atomic type converter provider
+ *
+ */
+ public ObjectConverterImpl(Mapper mapper, AtomicTypeConverterProvider converterProvider) {
+ this.mapper = mapper;
+ this.atomicTypeConverterProvider = converterProvider;
+ }
+
+ /**
+ * Set the <code>Mapper</code> used to solve mappings.
+ * @param mapper a <code>Mapper</code>
+ */
+ public void setMapper(Mapper mapper) {
+ this.mapper = mapper;
+ }
+
+ /**
+ * Sets the converter provider.
+ *
+ * @param converterProvider an <code>AtomicTypeConverterProvider</code>
+ */
+ public void setAtomicTypeConverterProvider(AtomicTypeConverterProvider converterProvider) {
+ this.atomicTypeConverterProvider = converterProvider;
+ }
+
+ /**
+ * @see org.apache.portals.graffito.jcr.persistence.objectconverter.ObjectConverter#insert(javax.jcr.Session, java.lang.Object)
+ */
+ public void insert(Session session, Object object) {
+ String path = this.getPath(session, object);
+ try {
+ String parentPath = RepositoryUtil.getParentPath(path);
+ String nodeName = RepositoryUtil.getNodeName(path);
+ Node parentNode = (Node) session.getItem(parentPath);
+ this.insert(session, parentNode, nodeName, object);
+
+ } catch (PathNotFoundException pnfe) {
+ throw new PersistenceException("Impossible to insert the object at '" + path + "'",
+ pnfe);
+ } catch (RepositoryException re) {
+ throw new org.apache.portals.graffito.jcr.exception.RepositoryException(
+ "Impossible to insert the object at '" + path + "'",
+ re);
+ }
+ }
+
+ /**
+ *
+ * @see org.apache.portals.graffito.jcr.persistence.objectconverter.ObjectConverter#insert(javax.jcr.Session, javax.jcr.Node, java.lang.String, java.lang.Object)
+ */
+ public void insert(Session session, Node parentNode, String nodeName, Object object) {
+ ClassDescriptor classDescriptor = mapper.getClassDescriptor(object.getClass());
+ if (classDescriptor == null) {
+ throw new JcrMappingException("Class of type: " + object.getClass().getName()
+ + " is not JCR persistable. Maybe element 'class-descriptor' for this type in mapping file is missing");
+ }
+
+ String jcrNodeType = classDescriptor.getJcrNodeType();
+ if ((jcrNodeType == null) || jcrNodeType.equals("")) {
+ throw new JcrMappingException("Undefined node type for " + parentNode);
+ }
+
+ Node objectNode = null;
+ try {
+ objectNode = parentNode.addNode(nodeName, jcrNodeType);
+ }
+ catch (NoSuchNodeTypeException nsnte) {
+ throw new JcrMappingException("Unknown node type " + jcrNodeType
+ + " for mapped class " + object.getClass());
+ }
+ catch (RepositoryException re) {
+ throw new PersistenceException("Cannot create new node of type " + jcrNodeType
+ + " from mapped class " + object.getClass());
+ }
+
+ if (null != classDescriptor.getJcrMixinTypes()) {
+ String[] mixinTypes = classDescriptor.getJcrMixinTypes();
+ for (int i = 0; i < mixinTypes.length; i++) {
+ try {
+ objectNode.addMixin(mixinTypes[i].trim());
+ } catch (NoSuchNodeTypeException nsnte) {
+ throw new JcrMappingException("Unknown mixin type " + mixinTypes[i].trim()
+ + " for mapped class " + object.getClass());
+ } catch (RepositoryException re) {
+ throw new PersistenceException("Cannot create new node of type " + jcrNodeType
+ + " from mapped class " + object.getClass());
+ }
+ }
+ }
+
+ storeSimpleFields(session, object, classDescriptor, objectNode);
+ insertBeanFields(session, object, classDescriptor, objectNode);
+ insertCollectionFields(session, object, classDescriptor, objectNode);
+ }
+
+ /**
+ * @see org.apache.portals.graffito.jcr.persistence.objectconverter.ObjectConverter#update(javax.jcr.Session, java.lang.Object)
+ */
+ public void update(Session session, Object object) {
+ String path = this.getPath(session, object);
+ try {
+ String parentPath = RepositoryUtil.getParentPath(path);
+ String nodeName = RepositoryUtil.getNodeName(path);
+ Node parentNode = (Node) session.getItem(parentPath);
+ this.update(session, parentNode, nodeName, object);
+ }
+ catch(PathNotFoundException pnfe) {
+ throw new PersistenceException("Impossible to update the object at '"
+ + path + "'",
+ pnfe);
+ }
+ catch(RepositoryException re) {
+ throw new org.apache.portals.graffito.jcr.exception.RepositoryException(
+ "Impossible to update the object at '" + path + "'",
+ re);
+ }
+ }
+
+ /**
+ *
+ * @see org.apache.portals.graffito.jcr.persistence.objectconverter.ObjectConverter#update(javax.jcr.Session, javax.jcr.Node, java.lang.String, java.lang.Object)
+ */
+ public void update(Session session, Node parentNode, String nodeName, Object object) {
+ try {
+ ClassDescriptor classDescriptor = mapper.getClassDescriptor(object.getClass());
+ if (classDescriptor == null) {
+ throw new JcrMappingException("Class of type: "
+ + object.getClass().getName()
+ + " is not JCR persistable. Maybe element 'class-descriptor' for this type in mapping file is missing");
+ }
+
+ Node objectNode = parentNode.getNode(nodeName);
+
+ storeSimpleFields(session, object, classDescriptor, objectNode);
+ updateBeanFields(session, object, classDescriptor, objectNode);
+ updateCollectionFields(session, object, classDescriptor, objectNode);
+ }
+ catch(PathNotFoundException pnfe) {
+ throw new PersistenceException("Impossible to update the object: "
+ + nodeName
+ + " at node : " + parentNode, pnfe);
+ }
+ catch(RepositoryException re) {
+ throw new org.apache.portals.graffito.jcr.exception.RepositoryException(
+ "Impossible to update the object: " + nodeName
+ + " at node : " + parentNode, re);
+ }
+ }
+
+ /**
+ * @see org.apache.portals.graffito.jcr.persistence.objectconverter.ObjectConverter#getObject(javax.jcr.Session, java.lang.Class, java.lang.String)
+ */
+ public Object getObject(Session session, Class clazz, String path) {
+ try {
+ if (!session.itemExists(path)) {
+ return null;
+ }
+
+ ClassDescriptor classDescriptor = mapper.getClassDescriptor(clazz);
+ if (classDescriptor == null) {
+ throw new JcrMappingException("Class of type: " + clazz.getName()
+ + " is not JCR persistable. Maybe element 'class-descriptor' for this type in mapping file is missing");
+ }
+
+ Node node = (Node) session.getItem(path);
+ Object object = ReflectionUtils.newInstance(clazz);
+
+ retrieveSimpleFields(session, classDescriptor, node, object);
+ retrieveBeanFields(session, path, classDescriptor, object);
+ retrieveCollectionFields(session, classDescriptor, node, object);
+
+ return object;
+
+ }
+ catch(PathNotFoundException pnfe) {
+ // HINT should never get here
+ throw new PersistenceException("Impossible to get the object at " + path, pnfe);
+ }
+ catch(RepositoryException re) {
+ throw new org.apache.portals.graffito.jcr.exception.RepositoryException(
+ "Impossible to get the object at " + path, re);
+ }
+ }
+
+ /**
+ * @see org.apache.portals.graffito.jcr.persistence.objectconverter.ObjectConverter#getPath(javax.jcr.Session, java.lang.Object)
+ * @throws JcrMappingException
+ */
+ public String getPath(Session session, Object object) {
+ ClassDescriptor classDescriptor = mapper.getClassDescriptor(object.getClass());
+ if (classDescriptor == null) {
+ throw new JcrMappingException("Class of type: "
+ + object.getClass().getName()
+ + " is not JCR persistable. Maybe element 'class-descriptor' for this type in mapping file is missing"
+ ); }
+
+ final FieldDescriptor pathFieldDescriptor = classDescriptor.getPathFieldDescriptor();
+ if (pathFieldDescriptor == null) {
+ throw new JcrMappingException("Class of type: "
+ + object.getClass().getName()
+ + " has no path mapping. Maybe attribute path=\"true\" for a field element of this class in jcrmapping.xml is missing?"
+ );
+ }
+ String pathField = pathFieldDescriptor.getFieldName();
+
+ return (String) ReflectionUtils.getNestedProperty(object, pathField);
+ }
+
+ /**
+ * Retrieve simple fields (atomic fields)
+ *
+ * @throws JcrMappingException
+ * @throws org.apache.portals.graffito.jcr.exception.RepositoryException
+ */
+ private void retrieveSimpleFields(Session session,
+ ClassDescriptor classDescriptor,
+ Node node,
+ Object object) {
+ try {
+ Iterator fieldDescriptorIterator = classDescriptor.getFieldDescriptors().iterator();
+
+ while (fieldDescriptorIterator.hasNext()) {
+ FieldDescriptor fieldDescriptor = (FieldDescriptor) fieldDescriptorIterator.next();
+
+ String fieldName = fieldDescriptor.getFieldName();
+ String propertyName = fieldDescriptor.getJcrName();
+
+ if (fieldDescriptor.isPath()) {
+ ReflectionUtils.setNestedProperty(object, fieldName, node.getPath());
+ } else {
+ AtomicTypeConverter converter= getAtomicTypeConverter(fieldDescriptor,
+ object,
+ fieldName);
+ if (node.hasProperty(propertyName)) {
+ Object fieldValue = converter.getObject(
+ node.getProperty(propertyName).getValue());
+ ReflectionUtils.setNestedProperty(object, fieldName, fieldValue);
+ }
+ }
+ }
+ }
+ catch(RepositoryException re) {
+ throw new org.apache.portals.graffito.jcr.exception.RepositoryException(
+ "Cannot retrieve properties of object"
+ + object
+ + " from node "
+ + node,
+ re);
+ }
+ }
+
+ /**
+ * Retrieve bean fields
+ */
+ private void retrieveBeanFields(Session session,
+ String path,
+ ClassDescriptor classDescriptor,
+ Object object) {
+ Iterator beanDescriptorIterator = classDescriptor.getBeanDescriptors().iterator();
+ while (beanDescriptorIterator.hasNext()) {
+ BeanDescriptor beanDescriptor = (BeanDescriptor) beanDescriptorIterator.next();
+ String beanName = beanDescriptor.getFieldName();
+ Class beanClass = ReflectionUtils.getPropertyType(object, beanName);
+ Object bean = this.getObject(session,
+ beanClass,
+ path + "/" + beanDescriptor.getJcrName());
+ ReflectionUtils.setNestedProperty(object, beanName, bean);
+ }
+ }
+
+ /**
+ * Retrieve Collection fields
+ */
+ private void retrieveCollectionFields(Session session,
+ ClassDescriptor classDescriptor,
+ Node node,
+ Object object) {
+ Iterator collectionDescriptorIterator = classDescriptor.getCollectionDescriptors()
+ .iterator();
+ while (collectionDescriptorIterator.hasNext()) {
+ CollectionDescriptor collectionDescriptor = (CollectionDescriptor)
+ collectionDescriptorIterator.next();
+ CollectionConverter collectionConverter = this.getCollectionConverter(session, collectionDescriptor);
+ Class collectionFieldClass = ReflectionUtils.getPropertyType(object,
+ collectionDescriptor.getFieldName());
+ ManageableCollection collection = collectionConverter.getCollection(session,
+ node,
+ collectionDescriptor,
+ collectionFieldClass);
+ ReflectionUtils.setNestedProperty(object,
+ collectionDescriptor.getFieldName(),
+ collection);
+ }
+ }
+
+ /**
+ * Insert Bean fields
+ */
+ private void insertBeanFields(Session session,
+ Object object,
+ ClassDescriptor classDescriptor,
+ Node objectNode) {
+ Iterator beanDescriptorIterator = classDescriptor.getBeanDescriptors().iterator();
+ while (beanDescriptorIterator.hasNext()) {
+ BeanDescriptor beanDescriptor = (BeanDescriptor) beanDescriptorIterator.next();
+ String jcrName = beanDescriptor.getJcrName();
+ Object bean = ReflectionUtils.getNestedProperty(object,
+ beanDescriptor.getFieldName());
+ if (bean != null) {
+ this.insert(session, objectNode, jcrName, bean);
+ }
+ }
+ }
+
+ /**
+ * Update Bean fields
+ */
+ private void updateBeanFields(Session session,
+ Object object,
+ ClassDescriptor classDescriptor,
+ Node objectNode) {
+ String jcrName = null;
+ try {
+ Iterator beanDescriptorIterator = classDescriptor.getBeanDescriptors().iterator();
+ while (beanDescriptorIterator.hasNext()) {
+ BeanDescriptor beanDescriptor = (BeanDescriptor) beanDescriptorIterator.next();
+ jcrName = beanDescriptor.getJcrName();
+ Object bean = ReflectionUtils.getNestedProperty(object,
+ beanDescriptor.getFieldName());
+
+ // if the bean is null, remove existing node
+ if ((bean == null)) {
+ if (objectNode.hasNode(jcrName)) {
+ objectNode.getNode(jcrName).remove();
+ }
+ } else {
+ this.update(session, objectNode, jcrName, bean);
+ }
+
+ }
+ }
+ catch(VersionException ve) {
+ throw new PersistenceException("Cannot remove bean at path " + jcrName,
+ ve);
+ }
+ catch(LockException le) {
+ throw new PersistenceException("Cannot remove bean at path " + jcrName + ". Item is locked.",
+ le);
+ }
+ catch(ConstraintViolationException cve) {
+ throw new PersistenceException("Cannot remove bean at path " + jcrName + ". Contraint violation.",
+ cve);
+ }
+ catch(RepositoryException re) {
+ throw new org.apache.portals.graffito.jcr.exception.RepositoryException(
+ "Cannot remove bean at path " + jcrName,
+ re);
+ }
+ }
+
+ private void insertCollectionFields(Session session,
+ Object object,
+ ClassDescriptor classDescriptor,
+ Node objectNode) {
+ Iterator collectionDescriptorIterator = classDescriptor.getCollectionDescriptors()
+ .iterator();
+ while (collectionDescriptorIterator.hasNext()) {
+ CollectionDescriptor collectionDescriptor = (CollectionDescriptor)
+ collectionDescriptorIterator.next();
+ CollectionConverter collectionConverter = this.getCollectionConverter(session, collectionDescriptor);
+ Object collection = ReflectionUtils.getNestedProperty(object, collectionDescriptor.getFieldName());
+ ManageableCollection manageableCollection = ManageableCollectionUtil
+ .getManageableCollection(collection);
+ collectionConverter.insertCollection(session,
+ objectNode,
+ collectionDescriptor,
+ manageableCollection);
+ }
+ }
+
+ private void updateCollectionFields(Session session,
+ Object object,
+ ClassDescriptor classDescriptor,
+ Node objectNode) {
+ Iterator collectionDescriptorIterator = classDescriptor.getCollectionDescriptors()
+ .iterator();
+ while (collectionDescriptorIterator.hasNext()) {
+ CollectionDescriptor collectionDescriptor = (CollectionDescriptor)
+ collectionDescriptorIterator.next();
+ CollectionConverter collectionConverter = this.getCollectionConverter(session, collectionDescriptor);
+ Object collection = ReflectionUtils.getNestedProperty(object,
+ collectionDescriptor.getFieldName());
+ ManageableCollection manageableCollection = ManageableCollectionUtil
+ .getManageableCollection(collection);
+ collectionConverter.updateCollection(session,
+ objectNode,
+ collectionDescriptor,
+ manageableCollection);
+ }
+ }
+
+ private void storeSimpleFields(Session session,
+ Object object,
+ ClassDescriptor classDescriptor,
+ Node objectNode) {
+ try {
+ ValueFactory valueFactory = session.getValueFactory();
+
+ Iterator fieldDescriptorIterator = classDescriptor.getFieldDescriptors().iterator();
+ while (fieldDescriptorIterator.hasNext()) {
+ FieldDescriptor fieldDescriptor = (FieldDescriptor) fieldDescriptorIterator.next();
+
+ //Of course, Path field is not updated as property
+ if (fieldDescriptor.isPath()) {
+ continue;
+ }
+
+ String fieldName = fieldDescriptor.getFieldName();
+ String jcrName = fieldDescriptor.getJcrName();
+
+ boolean protectedProperty= fieldDescriptor.isJcrProtected();
+
+ if(objectNode.hasProperty(jcrName)) {
+ protectedProperty= objectNode.getProperty(jcrName).getDefinition().isProtected();
+ }
+
+ if(!protectedProperty) { // DO NOT TRY TO WRITE PROTECTED PROPERTIES
+ Object fieldValue = ReflectionUtils.getNestedProperty(object, fieldName);
+ AtomicTypeConverter converter= getAtomicTypeConverter(fieldDescriptor,
+ object,
+ fieldName);
+ Value value = converter.getValue(valueFactory, fieldValue);
+
+ // Check if the node property is "autocreated"
+ boolean autoCreated= fieldDescriptor.isJcrAutoCreated();
+
+ if(objectNode.hasProperty(jcrName)) {
+ autoCreated= objectNode.getProperty(jcrName).getDefinition().isAutoCreated();
+ }
+
+ if(!autoCreated) {
+ // Check if mandatory property are not null
+ checkMandatoryProperty(objectNode, fieldDescriptor, value);
+ }
+
+ objectNode.setProperty(jcrName, value);
+ }
+ }
+ }
+ catch(RepositoryException re) {
+ throw new org.apache.portals.graffito.jcr.exception.RepositoryException(
+ "Cannot persist properties of object" + object,
+ re);
+ }
+ }
+
+ private CollectionConverter getCollectionConverter(Session session, CollectionDescriptor collectionDescriptor) {
+ String className = collectionDescriptor.getCollectionConverterClassName();
+ Map atomicTypeConverters= this.atomicTypeConverterProvider.getAtomicTypeConverters();
+ if (className == null) {
+ return new DefaultCollectionConverterImpl(atomicTypeConverters, this, this.mapper);
+ } else {
+ return (CollectionConverter) ReflectionUtils.invokeConstructor(className,
+ new Object[] {atomicTypeConverters, this, this.mapper});
+ }
+
+ }
+
+ private void checkMandatoryProperty(Node objectNode,
+ FieldDescriptor fieldDescriptor,
+ Value value) throws RepositoryException {
+ PropertyDefinition[] propertyDefinitions = objectNode.getPrimaryNodeType()
+ .getDeclaredPropertyDefinitions();
+ for (int i = 0; i < propertyDefinitions.length; i++) {
+ PropertyDefinition definition = propertyDefinitions[i];
+ if (definition.getName().equals(fieldDescriptor.getJcrName())
+ && definition.isMandatory()
+ && (definition.isAutoCreated() == false)
+ && (value == null))
+ {
+ throw new PersistenceException("Class of type:"
+ + fieldDescriptor.getClassDescriptor().getClassName()
+ + " has property: "
+ + fieldDescriptor.getFieldName()
+ + " declared as JCR property: "
+ + fieldDescriptor.getJcrName()
+ + " This property is mandatory but property in bean has value null");
+ }
+ }
+ }
+
+ private AtomicTypeConverter getAtomicTypeConverter(FieldDescriptor fd,
+ Object object,
+ String fieldName) {
+ Class fieldTypeClass= fd.getFieldTypeClass() != null
+ ? fd.getFieldTypeClass() : ReflectionUtils.getPropertyType(object, fieldName);
+
+ return this.atomicTypeConverterProvider.getAtomicTypeConverter(fieldTypeClass);
+ }
+}