public SifSchema( string xsdPath ) : base(xsdPath) { fDB = new DB ( SifVersion.ParseXmlns( this.Schema.TargetNamespace ), this.Schema.TargetNamespace, "SIF XmlSchema(XSD)" ); BuildDb(); }
/// <summary> Gets the DB object associated with the specified version of SIF (or /// creates a new object if none currently exists). /// </summary> /// <param name="version">The SIF version (e.g. "1.0r1") /// </param> public static DB getDB( SifVersion version ) { DB db = (DB) fDBs[version.ToString()]; if ( db == null ) { db = new DB( version, version.Xmlns, "Edustructures MetaData" ); fDBs[version.ToString()] = db; } return db; }
/// <summary> Merge the definitions of this DB into another DB /// </summary> public virtual void mergeInto( DB target ) { Console.Out.WriteLine ( "Merging metadata for \"" + this.fVersion + "\" into \"" + target.Version + "\"..." ); Console.Out.WriteLine( "- Processing enumerated types..." ); for ( IEnumerator e = fEnums.Keys.GetEnumerator(); e.MoveNext(); ) { String key = (String) e.Current; Object val = fEnums[key]; EnumDef targetEnum = (EnumDef) target.fEnums[key]; if ( targetEnum == null ) { // Add the missing EnumDef to the target Console.Out.WriteLine( " (+) \"" + key + "\" not found in target; adding" ); target.fEnums[key] = val; } else { // Visit all values in the target's enumeration and add values // for any that are new in this version of SIF foreach(ValueDef def in ((EnumDef)val).Values ) { if ( !targetEnum.ContainsValue( def.Value ) ) { Console.Out.WriteLine ( " (~) \"" + key + "::" + def.Value + "\" not found in target; adding" ); targetEnum.DefineValue( def.Name, def.Value, def.Desc ); } } } } // Update the target's SifVersion range for ( IEnumerator e = target.fEnums.Keys.GetEnumerator(); e.MoveNext(); ) { String key = (String) e.Current; EnumDef enumDef = (EnumDef) target.fEnums[key]; enumDef.LatestVersion = fVersion; Console.Out.WriteLine ( "Enum " + enumDef.Name + " now has SifVersion range of " + enumDef.EarliestVersion + ".." + enumDef.LatestVersion ); } for ( IEnumerator e = target.fObjects.Keys.GetEnumerator(); e.MoveNext(); ) { String key = (String) e.Current; ObjectDef objDef = (ObjectDef) target.fObjects[key]; objDef.LatestVersion = fVersion; Console.Out.WriteLine ( "Object " + objDef.Name + " now has SifVersion range of " + objDef.EarliestVersion + ".." + objDef.LatestVersion ); for ( IEnumerator e2 = objDef.fFields.Keys.GetEnumerator(); e2.MoveNext(); ) { key = (String) e2.Current; FieldDef fldDef = objDef.fFields[key]; fldDef.LatestVersion = fVersion; Console.Out.WriteLine ( " Field " + fldDef.Name + " now has SifVersion range of " + fldDef.EarliestVersion + ".." + fldDef.LatestVersion ); } } Console.Out.WriteLine( "- Processing object definitions..." ); for ( IEnumerator e = fObjects.Keys.GetEnumerator(); e.MoveNext(); ) { String key = (String) e.Current; ObjectDef val = (ObjectDef) fObjects[key]; ObjectDef targetObj = (ObjectDef) target.fObjects[key]; if ( targetObj == null ) { // Add the missing ObjectDef to the target Console.Out.WriteLine ( " (+) \"" + key + "\" (" + val.Fields.Length + " fields) not found in target; adding" ); target.fObjects[key] = val; } else { // Do some sanity checking if ( !targetObj.LocalPackage.Equals( val.LocalPackage ) ) { throw new MergeException ( "Target and source have different package values (target=\"" + targetObj.Name + "\", package=\"" + targetObj.LocalPackage + "\", source=\"" + val.Name + "\", package=\"" + val.LocalPackage + "\"" ); } if ( !targetObj.Superclass.Equals( val.Superclass ) ) { throw new MergeException ( "Target and source have different superclass values (target=\"" + targetObj.Name + "\", superclass=\"" + targetObj.Superclass + "\", source=\"" + val.Name + "\", superclass=\"" + val.Superclass + "\"" ); } // Append this fExtrasFile to the target's if necessary if ( val.ExtrasFile != null ) { Console.Out.WriteLine( " (+) \"" + key + "\" has an Extras File; adding" ); targetObj.ExtrasFile = targetObj.ExtrasFile + ";" + val.ExtrasFile; } // Determine if the object's key fields (required elements and // attributes) differ StringBuilder keyCmp1s = new StringBuilder(); FieldDef[] keyCmp1 = val.Key; for ( int n = 0; n < keyCmp1.Length; n++ ) { keyCmp1s.Append( keyCmp1[n].Name == null ? "null" : keyCmp1[n].Name ); if ( n != keyCmp1.Length - 1 ) { keyCmp1s.Append( '+' ); } } StringBuilder keyCmp2s = new StringBuilder(); FieldDef[] keyCmp2 = targetObj.Key; for ( int n = 0; n < keyCmp2.Length; n++ ) { keyCmp2s.Append( keyCmp2[n].Name == null ? "null" : keyCmp2[n].Name ); if ( n != keyCmp2.Length - 1 ) { keyCmp2s.Append( '+' ); } } if ( !keyCmp1s.ToString().Equals( keyCmp2s.ToString() ) ) { throw new MergeException ( "\"" + key + "\" target and source have different key signature; merge not yet supported by adkgen." + " Target=\"" + keyCmp2s + "\"; Source=\"" + keyCmp1s + "\"" ); } targetObj.LatestVersion = Version; // Determine if any of the object's fields differ in their definition for ( IEnumerator k = val.fFields.Keys.GetEnumerator(); k.MoveNext(); ) { String key2 = (String) k.Current; FieldDef srcFld = val.fFields[key2]; FieldDef targetFld; targetFld = targetObj.fFields[key2]; if ( targetFld == null ) { Console.Out.WriteLine ( " (+) Field \"" + key + "::" + key2 + "\" not found in target; adding" ); targetObj.fFields[key2] = srcFld; } else { bool methodDiff = false; bool attrDiff = false; // Check the field for differences... if ( !Equals( srcFld.FieldType, targetFld.FieldType ) ) { Console.Out.WriteLine ( " (~) Field \"" + key + "::" + key2 + "\" has different ClassType; adding version-specific field" ); methodDiff = true; } if ( !targetFld.Tag.Equals( srcFld.Tag ) ) { Console.Out.WriteLine ( " (~) Field \"" + key + "::" + key2 + "\" has different tag; adding alias" ); Console.Out.WriteLine( " " + fVersion + " -> " + srcFld.Tag ); Console.Out.WriteLine ( " " + target.Version + " -> " + targetFld.Tag ); attrDiff = true; } if ( targetFld.Sequence != srcFld.Sequence ) { Console.Out.WriteLine ( " (~) Field \"" + key + "::" + key2 + "\" has different sequence number; adding alias" ); Console.Out.WriteLine ( " " + fVersion + " -> " + srcFld.Sequence ); Console.Out.WriteLine ( " " + target.Version + " -> " + targetFld.Sequence ); attrDiff = true; } if ( methodDiff ) { // If there were any differences that would result in new // methods to the implementation class, create a new FieldDef Console.Out.WriteLine( "*** DIFF ***" ); throw new MergeException( "Method merge not yet supported" ); } else if ( attrDiff ) { // If there were any differences in tag name or sequence // number, add an alias to the FieldDef targetFld.addAlias( fVersion, srcFld.Tag, srcFld.Sequence ); } else { targetFld.LatestVersion = fVersion; } } } } } }
protected internal virtual void onRoot( XmlElement node ) { fLocalPackage = getAttr( node, "package" ); String ver = getAttr( node, "version" ); fNamespace = getAttr( node, "namespace" ); if ( fLocalPackage == null || ver == null || fNamespace == null ) { throw new ParseException ( "<adk> must specify the package=, version=, and namespace= attributes" ); } fVersion = SifVersion.Parse( ver ); fPackage = "Edustructures.SifWorks." + fLocalPackage; Console.Out.WriteLine( " Package=" + fPackage ); Console.Out.WriteLine( " Version=" + ver + " (" + this.fVersion + ")" ); Console.Out.WriteLine( " Namespace=" + fNamespace ); fDB = MetaDataSchema.getDB( fVersion ); }