View Javadoc

1   /*
2    * ModeShape (http://www.modeshape.org)
3    * See the COPYRIGHT.txt file distributed with this work for information
4    * regarding copyright ownership.  Some portions may be licensed
5    * to Red Hat, Inc. under one or more contributor license agreements.
6    * See the AUTHORS.txt file in the distribution for a full listing of 
7    * individual contributors. 
8    *
9    * ModeShape is free software. Unless otherwise indicated, all code in ModeShape
10   * is licensed to you under the terms of the GNU Lesser General Public License as
11   * published by the Free Software Foundation; either version 2.1 of
12   * the License, or (at your option) any later version.
13   *
14   * ModeShape is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17   * Lesser General Public License for more details.
18   *
19   * You should have received a copy of the GNU Lesser General Public
20   * License along with this software; if not, write to the Free
21   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
23   */
24  package org.modeshape.jcr;
25  
26  import java.io.InputStream;
27  import java.math.BigDecimal;
28  import java.util.ArrayList;
29  import java.util.Calendar;
30  import java.util.Iterator;
31  import java.util.List;
32  import javax.jcr.Binary;
33  import javax.jcr.Node;
34  import javax.jcr.PropertyType;
35  import javax.jcr.RepositoryException;
36  import javax.jcr.Value;
37  import javax.jcr.ValueFormatException;
38  import javax.jcr.lock.LockException;
39  import javax.jcr.nodetype.ConstraintViolationException;
40  import javax.jcr.version.VersionException;
41  import net.jcip.annotations.NotThreadSafe;
42  import org.modeshape.graph.property.Name;
43  import org.modeshape.graph.property.Property;
44  
45  /**
46   * A {@link javax.jcr.Property JCR Property} implementation that has multiple values.
47   * 
48   * @see JcrSingleValueProperty
49   */
50  @NotThreadSafe
51  final class JcrMultiValueProperty extends AbstractJcrProperty {
52  
53      static final JcrValue[] EMPTY_VALUES = new JcrValue[] {};
54  
55      JcrMultiValueProperty( SessionCache cache,
56                             AbstractJcrNode node,
57                             Name name ) {
58          super(cache, node, name);
59      }
60  
61      /**
62       * {@inheritDoc}
63       * 
64       * @see org.modeshape.jcr.AbstractJcrProperty#isMultiple()
65       */
66      @Override
67      public boolean isMultiple() {
68          return true;
69      }
70  
71      /**
72       * {@inheritDoc}
73       * 
74       * @throws ValueFormatException always
75       * @see javax.jcr.Property#getBoolean()
76       */
77      public boolean getBoolean() throws ValueFormatException {
78          throw new ValueFormatException(JcrI18n.invalidMethodForMultiValuedProperty.text());
79      }
80  
81      /**
82       * {@inheritDoc}
83       * 
84       * @throws ValueFormatException always
85       * @see javax.jcr.Property#getDate()
86       */
87      public Calendar getDate() throws ValueFormatException {
88          throw new ValueFormatException(JcrI18n.invalidMethodForMultiValuedProperty.text());
89      }
90  
91      /**
92       * {@inheritDoc}
93       * 
94       * @throws ValueFormatException always
95       * @see javax.jcr.Property#getDouble()
96       */
97      public double getDouble() throws ValueFormatException {
98          throw new ValueFormatException(JcrI18n.invalidMethodForMultiValuedProperty.text());
99      }
100 
101     /**
102      * {@inheritDoc}
103      * 
104      * @see javax.jcr.Property#getNode()
105      */
106     public Node getNode() throws ValueFormatException, RepositoryException {
107         throw new ValueFormatException(JcrI18n.invalidMethodForMultiValuedProperty.text());
108     }
109 
110     /**
111      * {@inheritDoc}
112      * 
113      * @throws ValueFormatException always
114      * @see javax.jcr.Property#getLength()
115      */
116     public long getLength() throws ValueFormatException {
117         throw new ValueFormatException(JcrI18n.invalidMethodForMultiValuedProperty.text());
118     }
119 
120     /**
121      * {@inheritDoc}
122      * 
123      * @see javax.jcr.Property#getLengths()
124      */
125     public long[] getLengths() throws RepositoryException {
126         checkSession();
127         Property dnaProperty = propertyInfo().getProperty();
128         long[] lengths = new long[dnaProperty.size()];
129         Iterator<?> iter = dnaProperty.iterator();
130         for (int ndx = 0; iter.hasNext(); ndx++) {
131             lengths[ndx] = createValue(iter.next()).getLength();
132         }
133         return lengths;
134     }
135 
136     /**
137      * {@inheritDoc}
138      * 
139      * @throws ValueFormatException always
140      * @see javax.jcr.Property#getLong()
141      */
142     public long getLong() throws ValueFormatException {
143         throw new ValueFormatException(JcrI18n.invalidMethodForMultiValuedProperty.text());
144     }
145 
146     /**
147      * {@inheritDoc}
148      * 
149      * @throws ValueFormatException always
150      * @see javax.jcr.Property#getStream()
151      */
152     public InputStream getStream() throws ValueFormatException {
153         throw new ValueFormatException(JcrI18n.invalidMethodForMultiValuedProperty.text());
154     }
155 
156     /**
157      * {@inheritDoc}
158      * 
159      * @throws ValueFormatException always
160      * @see javax.jcr.Property#getString()
161      */
162     public String getString() throws ValueFormatException {
163         throw new ValueFormatException(JcrI18n.invalidMethodForMultiValuedProperty.text());
164     }
165 
166     /**
167      * {@inheritDoc}
168      * <p>
169      * Per the JCR specification, these values need to be created each time this method is called, since the Value cannot be used
170      * after {@link Value#getStream()} is called/processed. The spec says that the client simply needs to obtain a new Value (or
171      * {@link #getValues()} for {@link JcrMultiValueProperty multi-valued properites}).
172      * </p>
173      * 
174      * @see javax.jcr.Property#getValues()
175      */
176     public Value[] getValues() throws RepositoryException {
177         checkSession();
178         Property dnaProperty = propertyInfo().getProperty();
179         Value[] values = new JcrValue[dnaProperty.size()];
180         Iterator<?> iter = dnaProperty.iterator();
181         for (int ndx = 0; iter.hasNext(); ndx++) {
182             values[ndx] = createValue(iter.next());
183         }
184         return values;
185     }
186 
187     /**
188      * {@inheritDoc}
189      * 
190      * @see javax.jcr.Property#setValue(javax.jcr.Value[])
191      */
192     public final void setValue( Value[] values )
193         throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
194         checkForLock();
195 
196         if (values == null) {
197             this.remove();
198             return;
199         }
200         checkSession();
201 
202         for (int i = 0; i < values.length; i++) {
203             // Force a conversion as per SetValueValueFormatExceptionTest in JR TCK
204             if (values[i] != null) ((JcrValue)values[i]).asType(this.getType());
205         }
206 
207         editor().setProperty(name(), values, PropertyType.UNDEFINED);
208     }
209 
210     /**
211      * {@inheritDoc}
212      * 
213      * @see javax.jcr.Property#setValue(java.lang.String[])
214      */
215     public final void setValue( String[] values )
216         throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException {
217         checkForLock();
218 
219         if (values == null) {
220             this.remove();
221             return;
222         }
223         checkSession();
224 
225         Value[] jcrValues = null;
226         if (values.length != 0) {
227             int numValues = values.length;
228             List<Value> valuesList = new ArrayList<Value>(numValues);
229             jcrValues = new JcrValue[numValues];
230             for (int i = 0; i != numValues; ++i) {
231                 String value = values[i];
232                 if (value == null) continue; // skip null values
233                 valuesList.add(createValue(values[i], PropertyType.STRING).asType(this.getType()));
234             }
235             if (valuesList.isEmpty()) {
236                 jcrValues = EMPTY_VALUES;
237             } else {
238                 jcrValues = valuesList.toArray(new Value[valuesList.size()]);
239             }
240         } else {
241             jcrValues = EMPTY_VALUES;
242         }
243 
244         editor().setProperty(name(), jcrValues, this.getType());
245     }
246 
247     /**
248      * {@inheritDoc}
249      * 
250      * @throws ValueFormatException always
251      * @see javax.jcr.Property#getValue()
252      */
253     public Value getValue() throws ValueFormatException {
254         throw new ValueFormatException(JcrI18n.invalidMethodForMultiValuedProperty.text());
255     }
256 
257     /**
258      * {@inheritDoc}
259      * 
260      * @throws ValueFormatException always
261      * @see javax.jcr.Property#setValue(javax.jcr.Value)
262      */
263     public final void setValue( Value value ) throws ValueFormatException {
264         throw new ValueFormatException(JcrI18n.invalidMethodForMultiValuedProperty.text());
265     }
266 
267     /**
268      * {@inheritDoc}
269      * 
270      * @throws ValueFormatException always
271      * @see javax.jcr.Property#setValue(java.lang.String)
272      */
273     public final void setValue( String value ) throws ValueFormatException {
274         throw new ValueFormatException(JcrI18n.invalidMethodForMultiValuedProperty.text());
275     }
276 
277     /**
278      * {@inheritDoc}
279      * 
280      * @throws ValueFormatException always
281      * @see javax.jcr.Property#setValue(java.io.InputStream)
282      */
283     public final void setValue( InputStream value ) throws ValueFormatException {
284         throw new ValueFormatException(JcrI18n.invalidMethodForMultiValuedProperty.text());
285     }
286 
287     /**
288      * {@inheritDoc}
289      * 
290      * @throws ValueFormatException always
291      * @see javax.jcr.Property#setValue(long)
292      */
293     public final void setValue( long value ) throws ValueFormatException {
294         throw new ValueFormatException(JcrI18n.invalidMethodForMultiValuedProperty.text());
295     }
296 
297     /**
298      * {@inheritDoc}
299      * 
300      * @throws ValueFormatException always
301      * @see javax.jcr.Property#setValue(double)
302      */
303     public final void setValue( double value ) throws ValueFormatException {
304         throw new ValueFormatException(JcrI18n.invalidMethodForMultiValuedProperty.text());
305     }
306 
307     /**
308      * {@inheritDoc}
309      * 
310      * @throws ValueFormatException always
311      * @see javax.jcr.Property#setValue(java.util.Calendar)
312      */
313     public final void setValue( Calendar value ) throws ValueFormatException {
314         throw new ValueFormatException(JcrI18n.invalidMethodForMultiValuedProperty.text());
315     }
316 
317     /**
318      * {@inheritDoc}
319      * 
320      * @throws ValueFormatException always
321      * @see javax.jcr.Property#setValue(boolean)
322      */
323     public final void setValue( boolean value ) throws ValueFormatException {
324         throw new ValueFormatException(JcrI18n.invalidMethodForMultiValuedProperty.text());
325     }
326 
327     /**
328      * {@inheritDoc}
329      * 
330      * @throws ValueFormatException always
331      * @see javax.jcr.Property#setValue(javax.jcr.Node)
332      */
333     public final void setValue( Node value ) throws ValueFormatException {
334         throw new ValueFormatException(JcrI18n.invalidMethodForMultiValuedProperty.text());
335     }
336 
337     @Override
338     public Binary getBinary() throws ValueFormatException, RepositoryException {
339         throw new ValueFormatException(JcrI18n.invalidMethodForMultiValuedProperty.text());
340     }
341 
342     @Override
343     public BigDecimal getDecimal() throws ValueFormatException, RepositoryException {
344         throw new ValueFormatException(JcrI18n.invalidMethodForMultiValuedProperty.text());
345     }
346 
347     @Override
348     public javax.jcr.Property getProperty() throws ValueFormatException, RepositoryException {
349         throw new ValueFormatException(JcrI18n.invalidMethodForMultiValuedProperty.text());
350     }
351 
352     @Override
353     public void setValue( BigDecimal value ) throws ValueFormatException, RepositoryException {
354         throw new ValueFormatException(JcrI18n.invalidMethodForMultiValuedProperty.text());
355     }
356 
357     @Override
358     public void setValue( Binary value ) throws ValueFormatException, RepositoryException {
359         throw new ValueFormatException(JcrI18n.invalidMethodForMultiValuedProperty.text());
360     }
361 
362 }