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 }