View Javadoc

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