001 /* 002 * JBoss DNA (http://www.jboss.org/dna) 003 * See the COPYRIGHT.txt file distributed with this work for information 004 * regarding copyright ownership. Some portions may be licensed 005 * to Red Hat, Inc. under one or more contributor license agreements. 006 * See the AUTHORS.txt file in the distribution for a full listing of 007 * individual contributors. 008 * 009 * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA 010 * is licensed to you under the terms of the GNU Lesser General Public License as 011 * published by the Free Software Foundation; either version 2.1 of 012 * the License, or (at your option) any later version. 013 * 014 * JBoss DNA is distributed in the hope that it will be useful, 015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 017 * Lesser General Public License for more details. 018 * 019 * You should have received a copy of the GNU Lesser General Public 020 * License along with this software; if not, write to the Free 021 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 022 * 02110-1301 USA, or see the FSF site: http://www.fsf.org. 023 */ 024 package org.jboss.dna.graph.property; 025 026 import java.util.Iterator; 027 import net.jcip.annotations.Immutable; 028 029 /** 030 * Representation of a property consisting of a name and value(s). Note that this property is immutable, meaning that the property 031 * values may not be changed through this interface. 032 * <p> 033 * This class is designed to be used with the {@link ValueFactories} interface and the particular {@link ValueFactory} that 034 * corresponds to the type of value you'd like to use. The <code>ValueFactory</code> will then return the values (if no type 035 * conversion is required) or will convert the values using the appropriate conversion algorithm. 036 * </p> 037 * <p> 038 * The following example shows how to obtain the {@link String} representations of the {@link #getValues() property values}: 039 * 040 * <pre> 041 * ValueFactories valueFactories = ... 042 * Property property = ... 043 * Iterator<String> iter = valueFactories.getStringFactory().create(property.getValues()); 044 * while ( iter.hasNext() ) { 045 * System.out.println(iter.next()); 046 * } 047 * </pre> 048 * 049 * Meanwhile, the {@link ValueFactories#getLongFactory() long value factory} converts the values to <code>long</code>, the 050 * {@link ValueFactories#getDateFactory() date value factory} converts the values to {@link DateTime} instances, and so on. 051 * </p> 052 * <p> 053 * This technique is much better and far safer than casting the values. It is possible that some Property instances contain 054 * heterogeneous values, so casting may not always work. Also, this technique guarantees that the values are properly converted if 055 * the type is not what you expected. 056 * </p> 057 * 058 * @author Randall Hauch 059 */ 060 @Immutable 061 public interface Property extends Iterable<Object>, Comparable<Property>, Readable { 062 063 /** 064 * Get the name of the property. 065 * 066 * @return the property name; never null 067 */ 068 Name getName(); 069 070 /** 071 * Get the number of actual values in this property. If the property allows {@link #isMultiple() multiple values}, then this 072 * method may return a value greater than 1. If the property only allows a {@link #isSingle() single value}, then this method 073 * will return either 0 or 1. This method may return 0 regardless of whether the property allows a {@link #isSingle() single 074 * value}, or {@link #isMultiple() multiple values}. 075 * 076 * @return the number of actual values in this property; always non-negative 077 */ 078 int size(); 079 080 /** 081 * Determine whether the property currently has multiple values. 082 * 083 * @return true if the property has multiple values, or false otherwise. 084 * @see #isSingle() 085 * @see #isEmpty() 086 */ 087 boolean isMultiple(); 088 089 /** 090 * Determine whether the property currently has a single value. 091 * 092 * @return true if the property has a single value, or false otherwise. 093 * @see #isMultiple() 094 * @see #isEmpty() 095 */ 096 boolean isSingle(); 097 098 /** 099 * Determine whether this property has no actual values. This method may return <code>true</code> regardless of whether the 100 * property allows a {@link #isSingle() single value}, or {@link #isMultiple() multiple values}. 101 * <p> 102 * This method is a convenience method that is equivalent to <code>size() == 0</code>. 103 * </p> 104 * 105 * @return true if this property has no values, or false otherwise 106 * @see #isMultiple() 107 * @see #isSingle() 108 */ 109 boolean isEmpty(); 110 111 /** 112 * Obtain the property's first value in its natural form. This is equivalent to calling 113 * <code>isEmpty() ? null : iterator().next()</code> 114 * 115 * @return the first value, or null if the property is {@link #isEmpty() empty} 116 * @see Iterable#iterator() 117 * @see #getValues() 118 * @see #getValuesAsArray() 119 * @see #isEmpty() 120 */ 121 Object getFirstValue(); 122 123 /** 124 * Obtain the property's values in their natural form. This is equivalent to calling {@link Iterable#iterator() iterator()}. 125 * <p> 126 * A valid iterator is returned if the property has {@link #isSingle() single valued} or {@link #isMultiple() multi-valued}. 127 * </p> 128 * <p> 129 * The resulting iterator is immutable, and all property values are immutable. 130 * </p> 131 * 132 * @return an iterator over the values; never null 133 * @see #getFirstValue() 134 * @see Iterable#iterator() 135 * @see #getValuesAsArray() 136 * @see ValueFactory#create(Iterator) 137 */ 138 Iterator<?> getValues(); 139 140 /** 141 * Obtain the property's values as an array of objects in their natural form. 142 * <p> 143 * A valid array is return if the property has {@link #isSingle() single valued} or {@link #isMultiple() multi-valued}, or a 144 * null value is returned if the property is {@link #isEmpty() empty}. 145 * </p> 146 * <p> 147 * The resulting array is a copy, guaranteeing immutability for the property. 148 * </p> 149 * 150 * @return the array of values 151 * @see #getFirstValue() 152 * @see Iterable#iterator() 153 * @see #getValues() 154 * @see ValueFactory#create(Object[]) 155 */ 156 Object[] getValuesAsArray(); 157 }