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<String> 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 }