1 /*
2
3 dsh-codegen Source code generation suite.
4 Copyright (c) 2004-2011 held jointly by the individual authors.
5
6 This library is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published
8 by the Free Software Foundation; either version 3 of the License, or (at
9 your option) any later version.
10
11 This library is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with this library; if not, write to the Free Software Foundation,
18 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
19
20 > http://www.fsf.org/licensing/licenses/lgpl.html
21 > http://www.opensource.org/licenses/lgpl-license.php
22
23 */
24 package org.dishevelled.codegen;
25
26 import java.util.Set;
27 import java.util.LinkedHashSet;
28 import java.util.Collections;
29
30 /**
31 * A description of the attributes and associations for an interface.
32 *
33 * @author Michael Heuer
34 * @version $Revision: 993 $ $Date: 2011-02-25 14:18:11 -0600 (Fri, 25 Feb 2011) $
35 */
36 public final class InterfaceDescription
37 {
38 /** License for this interface description. */
39 private String license;
40
41 /** Package name for this interface description. */
42 private String packageName;
43
44 /** Lowercase name for this interface description. */
45 private String lower;
46
47 /** Mixed-case name for this interface description. */
48 private String mixed;
49
50 /** Uppercase name for this interface description. */
51 private String upper;
52
53 /** Author for this interface description. */
54 private String author;
55
56 /** Version for this interface description. */
57 private String version;
58
59 /** Description for this interface description. */
60 private String description;
61
62 /** Set of interfaces this interface description specializes. */
63 private final Set<InterfaceDescription> specializes;
64
65 /** Set of attributes for this interface description. */
66 private final Set<Attribute> attributes;
67
68 /** Set of associations for this interface description. */
69 private final Set<Association> associations;
70
71
72 /**
73 * Create a new interface description with the specified package name
74 * and name.
75 *
76 * @param packageName package name for this interface description
77 * @param name name of this interface description
78 */
79 public InterfaceDescription(final String packageName, final String name)
80 {
81 this.packageName = packageName;
82 this.lower = CodegenUtils.makeLowercase(name);
83 this.mixed = CodegenUtils.makeMixedCase(name);
84 this.upper = CodegenUtils.makeUppercase(name);
85 this.description = CodegenUtils.makeSentenceCaseDescription(name);
86 this.author = "codegen";
87 this.version = "$" + "Revision$ $" + "Date$"; // split to prevent svn expansion
88 this.specializes = new LinkedHashSet<InterfaceDescription>();
89 this.attributes = new LinkedHashSet<Attribute>();
90 this.associations = new LinkedHashSet<Association>();
91 }
92
93 /**
94 * Create a new interface description with the specified package name
95 * and name.
96 *
97 * @param license license for this interface description
98 * @param packageName package name for this interface description
99 * @param name name of this interface description
100 */
101 public InterfaceDescription(final String license, final String packageName, final String name)
102 {
103 this.license = license;
104 this.packageName = packageName;
105 this.lower = CodegenUtils.makeLowercase(name);
106 this.mixed = CodegenUtils.makeMixedCase(name);
107 this.upper = CodegenUtils.makeUppercase(name);
108 this.description = CodegenUtils.makeSentenceCaseDescription(name);
109 this.author = "codegen";
110 this.version = "$" + "Revision$ $" + "Date$"; // split to prevent svn expansion
111 this.specializes = new LinkedHashSet<InterfaceDescription>();
112 this.attributes = new LinkedHashSet<Attribute>();
113 this.associations = new LinkedHashSet<Association>();
114 }
115
116 /**
117 * Create a new interface description from the specified parameters.
118 *
119 * @param packageName package name for this interface description
120 * @param name uppercase name for this interface description
121 * @param author author for this interface description
122 * @param version version for this interface description
123 * @param description description for this interface description
124 */
125 public InterfaceDescription(final String packageName, final String name,
126 final String author, final String version, final String description)
127 {
128 this.packageName = packageName;
129 this.lower = CodegenUtils.makeLowercase(name);
130 this.mixed = CodegenUtils.makeMixedCase(name);
131 this.upper = CodegenUtils.makeUppercase(name);
132 this.author = author;
133 this.version = version;
134 this.description = CodegenUtils.makeSentenceCaseDescription(name) + ".";
135 this.specializes = new LinkedHashSet<InterfaceDescription>();
136 this.attributes = new LinkedHashSet<Attribute>();
137 this.associations = new LinkedHashSet<Association>();
138 }
139
140 /**
141 * Create a new interface description from the specified parameters.
142 *
143 * @param packageName package name for this interface description
144 * @param lower lowercase name for this interface description
145 * @param mixed mixed-case name for this interface description
146 * @param upper uppercase name for this interface description
147 * @param author author for this interface description
148 * @param version version for this interface description
149 * @param description description for this interface description
150 */
151 public InterfaceDescription(final String packageName, final String lower, final String mixed, final String upper,
152 final String author, final String version, final String description)
153 {
154 this.packageName = packageName;
155 this.lower = lower;
156 this.mixed = mixed;
157 this.upper = upper;
158 this.author = author;
159 this.version = version;
160 this.description = description;
161 this.specializes = new LinkedHashSet<InterfaceDescription>();
162 this.attributes = new LinkedHashSet<Attribute>();
163 this.associations = new LinkedHashSet<Association>();
164 }
165
166 /**
167 * Create a new interface description from the specified parameters.
168 *
169 * <p>The interfaces this interface description specializes in <code>specializes</code> are copied defensively
170 * into this class.</p>
171 *
172 * <p>The attributes in <code>attributes</code> are copied defensively
173 * into this class.</p>
174 *
175 * <p>The associations in <code>associations</code> are copied defensively
176 * into this class.</p>
177 *
178 * @param packageName package name for this interface description
179 * @param lower lowercase name for this interface description
180 * @param mixed mixed-case name for this interface description
181 * @param upper uppercase name for this interface description
182 * @param author author for this interface description
183 * @param version version for this interface description
184 * @param description description for this interface description
185 * @param specializes set of interfaces this interface description specializes, must not be null
186 * @param attributes set of attributes, must not be null
187 * @param associations set of associations, must not be null
188 */
189 public InterfaceDescription(final String packageName,
190 final String lower,
191 final String mixed,
192 final String upper,
193 final String author,
194 final String version,
195 final String description,
196 final Set<InterfaceDescription> specializes,
197 final Set<Attribute> attributes,
198 final Set<Association> associations)
199 {
200 this.packageName = packageName;
201 this.lower = lower;
202 this.mixed = mixed;
203 this.upper = upper;
204 this.author = author;
205 this.version = version;
206 this.description = description;
207
208 this.specializes = new LinkedHashSet<InterfaceDescription>(specializes.size());
209 this.specializes.addAll(specializes);
210
211 this.attributes = new LinkedHashSet<Attribute>(attributes.size());
212 this.attributes.addAll(attributes);
213
214 this.associations = new LinkedHashSet<Association>(associations.size());
215 this.associations.addAll(associations);
216 }
217
218
219 /**
220 * Return the license for this interface description.
221 *
222 * @return the license for this interface description
223 */
224 public String getLicense()
225 {
226 return license;
227 }
228
229 /**
230 * Return the package name for this interface description.
231 *
232 * @return the package name for this interface description
233 */
234 public String getPackageName()
235 {
236 return packageName;
237 }
238
239 /**
240 * Return the lowercase name for this interface description.
241 *
242 * @return the lowercase name for this interface description
243 */
244 public String getLower()
245 {
246 return lower;
247 }
248
249 /**
250 * Return the mixed-case name for this interface description.
251 *
252 * @return the mixed-case name for this interface description
253 */
254 public String getMixed()
255 {
256 return mixed;
257 }
258
259 /**
260 * Return the uppercase name for this interface description.
261 *
262 * @return the uppercase name for this interface description
263 */
264 public String getUpper()
265 {
266 return upper;
267 }
268
269 /**
270 * Return the author for this interface description.
271 *
272 * @return the author for this interface description
273 */
274 public String getAuthor()
275 {
276 return author;
277 }
278
279 /**
280 * Return the version for this interface description.
281 *
282 * @return the version for this interface description
283 */
284 public String getVersion()
285 {
286 return version;
287 }
288
289 /**
290 * Return the description for this interface description.
291 *
292 * @return the description for this interface description
293 */
294 public String getDescription()
295 {
296 return description;
297 }
298
299 /**
300 * Return an unmodifiable set of interfaces this interface description specializes.
301 *
302 * @return an unmodifiable set of interfaces this interface description specializes
303 */
304 public Set<InterfaceDescription> getSpecializes()
305 {
306 return Collections.unmodifiableSet(specializes);
307 }
308
309 /**
310 * Add the specified interface description to the set of interfaces this interface
311 * description specializes. Return <code>true</code> if the set of interfaces this
312 * interface description specializes changed as a result of this call.
313 *
314 * @param specializes interface description to add, must not be null
315 * @return <code>true</code> if the set of interfaces this interface description specializes
316 * changed as a result of this call
317 */
318 public boolean addSpecializes(final InterfaceDescription specializes)
319 {
320 if (specializes == null)
321 {
322 throw new IllegalArgumentException("specializes must not be null");
323 }
324 if (this.specializes.contains(specializes))
325 {
326 return false;
327 }
328 boolean rv = this.specializes.add(specializes);
329
330 if (rv)
331 {
332 for (Attribute a : specializes.getAttributes())
333 {
334 addAttribute(a);
335 }
336 for (Association a : specializes.getAssociations())
337 {
338 addAssociation(a);
339 }
340 }
341 return rv;
342 }
343
344 /**
345 * Add the specified interface description to the set of interfaces this interface
346 * description specializes. Return <code>true</code> if the set of interfaces this
347 * interface description specializes changed as a result of this call.
348 *
349 * @param specializes interface description to add, must not be null
350 * @return <code>true</code> if the set of interfaces this interface description specializes
351 * changed as a result of this call
352 */
353 public boolean specializes(final InterfaceDescription specializes)
354 {
355 return addSpecializes(specializes);
356 }
357
358 /**
359 * Return an unmodifiable set of attributes for this interface description.
360 *
361 * @return an unmodifiable set of attributes for this interface description
362 */
363 public Set<Attribute> getAttributes()
364 {
365 return Collections.unmodifiableSet(attributes);
366 }
367
368 /**
369 * Add the specified attribute to the set of attributes
370 * for this interface description. Return <code>true</code> if the set
371 * of attributes changed as a result of this call.
372 *
373 * @param attribute attribute to add, must not be null
374 * @return <code>true</code> if the set of attributes
375 * changed as a result of this call
376 */
377 public boolean addAttribute(final Attribute attribute)
378 {
379 if (attribute == null)
380 {
381 throw new IllegalArgumentException("attribute must not be null");
382 }
383 return attributes.add(attribute);
384 }
385
386 /**
387 * Add the specified attribute to the set of attributes
388 * for this interface description. Return <code>true</code> if the set
389 * of attributes changed as a result of this call.
390 *
391 * @param attribute attribute to add, must not be null
392 * @return <code>true</code> if the set of attributes
393 * changed as a result of this call
394 */
395 public boolean attribute(final Attribute attribute)
396 {
397 return addAttribute(attribute);
398 }
399
400 /**
401 * Add a new attribute to the set of attributes for this
402 * interface description with the specified name, role name,
403 * and cardinality. The cardinality must be one of <b>Cardinality.ZeroToOne</b>
404 * or <b>Cardinality.StrictlyOne</b>. Return <code>true</code> if
405 * the set of attributes changed as a result of this call.
406 *
407 * @param name attribute name
408 * @param roleName role name
409 * @param cardinality cardinality, must not be null and must be
410 * one of <b>Cardinality.ZeroToOne</b> or <b>Cardinality.StrictlyOne</b>
411 * @return <code>true</code> if the set of attributes
412 * changed as a result of this call
413 */
414 public boolean attribute(final String name, final String roleName, final Cardinality cardinality)
415 {
416 Attribute a = new Attribute(name, roleName, cardinality);
417 return addAttribute(a);
418 }
419
420 /**
421 * Add a new attribute to the set of attributes for this
422 * interface description with the specified parameters.
423 * Return <code>true</code> if the set of attributes changed as
424 * a result of this call.
425 *
426 * @param name attribute name
427 * @param roleName role name
428 * @param cardinality cardinality, must not be null
429 * @param indexed true if the collection should be indexed
430 * @param unique true if the collection should not allow duplicate elements
431 * @param ordered true if the collection should iterate over elements in <i>insertion-order</i>
432 * @param sorted true if the collection should iterate over elements in ascending element order,
433 * sorted according to the <i>natural ordering</i> of its elements (see Comparable), or by a Comparator
434 * provided at creation time
435 * @return <code>true</code> if the set of attributes
436 * changed as a result of this call
437 */
438 public boolean attribute(final String name, final String roleName, final Cardinality cardinality,
439 final boolean indexed, final boolean unique, final boolean ordered, final boolean sorted)
440 {
441 Attribute a = new Attribute(name, roleName, cardinality, indexed, unique, ordered, sorted);
442 return addAttribute(a);
443 }
444
445 /**
446 * Return an unmodifiable set of associations for this interface description.
447 *
448 * @return an unmodifiable set of associations for this interface description
449 */
450 public Set<Association> getAssociations()
451 {
452 return Collections.unmodifiableSet(associations);
453 }
454
455 /**
456 * Add the specified association to the set of associations
457 * for this interface description. Return <code>true</code> if the set
458 * of associations changed as a result of this call.
459 *
460 * @param association association to add, must not be null
461 * @return <code>true</code> if the set of associations
462 * changed as a result of this call
463 */
464 public boolean addAssociation(final Association association)
465 {
466 if (association == null)
467 {
468 throw new IllegalArgumentException("association must not be null");
469 }
470 return associations.add(association);
471 }
472
473 /**
474 * Add the specified association to the set of associations
475 * for this interface description. Return <code>true</code> if the set
476 * of associations changed as a result of this call.
477 *
478 * @param association association to add, must not be null
479 * @return <code>true</code> if the set of associations
480 * changed as a result of this call
481 */
482 public boolean associate(final Association association)
483 {
484 return addAssociation(association);
485 }
486
487 /**
488 * Add a new association to the set of associations for this
489 * interface description to the specified class with the
490 * specified cardinality. The assocation's role name will be
491 * the same as the class' name. The cardinality must be one of
492 * <b>Cardinality.ZeroToOne</b> or <b>Cardinality.StrictlyOne</b>.
493 * Return <code>true</code> if the set of associations changed as a result of
494 * this call.
495 *
496 * @param cd class description, must not be null
497 * @param cardinality cardinality, must not be null and must be
498 * one of <b>Cardinality.ZeroToOne</b> or <b>Cardinality.StrictlyOne</b>
499 * @return <code>true</code> if the set of associations
500 * changed as a result of this call
501 */
502 public boolean associate(final ClassDescription cd, final Cardinality cardinality)
503 {
504 Association a = new Association(cd, cd.getUpper(), cardinality);
505 return addAssociation(a);
506 }
507
508 /**
509 * Add a new association to the set of attributes for this
510 * interface description to the specified class with the
511 * specified role name and cardinality. The cardinality must be one of
512 * <b>Cardinality.ZeroToOne</b> or <b>Cardinality.StrictlyOne</b>.
513 * Return <code>true</code> if the set of associations changed as a result of
514 * this call.
515 *
516 * @param cd class description, must not be null
517 * @param roleName role name
518 * @param cardinality cardinality, must not be null and must be
519 * one of <b>Cardinality.ZeroToOne</b> or <b>Cardinality.StrictlyOne</b>
520 * @return <code>true</code> if the set of associations
521 * changed as a result of this call
522 */
523 public boolean associate(final ClassDescription cd, final String roleName, final Cardinality cardinality)
524 {
525 Association a = new Association(cd, roleName, cardinality);
526 return addAssociation(a);
527 }
528
529 /**
530 * Add a new association to the set of associations for this
531 * interface description to the specified class with the specified
532 * parameters. The association's role name will be the same as
533 * the class' name.
534 *
535 * @param cd class description, must not be null
536 * @param cardinality cardinality, must not be null
537 * @param indexed true if the collection should be indexed
538 * @param unique true if the collection should not allow duplicate elements
539 * @param ordered true if the collection should iterate over elements in <i>insertion-order</i>
540 * @param sorted true if the collection should iterate over elements in ascending element order,
541 * sorted according to the <i>natural ordering</i> of its elements (see Comparable), or by a Comparator
542 * provided at creation time
543 * @return <code>true</code> if the set of associations
544 * changed as a result of this call
545 */
546 public boolean associate(final ClassDescription cd, final Cardinality cardinality,
547 final boolean indexed, final boolean unique, final boolean ordered, final boolean sorted)
548 {
549 Association a = new Association(cd, cd.getUpper(), cardinality, indexed, unique, ordered, sorted);
550 return addAssociation(a);
551 }
552
553 /**
554 * Add a new association to the set of associations for this
555 * interface description to the specified class with the specified
556 * parameters.
557 *
558 * @param cd class description, must not be null
559 * @param roleName role name
560 * @param cardinality cardinality, must not be null
561 * @param indexed true if the collection should be indexed
562 * @param unique true if the collection should not allow duplicate elements
563 * @param ordered true if the collection should iterate over elements in <i>insertion-order</i>
564 * @param sorted true if the collection should iterate over elements in ascending element order,
565 * sorted according to the <i>natural ordering</i> of its elements (see Comparable), or by a Comparator
566 * provided at creation time
567 * @return <code>true</code> if the set of associations
568 * changed as a result of this call
569 */
570 public boolean associate(final ClassDescription cd, final String roleName, final Cardinality cardinality,
571 final boolean indexed, final boolean unique, final boolean ordered, final boolean sorted)
572 {
573 Association a = new Association(cd, roleName, cardinality, indexed, unique, ordered, sorted);
574 return addAssociation(a);
575 }
576
577 /**
578 * Add a new association to the set of associations for this
579 * interface description to the specified interface with the
580 * specified cardinality. The assocation's role name will be
581 * the same as the interface's name. The cardinality must be one of
582 * <b>Cardinality.ZeroToOne</b> or <b>Cardinality.StrictlyOne</b>.
583 * Return <code>true</code> if the set of associations changed as a result of
584 * this call.
585 *
586 * @param id interface description, must not be null
587 * @param cardinality cardinality, must not be null and must be
588 * one of <b>Cardinality.ZeroToOne</b> or <b>Cardinality.StrictlyOne</b>
589 * @return <code>true</code> if the set of associations
590 * changed as a result of this call
591 */
592 public boolean associate(final InterfaceDescription id, final Cardinality cardinality)
593 {
594 Association a = new Association(id, id.getUpper(), cardinality);
595 return addAssociation(a);
596 }
597
598
599 /**
600 * Add a new association to the set of attributes for this
601 * interface description to the specified interface with the
602 * specified role name and cardinality. The cardinality must be one of
603 * <b>Cardinality.ZeroToOne</b> or <b>Cardinality.StrictlyOne</b>.
604 * Return <code>true</code> if the set of associations changed as a result of
605 * this call.
606 *
607 * @param id interface description, must not be null
608 * @param roleName role name
609 * @param cardinality cardinality, must not be null and must be
610 * one of <b>Cardinality.ZeroToOne</b> or <b>Cardinality.StrictlyOne</b>
611 * @return <code>true</code> if the set of associations
612 * changed as a result of this call
613 */
614 public boolean associate(final InterfaceDescription id, final String roleName, final Cardinality cardinality)
615 {
616 Association a = new Association(id, roleName, cardinality);
617 return addAssociation(a);
618 }
619
620 /**
621 * Add a new association to the set of associations for this
622 * interface description to the specified interface with the specified
623 * parameters. The association's role name will be the same as
624 * the interface's name.
625 *
626 * @param id interface description, must not be null
627 * @param cardinality cardinality, must not be null
628 * @param indexed true if the collection should be indexed
629 * @param unique true if the collection should not allow duplicate elements
630 * @param ordered true if the collection should iterate over elements in <i>insertion-order</i>
631 * @param sorted true if the collection should iterate over elements in ascending element order,
632 * sorted according to the <i>natural ordering</i> of its elements (see Comparable), or by a Comparator
633 * provided at creation time
634 * @return <code>true</code> if the set of associations
635 * changed as a result of this call
636 */
637 public boolean associate(final InterfaceDescription id, final Cardinality cardinality,
638 final boolean indexed, final boolean unique, final boolean ordered, final boolean sorted)
639 {
640 Association a = new Association(id, id.getUpper(), cardinality, indexed, unique, ordered, sorted);
641 return addAssociation(a);
642 }
643
644 /**
645 * Add a new association to the set of associations for this
646 * interface description to the specified interface with the specified
647 * parameters.
648 *
649 * @param id interface description, must not be null
650 * @param roleName role name
651 * @param cardinality cardinality, must not be null
652 * @param indexed true if the collection should be indexed
653 * @param unique true if the collection should not allow duplicate elements
654 * @param ordered true if the collection should iterate over elements in <i>insertion-order</i>
655 * @param sorted true if the collection should iterate over elements in ascending element order,
656 * sorted according to the <i>natural ordering</i> of its elements (see Comparable), or by a Comparator
657 * provided at creation time
658 * @return <code>true</code> if the set of associations
659 * changed as a result of this call
660 */
661 public boolean associate(final InterfaceDescription id, final String roleName, final Cardinality cardinality,
662 final boolean indexed, final boolean unique, final boolean ordered, final boolean sorted)
663 {
664 Association a = new Association(id, roleName, cardinality, indexed, unique, ordered, sorted);
665 return addAssociation(a);
666 }
667 }