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 cl...@apache.org on 2006/09/20 19:37:21 UTC
svn commit: r448311 [21/25] - in /incubator/graffito/trunk: ./ api/
api/src/java/org/apache/portals/graffito/context/
api/src/java/org/apache/portals/graffito/exception/
api/src/java/org/apache/portals/graffito/services/core/
api/src/java/org/apache/po...
Modified: incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/persistence/objectconverter/impl/ObjectConverterImpl.java
URL: http://svn.apache.org/viewvc/incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/persistence/objectconverter/impl/ObjectConverterImpl.java?view=diff&rev=448311&r1=448310&r2=448311
==============================================================================
--- 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 Wed Sep 20 12:37:05 2006
@@ -1,900 +1,900 @@
-/*
- * 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.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.NodeType;
-import javax.jcr.nodetype.NodeTypeManager;
-import javax.jcr.nodetype.PropertyDefinition;
-import javax.jcr.version.VersionException;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-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.PersistenceConstant;
-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.atomictypeconverter.impl.NullTypeConverterImpl;
-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.BeanConverter;
-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@gmail.com">Lombart Christophe </a>
- * @author <a href='mailto:the_mindstorm[at]evolva[dot]ro'>Alexandru Popescu</a>
- */
-public class ObjectConverterImpl implements ObjectConverter {
-
- private final static Log log = LogFactory.getLog(ObjectConverterImpl.class);
-
- private static final AtomicTypeConverter NULL_CONVERTER = new NullTypeConverterImpl();
-
- private Mapper mapper;
-
- private AtomicTypeConverterProvider atomicTypeConverterProvider;
-
- private ProxyManager proxyManager;
-
- /**
- * 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;
- this.proxyManager = new ProxyManager();
- }
-
- /**
- * 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.getClassDescriptorByClass(object.getClass());
-
- String jcrNodeType = classDescriptor.getJcrNodeType();
- if ((jcrNodeType == null) || jcrNodeType.equals("")) {
- jcrNodeType = PersistenceConstant.NT_UNSTRUCTURED;
- }
-
- Node objectNode = null;
- try {
- objectNode = parentNode.addNode(nodeName, jcrNodeType);
-
- } catch (NoSuchNodeTypeException nsnte) {
- throw new JcrMappingException("Unknown node type " + jcrNodeType + " for mapped class " + object.getClass(), nsnte);
- } catch (RepositoryException re) {
- throw new PersistenceException("Cannot create new node of type " + jcrNodeType + " from mapped class "
- + object.getClass(), re);
- }
-
- String[] mixinTypes = classDescriptor.getJcrMixinTypes();
- String mixinTypeName = null;
- try {
-
- // Add mixin types
- if (null != classDescriptor.getJcrMixinTypes()) {
- for (int i = 0; i < mixinTypes.length; i++) {
- mixinTypeName = mixinTypes[i].trim();
- objectNode.addMixin(mixinTypeName);
- }
- }
-
- // Add mixin types defined in the associated interfaces
- if (!classDescriptor.hasDiscriminator() && classDescriptor.hasInterfaces()) {
- Iterator interfacesIterator = classDescriptor.getImplements().iterator();
- while (interfacesIterator.hasNext()) {
- String interfaceName = (String) interfacesIterator.next();
- ClassDescriptor interfaceDescriptor = mapper
- .getClassDescriptorByClass(ReflectionUtils.forName(interfaceName));
- objectNode.addMixin(interfaceDescriptor.getJcrNodeType().trim());
- }
- }
-
- // If required, add the discriminator node type
- if (classDescriptor.hasDiscriminator()) {
- mixinTypeName = PersistenceConstant.DISCRIMINATOR_NODE_TYPE;
- objectNode.addMixin(mixinTypeName);
- objectNode.setProperty(PersistenceConstant.DISCRIMINATOR_PROPERTY_NAME, ReflectionUtils.getBeanClass(object)
- .getName());
- }
- } catch (NoSuchNodeTypeException nsnte) {
- throw new JcrMappingException("Unknown mixin type " + mixinTypeName + " for mapped class " + object.getClass(), nsnte);
- } catch (RepositoryException re) {
- throw new PersistenceException("Cannot create new node of type " + jcrNodeType + " from mapped class "
- + object.getClass(), re);
- }
-
- 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.getClassDescriptorByClass(ReflectionUtils.getBeanClass(object));
- Node objectNode = parentNode.getNode(nodeName);
-
- checkNodeType(session, classDescriptor);
-
- checkCompatiblePrimaryNodeTypes(session, objectNode, classDescriptor, false);
-
- 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, String path) {
- try {
- if (!session.itemExists(path)) {
- return null;
- }
-
- ClassDescriptor classDescriptor = null;
- Node node = (Node) session.getItem(path);
- if (node.hasProperty(PersistenceConstant.DISCRIMINATOR_PROPERTY_NAME)) {
- String className = node.getProperty(PersistenceConstant.DISCRIMINATOR_PROPERTY_NAME).getValue().getString();
- classDescriptor = mapper.getClassDescriptorByClass(ReflectionUtils.forName(className));
- } else {
- String nodeType = node.getPrimaryNodeType().getName();
- if (nodeType.equals(PersistenceConstant.FROZEN_NODE_TYPE)) {
- nodeType = node.getProperty(PersistenceConstant.FROZEN_PRIMARY_TYPE_PROPERTY).getString();
- }
- classDescriptor = mapper.getClassDescriptorByNodeType(nodeType);
- }
-
- if (null == classDescriptor) {
- throw new JcrMappingException("Impossible to find the classdescriptor for " + path
- + ". There is no discriminator and associated JCR node type");
- }
-
- Object object = ReflectionUtils.newInstance(classDescriptor.getClassName());
-
- retrieveSimpleFields(session, classDescriptor, node, object);
- retrieveBeanFields(session, classDescriptor, node, path, object, false);
- retrieveCollectionFields(session, classDescriptor, node, object, false);
-
- return object;
-// } catch (ClassNotFoundException clnf) {
-// throw new PersistenceException("Impossible to instantiate the object at " + path, clnf);
- } 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#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 = getClassDescriptor(clazz);
-
- checkNodeType(session, classDescriptor);
-
- Node node = (Node) session.getItem(path);
- if (!classDescriptor.isInterface()) {
- checkCompatiblePrimaryNodeTypes(session, node, classDescriptor, true);
- }
-
- Object object = null;
- if (classDescriptor.usesNodeTypePerHierarchyStrategy()) {
- if (!node.hasProperty(PersistenceConstant.DISCRIMINATOR_PROPERTY_NAME)) {
- throw new PersistenceException("Cannot fetch object of type '" + clazz.getName()
- + "' using NODETYPE_PER_HIERARCHY. Discriminator property is not present.");
- }
-
- String className = node.getProperty(PersistenceConstant.DISCRIMINATOR_PROPERTY_NAME).getValue().getString();
- classDescriptor = getClassDescriptor(ReflectionUtils.forName(className));
- object = ReflectionUtils.newInstance(className);
- } else {
- if (classDescriptor.usesNodeTypePerConcreteClassStrategy()) {
- String nodeType = node.getPrimaryNodeType().getName();
- if (!nodeType.equals(classDescriptor.getJcrNodeType())) {
- classDescriptor = classDescriptor.getDescendantClassDescriptor(nodeType);
- }
- }
- object = ReflectionUtils.newInstance(classDescriptor.getClassName());
-
- }
-
- retrieveSimpleFields(session, classDescriptor, node, object);
- retrieveBeanFields(session, classDescriptor, node, path, object, false);
- retrieveCollectionFields(session, classDescriptor, node, object, false);
-
- return object;
-// } catch (ClassNotFoundException clnf) {
-// throw new PersistenceException("Impossible to instantiate the object at " + path, clnf);
- } 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);
- }
- }
-
- public void retrieveAllMappedAttributes(Session session, Object object) {
- String path = null;
- try {
- ClassDescriptor classDescriptor = getClassDescriptor(object.getClass());
- String pathFieldName = classDescriptor.getPathFieldDescriptor().getFieldName();
- path = (String) ReflectionUtils.getNestedProperty(object, pathFieldName);
- Node node = (Node) session.getItem(path);
- retrieveBeanFields(session, classDescriptor, node, path, object, true);
- retrieveCollectionFields(session, classDescriptor, node, object, true);
-
- } catch (PathNotFoundException pnfe) {
-
- 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);
- }
- }
-
- public void retrieveMappedAttribute(Session session, Object object, String attributeName) {
- String path = null;
- ClassDescriptor classDescriptor = null;
- try {
- classDescriptor = getClassDescriptor(object.getClass());
- String pathFieldName = classDescriptor.getPathFieldDescriptor().getFieldName();
- path = (String) ReflectionUtils.getNestedProperty(object, pathFieldName);
- Node node = (Node) session.getItem(path);
- BeanDescriptor beanDescriptor = classDescriptor.getBeanDescriptor(attributeName);
- if (beanDescriptor != null)
- {
- this.retrieveBeanField(session, beanDescriptor, node, path, object, true);
- }
- // Check if the attribute is a collection
- else
- {
- CollectionDescriptor collectionDescriptor = classDescriptor.getCollectionDescriptor(attributeName);
- if (collectionDescriptor != null)
- {
- this.retrieveCollectionField(session, collectionDescriptor, node, object, true);
- }
- else
- {
- throw new PersistenceException("Impossible to retrieve the mapped attribute. The attribute '" +
- attributeName + "' is not a bean or a collection for the class : " + classDescriptor.getClassName());
- }
- }
-
- } catch (PathNotFoundException pnfe) {
-
- 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);
- }
- }
-
- /**
- * Validates the node type used by the class descriptor.
- *
- * @param session
- * the current session
- * @param classDescriptor
- * descriptor
- * @throws JcrMappingException
- * thrown if the node type is unknown
- * @throws org.apache.portals.graffito.jcr.exception.RepositoryException
- * thrown if an error occured in the underlying repository
- */
- private void checkNodeType(Session session, ClassDescriptor classDescriptor) {
- String jcrTypeName = null;
- try {
-
- //Don't check the primary node type for interfaces. They are only associated to mixin node type
- if (classDescriptor.isInterface()) {
- String[] mixinTypes = classDescriptor.getJcrMixinTypes();
- for (int i = 0; i < mixinTypes.length; i++) {
- jcrTypeName = mixinTypes[i];
- session.getWorkspace().getNodeTypeManager().getNodeType(jcrTypeName);
- }
- } else {
- jcrTypeName = classDescriptor.getJcrNodeType();
- if (jcrTypeName != null && !jcrTypeName.equals("")) {
- session.getWorkspace().getNodeTypeManager().getNodeType(jcrTypeName);
- }
- }
- } catch (NoSuchNodeTypeException nsnte) {
- throw new JcrMappingException("Mapping for class '" + classDescriptor.getClassName()
- + "' use unknown primary or mixin node type '" + jcrTypeName + "'");
- } catch (RepositoryException re) {
- throw new org.apache.portals.graffito.jcr.exception.RepositoryException(re);
- }
- }
-
- /**
- * Checks if the node type in the class descriptor is compatible with the
- * specified node node type.
- *
- * @param session
- * the current session
- * @param node
- * node against whose node type the compatibility is checked
- * @param classDescriptor
- * class descriptor
- * @param checkVersionNode
- * <tt>true</tt> if the check should continue in case the
- * <tt>node</tt> is a version node, <tt>false</tt> if no
- * check against version node should be performed
- *
- * @throws PersistenceException
- * thrown if node types are incompatible
- * @throws org.apache.portals.graffito.jcr.exception.RepositoryException
- * thrown if an error occured in the underlying repository
- */
- private void checkCompatiblePrimaryNodeTypes(Session session, Node node, ClassDescriptor classDescriptor,
- boolean checkVersionNode) {
- try {
- NodeType nodeType = node.getPrimaryNodeType();
-
- boolean compatible = checkCompatibleNodeTypes(nodeType, classDescriptor);
-
- if (!compatible && checkVersionNode && PersistenceConstant.FROZEN_NODE_TYPE.equals(nodeType.getName())) {
- NodeTypeManager ntMgr = session.getWorkspace().getNodeTypeManager();
- nodeType = ntMgr.getNodeType(node.getProperty(PersistenceConstant.FROZEN_PRIMARY_TYPE_PROPERTY).getString());
-
- compatible = checkCompatibleNodeTypes(nodeType, classDescriptor);
- }
-
- if (!compatible) {
- throw new PersistenceException("Cannot map object of type '" + classDescriptor.getClassName() + "'. Node type '"
- + node.getPrimaryNodeType().getName() + "' does not match descriptor node type '"
- + classDescriptor.getJcrNodeType() + "'");
- }
- } catch (RepositoryException re) {
- throw new org.apache.portals.graffito.jcr.exception.RepositoryException(re);
- }
- }
-
- /**
- * Node types compatibility check.
- *
- * @param nodeType
- * target node type
- * @param descriptor
- * descriptor containing source node type
- * @return <tt>true</tt> if nodes are considered compatible,
- * <tt>false</tt> otherwise
- */
- private boolean checkCompatibleNodeTypes(NodeType nodeType, ClassDescriptor descriptor) {
-
- //return true if node type is not used
- if (descriptor.getJcrNodeType() == null || descriptor.getJcrNodeType().equals("")) {
- return true;
- }
-
- if (nodeType.getName().equals(descriptor.getJcrNodeType())) {
- return true;
- }
-
- NodeType[] superTypes = nodeType.getSupertypes();
- for (int i = 0; i < superTypes.length; i++) {
- if (superTypes[i].getName().equals(descriptor.getJcrNodeType())) {
- return true;
- }
- }
-
- return false;
- }
-
- /**
- * @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.getClassDescriptorByClass(object.getClass());
-
- 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 Object retrieveSimpleFields(Session session, ClassDescriptor classDescriptor, Node node, Object object) {
- Object initializedBean = 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()) {
- // HINT: lazy initialize target bean - The bean can be null
- // when it is inline
- if (null == initializedBean) {
- initializedBean = ReflectionUtils.newInstance(classDescriptor.getClassName());
- }
-
- ReflectionUtils.setNestedProperty(initializedBean, fieldName, node.getPath());
-
- } else if (classDescriptor.usesNodeTypePerHierarchyStrategy() && classDescriptor.hasDiscriminator()) {
-
- if (node.hasProperty(PersistenceConstant.DISCRIMINATOR_PROPERTY_NAME)) {
- if (null == initializedBean) {
- initializedBean = ReflectionUtils.newInstance(classDescriptor.getClassName());
- }
- String value = node.getProperty(propertyName).getValue().getString();
- ReflectionUtils.setNestedProperty(initializedBean, fieldName, value);
- } else {
- throw new PersistenceException("Class '" + classDescriptor.getClassName()
- + "' have not a discriminator property.");
- }
- } else {
- if (node.hasProperty(propertyName)) {
- Value propValue = node.getProperty(propertyName).getValue();
- // HINT: lazy initialize target bean - The bean can be
- // null when it is inline
- if (null != propValue && null == initializedBean) {
- initializedBean = ReflectionUtils.newInstance(classDescriptor.getClassName());
- }
-
- AtomicTypeConverter converter = getAtomicTypeConverter(fieldDescriptor, initializedBean, fieldName);
-
- Object fieldValue = converter.getObject(propValue);
- ReflectionUtils.setNestedProperty(initializedBean, fieldName, fieldValue);
- } else {
- log.warn("Class '" + classDescriptor.getClassName() + "' has an unmapped property : " + propertyName);
- }
- }
- }
- } catch (ValueFormatException vfe) {
- throw new PersistenceException("Cannot retrieve properties of object " + object + " from node " + node, vfe);
- } catch (RepositoryException re) {
- throw new org.apache.portals.graffito.jcr.exception.RepositoryException("Cannot retrieve properties of object "
- + object + " from node " + node, re);
- }
-
- return initializedBean;
- }
-
- /**
- * Retrieve bean fields
- */
- private void retrieveBeanFields(Session session, ClassDescriptor classDescriptor, Node node, String path, Object object,
- boolean forceToRetrieve) {
- Iterator beanDescriptorIterator = classDescriptor.getBeanDescriptors().iterator();
- while (beanDescriptorIterator.hasNext()) {
- BeanDescriptor beanDescriptor = (BeanDescriptor) beanDescriptorIterator.next();
- this.retrieveBeanField(session, beanDescriptor, node, path, object, forceToRetrieve);
- }
- }
-
-
- private void retrieveBeanField(Session session,BeanDescriptor beanDescriptor, Node node, String path, Object object, boolean forceToRetrieve )
- {
- if (!beanDescriptor.isAutoRetrieve() && !forceToRetrieve) {
- return;
- }
-
- String beanName = beanDescriptor.getFieldName();
- Class beanClass = ReflectionUtils.getPropertyType(object, beanName);
- Object bean = null;
- if (beanDescriptor.isProxy()) {
- bean = proxyManager.createBeanProxy(session, this, beanClass, path + "/" + beanDescriptor.getJcrName());
-
- } else {
- if (beanDescriptor.isInline()) {
- bean = this.retrieveSimpleFields(session, mapper.getClassDescriptorByClass(beanClass), node, bean);
- } else if (null != beanDescriptor.getConverter() && !"".equals(beanDescriptor.getConverter())) {
- String converterClassName = beanDescriptor.getConverter();
- Object[] param = {this};
- BeanConverter beanConverter = (BeanConverter) ReflectionUtils.invokeConstructor(converterClassName, param);
- bean = beanConverter.getObject(session, node, beanDescriptor, beanClass);
- } else {
- bean = this.getObject(session, path + "/" + beanDescriptor.getJcrName());
- }
- }
- ReflectionUtils.setNestedProperty(object, beanName, bean);
- }
-
-
-
- /**
- * Retrieve Collection fields
- */
- private void retrieveCollectionFields(Session session, ClassDescriptor classDescriptor, Node parentNode, Object object,
- boolean forceToRetrieve) {
- Iterator collectionDescriptorIterator = classDescriptor.getCollectionDescriptors().iterator();
- while (collectionDescriptorIterator.hasNext()) {
- CollectionDescriptor collectionDescriptor = (CollectionDescriptor) collectionDescriptorIterator.next();
- this.retrieveCollectionField(session, collectionDescriptor, parentNode, object, forceToRetrieve);
- }
- }
-
- private void retrieveCollectionField(Session session, CollectionDescriptor collectionDescriptor, Node parentNode, Object object, boolean forceToRetrieve)
- {
- if (!collectionDescriptor.isAutoRetrieve() && !forceToRetrieve) {
- return;
- }
-
- CollectionConverter collectionConverter = this.getCollectionConverter(session, collectionDescriptor);
- Class collectionFieldClass = ReflectionUtils.getPropertyType(object, collectionDescriptor.getFieldName());
- ManageableCollection collection = null;
- if (collectionDescriptor.isProxy()) {
- collection = (ManageableCollection) proxyManager.createCollectionProxy(session, collectionConverter, parentNode,
- collectionDescriptor, collectionFieldClass);
-
- } else {
- collection = collectionConverter.getCollection(session, parentNode, 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();
-
- if (!beanDescriptor.isAutoInsert()) {
- continue;
- }
-
- String jcrName = beanDescriptor.getJcrName();
- Object bean = ReflectionUtils.getNestedProperty(object, beanDescriptor.getFieldName());
- if (bean != null) {
- if (beanDescriptor.isInline()) {
- this.storeSimpleFields(session, bean, mapper.getClassDescriptorByClass(bean.getClass()), objectNode);
- } else if (null != beanDescriptor.getConverter() && !"".equals(beanDescriptor.getConverter())) {
- String converterClassName = beanDescriptor.getConverter();
- Object[] param = {this};
- BeanConverter beanConverter = (BeanConverter) ReflectionUtils.invokeConstructor(converterClassName, param);
- beanConverter.insert(session, objectNode, beanDescriptor, object);
- } else {
- 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();
- if (!beanDescriptor.isAutoUpdate()) {
- continue;
- }
-
- jcrName = beanDescriptor.getJcrName();
- Object bean = ReflectionUtils.getNestedProperty(object, beanDescriptor.getFieldName());
-
- // if the bean is null, remove existing node
- if ((bean == null)) {
- if (beanDescriptor.isInline()) {
- Class beanClass = ReflectionUtils.getPropertyType(object, beanDescriptor.getFieldName());
- this.storeSimpleFields(session, bean, mapper.getClassDescriptorByClass(beanClass), objectNode);
- } else if (null != beanDescriptor.getConverter() && !"".equals(beanDescriptor.getConverter())) {
- String converterClassName = beanDescriptor.getConverter();
- Object[] param = {this};
- BeanConverter beanConverter = (BeanConverter) ReflectionUtils
- .invokeConstructor(converterClassName, param);
- beanConverter.remove(session, objectNode, beanDescriptor);
- } else {
- if (objectNode.hasNode(jcrName)) {
- objectNode.getNode(jcrName).remove();
- }
- }
- } else {
- if (beanDescriptor.isInline()) {
- this.storeSimpleFields(session, bean, mapper.getClassDescriptorByClass(bean.getClass()), objectNode);
- } else if (null != beanDescriptor.getConverter() && !"".equals(beanDescriptor.getConverter())) {
- String converterClassName = beanDescriptor.getConverter();
- Object[] param = {this};
- BeanConverter beanConverter = (BeanConverter) ReflectionUtils
- .invokeConstructor(converterClassName, param);
- beanConverter.update(session, objectNode, beanDescriptor, bean);
- } 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();
-
- if (!collectionDescriptor.isAutoInsert()) {
- continue;
- }
-
- 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();
- if (!collectionDescriptor.isAutoUpdate()) {
- continue;
- }
-
- 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();
-
- String fieldName = fieldDescriptor.getFieldName();
- String jcrName = fieldDescriptor.getJcrName();
-
- // Of course, Path field is not stored as property
- if (fieldDescriptor.isPath()) {
- continue;
- }
-
- 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 (ValueFormatException vfe) {
- throw new PersistenceException("Cannot persist properties of object " + object + ". Value format exception.", vfe);
- } catch (VersionException ve) {
- throw new PersistenceException("Cannot persist properties of object " + object + ". Versioning exception.", ve);
- } catch (LockException le) {
- throw new PersistenceException("Cannot persist properties of object " + object + " on locked node.", le);
- } catch (ConstraintViolationException cve) {
- throw new PersistenceException("Cannot persist properties of object " + object + ". Constraint violation.", cve);
- } 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.getCollectionConverter();
- 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 = null;
- if (null != fd.getFieldTypeClass()) {
- fieldTypeClass = fd.getFieldTypeClass();
- } else if (null != object) {
- fieldTypeClass = ReflectionUtils.getPropertyType(object, fieldName);
- }
-
- if (null != fieldTypeClass) {
- return this.atomicTypeConverterProvider.getAtomicTypeConverter(fieldTypeClass);
- } else {
- return NULL_CONVERTER;
- }
- }
-
- private ClassDescriptor getClassDescriptor(Class beanClass) {
- ClassDescriptor classDescriptor = mapper.getClassDescriptorByClass(beanClass);
- if (null == classDescriptor) {
- throw new JcrMappingException("Class of type: " + beanClass.getName()
- + " is not JCR persistable. Maybe element 'class-descriptor' for this type in mapping file is missing");
- }
-
- return classDescriptor;
- }
-
-}
+/*
+ * 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.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.NodeType;
+import javax.jcr.nodetype.NodeTypeManager;
+import javax.jcr.nodetype.PropertyDefinition;
+import javax.jcr.version.VersionException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+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.PersistenceConstant;
+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.atomictypeconverter.impl.NullTypeConverterImpl;
+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.BeanConverter;
+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@gmail.com">Lombart Christophe </a>
+ * @author <a href='mailto:the_mindstorm[at]evolva[dot]ro'>Alexandru Popescu</a>
+ */
+public class ObjectConverterImpl implements ObjectConverter {
+
+ private final static Log log = LogFactory.getLog(ObjectConverterImpl.class);
+
+ private static final AtomicTypeConverter NULL_CONVERTER = new NullTypeConverterImpl();
+
+ private Mapper mapper;
+
+ private AtomicTypeConverterProvider atomicTypeConverterProvider;
+
+ private ProxyManager proxyManager;
+
+ /**
+ * 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;
+ this.proxyManager = new ProxyManager();
+ }
+
+ /**
+ * 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.getClassDescriptorByClass(object.getClass());
+
+ String jcrNodeType = classDescriptor.getJcrNodeType();
+ if ((jcrNodeType == null) || jcrNodeType.equals("")) {
+ jcrNodeType = PersistenceConstant.NT_UNSTRUCTURED;
+ }
+
+ Node objectNode = null;
+ try {
+ objectNode = parentNode.addNode(nodeName, jcrNodeType);
+
+ } catch (NoSuchNodeTypeException nsnte) {
+ throw new JcrMappingException("Unknown node type " + jcrNodeType + " for mapped class " + object.getClass(), nsnte);
+ } catch (RepositoryException re) {
+ throw new PersistenceException("Cannot create new node of type " + jcrNodeType + " from mapped class "
+ + object.getClass(), re);
+ }
+
+ String[] mixinTypes = classDescriptor.getJcrMixinTypes();
+ String mixinTypeName = null;
+ try {
+
+ // Add mixin types
+ if (null != classDescriptor.getJcrMixinTypes()) {
+ for (int i = 0; i < mixinTypes.length; i++) {
+ mixinTypeName = mixinTypes[i].trim();
+ objectNode.addMixin(mixinTypeName);
+ }
+ }
+
+ // Add mixin types defined in the associated interfaces
+ if (!classDescriptor.hasDiscriminator() && classDescriptor.hasInterfaces()) {
+ Iterator interfacesIterator = classDescriptor.getImplements().iterator();
+ while (interfacesIterator.hasNext()) {
+ String interfaceName = (String) interfacesIterator.next();
+ ClassDescriptor interfaceDescriptor = mapper
+ .getClassDescriptorByClass(ReflectionUtils.forName(interfaceName));
+ objectNode.addMixin(interfaceDescriptor.getJcrNodeType().trim());
+ }
+ }
+
+ // If required, add the discriminator node type
+ if (classDescriptor.hasDiscriminator()) {
+ mixinTypeName = PersistenceConstant.DISCRIMINATOR_NODE_TYPE;
+ objectNode.addMixin(mixinTypeName);
+ objectNode.setProperty(PersistenceConstant.DISCRIMINATOR_PROPERTY_NAME, ReflectionUtils.getBeanClass(object)
+ .getName());
+ }
+ } catch (NoSuchNodeTypeException nsnte) {
+ throw new JcrMappingException("Unknown mixin type " + mixinTypeName + " for mapped class " + object.getClass(), nsnte);
+ } catch (RepositoryException re) {
+ throw new PersistenceException("Cannot create new node of type " + jcrNodeType + " from mapped class "
+ + object.getClass(), re);
+ }
+
+ 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.getClassDescriptorByClass(ReflectionUtils.getBeanClass(object));
+ Node objectNode = parentNode.getNode(nodeName);
+
+ checkNodeType(session, classDescriptor);
+
+ checkCompatiblePrimaryNodeTypes(session, objectNode, classDescriptor, false);
+
+ 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, String path) {
+ try {
+ if (!session.itemExists(path)) {
+ return null;
+ }
+
+ ClassDescriptor classDescriptor = null;
+ Node node = (Node) session.getItem(path);
+ if (node.hasProperty(PersistenceConstant.DISCRIMINATOR_PROPERTY_NAME)) {
+ String className = node.getProperty(PersistenceConstant.DISCRIMINATOR_PROPERTY_NAME).getValue().getString();
+ classDescriptor = mapper.getClassDescriptorByClass(ReflectionUtils.forName(className));
+ } else {
+ String nodeType = node.getPrimaryNodeType().getName();
+ if (nodeType.equals(PersistenceConstant.FROZEN_NODE_TYPE)) {
+ nodeType = node.getProperty(PersistenceConstant.FROZEN_PRIMARY_TYPE_PROPERTY).getString();
+ }
+ classDescriptor = mapper.getClassDescriptorByNodeType(nodeType);
+ }
+
+ if (null == classDescriptor) {
+ throw new JcrMappingException("Impossible to find the classdescriptor for " + path
+ + ". There is no discriminator and associated JCR node type");
+ }
+
+ Object object = ReflectionUtils.newInstance(classDescriptor.getClassName());
+
+ retrieveSimpleFields(session, classDescriptor, node, object);
+ retrieveBeanFields(session, classDescriptor, node, path, object, false);
+ retrieveCollectionFields(session, classDescriptor, node, object, false);
+
+ return object;
+// } catch (ClassNotFoundException clnf) {
+// throw new PersistenceException("Impossible to instantiate the object at " + path, clnf);
+ } 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#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 = getClassDescriptor(clazz);
+
+ checkNodeType(session, classDescriptor);
+
+ Node node = (Node) session.getItem(path);
+ if (!classDescriptor.isInterface()) {
+ checkCompatiblePrimaryNodeTypes(session, node, classDescriptor, true);
+ }
+
+ Object object = null;
+ if (classDescriptor.usesNodeTypePerHierarchyStrategy()) {
+ if (!node.hasProperty(PersistenceConstant.DISCRIMINATOR_PROPERTY_NAME)) {
+ throw new PersistenceException("Cannot fetch object of type '" + clazz.getName()
+ + "' using NODETYPE_PER_HIERARCHY. Discriminator property is not present.");
+ }
+
+ String className = node.getProperty(PersistenceConstant.DISCRIMINATOR_PROPERTY_NAME).getValue().getString();
+ classDescriptor = getClassDescriptor(ReflectionUtils.forName(className));
+ object = ReflectionUtils.newInstance(className);
+ } else {
+ if (classDescriptor.usesNodeTypePerConcreteClassStrategy()) {
+ String nodeType = node.getPrimaryNodeType().getName();
+ if (!nodeType.equals(classDescriptor.getJcrNodeType())) {
+ classDescriptor = classDescriptor.getDescendantClassDescriptor(nodeType);
+ }
+ }
+ object = ReflectionUtils.newInstance(classDescriptor.getClassName());
+
+ }
+
+ retrieveSimpleFields(session, classDescriptor, node, object);
+ retrieveBeanFields(session, classDescriptor, node, path, object, false);
+ retrieveCollectionFields(session, classDescriptor, node, object, false);
+
+ return object;
+// } catch (ClassNotFoundException clnf) {
+// throw new PersistenceException("Impossible to instantiate the object at " + path, clnf);
+ } 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);
+ }
+ }
+
+ public void retrieveAllMappedAttributes(Session session, Object object) {
+ String path = null;
+ try {
+ ClassDescriptor classDescriptor = getClassDescriptor(object.getClass());
+ String pathFieldName = classDescriptor.getPathFieldDescriptor().getFieldName();
+ path = (String) ReflectionUtils.getNestedProperty(object, pathFieldName);
+ Node node = (Node) session.getItem(path);
+ retrieveBeanFields(session, classDescriptor, node, path, object, true);
+ retrieveCollectionFields(session, classDescriptor, node, object, true);
+
+ } catch (PathNotFoundException pnfe) {
+
+ 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);
+ }
+ }
+
+ public void retrieveMappedAttribute(Session session, Object object, String attributeName) {
+ String path = null;
+ ClassDescriptor classDescriptor = null;
+ try {
+ classDescriptor = getClassDescriptor(object.getClass());
+ String pathFieldName = classDescriptor.getPathFieldDescriptor().getFieldName();
+ path = (String) ReflectionUtils.getNestedProperty(object, pathFieldName);
+ Node node = (Node) session.getItem(path);
+ BeanDescriptor beanDescriptor = classDescriptor.getBeanDescriptor(attributeName);
+ if (beanDescriptor != null)
+ {
+ this.retrieveBeanField(session, beanDescriptor, node, path, object, true);
+ }
+ // Check if the attribute is a collection
+ else
+ {
+ CollectionDescriptor collectionDescriptor = classDescriptor.getCollectionDescriptor(attributeName);
+ if (collectionDescriptor != null)
+ {
+ this.retrieveCollectionField(session, collectionDescriptor, node, object, true);
+ }
+ else
+ {
+ throw new PersistenceException("Impossible to retrieve the mapped attribute. The attribute '" +
+ attributeName + "' is not a bean or a collection for the class : " + classDescriptor.getClassName());
+ }
+ }
+
+ } catch (PathNotFoundException pnfe) {
+
+ 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);
+ }
+ }
+
+ /**
+ * Validates the node type used by the class descriptor.
+ *
+ * @param session
+ * the current session
+ * @param classDescriptor
+ * descriptor
+ * @throws JcrMappingException
+ * thrown if the node type is unknown
+ * @throws org.apache.portals.graffito.jcr.exception.RepositoryException
+ * thrown if an error occured in the underlying repository
+ */
+ private void checkNodeType(Session session, ClassDescriptor classDescriptor) {
+ String jcrTypeName = null;
+ try {
+
+ //Don't check the primary node type for interfaces. They are only associated to mixin node type
+ if (classDescriptor.isInterface()) {
+ String[] mixinTypes = classDescriptor.getJcrMixinTypes();
+ for (int i = 0; i < mixinTypes.length; i++) {
+ jcrTypeName = mixinTypes[i];
+ session.getWorkspace().getNodeTypeManager().getNodeType(jcrTypeName);
+ }
+ } else {
+ jcrTypeName = classDescriptor.getJcrNodeType();
+ if (jcrTypeName != null && !jcrTypeName.equals("")) {
+ session.getWorkspace().getNodeTypeManager().getNodeType(jcrTypeName);
+ }
+ }
+ } catch (NoSuchNodeTypeException nsnte) {
+ throw new JcrMappingException("Mapping for class '" + classDescriptor.getClassName()
+ + "' use unknown primary or mixin node type '" + jcrTypeName + "'");
+ } catch (RepositoryException re) {
+ throw new org.apache.portals.graffito.jcr.exception.RepositoryException(re);
+ }
+ }
+
+ /**
+ * Checks if the node type in the class descriptor is compatible with the
+ * specified node node type.
+ *
+ * @param session
+ * the current session
+ * @param node
+ * node against whose node type the compatibility is checked
+ * @param classDescriptor
+ * class descriptor
+ * @param checkVersionNode
+ * <tt>true</tt> if the check should continue in case the
+ * <tt>node</tt> is a version node, <tt>false</tt> if no
+ * check against version node should be performed
+ *
+ * @throws PersistenceException
+ * thrown if node types are incompatible
+ * @throws org.apache.portals.graffito.jcr.exception.RepositoryException
+ * thrown if an error occured in the underlying repository
+ */
+ private void checkCompatiblePrimaryNodeTypes(Session session, Node node, ClassDescriptor classDescriptor,
+ boolean checkVersionNode) {
+ try {
+ NodeType nodeType = node.getPrimaryNodeType();
+
+ boolean compatible = checkCompatibleNodeTypes(nodeType, classDescriptor);
+
+ if (!compatible && checkVersionNode && PersistenceConstant.FROZEN_NODE_TYPE.equals(nodeType.getName())) {
+ NodeTypeManager ntMgr = session.getWorkspace().getNodeTypeManager();
+ nodeType = ntMgr.getNodeType(node.getProperty(PersistenceConstant.FROZEN_PRIMARY_TYPE_PROPERTY).getString());
+
+ compatible = checkCompatibleNodeTypes(nodeType, classDescriptor);
+ }
+
+ if (!compatible) {
+ throw new PersistenceException("Cannot map object of type '" + classDescriptor.getClassName() + "'. Node type '"
+ + node.getPrimaryNodeType().getName() + "' does not match descriptor node type '"
+ + classDescriptor.getJcrNodeType() + "'");
+ }
+ } catch (RepositoryException re) {
+ throw new org.apache.portals.graffito.jcr.exception.RepositoryException(re);
+ }
+ }
+
+ /**
+ * Node types compatibility check.
+ *
+ * @param nodeType
+ * target node type
+ * @param descriptor
+ * descriptor containing source node type
+ * @return <tt>true</tt> if nodes are considered compatible,
+ * <tt>false</tt> otherwise
+ */
+ private boolean checkCompatibleNodeTypes(NodeType nodeType, ClassDescriptor descriptor) {
+
+ //return true if node type is not used
+ if (descriptor.getJcrNodeType() == null || descriptor.getJcrNodeType().equals("")) {
+ return true;
+ }
+
+ if (nodeType.getName().equals(descriptor.getJcrNodeType())) {
+ return true;
+ }
+
+ NodeType[] superTypes = nodeType.getSupertypes();
+ for (int i = 0; i < superTypes.length; i++) {
+ if (superTypes[i].getName().equals(descriptor.getJcrNodeType())) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * @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.getClassDescriptorByClass(object.getClass());
+
+ 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 Object retrieveSimpleFields(Session session, ClassDescriptor classDescriptor, Node node, Object object) {
+ Object initializedBean = 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()) {
+ // HINT: lazy initialize target bean - The bean can be null
+ // when it is inline
+ if (null == initializedBean) {
+ initializedBean = ReflectionUtils.newInstance(classDescriptor.getClassName());
+ }
+
+ ReflectionUtils.setNestedProperty(initializedBean, fieldName, node.getPath());
+
+ } else if (classDescriptor.usesNodeTypePerHierarchyStrategy() && classDescriptor.hasDiscriminator()) {
+
+ if (node.hasProperty(PersistenceConstant.DISCRIMINATOR_PROPERTY_NAME)) {
+ if (null == initializedBean) {
+ initializedBean = ReflectionUtils.newInstance(classDescriptor.getClassName());
+ }
+ String value = node.getProperty(propertyName).getValue().getString();
+ ReflectionUtils.setNestedProperty(initializedBean, fieldName, value);
+ } else {
+ throw new PersistenceException("Class '" + classDescriptor.getClassName()
+ + "' have not a discriminator property.");
+ }
+ } else {
+ if (node.hasProperty(propertyName)) {
+ Value propValue = node.getProperty(propertyName).getValue();
+ // HINT: lazy initialize target bean - The bean can be
+ // null when it is inline
+ if (null != propValue && null == initializedBean) {
+ initializedBean = ReflectionUtils.newInstance(classDescriptor.getClassName());
+ }
+
+ AtomicTypeConverter converter = getAtomicTypeConverter(fieldDescriptor, initializedBean, fieldName);
+
+ Object fieldValue = converter.getObject(propValue);
+ ReflectionUtils.setNestedProperty(initializedBean, fieldName, fieldValue);
+ } else {
+ log.warn("Class '" + classDescriptor.getClassName() + "' has an unmapped property : " + propertyName);
+ }
+ }
+ }
+ } catch (ValueFormatException vfe) {
+ throw new PersistenceException("Cannot retrieve properties of object " + object + " from node " + node, vfe);
+ } catch (RepositoryException re) {
+ throw new org.apache.portals.graffito.jcr.exception.RepositoryException("Cannot retrieve properties of object "
+ + object + " from node " + node, re);
+ }
+
+ return initializedBean;
+ }
+
+ /**
+ * Retrieve bean fields
+ */
+ private void retrieveBeanFields(Session session, ClassDescriptor classDescriptor, Node node, String path, Object object,
+ boolean forceToRetrieve) {
+ Iterator beanDescriptorIterator = classDescriptor.getBeanDescriptors().iterator();
+ while (beanDescriptorIterator.hasNext()) {
+ BeanDescriptor beanDescriptor = (BeanDescriptor) beanDescriptorIterator.next();
+ this.retrieveBeanField(session, beanDescriptor, node, path, object, forceToRetrieve);
+ }
+ }
+
+
+ private void retrieveBeanField(Session session,BeanDescriptor beanDescriptor, Node node, String path, Object object, boolean forceToRetrieve )
+ {
+ if (!beanDescriptor.isAutoRetrieve() && !forceToRetrieve) {
+ return;
+ }
+
+ String beanName = beanDescriptor.getFieldName();
+ Class beanClass = ReflectionUtils.getPropertyType(object, beanName);
+ Object bean = null;
+ if (beanDescriptor.isProxy()) {
+ bean = proxyManager.createBeanProxy(session, this, beanClass, path + "/" + beanDescriptor.getJcrName());
+
+ } else {
+ if (beanDescriptor.isInline()) {
+ bean = this.retrieveSimpleFields(session, mapper.getClassDescriptorByClass(beanClass), node, bean);
+ } else if (null != beanDescriptor.getConverter() && !"".equals(beanDescriptor.getConverter())) {
+ String converterClassName = beanDescriptor.getConverter();
+ Object[] param = {this};
+ BeanConverter beanConverter = (BeanConverter) ReflectionUtils.invokeConstructor(converterClassName, param);
+ bean = beanConverter.getObject(session, node, beanDescriptor, beanClass);
+ } else {
+ bean = this.getObject(session, path + "/" + beanDescriptor.getJcrName());
+ }
+ }
+ ReflectionUtils.setNestedProperty(object, beanName, bean);
+ }
+
+
+
+ /**
+ * Retrieve Collection fields
+ */
+ private void retrieveCollectionFields(Session session, ClassDescriptor classDescriptor, Node parentNode, Object object,
+ boolean forceToRetrieve) {
+ Iterator collectionDescriptorIterator = classDescriptor.getCollectionDescriptors().iterator();
+ while (collectionDescriptorIterator.hasNext()) {
+ CollectionDescriptor collectionDescriptor = (CollectionDescriptor) collectionDescriptorIterator.next();
+ this.retrieveCollectionField(session, collectionDescriptor, parentNode, object, forceToRetrieve);
+ }
+ }
+
+ private void retrieveCollectionField(Session session, CollectionDescriptor collectionDescriptor, Node parentNode, Object object, boolean forceToRetrieve)
+ {
+ if (!collectionDescriptor.isAutoRetrieve() && !forceToRetrieve) {
+ return;
+ }
+
+ CollectionConverter collectionConverter = this.getCollectionConverter(session, collectionDescriptor);
+ Class collectionFieldClass = ReflectionUtils.getPropertyType(object, collectionDescriptor.getFieldName());
+ ManageableCollection collection = null;
+ if (collectionDescriptor.isProxy()) {
+ collection = (ManageableCollection) proxyManager.createCollectionProxy(session, collectionConverter, parentNode,
+ collectionDescriptor, collectionFieldClass);
+
+ } else {
+ collection = collectionConverter.getCollection(session, parentNode, 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();
+
+ if (!beanDescriptor.isAutoInsert()) {
+ continue;
+ }
+
+ String jcrName = beanDescriptor.getJcrName();
+ Object bean = ReflectionUtils.getNestedProperty(object, beanDescriptor.getFieldName());
+ if (bean != null) {
+ if (beanDescriptor.isInline()) {
+ this.storeSimpleFields(session, bean, mapper.getClassDescriptorByClass(bean.getClass()), objectNode);
+ } else if (null != beanDescriptor.getConverter() && !"".equals(beanDescriptor.getConverter())) {
+ String converterClassName = beanDescriptor.getConverter();
+ Object[] param = {this};
+ BeanConverter beanConverter = (BeanConverter) ReflectionUtils.invokeConstructor(converterClassName, param);
+ beanConverter.insert(session, objectNode, beanDescriptor, object);
+ } else {
+ 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();
+ if (!beanDescriptor.isAutoUpdate()) {
+ continue;
+ }
+
+ jcrName = beanDescriptor.getJcrName();
+ Object bean = ReflectionUtils.getNestedProperty(object, beanDescriptor.getFieldName());
+
+ // if the bean is null, remove existing node
+ if ((bean == null)) {
+ if (beanDescriptor.isInline()) {
+ Class beanClass = ReflectionUtils.getPropertyType(object, beanDescriptor.getFieldName());
+ this.storeSimpleFields(session, bean, mapper.getClassDescriptorByClass(beanClass), objectNode);
+ } else if (null != beanDescriptor.getConverter() && !"".equals(beanDescriptor.getConverter())) {
+ String converterClassName = beanDescriptor.getConverter();
+ Object[] param = {this};
+ BeanConverter beanConverter = (BeanConverter) ReflectionUtils
+ .invokeConstructor(converterClassName, param);
+ beanConverter.remove(session, objectNode, beanDescriptor);
+ } else {
+ if (objectNode.hasNode(jcrName)) {
+ objectNode.getNode(jcrName).remove();
+ }
+ }
+ } else {
+ if (beanDescriptor.isInline()) {
+ this.storeSimpleFields(session, bean, mapper.getClassDescriptorByClass(bean.getClass()), objectNode);
+ } else if (null != beanDescriptor.getConverter() && !"".equals(beanDescriptor.getConverter())) {
+ String converterClassName = beanDescriptor.getConverter();
+ Object[] param = {this};
+ BeanConverter beanConverter = (BeanConverter) ReflectionUtils
+ .invokeConstructor(converterClassName, param);
+ beanConverter.update(session, objectNode, beanDescriptor, bean);
+ } 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();
+
+ if (!collectionDescriptor.isAutoInsert()) {
+ continue;
+ }
+
+ 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();
+ if (!collectionDescriptor.isAutoUpdate()) {
+ continue;
+ }
+
+ 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();
+
+ String fieldName = fieldDescriptor.getFieldName();
+ String jcrName = fieldDescriptor.getJcrName();
+
+ // Of course, Path field is not stored as property
+ if (fieldDescriptor.isPath()) {
+ continue;
+ }
+
+ 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 (ValueFormatException vfe) {
+ throw new PersistenceException("Cannot persist properties of object " + object + ". Value format exception.", vfe);
+ } catch (VersionException ve) {
+ throw new PersistenceException("Cannot persist properties of object " + object + ". Versioning exception.", ve);
+ } catch (LockException le) {
+ throw new PersistenceException("Cannot persist properties of object " + object + " on locked node.", le);
+ } catch (ConstraintViolationException cve) {
+ throw new PersistenceException("Cannot persist properties of object " + object + ". Constraint violation.", cve);
+ } 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.getCollectionConverter();
+ 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 = null;
+ if (null != fd.getFieldTypeClass()) {
+ fieldTypeClass = fd.getFieldTypeClass();
+ } else if (null != object) {
+ fieldTypeClass = ReflectionUtils.getPropertyType(object, fieldName);
+ }
+
+ if (null != fieldTypeClass) {
+ return this.atomicTypeConverterProvider.getAtomicTypeConverter(fieldTypeClass);
+ } else {
+ return NULL_CONVERTER;
+ }
+ }
+
+ private ClassDescriptor getClassDescriptor(Class beanClass) {
+ ClassDescriptor classDescriptor = mapper.getClassDescriptorByClass(beanClass);
+ if (null == classDescriptor) {
+ throw new JcrMappingException("Class of type: " + beanClass.getName()
+ + " is not JCR persistable. Maybe element 'class-descriptor' for this type in mapping file is missing");
+ }
+
+ return classDescriptor;
+ }
+
+}
Propchange: incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/persistence/objectconverter/impl/ObjectConverterImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/persistence/objectconverter/impl/ParentBeanConverterImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/persistence/objectconverter/impl/ProxyManager.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/query/Filter.java
URL: http://svn.apache.org/viewvc/incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/query/Filter.java?view=diff&rev=448311&r1=448310&r2=448311
==============================================================================
--- incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/query/Filter.java (original)
+++ incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/query/Filter.java Wed Sep 20 12:37:05 2006
@@ -1,89 +1,89 @@
-/*
- * Copyright 2004-2005 The Apache Software Foundation or its licensors,
- * as applicable.
- *
- * 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.query;
-
-import org.apache.portals.graffito.jcr.exception.IncorrectAtomicTypeException;
-
-
-/**
- *
- * Graffito JCR Filter interface.
- *
- * @author <a href="mailto:christophe.lombart@sword-technologies.com">Christophe Lombart</a>
- *
- */
-public interface Filter
-{
- /**
- * Set the filter scope. The scope is an Node path specifying where to search in the content tree.
- * For example,
- * /mynode/mysecondnode/', the search engine will search on child objects in the /mynode/mysecondnode
- * /mynode/mysecondnode//', the search engine will search on desncendant objects in the /mynode/mysecondnode (the complete subnode tree)
- *
- * @param scope The filter scope
- *
- */
- void setScope(String scope);
-
-
- /**
- * Get the filter scope.
- *
- * @return The filter scope
- */
- String getScope();
-
-
- /**
- * Search content based on a fullTextSearch.
- * Depending on the full text search engine, you can also filter on properties.
- *
- * @param scope either a a jcr node or propserty. If a node is used, all properties of this node are searche (following the internal index
- * @param fullTextSearch The full text search string
- */
- Filter addContains(String scope, String fullTextSearch);
-
- Filter addBetween(String arg0, Object arg1, Object arg2);
-
- Filter addEqualTo(String arg0, Object arg1);
-
- Filter addGreaterOrEqualThan(String arg0, Object arg1);
-
- Filter addGreaterThan(String arg0, Object arg1);
-
- Filter addLessOrEqualThan(String arg0, Object arg1);
-
- Filter addLessThan(String arg0, Object arg1);
-
- Filter addLike(String arg0, Object arg1);
-
- Filter addNotEqualTo(String arg0, Object arg1);
-
- Filter addNotNull(String arg0);
-
- Filter addIsNull(String arg0);
-
- Filter addOrFilter(Filter arg0);
-
- Filter addAndFilter(Filter filter);
-
- Filter addJCRExpression(String jcrExpression);
-
- Class getFilterClass();
-
-
-}
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * 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.query;
+
+import org.apache.portals.graffito.jcr.exception.IncorrectAtomicTypeException;
+
+
+/**
+ *
+ * Graffito JCR Filter interface.
+ *
+ * @author <a href="mailto:christophe.lombart@sword-technologies.com">Christophe Lombart</a>
+ *
+ */
+public interface Filter
+{
+ /**
+ * Set the filter scope. The scope is an Node path specifying where to search in the content tree.
+ * For example,
+ * /mynode/mysecondnode/', the search engine will search on child objects in the /mynode/mysecondnode
+ * /mynode/mysecondnode//', the search engine will search on desncendant objects in the /mynode/mysecondnode (the complete subnode tree)
+ *
+ * @param scope The filter scope
+ *
+ */
+ void setScope(String scope);
+
+
+ /**
+ * Get the filter scope.
+ *
+ * @return The filter scope
+ */
+ String getScope();
+
+
+ /**
+ * Search content based on a fullTextSearch.
+ * Depending on the full text search engine, you can also filter on properties.
+ *
+ * @param scope either a a jcr node or propserty. If a node is used, all properties of this node are searche (following the internal index
+ * @param fullTextSearch The full text search string
+ */
+ Filter addContains(String scope, String fullTextSearch);
+
+ Filter addBetween(String arg0, Object arg1, Object arg2);
+
+ Filter addEqualTo(String arg0, Object arg1);
+
+ Filter addGreaterOrEqualThan(String arg0, Object arg1);
+
+ Filter addGreaterThan(String arg0, Object arg1);
+
+ Filter addLessOrEqualThan(String arg0, Object arg1);
+
+ Filter addLessThan(String arg0, Object arg1);
+
+ Filter addLike(String arg0, Object arg1);
+
+ Filter addNotEqualTo(String arg0, Object arg1);
+
+ Filter addNotNull(String arg0);
+
+ Filter addIsNull(String arg0);
+
+ Filter addOrFilter(Filter arg0);
+
+ Filter addAndFilter(Filter filter);
+
+ Filter addJCRExpression(String jcrExpression);
+
+ Class getFilterClass();
+
+
+}
Propchange: incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/query/Filter.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/query/Query.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/query/QueryManager.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/query/impl/FilterImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/graffito/trunk/jcr/jcr-mapping/src/java/org/apache/portals/graffito/jcr/query/impl/QueryImpl.java
------------------------------------------------------------------------------
svn:eol-style = native