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