View Javadoc

1   /*
2    * Copyright 2000-2005 The Apache Software Foundation.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
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         // Delete existing values
108         if (parentNode.hasProperty(jcrName)) {
109             parentNode.setProperty(jcrName, (Value[]) null);
110         }
111 
112         if (collection == null) {
113             return;
114         }
115 
116 
117         // Add all collection element into an Value array
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 }