* @throws DmcValueExceptionSet
*/
public void handleObject(DmcUncheckedObject uco, String infile, int lineNumber) throws ResultException, DmcValueException, DmcRuleExceptionSet {
ClassDefinition cd = null;
boolean isSchema = false;
DmsDefinition newDef = null;
Iterator<String> dependsOnSchemas = null;
Iterator<String> defFiles = null;
SchemaDefinition currSchema = null;
String depSchema = null;
SchemaDefinition newSchema = null;
String currFile = null;
String srcFile = "";
// Determine if we have a valid class
if ((cd = allSchema.isClass((String)uco.classes.get(0))) == null){
ResultException ex = new ResultException();
ex.result.addResult(Result.ERROR,"Unknown class: " + uco.classes.get(0));
ex.result.lastResult().lineNumber(uco.lineNumber);
ex.result.lastResult().fileName(infile);
throw(ex);
}
else{
try {
if (uco.classes.get(0).equals(MetaSchema._SchemaDefinition.getName())){
// Okay, a bit of cheating to handle schema extensions - since the
// schema extensions are defined in schemas themselves, those schemas
// have to be loaded before we attempt to resolve the schema extension
// AUX class. So, we let the schema manager know that we're loading
// a new schema with just the unchecked object.
allSchema.schemaPreAdd(uco);
}
// If we're underneath a standard eclipse project, we ignore everything before
// the /src folder name.
int srcloc = infile.indexOf("/src");
srcFile = "";
if (srcloc != -1)
srcFile = infile.substring(srcloc);
else
srcFile = infile;
// More interesting hand waving to handle rule instances. For most of the
// objects that are found in schema definitions everything can be handled
// in the usual way i.e. for ClassDefinitions, AttributeDefinitions,
// RuleDefinitions etc. all of those classes are defined as part of the
// meta schema and we have loaded the MetaSchemaAG. This means that we
// can use the dmwfactory to instantiate these objects. However, for
// instances of RuleDefinition, we're dealing with objects that are read
// from the schema definition files and not using the loaded schemas. In
// that case, we don't have all the information required to instantiate
// objects.
//
// Rule data objects are stored against the schema for processing once
// all schemas have been read.
ClassDefinition checkClass = allSchema.isClass(uco.classes.get(0));
if (checkClass != null){
if (checkClass.getRuleDefinition() != null){
uco.addValue(MetaDMSAG.__lineNumber.name, lineNumber + "");
uco.addValue(MetaDMSAG.__file.name, srcFile);
uco.addValue(MetaDMSAG.__definedIn.name, schemaLoading.getName().getNameString());
schemaLoading.addParsedRule(uco);
return;
}
}
DmwWrapper newObj = dmwfactory.createWrapper(uco);
newDef = null;
newDef = (DmsDefinition) newObj;
newDef.setFile(srcFile);
newDef.setLineNumber(lineNumber);
// DmvDMSAG.__dmvAllowedAttributes.execute(newDef.getDMO());
// NOTE: We used to be able to resolve objects as we went, but, because
// we now generate the TypeDefinitions for object references internally,
// we run into issues with attributes (which are loaded first) referring
// to classes that aren't yet defined. So, we have to do our object resolution
// in a second pass.
// TODO: Apply rules to the object
// DebugInfo.debug("APPLYING RULES");
ruleManager.executeAttributeValidation(newDef.getDmcObject());
ruleManager.executeObjectValidation(newDef.getDmcObject());
} catch (ResultException e) {
e.result.lastResult().fileName(infile);
e.result.lastResult().lineNumber(lineNumber);
throw(e);
} catch (DmcValueException e) {
ResultException ex = new ResultException(e.getMessage());
ex.result.lastResult().fileName(infile);
ex.result.lastResult().lineNumber(lineNumber);
throw(ex);
} catch (ClassCastException e){
ResultException ex = new ResultException();
ex.addError("Invalid object in a schema definition: " + uco.classes.get(0));
ex.result.lastResult().moreMessages(e.getMessage());
ex.result.lastResult().moreMessages(DebugInfo.extractTheStack(e));
ex.result.lastResult().lineNumber(uco.lineNumber);
ex.result.lastResult().fileName(infile);
throw(ex);
} catch (ClassNotFoundException e) {
ResultException ex = new ResultException();
ex.addError(e.getMessage());
ex.result.lastResult().moreMessages(DebugInfo.extractTheStack(e));
throw(ex);
} catch(DmcRuleExceptionSet e){
e.source(new SourceInfo(srcFile, lineNumber + ""));
throw(e);
}
if (cd.getObjectName().getNameString().compareTo("SchemaDefinition") == 0)
isSchema = true;
if (schemaLoading == null){
// We're not loading a schema, so this had better be a new schema
// object - if not, we complain and return false
if (isSchema == true){
// This is a new schema, so indicate that we're loading one
schemaLoading = (SchemaDefinition)newDef;
schemaStack.push(schemaLoading);
if ((dependsOnSchemas = schemaLoading.getDependsOn()) != null){
// This schema depends on others, make a recursive call to load them
// Hold on to the current schema
currSchema = schemaLoading;
// Reset the global schema pointer for now
schemaLoading = null;
while(dependsOnSchemas.hasNext()){
depSchema = dependsOnSchemas.next();
//DebugInfo.debug("Reading dependsOn: " + depSchema);
//if (depSchema.equals("dmv"))
// DebugInfo.debugWithTrace("Parsing DMV");
ConfigVersion config = finder.getConfig(depSchema);
ConfigLocation location = null;
if (config == null){
ResultException ex = new ResultException();
ex.addError("Couldn't find schema: " + depSchema + " on which schema: " + currSchema.getObjectName() + " depends.");
throw(ex);
}
location = config.getLatestVersion();
currFile = location.getFileName();
if (loadedFiles.containsKey(currFile) == false){
// Only load the schema if we haven't already parsed it
if ( (newSchema = this.parseSchemaInternal(depSchema)) == null){
ResultException ex = new ResultException();
ex.result.addResult(Result.FATAL,"Failed to parse schema: " + depSchema);
throw(ex);
}
currSchema.addDependsOnRef(newSchema);
// Now reset schemaLoading to be null once more to
// mask the schema that we just read
schemaLoading = null;
}
else{
// We've already loaded this file, but we still
// need to update the dependsOnRef
// System.out.println("Adding ref to previously parsed schema: " + ((SchemaDefinition)loadedFiles.get(currFile)).getName());
currSchema.addDependsOnRef(loadedFiles.get(currFile));
}
}
// Switch back to the schema at this level of parsing
schemaLoading = currSchema;
//DebugInfo.debug("Switching back to : " + schemaLoading.getName());
allSchema.schemaBeingLoaded(schemaLoading);
}
// // We let the SchemaManager know that we're loading a new schema.
// // This gives it the opportunity to notify its schema extensions
// // that this is happening.
// allSchema.schemaBeingLoaded(schemaLoading);
if ((defFiles = schemaLoading.getDefFiles()) != null){
ConfigLocation location = finder.getConfig(schemaLoading.getName().getNameString()).getLatestVersion();
// And now load the files associated with this schema
while(defFiles.hasNext()){
if (location.isFromJAR())
currFile = "/" + location.getDirectory() + "/" + defFiles.next();
else
currFile = location.getDirectory() + File.separator + defFiles.next();
// currFile = schemaDir + File.separator + defFiles.next();
//DebugInfo.debug("Reading def file: " + currFile);
if (!terseV){
if (location.isFromJAR())
System.out.println(" Reading " + currFile + " - from " + location.getJarFilename());
else
System.out.println(" Reading " + currFile);
}
if (location.isFromJAR()){
defParser.parseFile(currFile,true);
}
else{
defParser.parseFile(currFile);
}
}
}
}
}
else{
// We're currently loading a schema, so if this object is another
// schema, things are screwy. Complain and return false.
if (isSchema == true){
ResultException ex = new ResultException();
ex.result.addResult(Result.FATAL,"Already loading schema: " + schemaLoading.getObjectName());
ex.result.lastResult().moreMessages("This may have occurred because you have two schema definitions in the same file.");
ex.result.lastResult().fileName(infile);
throw(ex);
}
else{
// The object isn't a schema, so it must be another type of definition class
// The definedIn attribute must be set before we add the schema to the SchemaManagers
// because it is used for a variety of purposes, including the generation of the
// internal types for enums and object references. The definedIn schema will have
// its internalTypeDefList attribute augmented with these types.
// if (newDef == null){
// newRuleData.setDefinedIn(schemaLoading);
// allSchema.addRuleData(newRuleData);
// schemaLoading.addRuleDataList(newRuleData);
// }
// else{
newDef.setDefinedIn(schemaLoading);
allSchema.addDefinition(newDef);
schemaLoading.addDefinition(newDef);
// }
}
}