View Javadoc

1   package org.lsst.ccs.config;
2   
3   import org.hibernate.annotations.Immutable;
4   
5   import javax.persistence.*;
6   import java.io.Serializable;
7   import java.util.*;
8   
9   /**
10   * An active subsystem Description.
11   * Can be "unregistered" (id is zero) or "registered" in the database (Id is not zero)
12   * in that case the object is immutable (more precisely only comments can be modified).
13   *
14   * Subsystem name and tag constitute a unique key in the active  table.
15   *
16   * @author bamade
17   */
18  // Date: 10/04/12
19  @Table(name="ASubsystemDescription",
20          uniqueConstraints = {@UniqueConstraint(columnNames={"subsystemName", "tag"})}
21  )
22      @Entity
23      @Immutable
24  class ASubsystemDescription  extends SubsystemDescription implements Cloneable{
25      private static final long serialVersionUID = 7518445583831244327L;
26      @Id
27      @GeneratedValue
28      private long id ; //generated
29      // TODO: a map<Path, XXX> instead
30      /**
31       * the set containing the parameter descriptions
32       */
33      @OneToMany(cascade = CascadeType.ALL, fetch=FetchType.EAGER)
34      protected /*@NonNull*/ Set<AParameterDescription> paramDescriptions =
35              // just in case! not ideal when handled as a bean
36              new HashSet<AParameterDescription>();
37      /**
38       * a unModifiable view of the parameter description set.
39       */
40      @Transient
41      private Set<AParameterDescription> unModifiableParams = Collections.unmodifiableSet(paramDescriptions) ;
42  
43  
44      /////////////////////////////// CONSTRUCTORS
45  
46      /***
47       * for reconstruction tool purposes only
48       */
49      ASubsystemDescription(){
50      }
51  
52      /**
53       * same parameters and constraints as the superclass constructor
54       * @param subsystemName
55       * @param tag
56       * @param user
57       * @param version
58       * @param configurationData
59       * @param dataFlavour
60       */
61      public ASubsystemDescription(String subsystemName, String tag, String user, String version, Serializable configurationData, DataFlavour dataFlavour) {
62          super(subsystemName, tag, user, version, configurationData, dataFlavour);
63      }
64  
65      /**
66       * creates a new SubsystemDescription without information set up by the database (id, startDate)
67       * @param other
68       */
69      public ASubsystemDescription(SubsystemDescription other) {
70          super(other) ;
71          // now fill
72          for(ParameterDescription parmDesc: other.getParamDescriptionSet()) {
73              this.paramDescriptions.add(new AParameterDescription(parmDesc)) ;
74          }
75      }
76  
77  
78      ////////////////////////////// ACCESSORS/MUTATORS
79  
80      //    @Override
81      public long getId() {
82          return id;
83      }
84  
85      @Override
86      void setId(long id) {
87          this.id = id ;
88      }
89  
90      @Override
91      public Set<? extends ParameterDescription> getParamDescriptionSet() {
92          return getParamDescriptions() ;
93      }
94  
95  
96      //@Generated(value = GenerationTime.INSERT)
97      //@Temporal(TemporalType.DATE)
98      @Override
99      public long getStartTimestamp() {
100         return super.getStartTimestamp();
101     }
102 
103 
104     /**
105      *a data in this set is modifiable only if the object is not registered.
106      * Use methods <TT>addParameterDescriptions</TT> and <TT>removeParameterDescriptions</TT>
107      * to modify the set.
108      * @return  an unmodifiable set
109      */
110     public Set<AParameterDescription> getParamDescriptions() {
111         return unModifiableParams ;
112     }
113 
114      void setParamDescriptions(Set<AParameterDescription> paramDescriptions) {
115         this.paramDescriptions = paramDescriptions;
116          unModifiableParams = Collections.unmodifiableSet(paramDescriptions) ;
117     }
118 
119     /**
120      * clone: the contained set of parameter description is also cloned.
121      * (each description is cloned)
122      * @return
123      */
124     public ASubsystemDescription clone() {
125         ASubsystemDescription res = null ;
126         try {
127             res = (ASubsystemDescription) super.clone() ;
128             HashSet<AParameterDescription> newSet = new HashSet<AParameterDescription>() ;
129             for(AParameterDescription description : paramDescriptions) {
130                 newSet.add(description.clone()) ;
131             }
132             res.setParamDescriptions(newSet);
133             //TODO: clone other members?
134         } catch (CloneNotSupportedException e) {/*IGNORE*/ }
135         return res ;
136     }
137 
138 
139 //////////////////////////////
140     ///////////////////// UTILITIES
141 
142     /**
143      * add Parameter descriptions: this is a public facade to the "real" method
144      * that adds only objects of type <TT>AParameterDescription</TT>
145      * So if objects are not ot this actual type new objects of the needed type are created
146      * (see <TT>AParameterDescription</TT> constructor documentation)
147      * @param descriptions
148      */
149     @Override
150     public void addParameterDescriptions(ParameterDescription... descriptions) {
151         addParameterDescriptions(buildSafeArray(descriptions));
152     }
153 
154     @Override
155     public void addParameterDescriptions(Collection<ParameterDescription> descriptions) {
156         for(ParameterDescription parm : descriptions) {
157             if(! (parm instanceof AParameterDescription)) {
158                 this.addParameterDescriptions(new AParameterDescription(parm));
159             } else {
160                 this.addParameterDescriptions((AParameterDescription) parm);
161             }
162         }
163     }
164 
165     private AParameterDescription[] buildSafeArray(ParameterDescription... descriptions){
166         List<ParameterDescription> list = Arrays.asList(descriptions);
167         AParameterDescription[] parms = new AParameterDescription[descriptions.length] ;
168         int ix = 0 ;
169         for(ParameterDescription description: list) {
170             if(! (description instanceof AParameterDescription)){
171                 parms[ix] = new AParameterDescription(description)  ;
172 
173             } else {
174                 parms[ix] = (AParameterDescription) description ;
175             }
176             ix++ ;
177         }
178         return parms ;
179     }
180 
181     /*
182     //works as is dues to equality rules
183     @Override
184     public void removeParameterDescriptions(ParameterDescription... descriptions) {
185         removeParameterDescriptions(buildSafeArray(descriptions));
186     }
187     */
188 
189     /**
190      * adds a list of parameter descriptions
191      * @param descriptions
192      * @throws ImmutableStateException if called on an immutable object
193      */
194     public void addParameterDescriptions(AParameterDescription... descriptions) {
195         if(isReadOnly()) {
196             throw new ImmutableStateException("parameter description list") ;
197         }
198         for(AParameterDescription description : descriptions) {
199             this.paramDescriptions.add(description) ;
200         }
201     }
202     /**
203      * removes a list of parameter descriptions.
204      * <P>
205      *     works with any subclass of parameterDescription (see equals method code)
206      * </P>
207      * @param descriptions
208      * @throws ImmutableStateException if called on an immutable object
209      */
210     public void removeParameterDescriptions(ParameterDescription... descriptions) {
211         if(isReadOnly()) {
212             throw new ImmutableStateException("parameter description list") ;
213         }
214         for(ParameterDescription description : descriptions) {
215             this.paramDescriptions.remove(description) ;
216         }
217     }
218 
219 }