Example #1
0
 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;
 }
Example #3
0
        /// <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 );
        }