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