1 /* 2 * Copyright 2012-2013 smartics, Kronseder & Reiner GmbH 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package de.smartics.properties.api.core.domain; 17 18 import java.io.Serializable; 19 20 import org.apache.commons.lang.ObjectUtils; 21 22 import de.smartics.util.lang.Arguments; 23 import de.smartics.util.lang.BlankArgumentException; 24 25 /** 26 * Defines a property key information. A property key uniquely identifies a 27 * property. It contains a name that is scoped by the name of the property set. 28 * That is, the name is only unique within its property set. To create the fully 29 * qualified property key, call {@link #toString()}. 30 */ 31 public final class PropertyKey implements Serializable, Comparable<PropertyKey> 32 { 33 // ********************************* Fields ********************************* 34 35 // --- constants ------------------------------------------------------------ 36 37 /** 38 * The class version identifier. 39 */ 40 private static final long serialVersionUID = 1L; 41 42 // --- members -------------------------------------------------------------- 43 44 /** 45 * The name of the set the property belongs to. This is the scope within the 46 * {@link #getName() name} is unique. It may be <code>null</code> (which 47 * indicates that the scope is global), but is must not be blank. 48 * 49 * @serial 50 */ 51 private final String propertySet; 52 53 /** 54 * The name of the property. 55 * <p> 56 * This value must not be blank. 57 * </p> 58 * 59 * @serial 60 */ 61 private final String name; 62 63 // ****************************** Initializer ******************************* 64 65 // ****************************** Constructors ****************************** 66 67 /** 68 * Convenience constructor without a property set name. 69 * 70 * @param name the name of the property. 71 * @throws IllegalArgumentException if {@code name} is blank. 72 */ 73 public PropertyKey(final String name) throws IllegalArgumentException 74 { 75 this(null, name); 76 } 77 78 /** 79 * Default constructor. 80 * 81 * @param propertySet the name of the set the property belongs to. 82 * @param name the name of the property. 83 * @throws IllegalArgumentException if {@code propertySet} is blank but not 84 * <code>null</code> or if {@code name} is blank. 85 */ 86 public PropertyKey(final String propertySet, final String name) 87 throws IllegalArgumentException 88 { 89 Arguments.checkNotBlankExceptNull("propertySet", propertySet); 90 Arguments.checkNotBlank("name", name); 91 92 this.propertySet = propertySet; 93 this.name = name; 94 } 95 96 // ****************************** Inner Classes ***************************** 97 98 // ********************************* Methods ******************************** 99 100 // --- init ----------------------------------------------------------------- 101 102 /** 103 * Creates an instance for the given qualified name. 104 * <p> 105 * The qualified name consists of two part that are separated by a 'at' ( 106 * <code>@</code>) sign. The first part is the name of the property set, the 107 * second part the name of the property. 108 * </p> 109 * {@example my-set@my.property.name} 110 * <p> 111 * The last 'at' sign is significant for the separation. That is, the property 112 * set name may contain any number of 'at' signs. An 'at' sign at the end of 113 * the qualified name is ignored. 114 * </p> 115 * 116 * @param qualifiedName a name optionally prefixed with a property set name 117 * separated by a 'at' (<code>@</code>) sign. 118 * @return the created instance. 119 */ 120 public static PropertyKey create(final String qualifiedName) 121 { 122 return create(qualifiedName, '@'); 123 } 124 125 /** 126 * Creates an instance for the given qualified name. 127 * 128 * @param qualifiedName a name optionally prefixed with a property set name 129 * separated by the last occurrence (excluding the very end) of the 130 * {@code separator}. 131 * @param separator the separator to use if for some reason the default is not 132 * appropriate. 133 * @return the created instance. 134 * @throws BlankArgumentException if {@code qualifiedName} is blank. 135 */ 136 public static PropertyKey create(final String qualifiedName, 137 final char separator) throws BlankArgumentException 138 { 139 Arguments.checkNotBlank("qualifiedName", qualifiedName); 140 141 final int dotIndex = qualifiedName.lastIndexOf(separator); 142 if (dotIndex > 0 && dotIndex < qualifiedName.length() - 1) 143 { 144 final String propertySetName = qualifiedName.substring(0, dotIndex); 145 final String name = qualifiedName.substring(dotIndex + 1); 146 return new PropertyKey(propertySetName, name); 147 } 148 else 149 { 150 return new PropertyKey(null, qualifiedName); 151 } 152 } 153 154 /** 155 * Creates an instance for the given set and name. 156 * 157 * @param propertySet the name of the set the property belongs to. 158 * @param name the name of the property. 159 * @return the created instance. 160 * @throws IllegalArgumentException if {@code propertySet} is blank but not 161 * <code>null</code> or if {@code name} is blank. 162 */ 163 public static PropertyKey create(final String propertySet, final String name) 164 throws IllegalArgumentException 165 { 166 return new PropertyKey(propertySet, name); 167 } 168 169 // --- get&set -------------------------------------------------------------- 170 171 /** 172 * Returns the name of the set the property belongs to. This is the scope 173 * within the {@link #getName() name} is unique. It may be <code>null</code> 174 * (which indicates that the scope is global), but is must not be blank. 175 * 176 * @return the name of the set the property belongs to. 177 */ 178 public String getPropertySet() 179 { 180 return propertySet; 181 } 182 183 /** 184 * Returns the name of the property. 185 * <p> 186 * This value must not be <code>null</code>. 187 * </p> 188 * 189 * @return the name of the property. 190 */ 191 public String getName() 192 { 193 return name; 194 } 195 196 // --- business ------------------------------------------------------------- 197 198 // --- object basics -------------------------------------------------------- 199 200 @Override 201 public int compareTo(final PropertyKey o) 202 { 203 int result = ObjectUtils.compare(propertySet, o.propertySet); 204 if (result == 0) 205 { 206 result = name.compareTo(o.name); 207 } 208 return result; 209 } 210 211 @Override 212 public int hashCode() 213 { 214 int result = 17; 215 result = 37 * result + ObjectUtils.hashCode(propertySet); 216 result = 37 * result + name.hashCode(); 217 return result; 218 } 219 220 @Override 221 public boolean equals(final Object object) 222 { 223 if (this == object) 224 { 225 return true; 226 } 227 else if (object == null || getClass() != object.getClass()) 228 { 229 return false; 230 } 231 232 final PropertyKey other = (PropertyKey) object; 233 234 return ObjectUtils.equals(propertySet, other.propertySet) 235 && name.equals(other.name); 236 } 237 238 /** 239 * Returns the string representation of the object. 240 * 241 * @return the string representation of the object. 242 */ 243 @Override 244 public String toString() 245 { 246 final StringBuilder buffer = new StringBuilder(); 247 248 if (propertySet != null) 249 { 250 buffer.append(propertySet).append('.'); 251 } 252 buffer.append(name); 253 254 return buffer.toString(); 255 } 256 }