1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.portals.graffito.jcr.persistence.collectionconverter.impl;
18
19
20 import java.util.Iterator;
21 import java.util.Map;
22
23 import javax.jcr.Node;
24 import javax.jcr.Property;
25 import javax.jcr.RepositoryException;
26 import javax.jcr.Session;
27 import javax.jcr.Value;
28 import javax.jcr.ValueFactory;
29 import javax.jcr.ValueFormatException;
30
31 import org.apache.portals.graffito.jcr.exception.PersistenceException;
32 import org.apache.portals.graffito.jcr.mapper.Mapper;
33 import org.apache.portals.graffito.jcr.mapper.model.CollectionDescriptor;
34 import org.apache.portals.graffito.jcr.persistence.atomictypeconverter.AtomicTypeConverter;
35 import org.apache.portals.graffito.jcr.persistence.collectionconverter.ManageableCollection;
36 import org.apache.portals.graffito.jcr.persistence.collectionconverter.ManageableCollectionUtil;
37 import org.apache.portals.graffito.jcr.persistence.objectconverter.ObjectConverter;
38 import org.apache.portals.graffito.jcr.reflection.ReflectionUtils;
39
40 /***
41 * Collection Mapping/convertion implementation used for multi values properties
42 *
43 * This collection mapping strategy maps a collection into a JCR multi value property
44 *
45 * @author <a href="mailto:christophe.lombart@gmail.com">Christophe Lombart</a>
46 * @author <a href='mailto:the_mindstorm[at]evolva[dot]ro'>Alexandru Popescu</a>
47 */
48 public class MultiValueCollectionConverterImpl extends AbstractCollectionConverterImpl {
49
50 /***
51 * Constructor
52 *
53 * @param atomicTypeConverters
54 * @param objectConverter
55 * @param mapper
56 */
57 public MultiValueCollectionConverterImpl(Map atomicTypeConverters,
58 ObjectConverter objectConverter,
59 Mapper mapper) {
60 super(atomicTypeConverters, objectConverter, mapper);
61 }
62
63 /***
64 *
65 * @see AbstractCollectionConverterImpl#doInsertCollection(Session, Node, CollectionDescriptor, ManageableCollection)
66 */
67 protected void doInsertCollection(Session session,
68 Node parentNode,
69 CollectionDescriptor collectionDescriptor,
70 ManageableCollection collection) throws RepositoryException {
71 try {
72 if (collection == null) {
73 return;
74 }
75
76 String jcrName = getCollectionJcrName(collectionDescriptor);
77 Value[] values = new Value[collection.getSize()];
78 ValueFactory valueFactory = session.getValueFactory();
79 Iterator collectionIterator = collection.getIterator();
80 for (int i = 0; i < collection.getSize(); i++) {
81 Object fieldValue = collectionIterator.next();
82 AtomicTypeConverter atomicTypeConverter = (AtomicTypeConverter) atomicTypeConverters
83 .get(fieldValue.getClass());
84 values[i] = atomicTypeConverter.getValue(valueFactory, fieldValue);
85 }
86
87 parentNode.setProperty(jcrName, values);
88 }
89 catch(ValueFormatException vfe) {
90 throw new PersistenceException("Cannot insert collection field : "
91 + collectionDescriptor.getFieldName()
92 + " of class "
93 + collectionDescriptor.getClassDescriptor().getClassName(), vfe);
94 }
95 }
96
97 /***
98 *
99 * @see AbstractCollectionConverterImpl#doUpdateCollection(Session, Node, CollectionDescriptor, ManageableCollection)
100 */
101 protected void doUpdateCollection(Session session,
102 Node parentNode,
103 CollectionDescriptor collectionDescriptor,
104 ManageableCollection collection) throws RepositoryException {
105 String jcrName = getCollectionJcrName(collectionDescriptor);
106
107
108 if (parentNode.hasProperty(jcrName)) {
109 parentNode.setProperty(jcrName, (Value[]) null);
110 }
111
112 if (collection == null) {
113 return;
114 }
115
116
117
118 Value[] values = new Value[collection.getSize()];
119 ValueFactory valueFactory = session.getValueFactory();
120 int i = 0;
121 for (Iterator collectionIterator = collection.getIterator(); collectionIterator.hasNext(); i++) {
122 Object fieldValue = collectionIterator.next();
123 AtomicTypeConverter atomicTypeConverter = (AtomicTypeConverter) atomicTypeConverters
124 .get(fieldValue.getClass());
125 values[i] = atomicTypeConverter.getValue(valueFactory, fieldValue);
126 }
127
128 parentNode.setProperty(jcrName, values);
129 }
130
131 /***
132 * @see AbstractCollectionConverterImpl#doGetCollection(Session, Node, CollectionDescriptor, Class)
133 */
134 protected ManageableCollection doGetCollection(Session session,
135 Node parentNode,
136 CollectionDescriptor collectionDescriptor,
137 Class collectionFieldClass) throws RepositoryException {
138 try {
139 String jcrName = getCollectionJcrName(collectionDescriptor);
140 if (!parentNode.hasProperty(jcrName)) {
141 return null;
142 }
143 Property property = parentNode.getProperty(jcrName);
144 Value[] values = property.getValues();
145
146 ManageableCollection collection = ManageableCollectionUtil.getManageableCollection(collectionFieldClass);
147 String elementClassName = collectionDescriptor.getElementClassName();
148 Class elementClass = ReflectionUtils.forName(elementClassName);
149 for (int i = 0; i < values.length; i++) {
150 AtomicTypeConverter atomicTypeConverter = (AtomicTypeConverter) atomicTypeConverters
151 .get(elementClass);
152 collection.addObject(atomicTypeConverter.getObject(values[i]));
153 }
154
155 return collection;
156 }
157 catch(ValueFormatException vfe) {
158 throw new PersistenceException("Cannot get the collection field : "
159 + collectionDescriptor.getFieldName()
160 + "for class " + collectionDescriptor.getClassDescriptor().getClassName(),
161 vfe);
162 }
163 }
164
165 /***
166 * @see AbstractCollectionConverterImpl#doIsNull(Session, Node, CollectionDescriptor, Class)
167 */
168 protected boolean doIsNull(Session session,
169 Node parentNode,
170 CollectionDescriptor collectionDescriptor,
171 Class collectionFieldClass) throws RepositoryException {
172 String jcrName = getCollectionJcrName(collectionDescriptor);
173
174 if (!parentNode.hasProperty(jcrName)) {
175 return true;
176 }
177 return false;
178 }
179 }