View Javadoc

1   /*
2    *  Copyright 2001-2013 Stephen Colebourne
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 org.joda.beans.gen;
17  
18  import java.util.ArrayList;
19  import java.util.Arrays;
20  import java.util.HashSet;
21  import java.util.List;
22  import java.util.Set;
23  
24  import org.joda.beans.PropertyReadWrite;
25  
26  /**
27   * A bean that can be generated.
28   * 
29   * @author Stephen Colebourne
30   */
31  class GeneratableProperty {
32  
33      /** Collection types. */
34      private static final Set<String> COLLECTIONS = new HashSet<String>(
35              Arrays.asList(
36                      "Collection", "Set", "SortedSet", "NavigableSet", "List",
37                      "ArrayList", "LinkedList",
38                      "HashSet", "LinkedHashSet", "TreeSet", "ConcurrentSkipListSet"));
39      /** Map types. */
40      private static final Set<String> MAPS = new HashSet<String>(
41              Arrays.asList(
42                      "Map", "SortedMap", "NavigableMap", "ConcurrentMap", "ConcurrentNavigableMap",
43                      "HashMap", "LinkedHashMap", "TreeMap", "ConcurrentHashMap", "ConcurrentSkipListMap"));
44  
45      /** Owning bean. */
46      private final GeneratableBean bean;
47      /** Property name. */
48      private String propertyName;
49      /** Field name. */
50      private String fieldName;
51      /** Upper property name. */
52      private String upperName;
53      /** Property type. */
54      private String type;
55      /** Whether the field is declared final. */
56      private boolean isFinal;
57      /** The getter style. */
58      private String getStyle;
59      /** The setter style. */
60      private String setStyle;
61      /** The validation string. */
62      private String validation;
63      /** Deprecated flag. */
64      private boolean deprecated;
65      /** First comment about the property. */
66      private String firstComment;
67      /** Other comments about the property. */
68      private final List<String> comments = new ArrayList<String>();
69  
70      /**
71       * Constructor.
72       */
73      GeneratableProperty(GeneratableBean bean) {
74          this.bean = bean;
75      }
76  
77      //-----------------------------------------------------------------------
78      /**
79       * Gets the bean.
80       * @return the bean, not null
81       */
82      public GeneratableBean getBean() {
83          return bean;
84      }
85  
86      /**
87       * Gets the property name.
88       * @return the property name
89       */
90      public String getPropertyName() {
91          return propertyName;
92      }
93  
94      /**
95       * Sets the property name.
96       * @param propertyName  the property name to set
97       */
98      public void setPropertyName(String propertyName) {
99          this.propertyName = propertyName;
100     }
101 
102     /**
103      * Gets the field name.
104      * @return the field name
105      */
106     public String getFieldName() {
107         return fieldName;
108     }
109 
110     /**
111      * Sets the field name.
112      * @param fieldName  the field name to set
113      */
114     public void setFieldName(String fieldName) {
115         this.fieldName = fieldName;
116     }
117 
118     /**
119      * Gets the upper property name.
120      * @return the upper name
121      */
122     public String getUpperName() {
123         return upperName;
124     }
125 
126     /**
127      * Sets the upper property name.
128      * @param upperName  the upper name to set
129      */
130     public void setUpperName(String upperName) {
131         this.upperName = upperName;
132     }
133 
134     /**
135      * Gets the type.
136      * @return the type
137      */
138     public String getType() {
139         return type;
140     }
141 
142     /**
143      * Sets the type.
144      * @param type  the type to set
145      */
146     public void setType(String type) {
147         this.type = type;
148     }
149 
150     /**
151      * Gets whether the field is declared final.
152      * @return the type
153      */
154     public boolean isFinal() {
155         return isFinal;
156     }
157 
158     /**
159      * Sets whether the field is declared final.
160      * @param type  the field is final flag
161      */
162     public void setFinal(boolean isFinal) {
163         this.isFinal = isFinal;
164     }
165 
166     /**
167      * Gets the getter style.
168      * @return the getter style
169      */
170     public String getGetStyle() {
171         return getStyle;
172     }
173 
174     /**
175      * Sets the getter style.
176      * @param getStyle  the getter style to set
177      */
178     public void setGetStyle(String getStyle) {
179         this.getStyle = getStyle;
180     }
181 
182     /**
183      * Gets the setter style.
184      * @return the setter style
185      */
186     public String getSetStyle() {
187         return setStyle;
188     }
189 
190     /**
191      * Sets the setter style.
192      * @param setStyle  the setter style to set
193      */
194     public void setSetStyle(String setStyle) {
195         this.setStyle = setStyle;
196     }
197 
198     /**
199      * Gets the validation.
200      * @return the validation
201      */
202     public String getValidation() {
203         return validation;
204     }
205 
206     /**
207      * Sets the validation.
208      * @param validation  the validation to set
209      */
210     public void setValidation(String validation) {
211         this.validation = validation;
212     }
213 
214     /**
215      * Checks if the property is deprecated.
216      * @return the deprecated flag
217      */
218     public boolean isDeprecated() {
219         return deprecated;
220     }
221 
222     /**
223      * Sets if the property is deprecated.
224      * @param deprecated  the deprecated to set
225      */
226     public void setDeprecated(boolean deprecated) {
227         this.deprecated = deprecated;
228     }
229 
230     /**
231      * Gets the first comment line.
232      * @return the first comment
233      */
234     public String getFirstComment() {
235         return firstComment;
236     }
237 
238     /**
239      * Sets the first comment line.
240      * @param firstComment  the first comment to set
241      */
242     public void setFirstComment(String firstComment) {
243         this.firstComment = firstComment;
244     }
245 
246     /**
247      * Gets the remaining comments.
248      * @return the remaining comments, not null
249      */
250     public List<String> getComments() {
251         return comments;
252     }
253 
254     //-----------------------------------------------------------------------
255     /**
256      * Checks if the property is parameterised with generics.
257      * @return true if generified
258      */
259     public boolean isGenericParamType() {
260         return type.indexOf("<") >= 0;
261     }
262 
263     /**
264      * Checks if the property is parameterised with generics.
265      * @return true if generified
266      */
267     public boolean isGenericWildcardParamType() {
268         return type.endsWith("<?>");
269     }
270 
271     /**
272      * Gets the parameterisation of the property.
273      * @return the generic type, or a blank string if not generic, not null
274      */
275     public String getGenericParamType() {
276         int pos = type.indexOf("<");
277         if (pos < 0) {
278             return "";
279         }
280         return type.substring(pos + 1, type.length() - 1);
281     }
282 
283     /**
284      * Gets the raw type of the property without generics.
285      * @return the raw type, not null
286      */
287     public String getRawType() {
288         int pos = type.indexOf("<");
289         return (pos < 0 ? type : type.substring(0, pos));
290     }
291 
292     /**
293      * Checks if the type is the generic type of the bean.
294      * For example, if the property is of type T in a bean of Foo[T].
295      * @return true if matches
296      */
297     public boolean isBeanGenericType() {
298         return type.equals(bean.getTypeGenericName(false));
299     }
300 
301     /**
302      * Checks if the property is generic in some way.
303      * @return true if generic
304      */
305     public boolean isGeneric() {
306         return isGenericParamType() || isBeanGenericType();
307     }
308 
309     /**
310      * Checks if the property is derived.
311      * @return true if derived
312      */
313     public boolean isDerived() {
314         return fieldName == null;
315     }
316 
317     //-----------------------------------------------------------------------
318     /**
319      * Checks if this property is a known collection type.
320      * 
321      * @return true if it is a known collection type
322      */
323     public boolean isCollectionType() {
324         return isGeneric() && COLLECTIONS.contains(getRawType());
325     }
326 
327     /**
328      * Checks if this property is a known map type.
329      * 
330      * @return true if it is a known map type
331      */
332     public boolean isMapType() {
333         return "FlexiBean".equals(getType()) || (isGeneric() && MAPS.contains(getRawType()));
334     }
335 
336     /**
337      * Gets the read-write flag.
338      * 
339      * @return the read write
340      */
341     public PropertyReadWrite getReadWrite() {
342         SetterGen generator = SetterGen.of(this);
343         if (getGetStyle().length() > 0 && getSetStyle().length() > 0 && (generator.isSetterGenerated(this) || getSetStyle().equals("manual"))) {
344             return PropertyReadWrite.READ_WRITE;
345         }
346         if (getGetStyle().length() > 0) {
347             return PropertyReadWrite.READ_ONLY;
348         }
349         if (getSetStyle().length() > 0) {
350             return PropertyReadWrite.WRITE_ONLY;
351         }
352         throw new RuntimeException("Property must have a getter or setter: " + propertyName);
353     }
354 
355     //-----------------------------------------------------------------------
356     /**
357      * Checks if the validation is non-null.
358      * @return true if non-null
359      */
360     public boolean isValidated() {
361         return getValidation() != null && getValidation().length() > 0;
362     }
363 
364     /**
365      * Checks if the validation is non-null.
366      * @return true if non-null
367      */
368     public boolean isNotNull() {
369         return getValidation().equals("notNull") || getValidation().equals("notEmpty");
370     }
371 
372     /**
373      * Gets the validation method name.
374      * @return the method name
375      */
376     public String getValidationMethodName() {
377         if (isValidated() == false) {
378             throw new IllegalStateException();
379         }
380         if (getValidation().equals("notNull") || getValidation().equals("notEmpty")) {
381             return "JodaBeanUtils." + getValidation();
382         }
383         return getValidation();  // method in bean or static
384     }
385 
386 }