jackrabbit-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ben Short <...@benshort.co.uk>
Subject Re: OCM
Date Tue, 27 Oct 2009 08:39:41 GMT
Hi Christophe,

As you said is was possible to create a collection converter to do
this. See code below.

I suppose that it could be taken a step further using the collection
annotation properties autoRetrieve, autoUpdate, autoInsert properties
and the ObjectConverter to insert and update collection elements when
the parent is saved.

public class BeanReferenceByPathCollectionConverterImpl extends
AbstractCollectionConverterImpl {

	public BeanReferenceByPathCollectionConverterImpl(Map
atomicTypeConverters, ObjectConverter objectConverter, Mapper mapper)
{
		super(atomicTypeConverters, objectConverter, mapper);
	}

	protected ManageableObjects doGetCollection(Session session, Node
parentNode, CollectionDescriptor collectionDescriptor, Class
collectionFieldClass) throws RepositoryException {
		try {
            String jcrName = getCollectionJcrName(collectionDescriptor);
            if (!parentNode.hasProperty(jcrName)) {
                return null;
            }
            Property property = parentNode.getProperty(jcrName);
            Value[] values = property.getValues();

            ManageableObjects objects =
ManageableObjectsUtil.getManageableObjects(collectionFieldClass);

            // For collection of bean references, only Collections are supported
            if (! (objects instanceof ManageableCollection))
            {

            	throw new JcrMappingException("Impossible to retrieve the
attribute "
            			+ collectionDescriptor.getFieldName() + " in the class "
            			+ collectionDescriptor.getClassDescriptor().getClassName()
            			+  " because it is not a collection");
            }

            for (int i = 0; i < values.length; i++) {
                String path = values[i].getString();
                Object object = objectConverter.getObject(session, path);
                ((ManageableCollection) objects).addObject(object);
            }

            return objects;
        }
        catch(Exception e) {
          throw new ObjectContentManagerException("Cannot get the
collection field : "
                  + collectionDescriptor.getFieldName()
                  + "for class " +
collectionDescriptor.getClassDescriptor().getClassName(), e);
        }
	}

	protected void doInsertCollection(Session session, Node parentNode,
CollectionDescriptor descriptor, ManageableObjects objects) throws
RepositoryException {
		addPathProperties(session, parentNode, descriptor, objects);
	}

	protected boolean doIsNull(Session session, Node parentNode,
CollectionDescriptor collectionDescriptor, Class collectionFieldClass)
throws RepositoryException {
		String jcrName = getCollectionJcrName(collectionDescriptor);
        return ! parentNode.hasProperty(jcrName);
	}

	protected void doUpdateCollection(Session session, Node parentNode,
CollectionDescriptor descriptor, ManageableObjects objects) throws
RepositoryException {
		String jcrName = getCollectionJcrName(descriptor);

        // Delete existing values
        if (parentNode.hasProperty(jcrName)) {
            parentNode.setProperty(jcrName, (Value[]) null);
        }

        if (objects == null) {
            return;
        }


        addPathProperties(session, parentNode, descriptor, objects);
	}

	private void addPathProperties(Session session, Node parentNode,
CollectionDescriptor collectionDescriptor, ManageableObjects objects)
throws RepositoryException {
		try {
            if (objects == null) {
                return;
            }

            String jcrName = getCollectionJcrName(collectionDescriptor);
            Value[] values = new Value[objects.getSize()];
            ValueFactory valueFactory = session.getValueFactory();
            Iterator collectionIterator = objects.getIterator();
            for (int i = 0; i < objects.getSize(); i++) {
                Object object = collectionIterator.next();
				if (object != null)
				{
					ClassDescriptor classDescriptor =
mapper.getClassDescriptorByClass(object.getClass());

					FieldDescriptor fieldDescriptor = classDescriptor.getPathFieldDescriptor();
					if (fieldDescriptor == null)
					{
						throw new JcrMappingException("The bean doesn't have an path -
classdescriptor : "
										              + classDescriptor.getClassName());
					}

					String path = (String) ReflectionUtils.getNestedProperty(object,
fieldDescriptor.getFieldName());
					values[i] = valueFactory.createValue(path, PropertyType.STRING);
				}
            }

            parentNode.setProperty(jcrName, values);
        }
        catch(Exception e) {
            throw new ObjectContentManagerException("Cannot insert
collection field : "
                    + collectionDescriptor.getFieldName()
                    + " of class "
                    +
collectionDescriptor.getClassDescriptor().getClassName(), e);
        }
	}
}

2009/10/26 Christophe Lombart <christophe.lombart@gmail.com>:
> It is supported but only by UUID.
> By path is also a good idea. It should be possible to add a new  OCM
> Collection converter for supporting reference by path .
>
> Christophe
>
>
> 2009/10/23 Ben Short <ben@benshort.co.uk>:
>> Hi,
>>
>> JCROM supports weak references as show in the following classes
>>
>> public class Person {
>>
>>        @JcrPath
>>        private String path;
>>        @JcrName
>>        private String name;
>>
>>        @JcrReference(byPath = true)
>>        private List<Pet> pets= new ArrayList<Pet>();
>>
>> }
>>
>> public class Pet {
>>
>>        @JcrPath
>>        private String path;
>>        @JcrName
>>        private String name;
>>
>> }
>>
>> This will result in a property on person node which contains a list of
>> paths to the pet nodes.
>>
>> Does jackrabbit-ocm support this?
>>
>> Regards
>>
>> Ben Short
>>
>

Mime
View raw message