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