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.Arg; 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 this.propertySet = Arg.checkNotBlankExceptNull("propertySet", propertySet); 90 this.name = Arg.checkNotBlank("name", name); 91 } 92 93 // ****************************** Inner Classes ***************************** 94 95 // ********************************* Methods ******************************** 96 97 // --- init ----------------------------------------------------------------- 98 99 /** 100 * Creates an instance for the given qualified name. 101 * <p> 102 * The qualified name consists of two part that are separated by a 'at' ( 103 * <code>@</code>) sign. The first part is the name of the property set, the 104 * second part the name of the property. 105 * </p> 106 * {@example my-set@my.property.name} 107 * <p> 108 * The last 'at' sign is significant for the separation. That is, the property 109 * set name may contain any number of 'at' signs. An 'at' sign at the end of 110 * the qualified name is ignored. 111 * </p> 112 * 113 * @param qualifiedName a name optionally prefixed with a property set name 114 * separated by a 'at' (<code>@</code>) sign. 115 * @return the created instance. 116 */ 117 public static PropertyKey create(final String qualifiedName) 118 { 119 return create(qualifiedName, '@'); 120 } 121 122 /** 123 * Creates an instance for the given qualified name. 124 * 125 * @param qualifiedName a name optionally prefixed with a property set name 126 * separated by the last occurrence (excluding the very end) of the 127 * {@code separator}. 128 * @param separator the separator to use if for some reason the default is not 129 * appropriate. 130 * @return the created instance. 131 * @throws BlankArgumentException if {@code qualifiedName} is blank. 132 */ 133 public static PropertyKey create(final String qualifiedName, 134 final char separator) throws BlankArgumentException 135 { 136 Arg.checkNotBlank("qualifiedName", qualifiedName); 137 138 final int dotIndex = qualifiedName.lastIndexOf(separator); 139 if (dotIndex > 0 && dotIndex < qualifiedName.length() - 1) 140 { 141 final String propertySetName = qualifiedName.substring(0, dotIndex); 142 final String name = qualifiedName.substring(dotIndex + 1); 143 return new PropertyKey(propertySetName, name); 144 } 145 else 146 { 147 return new PropertyKey(null, qualifiedName); 148 } 149 } 150 151 /** 152 * Creates an instance for the given set and name. 153 * 154 * @param propertySet the name of the set the property belongs to. 155 * @param name the name of the property. 156 * @return the created instance. 157 * @throws IllegalArgumentException if {@code propertySet} is blank but not 158 * <code>null</code> or if {@code name} is blank. 159 */ 160 public static PropertyKey create(final String propertySet, final String name) 161 throws IllegalArgumentException 162 { 163 return new PropertyKey(propertySet, name); 164 } 165 166 // --- get&set -------------------------------------------------------------- 167 168 /** 169 * Returns the name of the set the property belongs to. This is the scope 170 * within the {@link #getName() name} is unique. It may be <code>null</code> 171 * (which indicates that the scope is global), but is must not be blank. 172 * 173 * @return the name of the set the property belongs to. 174 */ 175 public String getPropertySet() 176 { 177 return propertySet; 178 } 179 180 /** 181 * Returns the name of the property. 182 * <p> 183 * This value must not be <code>null</code>. 184 * </p> 185 * 186 * @return the name of the property. 187 */ 188 public String getName() 189 { 190 return name; 191 } 192 193 // --- business ------------------------------------------------------------- 194 195 // --- object basics -------------------------------------------------------- 196 197 @Override 198 public int compareTo(final PropertyKey o) 199 { 200 int result = ObjectUtils.compare(propertySet, o.propertySet); 201 if (result == 0) 202 { 203 result = name.compareTo(o.name); 204 } 205 return result; 206 } 207 208 @Override 209 public int hashCode() 210 { 211 int result = 17; 212 result = 37 * result + ObjectUtils.hashCode(propertySet); 213 result = 37 * result + name.hashCode(); 214 return result; 215 } 216 217 @Override 218 public boolean equals(final Object object) 219 { 220 if (this == object) 221 { 222 return true; 223 } 224 else if (object == null || getClass() != object.getClass()) 225 { 226 return false; 227 } 228 229 final PropertyKey other = (PropertyKey) object; 230 231 return ObjectUtils.equals(propertySet, other.propertySet) 232 && name.equals(other.name); 233 } 234 235 /** 236 * Returns the string representation of the object. 237 * 238 * @return the string representation of the object. 239 */ 240 @Override 241 public String toString() 242 { 243 final StringBuilder buffer = new StringBuilder(); 244 245 if (propertySet != null) 246 { 247 buffer.append(propertySet).append('.'); 248 } 249 buffer.append(name); 250 251 return buffer.toString(); 252 } 253 }