001 /* 002 * file PropertyNameList.java 003 * 004 * Licensed Materials - Property of IBM 005 * Restricted Materials of IBM 006 * 007 * (c) Copyright IBM Corporation 2004, 2008. All Rights Reserved. 008 * Note to U.S. Government Users Restricted Rights: Use, duplication or 009 * disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 010 */ 011 package javax.wvcm; 012 013 import java.util.Arrays; 014 import java.util.Collections; 015 import java.util.HashSet; 016 import java.util.Set; 017 018 /** 019 * A list of resource property names. 020 * 021 * @since 1.0 022 */ 023 public final class PropertyNameList implements PropertyRequestItem { 024 025 /** 026 * The name of a property of a persistent resource. The PropertyName 027 * type parameter specifies the type of the value of the PropertyName 028 */ 029 public static class PropertyName<T> implements PropertyRequestItem { 030 031 private final String _namespace; 032 private final String _name; 033 034 /** 035 * Create a PropertyName with a null namespace and the given name. 036 * 037 * @param name the name for this property. May not be null. 038 */ 039 PropertyName(String name) { 040 this(null, name); 041 } 042 043 /** 044 * Create a PropertyName with the given namespace and name. 045 * 046 * @param namespace the namespace for this PropertyName. 047 * May be null to indicate a system property, or non-null 048 * to indicate a property in the specified name space. 049 * @param name the name for this property. May not be null. 050 */ 051 public PropertyName(String namespace, String name) { 052 _namespace = namespace; 053 _name = name; 054 } 055 056 /** 057 * Get the namespace of the property name. 058 * 059 * @return the namespace. May be null to indicate a system property, 060 * or non-null to indicate a property in the specified name space. 061 */ 062 public String getNamespace() { 063 return _namespace; 064 } 065 066 /** 067 * Get the property name. 068 * 069 * @return the name part of the property name */ 070 public String getName() { 071 return _name; 072 } 073 074 /** 075 * Calculate a hash code value for the object. 076 * 077 * @return the hash code for the object. 078 */ 079 @Override 080 public int hashCode() { 081 int result = 17; 082 result = 37*result + ((_namespace == null) ? 0 : _namespace.hashCode()); 083 result = 37*result + _name.hashCode(); 084 return result; 085 } 086 087 /** 088 * Indicates whether some other object is "equal to" this one. 089 * 090 * @param o the object to compare with. 091 * @return true if and only if the specified object is a PropertyName whose 092 * type, namespace value, and name value equals those of this object. 093 */ 094 @Override 095 public boolean equals(Object o) { 096 if (o == null || this.getClass() != o.getClass()) { 097 return false; 098 } 099 PropertyName<?> pn = (PropertyName<?>) o; 100 if (_namespace == null) { 101 return pn._namespace == null && _name.equals(pn._name); 102 } 103 return _namespace.equals(pn._namespace) && _name.equals(pn._name); 104 } 105 106 /** 107 * Returns a string representation of the PropertyName for diagnostic 108 * purposes. 109 * @see java.lang.Object#toString 110 * 111 * @return The string representation of this PropertyName in the format 112 * [namespace:]name. 113 */ 114 @Override 115 public String toString() { 116 if (_namespace != null) 117 return _namespace + ":" + _name; //$NON-NLS-1$ 118 else 119 return _name; 120 } 121 122 /** 123 * Constructs a NestedPropertyName whose root property is this 124 * PropertyName with the property request items supplied as arguments as 125 * its nested property request. This method allows a more succinct 126 * syntax for the declaration of PropertyRequest objects at compile 127 * time. For example, 128 * 129 * <pre> 130 * final static PropertyRequest WORKSPACE_PROPERTIES = 131 * new PropertyRequest( 132 * Workspace.DISPLAY_NAME, 133 * Workspace.COMMENT, 134 * Workspace.ACTIVITY_LIST.nest( 135 * Activity.DISPLAY_NAME, 136 * Activity.ACTIVITY_VERSION_LIST.nest( 137 * Version.DISPLAY_NAME, 138 * Version.COMMENT, 139 * Version.CREATION_DATE))); 140 * </pre> 141 * 142 * @param pnl An array of PropertyRequestItem objects that specify the 143 * properties to be requested from the value of the property 144 * identified by this PropertyName. 145 * @return A NestedPropertyName whose root is this PropertyName and 146 * whose nested properties are the property request items given 147 * as arguments. 148 */ 149 public NestedPropertyName<T> nest(PropertyRequestItem... pnl) 150 { 151 return new NestedPropertyName<T>(this, pnl); 152 } 153 154 /** 155 * A convenience method for constructing nested property names from a 156 * NestedPropertyName[] without requiring an explicit cast to 157 * PropertyRequestItem[] 158 * 159 * @param pnl A NestedPropertyName[] that specifies the nested 160 * properties of the NestedPropertyName to be constructed 161 * @return A NestedPropertyName whose root is this PropertyName and 162 * whose nested properties are the elements of the 163 * NestedPropertyNames[] argument. 164 */ 165 public NestedPropertyName<T> nest(NestedPropertyName<?>[] pnl) 166 { 167 return new NestedPropertyName<T>(this, (PropertyRequestItem[])pnl); 168 } 169 170 /** 171 * A convenience method for constructing nested property names from a 172 * PropertyName[] without requiring an explicit cast to 173 * PropertyRequestItem[] 174 * 175 * @param pnl A PropertyName[] that specifies the nested properties of 176 * the NestedPropertyName to be constructed 177 * @return A NestedPropertyName whose root is this PropertyName and 178 * whose nested properties are the elements of the 179 * PropertyNames[] argument. 180 */ 181 public NestedPropertyName<T> nest(PropertyName<?>[] pnl) 182 { 183 return new NestedPropertyName<T>(this, (PropertyRequestItem[])pnl); 184 } 185 } 186 187 // An empty immutable PropertyName[] 188 private static final PropertyName<?>[] EMPTY_PNA = new PropertyName[0]; 189 190 // The immutable array of property names for this PropertyNameList. 191 private final PropertyName<?>[] _propertyNames; 192 193 // The lazy initialized Set for this immutable object. 194 private volatile Set<PropertyName<?>> _asSet = null; 195 196 /** 197 * Construct a PropertyNameList from an array of property names. 198 * 199 * @param propertyNames an array of property names, or null. 200 * Passing null is equivalent to passing an empty array. 201 */ 202 public PropertyNameList(PropertyName<?>... propertyNames) { 203 _propertyNames = (propertyNames == null || propertyNames.length == 0) 204 ? EMPTY_PNA : propertyNames; 205 } 206 207 /** 208 * Get an array of property names from a property name list. 209 * 210 * @return the array of property names maintained by this 211 * PropertyNameList. Will never be <code>null</code>. 212 */ 213 public PropertyName<?>[] getPropertyNames() { 214 return _propertyNames; 215 } 216 217 /** 218 * Indicates whether some other object is "equal to" this one. 219 * 220 * @param o the object to compare with. 221 * @return true if and only if the specified object is a PropertyNameList 222 * whose property names array is equal to the property names array 223 * of this ignoring order. 224 */ 225 @Override 226 public boolean equals(Object o) { 227 if (o == null || this.getClass() != o.getClass()) { 228 return false; 229 } 230 PropertyNameList pnl = (PropertyNameList) o; 231 return getPropertyNamesAsSet().equals(pnl.getPropertyNamesAsSet()); 232 } 233 234 235 /** 236 * Calculate a hash code for a PropertyNameList. 237 * 238 * @return a hash code for the list. 239 */ 240 @Override 241 public int hashCode() { 242 return getPropertyNamesAsSet().hashCode(); 243 } 244 245 /** 246 * Returns a string representation of this PropertyNameList suitable for 247 * diagnostics. 248 * 249 * @return The string representation of this PropertyNameList formatted as 250 * "[<first property name>, <second property name>]" 251 */ 252 @Override 253 public String toString() { 254 255 StringBuffer builder = new StringBuffer(); 256 builder.append('['); 257 258 for(PropertyName<?> name: getPropertyNames()) { 259 if (builder.length() > 1) 260 builder.append(", "); //$NON-NLS-1$ 261 262 builder.append(name.toString()); 263 } 264 265 builder.append(']'); 266 267 return builder.toString(); 268 } 269 270 // the property names maintained by this PropertyNameList as a Set. 271 private Set<PropertyName<?>> getPropertyNamesAsSet() { 272 if (_asSet == null) { 273 if (_propertyNames == EMPTY_PNA) 274 _asSet = Collections.emptySet(); 275 else 276 _asSet = new HashSet<PropertyName<?>>(Arrays.asList(_propertyNames)); 277 } 278 return _asSet; 279 } 280 }