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: ObjectValidator.java 2936 2007-09-27 20:20:02Z pramirez $ 
14  //
15  
16  package gov.nasa.pds.tools.label.validate;
17  
18  import gov.nasa.pds.tools.dict.Dictionary;
19  import gov.nasa.pds.tools.dict.ElementDefinition;
20  import gov.nasa.pds.tools.dict.ObjectDefinition;
21  import gov.nasa.pds.tools.dict.type.UnsupportedTypeException;
22  import gov.nasa.pds.tools.label.AttributeStatement;
23  import gov.nasa.pds.tools.label.ObjectStatement;
24  import gov.nasa.pds.tools.logging.ToolsLogRecord;
25  
26  import java.util.Collections;
27  import java.util.Iterator;
28  import java.util.List;
29  import java.util.logging.Level;
30  import java.util.logging.Logger;
31  
32  /***
33   * @author pramirez
34   * @version $Revision: 2936 $
35   * 
36   */
37  public class ObjectValidator {
38      private static Logger log = Logger.getLogger(ObjectValidator.class.getName());
39      
40      public static boolean isValid(Dictionary dictionary, ObjectStatement object) throws 
41         DefinitionNotFoundException {
42          return isValid(dictionary, object, new DefaultValidationListener());
43      }
44      
45      public static boolean isValid(Dictionary dictionary, ObjectStatement object, ValidationListener listener) throws 
46         DefinitionNotFoundException {
47          boolean valid = true;
48          
49          //Find definition then validate
50          ObjectDefinition definition = dictionary.findObjectClassDefinition(object.getIdentifier());
51          if (definition == null)
52              throw new DefinitionNotFoundException("Could not find object definition for " +
53                      object.getIdentifier());
54          
55          //First check that required elements are captured in object
56          for (Iterator i = definition.getRequiredElements().iterator(); i.hasNext();) {
57              String required = (String) i.next();
58              //First check to see if attribute is found by its identifier or as a pointer
59              if (!object.hasAttribute(required) && !object.hasPointer(required)) {
60                  boolean foundAlias = false;
61                  //Next check to see if the attribute is present as an alias
62                  //Lookup definition for required element
63                  ElementDefinition elementDefinition = dictionary.getElementDefinition(required);
64                  //Now loop through aliases to see if the element appears
65                  for (Iterator a = elementDefinition.getAliases().iterator(); a.hasNext() && !foundAlias;) {
66                      //All element aliases take the form <object_identifier>.<element_identifier>
67                      String [] identifier = a.next().toString().split("//.");
68                      if (identifier[0].equals(definition.getIdentifier()) && object.hasAttribute(identifier[1]))
69                          foundAlias = true;
70                  }
71                  //Didn't find anything time to log
72                  if (!foundAlias) {
73                      valid = false;
74                      listener.reportError("Object " + object.getIdentifier() + 
75                              " does not contain required element " + required);
76                      log.log(new ToolsLogRecord(Level.SEVERE, "Object " + object.getIdentifier() + 
77                              " does not contain required element " + required, object.getFilename(), 
78                              object.getContext(), object.getLineNumber()));
79                  }
80              }
81          }
82          
83          //Run through and validate all attributes
84          List attributes = object.getAttributes();
85          Collections.sort(attributes);
86          for (Iterator i = object.getAttributes().iterator(); i.hasNext();) {
87              AttributeStatement attribute = (AttributeStatement) i.next();
88              //Check to make sure element is allowed within this definition
89              if (!definition.isElementPossible(attribute.getIdentifier())) {
90                  //Next check to see if the attribute is allowed as an alias
91                  //Lookup definition for element by its alias
92                  ElementDefinition elementDefinition = dictionary.getElementDefinition(attribute.getIdentifier());
93                  if (elementDefinition == null || !definition.isElementPossible(elementDefinition.getIdentifier())) {
94                      valid = false;
95                      listener.reportError("Object " + object.getIdentifier() +  " contains the element " +
96                              attribute.getIdentifier() + " which is neither required nor optional.");
97                      log.log(new ToolsLogRecord(Level.SEVERE, "Object " + object.getIdentifier() +  " contains the element " +
98                              attribute.getIdentifier() + " which is neither required nor optional.", attribute.getFilename(),
99                              attribute.getContext(), attribute.getLineNumber()));
100                 }
101             }
102             //Validate attribute
103             boolean elementValid = false;
104             try {
105                 elementValid = ElementValidator.isValid(dictionary, definition.getIdentifier(), attribute, listener);
106             } catch (UnsupportedTypeException ute) {
107                 listener.reportError(ute.getMessage());
108                 log.log(new ToolsLogRecord(Level.SEVERE, ute.getMessage(), attribute.getFilename(), 
109                         attribute.getContext(), attribute.getLineNumber()));
110             } catch (DefinitionNotFoundException dnfe) {
111                 listener.reportError(dnfe.getMessage());
112                 log.log(new ToolsLogRecord(Level.SEVERE, dnfe.getMessage(), attribute.getFilename(), 
113                         attribute.getContext(), attribute.getLineNumber()));
114             }
115             if (!elementValid)
116                 valid = false;
117         }
118         
119         //Check to make sure that all required objects are present
120         for (Iterator i = definition.getRequiredObjects().iterator(); i.hasNext();) {
121             String required = (String) i.next();
122             //First see if object is present
123             if (!object.hasObject(required)) {
124                 boolean foundAlias = false;
125                 //Next check to see if the object is present as an alias
126                 //Lookup definition for required object
127                 ObjectDefinition objectDefinition = dictionary.getObjectDefinition(required);
128                 //Now loop through aliases to see if the object appears
129                 for (Iterator a = objectDefinition.getAliases().iterator(); a.hasNext() && !foundAlias;) {
130                     String alias = a.next().toString();
131                     if (object.hasObject(alias))
132                         foundAlias = true;
133                 }
134                 //Didn't find anything time to log
135                 if (!foundAlias) {
136                     valid = false;
137                     listener.reportError("Object " + object.getIdentifier() + 
138                             " does not contain required object " + required);
139                     log.log(new ToolsLogRecord(Level.SEVERE, "Object " + object.getIdentifier() + 
140                             " does not contain required object " + required, object.getFilename(), 
141                             object.getContext(), object.getLineNumber()));
142                 }
143             }
144         }
145         
146         //Run through nested objects and check them
147         List objects = object.getObjects();
148         Collections.sort(objects);
149         for (Iterator i = objects.iterator(); i.hasNext();) {
150             ObjectStatement obj = (ObjectStatement) i.next();
151             //Check to make sure object is allowed within this definition
152             if (!definition.isObjectPossible(obj.getIdentifier())) {
153                 //Next check to see if the object is allowed as an alias
154                 //Lookup definition object by its alias
155                 ObjectDefinition objectDefinition = dictionary.getObjectDefinition(obj.getIdentifier());
156                 if (objectDefinition == null || !definition.isObjectPossible(objectDefinition.getIdentifier())) {
157                     valid = false;
158                     listener.reportError("Object " + object.getIdentifier() +  " contains the object " +
159                             obj.getIdentifier() + " which is neither required nor optional.");
160                     log.log(new ToolsLogRecord(Level.SEVERE, "Object " + object.getIdentifier() +  " contains the object " +
161                             obj.getIdentifier() + " which is neither required nor optional.", obj.getFilename(), 
162                             obj.getContext(), obj.getLineNumber()));
163                 }
164             }
165             //Validate nested object
166             boolean objValid = false;
167             try {
168                 objValid = ObjectValidator.isValid(dictionary, obj, listener);
169             } catch (DefinitionNotFoundException dnfe) {
170                 listener.reportError(dnfe.getMessage());
171                 log.log(new ToolsLogRecord(Level.SEVERE, dnfe.getMessage(), obj.getFilename(), 
172                         obj.getContext(), obj.getLineNumber()));
173             }
174             if (!objValid)
175                 valid = false;
176         }
177         
178         return valid;
179     }
180     
181 }