View Javadoc
1   package de.fhdw.wtf.common.ast;
2   
3   import java.util.Collection;
4   import java.util.Collections;
5   import java.util.Iterator;
6   
7   import de.fhdw.wtf.common.ast.type.Type;
8   import de.fhdw.wtf.common.ast.visitor.AttributeModifierVisitorReturn;
9   import de.fhdw.wtf.common.constants.parser.AstDescriptionConstants;
10  import de.fhdw.wtf.common.token.Token;
11  
12  /**
13   * 
14   * This class represents an attribute of a class. It is held by a ClassType, can contain multiple
15   * {@link AttributeModifier} and must contain a {@link Type}, which determines whether this attribute is a list or a
16   * single value.
17   */
18  public final class Attribute extends SyntaxObject {
19  	
20  	/**
21  	 * generated.
22  	 */
23  	private static final long serialVersionUID = 1438824751069001192L;
24  	
25  	/**
26  	 * The name of the attribute.
27  	 */
28  	private final String name;
29  	
30  	/**
31  	 * The type of the attribute.
32  	 */
33  	private final Type attrType;
34  	
35  	/**
36  	 * The modifiers of the attribute.
37  	 */
38  	private final Collection<AttributeModifier> modifiers;
39  	
40  	/**
41  	 * Holds the database type id, if available.
42  	 */
43  	private DatabaseIDState attributeId;
44  	
45  	/**
46  	 * Private Constructor of {@link Attribute}.
47  	 * 
48  	 * @param name
49  	 *            The name of the attribute.
50  	 * @param attrType
51  	 *            The type of the attribute.
52  	 * @param modifiers
53  	 *            The modifiers of the attribute.
54  	 * @param firstToken
55  	 *            firstToken
56  	 * @param lastToken
57  	 *            lastToken
58  	 */
59  	private Attribute(final String name,
60  			final Type attrType,
61  			final Collection<AttributeModifier> modifiers,
62  			final Token firstToken,
63  			final Token lastToken) {
64  		super(firstToken, lastToken);
65  		this.name = name;
66  		this.modifiers = modifiers;
67  		this.attrType = attrType;
68  		this.setAttributeId(new DatabaseIDNotSetState());
69  	}
70  	
71  	/**
72  	 * Creates a {@link Attribute}-Object.
73  	 * 
74  	 * @param name
75  	 *            The name of the attribute.
76  	 * @param attrType
77  	 *            The type of the attribute.
78  	 * @param modifiers
79  	 *            The modifiers of the attribute.
80  	 * @param firstToken
81  	 *            firstToken
82  	 * @param lastToken
83  	 *            lastToken
84  	 * @return The Attribute-Object.
85  	 */
86  	public static Attribute create(final String name,
87  			final Type attrType,
88  			final Collection<AttributeModifier> modifiers,
89  			final Token firstToken,
90  			final Token lastToken) {
91  		return new Attribute(name, attrType, modifiers, firstToken, lastToken);
92  	}
93  	
94  	/**
95  	 * Creates a {@link Attribute}-Object.
96  	 * 
97  	 * @param name
98  	 *            The name of the attribute.
99  	 * @param attrType
100 	 *            The type of the attribute.
101 	 * @param modifiers
102 	 *            The modifiers of the attribute.
103 	 * @param firstToken
104 	 *            firstToken
105 	 * @return The Attribute-Object.
106 	 */
107 	public static Attribute create(final String name,
108 			final Type attrType,
109 			final Collection<AttributeModifier> modifiers,
110 			final Token firstToken) {
111 		return new Attribute(name, attrType, modifiers, firstToken, null);
112 	}
113 	
114 	/**
115 	 * Returns true if <code>this</code> is a findable attribute. False otherwise.
116 	 * 
117 	 * @return boolean.
118 	 */
119 	public boolean isFindable() {
120 		final AttributeModifierVisitorReturn<Boolean> visitor = new AttributeModifierVisitorReturn<Boolean>() {
121 			@Override
122 			public Boolean handle(final AttributeModifierFindable modFindable) {
123 				return true;
124 			}
125 			
126 			@Override
127 			public Boolean handle(final AttributeModifierPrior modPrior) {
128 				return false;
129 			}
130 			
131 			@Override
132 			public Boolean handle(final AttributeModifierTransient modTransient) {
133 				return false;
134 			}
135 			
136 			@Override
137 			public Boolean handle(final AttributeModifierMutable modMutable) {
138 				return false;
139 			}
140 			
141 			@Override
142 			public Boolean handle(final AttributeModifierSymmetric modSymmetric) {
143 				return false;
144 			}
145 		};
146 		return this.processModifierVisitor(visitor);
147 	}
148 	
149 	/**
150 	 * Returns true if <code>this</code> is a prior attribute. False otherwise.
151 	 * 
152 	 * @return boolean.
153 	 */
154 	public boolean isPrior() {
155 		final AttributeModifierVisitorReturn<Boolean> visitor = new AttributeModifierVisitorReturn<Boolean>() {
156 			@Override
157 			public Boolean handle(final AttributeModifierFindable modFindable) {
158 				return false;
159 			}
160 			
161 			@Override
162 			public Boolean handle(final AttributeModifierPrior modPrior) {
163 				return true;
164 			}
165 			
166 			@Override
167 			public Boolean handle(final AttributeModifierTransient modTransient) {
168 				return false;
169 			}
170 			
171 			@Override
172 			public Boolean handle(final AttributeModifierMutable modMutable) {
173 				return false;
174 			}
175 			
176 			@Override
177 			public Boolean handle(final AttributeModifierSymmetric modSymmetric) {
178 				return false;
179 			}
180 		};
181 		return this.processModifierVisitor(visitor);
182 	}
183 	
184 	/**
185 	 * Returns true if <code>this</code> is a transient attribute. False otherwise.
186 	 * 
187 	 * @return boolean.
188 	 */
189 	public boolean isTransient() {
190 		final AttributeModifierVisitorReturn<Boolean> visitor = new AttributeModifierVisitorReturn<Boolean>() {
191 			@Override
192 			public Boolean handle(final AttributeModifierFindable modFindable) {
193 				return false;
194 			}
195 			
196 			@Override
197 			public Boolean handle(final AttributeModifierPrior modPrior) {
198 				return false;
199 			}
200 			
201 			@Override
202 			public Boolean handle(final AttributeModifierTransient modTransient) {
203 				return true;
204 			}
205 			
206 			@Override
207 			public Boolean handle(final AttributeModifierMutable modMutable) {
208 				return false;
209 			}
210 			
211 			@Override
212 			public Boolean handle(final AttributeModifierSymmetric modSymmetric) {
213 				return false;
214 			}
215 		};
216 		return this.processModifierVisitor(visitor);
217 	}
218 	
219 	/**
220 	 * Returns true if <code>this</code> is a mutable attribute. False otherwise.
221 	 * 
222 	 * @return boolean.
223 	 */
224 	public boolean isMutable() {
225 		final AttributeModifierVisitorReturn<Boolean> visitor = new AttributeModifierVisitorReturn<Boolean>() {
226 			@Override
227 			public Boolean handle(final AttributeModifierFindable modFindable) {
228 				return false;
229 			}
230 			
231 			@Override
232 			public Boolean handle(final AttributeModifierPrior modPrior) {
233 				return false;
234 			}
235 			
236 			@Override
237 			public Boolean handle(final AttributeModifierTransient modTransient) {
238 				return false;
239 			}
240 			
241 			@Override
242 			public Boolean handle(final AttributeModifierMutable modMutable) {
243 				return true;
244 			}
245 			
246 			@Override
247 			public Boolean handle(final AttributeModifierSymmetric modSymmetric) {
248 				return false;
249 			}
250 		};
251 		return this.processModifierVisitor(visitor);
252 	}
253 	
254 	/**
255 	 * Returns true if <code>this</code> is a symmetric attribute. False otherwise.
256 	 * 
257 	 * @return boolean.
258 	 */
259 	public boolean isSymmetric() {
260 		final AttributeModifierVisitorReturn<Boolean> visitor = new AttributeModifierVisitorReturn<Boolean>() {
261 			@Override
262 			public Boolean handle(final AttributeModifierFindable modFindable) {
263 				return false;
264 			}
265 			
266 			@Override
267 			public Boolean handle(final AttributeModifierPrior modPrior) {
268 				return false;
269 			}
270 			
271 			@Override
272 			public Boolean handle(final AttributeModifierTransient modTransient) {
273 				return false;
274 			}
275 			
276 			@Override
277 			public Boolean handle(final AttributeModifierMutable modMutable) {
278 				return false;
279 			}
280 			
281 			@Override
282 			public Boolean handle(final AttributeModifierSymmetric modSymmetric) {
283 				return true;
284 			}
285 		};
286 		return this.processModifierVisitor(visitor);
287 	}
288 	
289 	/**
290 	 * Processes a Returnvisitor with Return-Type Boolean and returns the result.
291 	 * 
292 	 * @param visitor
293 	 *            visitor.
294 	 * @return boolean.
295 	 */
296 	private boolean processModifierVisitor(final AttributeModifierVisitorReturn<Boolean> visitor) {
297 		for (final AttributeModifier current : this.getModifiers()) {
298 			if (current.accept(visitor)) {
299 				return true;
300 			}
301 		}
302 		return false;
303 	}
304 	
305 	/**
306 	 * @return the name
307 	 */
308 	public String getName() {
309 		return this.name;
310 	}
311 	
312 	/**
313 	 * @return the AttributeType
314 	 */
315 	public Type getAttrType() {
316 		return this.attrType;
317 	}
318 	
319 	/**
320 	 * Returns the local collection of {@link AttributeModifier}. The list can't be modified.
321 	 * 
322 	 * @return the modifiers
323 	 */
324 	public Collection<AttributeModifier> getModifiers() {
325 		return Collections.unmodifiableCollection(this.modifiers);
326 	}
327 	
328 	@Override
329 	public boolean equals(final Object o) {
330 		if (o instanceof Attribute) {
331 			boolean result = true;
332 			final Attribute other = (Attribute) o;
333 			
334 			result =
335 					result && this.getName().equals(other.getName()) && this.getAttrType().equals(other.getAttrType())
336 							&& this.getModifiers().size() == other.getModifiers().size();
337 			if (result) {
338 				final AttributeModifier[] thisModifier =
339 						this.getModifiers().toArray(new AttributeModifier[this.getModifiers().size()]);
340 				final AttributeModifier[] otherModifier =
341 						other.getModifiers().toArray(new AttributeModifier[other.getModifiers().size()]);
342 				for (int i = 0; i < this.getModifiers().size(); i++) {
343 					result = result && thisModifier[i].equals(otherModifier[i]);
344 				}
345 				return result;
346 			}
347 		}
348 		return false;
349 	}
350 	
351 	@Override
352 	public int hashCode() {
353 		int result = this.getName().hashCode() ^ this.getAttrType().hashCode();
354 		for (final AttributeModifier modifier : this.getModifiers()) {
355 			result ^= modifier.hashCode();
356 		}
357 		return result;
358 	}
359 	
360 	@Override
361 	public String toString() {
362 		final StringBuilder result = new StringBuilder();
363 		result.append(this.getName()).append(AstDescriptionConstants.COLON_TOKEN).append(this.getAttrType().toString());
364 		if (!this.getModifiers().isEmpty()) {
365 			final Iterator<AttributeModifier> i = this.getModifiers().iterator();
366 			while (i.hasNext()) {
367 				final AttributeModifier current = i.next();
368 				result.append(' ').append(current.toString());
369 			}
370 		}
371 		result.append(AstDescriptionConstants.SEMICOLON_TOKEN);
372 		return result.toString();
373 	}
374 	
375 	/**
376 	 * Returns the DatabaseIDState of this.
377 	 * 
378 	 * @return DatabaseIDState
379 	 */
380 	public DatabaseIDState getAttributeId() {
381 		return this.attributeId;
382 	}
383 	
384 	/**
385 	 * Set the DatabaseIDState of this.
386 	 * 
387 	 * @param attributeId
388 	 *            DatabaseIDState
389 	 */
390 	public void setAttributeId(final DatabaseIDState attributeId) {
391 		this.attributeId = attributeId;
392 	}
393 	
394 }