View Javadoc

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 }