View Javadoc

1   package org.lsst.ccs.config;
2   
3   import org.lsst.gruth.jutils.ComponentNode;
4   
5   import javax.persistence.MappedSuperclass;
6   import java.io.PrintWriter;
7   import java.io.Serializable;
8   import java.util.*;
9   
10  /**
11   * This class represents a set of parameter that have been modified for a given subsystem.
12  * <P>
13   *     <B>Important notice</B> : for the moment an active configuration profile has a name and a tag.
14   *     This combination is unique amongst active profile. BUT this is not the case once data of this type
15   *     has been "pushed in history" :
16   *     <UL>
17   *         <LI> in history there are many versions of the same config profile
18   *         <LI> it is not guaranteed that the same config name may be re-used for another subsystem
19   *     </UL>
20   *     So these naming strategies should be re-evaluated after some experimental uses.
21   * @author bamade
22   */
23  // Date: 11/04/12
24  @MappedSuperclass
25  public abstract class ConfigProfile implements Serializable {
26      /**
27       * first time the profile was valid
28       */
29      private long startTimestamp ;//generated
30      /**
31       * valid limit. defaults to eternity except when the object is pushed in history.
32       */
33      private long endTimestamp = PackCst.STILL_VALID ;
34  
35      /**
36       *
37       */
38      private String name ;
39  
40      /**
41       *
42       */
43      private String tag ;
44  
45      /**
46       * the user
47       */
48      private String userName ;
49  
50      //TODO add version
51  
52      // TODO engineering mode use?
53      private boolean beenInEngineeringMode ;
54  
55  
56      /**
57       * the level (defaults to END USER)
58       * see PackCst.
59       */
60      private int level = PackCst.END_USER_LEVEL ;
61  
62      /**
63       * comments
64       */
65      private String remarks ;
66  
67      /**
68       * config with same name and tag: id of previous version
69       */
70      private long previousConfigID ;
71  
72      ///////////////////////////// CONSTRUCTORS
73  
74  
75      protected ConfigProfile() {
76      }
77  
78      protected ConfigProfile(String name, String tag, String userName, int level) {
79          this.name = name ;
80          this.tag = tag ;
81          this.userName = userName;
82          this.level = level;
83      }
84      //TODO :copy constructor
85  
86      /////////////////////////// ACCESSORS/MUTATORS
87      protected abstract long getId() ;
88      protected abstract void setId(long id) ;
89  
90      public abstract SubsystemDescription getSubsystemDescription() ;
91  
92      public abstract Set<? extends ParameterConfiguration> getModifiedParameters() ;
93  
94      public abstract void temporaryChangeConfigurationValue(ParameterConfiguration parameter, long time, String value) ;
95  
96      //TODO make it abstract because we need to create one
97      public  abstract ParameterConfiguration temporaryChangeConfigurationValue(String  parameterPath, long time, String value)  ;
98          /*
99          // build path obejct
100         ParameterPath path = ParameterPath.valueOf(parameterPath) ;
101         // fetch the ParameterConfiguration
102         ParameterConfiguration parameter = this.fetch(path) ;
103         //TODO if null create a new one and put it in engineering mode
104         if(parameter == null) return null ;
105         //calls the other method
106         temporaryChangeConfigurationValue(parameter, time, value);
107         return parameter ;
108     }
109     */
110 
111 
112     public boolean isReadOnly() {
113         return getId() != 0L ;
114     }
115 
116     public boolean isBeenInEngineeringMode() {
117         return beenInEngineeringMode;
118     }
119 
120     void setBeenInEngineeringMode(boolean beenInEngineeringMode) {
121         this.beenInEngineeringMode = beenInEngineeringMode;
122     }
123 
124     public String getName() {
125         return name;
126     }
127 
128     void setName(String name) {
129         this.name = name;
130     }
131 
132 
133     public String getSubsystemName() {
134         return getSubsystemDescription().getSubsystemName() ;
135     }
136 
137     public String getTag() {
138         return tag;
139     }
140 
141     void setTag(String tag) {
142         this.tag = tag;
143     }
144 
145 
146     public long getStartTimestamp() {
147         return startTimestamp;
148     }
149 
150     protected void setStartTimestamp(long startTimestamp) {
151         this.startTimestamp = startTimestamp;
152     }
153 
154     public long getEndTimestamp() {
155         return endTimestamp;
156     }
157 
158     void setEndTimestamp(long endTimestamp) {
159         this.endTimestamp = endTimestamp;
160     }
161 
162     public String getUserName() {
163         return userName;
164     }
165 
166     void setUserName(String userName) {
167         this.userName = userName;
168     }
169 
170     public int getLevel() {
171         return level;
172     }
173 
174      void setLevel(int level) {
175         this.level = level;
176     }
177 
178     public String getRemarks() {
179         return remarks;
180     }
181 
182     /**
183      * no influence on behaviour.
184      * @param remarks
185      */
186     public  void setRemarks(String remarks) {
187         this.remarks = remarks;
188     }
189 
190     /**
191      * may return the id of a previous ConfigProfile (0L if none)
192      * @return
193      */
194     public long getPreviousConfigID() {
195         return previousConfigID;
196     }
197 
198     void setPreviousConfigID(long previousConfigID) {
199         this.previousConfigID = previousConfigID;
200     }
201 
202     //////////////////////////// IDENT METHODS
203 
204     @Override
205     public boolean equals(Object o) {
206         if (this == o) return true;
207         if (!(o instanceof ConfigProfile)) return false;
208 
209         ConfigProfile that = (ConfigProfile) o;
210         if (getId() != that.getId()) return false;
211         if (!getName().equals(that.getName())) return false;
212         String tag = getTag() ;
213         if (tag != null ? !tag.equals(that.getTag()) : that.getTag() != null) return false;
214 
215         return true;
216     }
217 
218     @Override
219     public int hashCode() {
220         long id = getId() ;
221         int result = (int) (id ^ (id >>> 32));
222         result = 31 * result + getName().hashCode();
223         String tag = getTag() ;
224         result = 31 * result + (tag != null ? tag.hashCode() : 0);
225         return result;
226     }
227     @Override
228     public String toString() {
229         return "{" +
230                 "id=" + getId() +
231                 ";configurations=" + this.getModifiedParameters() +
232                 '}';
233     }
234 
235     /////////////////////////// OTHER METHODS
236     public ParameterConfiguration fetch(PathObject path) {
237         for(ParameterConfiguration config: this.getModifiedParameters()) {
238             if(config.getPath().equals(path.getPath())) {
239                 return config ;
240             }
241         }
242         return null ;
243     }
244 
245     /**
246      * prints to a property file a template that represents this ConfigProfile
247      * @param printer
248      */
249     public void generateConfigProperties(PrintWriter printer) {
250         List<ParameterConfiguration> list = new ArrayList<ParameterConfiguration>(this.getModifiedParameters());
251         Collections.sort(list, PathObject.COMPARATOR);
252         for(ParameterConfiguration config: list) {
253             boolean commentOut = false ;
254             if(config.getValue().equals(config.getDescription().getDefaultValue())) {
255                 commentOut=  true ;
256             }
257             printer.println(config.getDescription().toPropertyString(config.getValue(), commentOut));
258         }
259     }
260 
261     /**
262      * populates this configProfile with values extracted from a Properties object.
263      * @param props
264      * @throws IllegalArgumentException if this profile is read only or if a value is illegal
265      *
266      */
267     public abstract  void mergeProperties(Properties props) ;
268 
269     /**
270      * registers a list of parameter configurations
271      * @param parameterConfigurations
272      * @throws ImmutableStateException if the object is already registered in database
273      * @throws IllegalArgumentException if levels are incompatibles
274      * @throws IllegalArgumentException if the corresponding parameter descriptions are not alive in the current
275      * subsystem description
276      */
277     // TODO: check if Description not deprecated!
278     public abstract void    addParameterConfigurations(ParameterConfiguration... parameterConfigurations) ;
279 
280     /**
281      * removes a list of parameter configurations
282      * @param parameterConfigurations
283      * @throws ImmutableStateException if operated on an object registered to the database
284      */
285     public abstract void removeParameterConfigurations(ParameterConfiguration... parameterConfigurations) ;
286 
287     /**
288      * prepares a new executable configuration data with these modified parameters.
289      * used by <TT>PreparedConfiguration</TT> objects.
290      * @return
291      */
292     public abstract ComponentNode getModifiedConfigurationData() ;
293 
294     /**
295      * gives the value of a given parameter at a given date on a ConfigProfile object.
296      * beware : the main goal of this method is to fetch a transient parameter set during
297      * an engineering mode session. Otherwise it just returns the value of the parameter
298      * without any time stamp check (it is supposed that the <TT>ConfigProfile</TT> object
299      * was the one active at this date.
300      * <P>
301      * @param parameterPath
302      * @param date
303      * @return
304      */
305     public  String getValueAt( String parameterPath, long date) {
306         //???? if (this == null) return null;
307         if (parameterPath == null) return null;
308         ParameterPath path = ParameterPath.valueOf(parameterPath);
309         ParameterConfiguration parmConfig = this.fetch(path);
310         if (parmConfig == null) { // look if subsystem parameter default value
311             SubsystemDescription subsystemDescription = this.getSubsystemDescription();
312             ParameterDescription description = subsystemDescription.fetch(path);
313             if (description != null) {
314                 return description.getParameterBase().getDefaultValue();
315             }
316             return null;
317         }
318         if (this.isBeenInEngineeringMode()) {
319             List<? extends ValueEvent> eventList = parmConfig.getValueEvents();
320             if (eventList == null) {
321                 return parmConfig.value;
322             }
323             //TODO: what to do with this values?
324             long begin = this.getStartTimestamp();
325             long end = this.getEndTimestamp();
326             String lastValue = parmConfig.value;
327             for (ValueEvent event : eventList) {
328                 if (event.getTime() > date) {
329                     return lastValue;
330                 }
331                 lastValue = event.getValue();
332             }
333             return null; // should NOT HAPPEN TODO: put assertion here
334         } else {
335             return parmConfig.value;
336         }
337     }
338 
339 
340 
341 }