View Javadoc

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 }