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.List;
20 import java.util.SortedSet;
21 import java.util.TreeSet;
22
23 /**
24 * A bean that can be generated.
25 *
26 * @author Stephen Colebourne
27 */
28 class GeneratableBean {
29
30 /** The list of current imports. */
31 private final SortedSet<String> currentImports = new TreeSet<String>();
32 /** The list of new imports. */
33 private final SortedSet<String> newImports = new TreeSet<String>();
34 /** The last import line. */
35 private int lastImportLine;
36 /** The flag as to whether the class can be constructed. */
37 private boolean constructable;
38 /** The full type of the bean class. */
39 private String typeFull;
40 /** The simple name of the bean class. */
41 private String typeRaw;
42 /** The name clause of the generic. */
43 private String typeGenericName;
44 /** The extends clause of the generic. */
45 private String typeGenericExtends;
46 /** The full name of the bean superclass. */
47 private String superTypeFull;
48 /** The simple name of the bean superclass. */
49 private String superTypeRaw;
50 /** The generic argument of the bean superclass. */
51 private String superTypeGeneric;
52 /** The list of properties, in the order they are declared. */
53 private List<GeneratableProperty> properties = new ArrayList<GeneratableProperty>();
54 /** Does the class have a manual equals or hash code. */
55 private boolean manualEqualsHashCode;
56
57 /**
58 * Constructor.
59 */
60 GeneratableBean() {
61 }
62
63 /**
64 * Gets the current set of imports.
65 * @return the imports
66 */
67 public SortedSet<String> getCurrentImports() {
68 return currentImports;
69 }
70
71 /**
72 * Gets the new imports.
73 * @return the imports
74 */
75 public SortedSet<String> getNewImports() {
76 return newImports;
77 }
78
79 /**
80 * Ensures an import is present.
81 * @param cls the class, not null
82 */
83 public void ensureImport(Class<?> cls) {
84 if (currentImports.contains(cls.getName()) == false) {
85 newImports.add(cls.getName());
86 }
87 }
88
89 /**
90 * Gets the import insert location.
91 * @return the insert location
92 */
93 public int getImportInsertLocation() {
94 return lastImportLine;
95 }
96
97 /**
98 * Sets the import insert location.
99 * @param location the insert location
100 */
101 public void setImportInsertLocation(int location) {
102 lastImportLine = location;
103 }
104
105 /**
106 * Sets whether the bean can be constructed.
107 * @return the flag
108 */
109 public boolean isConstructable() {
110 return constructable;
111 }
112
113 /**
114 * Sets whether the bean can be constructed.
115 * @param constructable the flag
116 */
117 public void setConstructable(boolean constructable) {
118 this.constructable = constructable;
119 }
120
121 /**
122 * Checks if the equals/hashCode is manual.
123 * @return true if manual
124 */
125 public boolean isManualEqualsHashCode() {
126 return manualEqualsHashCode;
127 }
128
129 /**
130 * Sets if the equals/hashCode is manual.
131 * @param manualEqualsHashCode true if manual
132 */
133 public void setManualEqualsHashCode(boolean manualEqualsHashCode) {
134 this.manualEqualsHashCode = manualEqualsHashCode;
135 }
136
137 /**
138 * Sets the bean type.
139 * @param parts the type to set
140 */
141 public void setTypeParts(String[] parts) {
142 this.typeFull = parts[0];
143 this.typeRaw = parts[1];
144 this.typeGenericName = parts[2] != null ? parts[2] : "";
145 this.typeGenericExtends = parts[3] != null ? parts[3] : "";
146 }
147
148 /**
149 * Sets the bean superclass type.
150 * @param parts the superclass to set
151 */
152 public void setSuperTypeParts(String[] parts) {
153 this.superTypeFull = parts[0];
154 this.superTypeRaw = parts[1];
155 this.superTypeGeneric = parts[2] != null ? parts[2] : "";
156 }
157
158 /**
159 * Gets the modifiable list of properties.
160 * @return the properties, not null
161 */
162 public List<GeneratableProperty> getProperties() {
163 return properties;
164 }
165
166 //-----------------------------------------------------------------------
167 /**
168 * Checks if this bean has a bean superclass.
169 * @param true if this is a subclass of another bean
170 */
171 public boolean isSubclass() {
172 return superTypeFull.equals("DirectBean") == false;
173 }
174
175 //-----------------------------------------------------------------------
176 /**
177 * Checks if the bean is parameterised with generics.
178 * @return true if generified
179 */
180 public boolean isTypeGeneric() {
181 return typeGenericName.length() > 0;
182 }
183
184 /**
185 * Gets the bean type, such as {@code Foo<T extends Bar>}
186 * @return the type
187 */
188 public String getType() {
189 return typeFull;
190 }
191
192 /**
193 * Gets the parameterisation of the bean including extends clause, such as {@code <T extends Bar>}
194 * @param includeBrackets whether to include the brackets
195 * @return the generic type, or a blank string if not generic, not null
196 */
197 public String getTypeGeneric(boolean includeBrackets) {
198 String result = typeGenericName + typeGenericExtends;
199 return includeBrackets && result.length() > 0 ? '<' + result + '>' : result;
200 }
201
202 /**
203 * Gets the name of the parameterisation of the bean, such as {@code T}
204 * @param includeBrackets whether to include the brackets
205 * @return the generic type name, or a blank string if not generic, not null
206 */
207 public String getTypeGenericName(boolean includeBrackets) {
208 return includeBrackets && typeGenericName.length() > 0 ? '<' + typeGenericName + '>' : typeGenericName;
209 }
210
211 /**
212 * Gets the extends clause of the parameterisation of the bean, such as {@code extends Foo}
213 * @return the generic type extends clause, or a blank string if not generic or no extends, not null
214 */
215 public String getTypeGenericExtends() {
216 return typeGenericExtends;
217 }
218
219 /**
220 * Gets the extends clause of the parameterisation of the bean, such as {@code Foo<T>}
221 * @return the generic type extends clause, or a blank string if not generic or no extends, not null
222 */
223 public String getTypeNoExtends() {
224 return typeFull.replace(typeGenericExtends, "");
225 }
226
227 /**
228 * Gets the raw type of the bean without generics.
229 * @return the raw type, not null
230 */
231 public String getTypeRaw() {
232 return typeRaw;
233 }
234
235 /**
236 * Gets the wildcarded type.
237 * @return the wildcarded type, not null
238 */
239 public String getTypeWildcard() {
240 return typeRaw + (isTypeGeneric() ? "<?>" : "");
241 }
242
243 //-----------------------------------------------------------------------
244 /**
245 * Checks if the super bean is parameterised with generics.
246 * @return true if generified
247 */
248 public boolean isSuperTypeGeneric() {
249 return superTypeGeneric.length() > 0;
250 }
251
252 /**
253 * Gets the bean superclass type.
254 * @return the superclass
255 */
256 public String getSuperType() {
257 return superTypeFull;
258 }
259
260 /**
261 * Gets the parameterisation of the super bean.
262 * @param includeBrackets whether to include the brackets
263 * @return the generic type, or a blank string if not generic, not null
264 */
265 public String getSuperTypeGeneric(boolean includeBrackets) {
266 return includeBrackets && superTypeGeneric.length() > 0 ? '<' + superTypeGeneric + '>' : superTypeGeneric;
267 }
268
269 /**
270 * Gets the raw type of the super bean without generics.
271 * @return the raw type, not null
272 */
273 public String getSuperTypeRaw() {
274 return superTypeRaw;
275 }
276
277 /**
278 * Checks if any property is validated.
279 * @return true if validated
280 */
281 public boolean isValidated() {
282 for (GeneratableProperty property : properties) {
283 if (property.isValidated()) {
284 return true;
285 }
286 }
287 return false;
288 }
289
290 }