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.graph.property;
25  
26  import java.io.Serializable;
27  import java.util.Iterator;
28  import net.jcip.annotations.Immutable;
29  
30  /**
31   * Representation of a property consisting of a name and value(s). Note that this property is immutable, meaning that the property
32   * values may not be changed through this interface.
33   * <p>
34   * This class is designed to be used with the {@link ValueFactories} interface and the particular {@link ValueFactory} that
35   * corresponds to the type of value you'd like to use. The <code>ValueFactory</code> will then return the values (if no type
36   * conversion is required) or will convert the values using the appropriate conversion algorithm.
37   * </p>
38   * <p>
39   * The following example shows how to obtain the {@link String} representations of the {@link #getValues() property values}:
40   * 
41   * <pre>
42   *   ValueFactories valueFactories = ...
43   *   Property property = ...
44   *   Iterator&lt;String&gt; iter = valueFactories.getStringFactory().create(property.getValues());
45   *   while ( iter.hasNext() ) {
46   *       System.out.println(iter.next());
47   *   }
48   * </pre>
49   * 
50   * Meanwhile, the {@link ValueFactories#getLongFactory() long value factory} converts the values to <code>long</code>, the
51   * {@link ValueFactories#getDateFactory() date value factory} converts the values to {@link DateTime} instances, and so on.
52   * </p>
53   * <p>
54   * This technique is much better and far safer than casting the values. It is possible that some Property instances contain
55   * heterogeneous values, so casting may not always work. Also, this technique guarantees that the values are properly converted if
56   * the type is not what you expected.
57   * </p>
58   */
59  @Immutable
60  public interface Property extends Iterable<Object>, Comparable<Property>, Readable, Serializable {
61  
62      /**
63       * Get the name of the property.
64       * 
65       * @return the property name; never null
66       */
67      Name getName();
68  
69      /**
70       * Get the number of actual values in this property. If the property allows {@link #isMultiple() multiple values}, then this
71       * method may return a value greater than 1. If the property only allows a {@link #isSingle() single value}, then this method
72       * will return either 0 or 1. This method may return 0 regardless of whether the property allows a {@link #isSingle() single
73       * value}, or {@link #isMultiple() multiple values}.
74       * 
75       * @return the number of actual values in this property; always non-negative
76       */
77      int size();
78  
79      /**
80       * Determine whether the property currently has multiple values.
81       * 
82       * @return true if the property has multiple values, or false otherwise.
83       * @see #isSingle()
84       * @see #isEmpty()
85       */
86      boolean isMultiple();
87  
88      /**
89       * Determine whether the property currently has a single value.
90       * 
91       * @return true if the property has a single value, or false otherwise.
92       * @see #isMultiple()
93       * @see #isEmpty()
94       */
95      boolean isSingle();
96  
97      /**
98       * Determine whether this property has no actual values. This method may return <code>true</code> regardless of whether the
99       * property allows a {@link #isSingle() single value}, or {@link #isMultiple() multiple values}.
100      * <p>
101      * This method is a convenience method that is equivalent to <code>size() == 0</code>.
102      * </p>
103      * 
104      * @return true if this property has no values, or false otherwise
105      * @see #isMultiple()
106      * @see #isSingle()
107      */
108     boolean isEmpty();
109 
110     /**
111      * Obtain the property's first value in its natural form. This is equivalent to calling
112      * <code>isEmpty() ? null : iterator().next()</code>
113      * 
114      * @return the first value, or null if the property is {@link #isEmpty() empty}
115      * @see Iterable#iterator()
116      * @see #getValues()
117      * @see #getValuesAsArray()
118      * @see #isEmpty()
119      */
120     Object getFirstValue();
121 
122     /**
123      * Obtain the property's values in their natural form. This is equivalent to calling {@link Iterable#iterator() iterator()}.
124      * <p>
125      * A valid iterator is returned if the property has {@link #isSingle() single valued} or {@link #isMultiple() multi-valued}.
126      * </p>
127      * <p>
128      * The resulting iterator is immutable, and all property values are immutable.
129      * </p>
130      * 
131      * @return an iterator over the values; never null
132      * @see #getFirstValue()
133      * @see Iterable#iterator()
134      * @see #getValuesAsArray()
135      * @see ValueFactory#create(Iterator)
136      */
137     Iterator<?> getValues();
138 
139     /**
140      * Obtain the property's values as an array of objects in their natural form.
141      * <p>
142      * A valid array is return if the property has {@link #isSingle() single valued} or {@link #isMultiple() multi-valued}, or a
143      * null value is returned if the property is {@link #isEmpty() empty}.
144      * </p>
145      * <p>
146      * The resulting array is a copy, guaranteeing immutability for the property.
147      * </p>
148      * 
149      * @return the array of values
150      * @see #getFirstValue()
151      * @see Iterable#iterator()
152      * @see #getValues()
153      * @see ValueFactory#create(Object[])
154      */
155     Object[] getValuesAsArray();
156 }