View Javadoc

1   // Copyright 2006-2007, by the California Institute of Technology.
2   // ALL RIGHTS RESERVED. United States Government Sponsorship acknowledged.
3   // Any commercial use must be negotiated with the Office of Technology Transfer
4   // at the California Institute of Technology.
5   //
6   // This software is subject to U. S. export control laws and regulations
7   // (22 C.F.R. 120-130 and 15 C.F.R. 730-774). To the extent that the software
8   // is subject to U.S. export control laws and regulations, the recipient has
9   // the responsibility to obtain export licenses or other export authority as
10  // may be required before exporting such information to foreign countries or
11  // providing access to foreign nationals.
12  //
13  // $Id: Dictionary.java 2897 2007-09-27 12:49:43Z pramirez $ 
14  //
15  
16  package gov.nasa.pds.tools.dict;
17  
18  import gov.nasa.pds.tools.label.validate.Status;
19  
20  import java.util.ArrayList;
21  import java.util.Collection;
22  import java.util.HashMap;
23  import java.util.Iterator;
24  import java.util.List;
25  import java.util.Map;
26  
27  /***
28   * This class represents a PDS data dictionary. 
29   * @author pramirez
30   * @version $Revision: 2897 $
31   * 
32   */
33  public class Dictionary implements Status {
34      private Map definitions;
35      private Map aliases;
36      private String information;
37      private Map units;
38      private List unitList;
39      private String status;
40      
41      public Dictionary() {
42          definitions = new HashMap();
43          aliases = new HashMap();
44          units = new HashMap();
45          unitList = new ArrayList();
46          information = "";
47          status = Status.UNKNOWN;
48      }
49      
50      /***
51       * Merges dictionary without overwriting
52       * @param dictionary to be merged
53       */
54      public void merge(Dictionary dictionary) {
55          merge(dictionary, false);
56      }
57      
58      /***
59       * Merges the definitions in the dictionaries
60       * @param dictionary to be merged
61       * @param overwrite flag
62       */
63      public void merge(Dictionary dictionary, boolean overwrite) {
64          if (overwrite) {
65              definitions.putAll(dictionary.definitions);
66              aliases.putAll(dictionary.aliases);
67          } else {
68              Map d = new HashMap(dictionary.definitions);
69              d.putAll(definitions);
70              definitions = d;
71              Map a = new HashMap(dictionary.aliases);
72              a.putAll(aliases);
73              aliases = a;
74          }
75      }
76      
77      /***
78       * Tests to see whether or not a definition exists
79       * @param identifier of the definition
80       * @return flag indicating existence
81       */
82      public boolean containsDefinition(String identifier) {
83          if (definitions.containsKey(identifier) || aliases.containsKey(identifier))
84              return true;
85          return false;
86      }
87      
88      /***
89       * Tests to see whether or not an object is defined
90       * @param identifier of the object
91       * @return flag indicating existence
92       */
93      public boolean containsObjectDefinition(String identifier) {
94          Definition definition = (Definition) definitions.get(identifier);
95          if (definition == null)
96              definition = (Definition) aliases.get(identifier);
97          if (definition != null && definition instanceof ObjectDefinition)
98              return true;
99          return false;
100     }
101     
102     /***
103      * Tests to see whether or not a group is defined 
104      * @param identifier of the the group
105      * @return flag indicating existence
106      */
107     public boolean containsGroupDefinition(String identifier) {
108         Definition definition = (Definition) definitions.get(identifier);
109         if (definition == null)
110             definition = (Definition) aliases.get(identifier);
111         if (definition != null && definition instanceof GroupDefinition)
112             return true;
113         return false;
114     }
115     
116     /***
117      * Tests to see whether or not an element is defined
118      * @param identifier of the element
119      * @return flag indicating existence
120      */
121     public boolean containsElementDefinition(String identifier) {
122         return containsElementDefinition(null, identifier);
123     }
124     
125     public boolean containsElementDefinition(String objectContext, String identifier) {
126         Definition definition = null;
127         
128         if (objectContext != null) {
129             definition = (Definition) aliases.get(objectContext + "." + identifier);
130             if (definition != null && definition instanceof ElementDefinition)
131                 return true;
132         }
133         
134         definition = (Definition) definitions.get(identifier);
135         if (definition != null && definition instanceof ElementDefinition)
136             return true;
137         
138         return false;
139     }
140     
141     /***
142      * Retrieves the definition from the dictionary or null if not found
143      * @param identifier of the definition
144      * @return the definition
145      */
146     public Definition getDefinition(String identifier) {
147         Definition definition = (Definition) definitions.get(identifier);
148         if (definition == null)
149             definition = (Definition) aliases.get(identifier);
150         return definition;
151     }
152     
153     /***
154      * Retrieves the object definition from the dictionary or null if not found
155      * @param identifier of the definition
156      * @return the object definition
157      */
158     public ObjectDefinition getObjectDefinition(String identifier) {
159         Definition definition = (Definition) definitions.get(identifier);
160         if (definition == null)
161             definition = (Definition) aliases.get(identifier);
162         if (definition != null && definition instanceof ObjectDefinition)
163             return (ObjectDefinition) definition;
164         return null;
165     }
166     
167     /***
168      * Retrieves the group definition from the dictionary or null if not found
169      * @param identifier of the definition
170      * @return the group definition
171      */
172     public GroupDefinition getGroupDefinition(String identifier) {
173         Definition definition = (Definition) definitions.get(identifier);
174         if (definition == null)
175             definition = (Definition) aliases.get(identifier);
176         if (definition != null && definition instanceof GroupDefinition)
177             return (GroupDefinition) definition;
178         return null;
179     }
180     
181     /***
182      * Retrieves the element definition from the dictionary or null if not found.
183      * @param identifier of the definition
184      * @return the element definition
185      */
186     public ElementDefinition getElementDefinition(String identifier) {
187         return getElementDefinition(null, identifier);
188     }
189     
190     public ElementDefinition getElementDefinition(String objectContext, String identifier) {
191         Definition definition = null;
192         
193         if (objectContext != null) {
194             definition = (Definition) aliases.get(objectContext + "." + identifier);
195             if (definition != null && definition instanceof ElementDefinition)
196                 return (ElementDefinition) definition;
197         }
198         
199         definition = (Definition) definitions.get(identifier);
200         if (definition != null && definition instanceof ElementDefinition)
201             return (ElementDefinition) definition;
202         
203         return null;
204     }
205     
206     /***
207      * Adds a definition to this dictionary to. Overwrites any existing definition.
208      * @param definition to be added to the dictionary
209      */
210     public void addDefinition(Definition definition) {
211         addDefinition(definition, true);
212     }
213     
214     /***
215      * Adds a defintion to this dictionary. The flag indicates whether a definition 
216      * should be overwriten.
217      * @param definition to be added to the dictionary
218      * @param overwrite indicates if definition should be overwriten
219      */
220     public void addDefinition(Definition definition, boolean overwrite) {
221         if (overwrite || (!overwrite && !definitions.containsKey(definition.getIdentifier()))) {
222             definitions.put(definition.getIdentifier(), definition);
223             if (definition instanceof ElementDefinition) {
224                 ElementDefinition elementDefinition = (ElementDefinition) definition;
225                 elementDefinition.setUnitList(unitList);
226             }
227             for (Iterator i = definition.getAliases().iterator(); i.hasNext();) {
228                 String alias = i.next().toString();
229                 if (overwrite || (!overwrite && !aliases.containsKey(alias)))
230                    aliases.put(alias, definition);
231             }
232         }
233     }
234     
235     /***
236      * Sets the description information for a dictionary. This is often captured informally in 
237      * comments at the top of a dictionary file.
238      * @param information
239      */
240     public void setInformation(String information) {
241         this.information = information;
242     }
243     
244     /***
245      * Return the dictionary's descriptive information.
246      * @return the information
247      */
248     public String getInformation() {
249         return information;
250     }
251     
252     /***
253      * Adds a list of defintions to this dictionary. The flag indicates whether the 
254      * definitions should be overwriten.
255      * @param definitions to be added to the dictionary
256      * @param overwrite
257      */
258     public void addDefinitions(Collection definitions, boolean overwrite) {
259         for (Iterator i = definitions.iterator(); i.hasNext();) {
260             Definition d = (Definition) i.next();
261             addDefinition(d, overwrite);
262         }
263     }
264     
265     /***
266      * Adds a list of defintions to this dictionary. By default definitions will be 
267      * overwritten.
268      * @param definitions to be added to the dictionary
269      */
270     public void addDefinitions(Collection definitions) {
271         addDefinitions(definitions, true);
272     }
273     
274     /***
275      * Retrieves the class definition for an object with the given identifier. 
276      * This method will search the dictionary for an ObjectDefinition whose 
277      * identifier is the greatest length and matches the end of the given identifier
278      * @param identifier to lookup up class of
279      * @return {@link ObjectDefinition} of class that will constrain object with 
280      * given identifier. Returns null if not found.
281      */
282     public ObjectDefinition findObjectClassDefinition(String identifier) {
283         ObjectDefinition definition = null;
284         String className = identifier;
285         boolean done = false;
286         
287         while (definition == null && !done) {
288             if (containsObjectDefinition(className)) {
289                 definition = getObjectDefinition(className);
290             } else {
291                 if (className.indexOf("_") == -1 || className.indexOf("_") == className.length()-1)
292                     done = true;
293                 else
294                     className = className.substring(className.indexOf("_") + 1);
295             }      
296         }
297         
298         return definition;
299     }
300     
301     /***
302      * Retrieves the class definition for a group with the given identifier. 
303      * This method will search the dictionary for a GroupDefinition whose 
304      * identifier is the greatest length and matches the end of the given identifier
305      * @param identifier to lookup up class of
306      * @return {@link GroupDefinition} of class that will constrain object with 
307      * given identifier. Returns null if not found.
308      */
309     public GroupDefinition findGroupClassDefinition(String identifier) {
310         GroupDefinition definition = null;
311         String className = identifier;
312         boolean done = false;
313         
314         while (definition == null && !done) {
315             if (containsGroupDefinition(className))
316                 definition = getGroupDefinition(className);
317             else {
318                 if (className.indexOf("_") == -1 || className.indexOf("_") == className.length()-1)
319                     done = true;
320                 else
321                     className = className.substring(className.indexOf("_") + 1);
322             }      
323         }
324         
325         return definition;
326     }
327     
328     /***
329      * Retrieves the map of definitions
330      * @return map of definitions.
331      */
332     public Map getDefinitions() {
333         return definitions;
334     }
335     
336     /***
337      * Retrieves map of valid units.
338      * @return map of UNIT_ID to list of valid units
339      */
340     public Map getUnits() {
341         return units;
342     }
343     
344     /***
345      * Sets the valid units for use when performing validation against this dictionary
346      * @param units mapped set of units of the form UNIT_ID to units list
347      *              (A) -> ('A', 'AMPERE')
348      */
349     public void setUnits(Map units) {
350         this.units = units;
351         unitList = new ArrayList();
352         for (Iterator i = units.values().iterator(); i.hasNext(); ) {
353             unitList.addAll((List) i.next());
354         }
355     }
356     
357     public String getStatus() {
358         return status;
359     }
360     
361     public void setStatus(String status) {
362         //Make sure we aren't trying to set status to unknown
363         if (!UNKNOWN.equals(status)) {
364            //Set to pass if unknown 
365            //Set to fail if that is the status being passed in
366            //Drop everything else
367            if (PASS.equals(status) && UNKNOWN.equals(this.status))
368               this.status = PASS;
369            else if (FAIL.equals(status))
370               this.status = FAIL;
371         }
372     }
373 }