/// <summary> /// This method loads and parses the rest of the supporting files /// (e.g. Presentation, Calculation, Labels, Definition, etc.) /// and completes the parsing of the taxonomy. /// It is called after the Taxonomy internal Xml Document is loaded. /// </summary> /// <param name="numErrors">The number of errors in parsing.</param> protected override void ParseInternal( out int numErrors ) { ProcessingFileChangedEventArgs e = new ProcessingFileChangedEventArgs( "Processing " + this.SchemaFile + "..." ); OnProcessingFileChanged( this, e ); numErrors = 0; // if we've already been through, don't go through again if (this.allElements != null) { return; } int errors = 0; errorList.Clear(); numWarnings = numErrors = 0; numPresErrors = numCalcErrors = numLabelErrors = numElementErrors = numDefErrors = 0; CheckForAucentExtension(); GetTargetNamespace(); #if UNITTEST DateTime start = DateTime.Now; #endif // this loads up all dependant taxonomies, and loads the corresponding presentation, calculation, label, and reference linkbases #if UNITTEST start = DateTime.Now; #endif LoadImports( out errors ); numErrors += errors; #if UNITTEST Console.WriteLine( "File: {0} Method: {1} ElapsedTime: {2}", schemaFilename, "LoadImports", DateTime.Now - start ); start = DateTime.Now; #endif // loads the presentation linkbase for this taxonomy and merges the dependant taxonomy presentation linkbases e = new ProcessingFileChangedEventArgs( "Processing Presentation files for " + this.SchemaFile + "..." ); OnProcessingFileChanged( this, e ); errors = 0; LoadPresentation( out errors ); /* BUG 3406 - Per spec 5.1.2, if a dependent taxonomy has presentation then it must be * included in the DTS, even if the current taxonomy does not have a presentation file. */ if ( presentationInfo != null && presentationInfo.Count > 0 ) HasPresentation = true; numErrors += errors; #if UNITTEST Console.WriteLine( "File: {0} Method: {1} ElapsedTime: {2}", schemaFilename, "LoadPresentation", DateTime.Now - start ); start = DateTime.Now; #endif // loads the calculation linkbase for this taxonomy and merges the dependant taxonomy calculation linkbases e = new ProcessingFileChangedEventArgs( "Processing Calculation files for " + this.SchemaFile + "..." ); OnProcessingFileChanged( this, e ); errors = 0; LoadCalculation( out errors ); //TODO /* BUG 3406 - Per spec 5.1.2, if a dependent taxonomy has calculation then it must be * included in the DTS, even if the current taxonomy does not have a calculation file. */ if ( calculationInfo != null && calculationInfo.Count > 0 ) HasCalculation = true; numErrors += errors; #if UNITTEST Console.WriteLine( "File: {0} Method: {1} ElapsedTime: {2}", schemaFilename, "LoadCalculation", DateTime.Now - start ); start = DateTime.Now; #endif if (!SkipDefinitionFileLoading) { LoadDefinition(out errors); numErrors += errors; #if UNITTEST Console.WriteLine("File: {0} Method: {1} ElapsedTime: {2}", schemaFilename, "LoadDefinitions", DateTime.Now - start); start = DateTime.Now; #endif } #region might have to add the discovered taxonomies found in the dep taxonomy foreach (Taxonomy depTax in new ArrayList(this.dependantTaxonomies)) { if (depTax.dependantTaxonomyFilenames != null && depTax.dependantTaxonomies != null && depTax.dependantTaxonomyFilenames.Count == depTax.dependantTaxonomies.Count) { for (int i = 0; i < depTax.dependantTaxonomyFilenames.Count; i++) { this.MergeDiscoveredTaxonomy(depTax.dependantTaxonomyFilenames[i], depTax.dependantTaxonomies[i] as Taxonomy, out errors); numErrors += errors; } } } #endregion // loads the labels for this taxonomy and merges the dependant taxonomy labels e = new ProcessingFileChangedEventArgs( "Processing Label files for " + this.SchemaFile + "..." ); OnProcessingFileChanged( this, e ); errors = 0; LoadLabels( out errors ); numErrors += errors; #if UNITTEST Console.WriteLine( "File: {0} Method: {1} ElapsedTime: {2}", schemaFilename, "LoadLabels", DateTime.Now - start ); start = DateTime.Now; #endif // loads the references for this taxonomy and merges the dependant taxonomy references e = new ProcessingFileChangedEventArgs( "Processing Reference files for " + this.SchemaFile + "..." ); OnProcessingFileChanged( this, e ); errors = 0; LoadReferences( out errors ); numErrors += errors; #if UNITTEST Console.WriteLine( "File: {0} Method: {1} ElapsedTime: {2}", schemaFilename, "LoadReferences", DateTime.Now - start ); start = DateTime.Now; #endif LoadRoleTypes(out errors); numErrors += errors; // loads the elements for this taxonomy and merges the dependant taxonomy elements errors = 0; LoadElements( out errors ); numErrors += errors; #if UNITTEST Console.WriteLine( "File: {0} Method: {1} ElapsedTime: {2}", schemaFilename, "LoadElements", DateTime.Now - start ); start = DateTime.Now; #endif if ( !innerTaxonomy ) { foreach (Taxonomy depTax in this.dependantTaxonomies) { this.MergeRoleRefsFromTaxonomy(depTax); this.MergeRoleTypes(depTax); this.MergeLinkbaseFileInfos(depTax); } if ( presentationInfo != null && presentationInfo.Count > 0 ) { errors = 0; BindPresentationCalculationElements( true, out errors ); numErrors += errors; #if UNITTEST Console.WriteLine( "File: {0} Method: {1} ElapsedTime: {2}", schemaFilename, "BindElementToLocator", DateTime.Now - start ); start = DateTime.Now; #endif } if ( labelHrefHash != null && labelHrefHash.Count > 0 ) { errors = 0; BindElements( new BindElementDelegate( BindLabelToElement ), out errors ); numErrors += errors; //do not clear for a cached taxonomy... if (!usedAsCachedBaseTaxonomy) labelHrefHash.Clear(); #if UNITTEST Console.WriteLine( "File: {0} Method: {1} ElapsedTime: {2}", schemaFilename, "BindLabelToElement", DateTime.Now - start ); start = DateTime.Now; #endif } if ( referenceTable != null && referenceTable.Count > 0 ) { errors = 0; BindElements( new BindElementDelegate( BindReferenceToElement ), out errors ); numErrors += errors; //do not clear for a cached taxonomy... if (!usedAsCachedBaseTaxonomy) referenceTable.Clear(); #if UNITTEST Console.WriteLine( "File: {0} Method: {1} ElapsedTime: {2}", schemaFilename, "BindReferenceToElement", DateTime.Now - start ); start = DateTime.Now; #endif } if ( calculationInfo != null && calculationInfo.Count > 0 ) { errors = 0; BindPresentationCalculationElements( false, out errors ); numErrors += errors; #if UNITTEST Console.WriteLine( "File: {0} Method: {1} ElapsedTime: {2}", schemaFilename, "BindElementToCalculationLocator", DateTime.Now - start ); start = DateTime.Now; #endif } if ( netDefinisionInfo != null && netDefinisionInfo.DefinitionLinks.Count > 0 ) { errors = 0; netDefinisionInfo.BindElementsToLocator( this.allElements ); //update information on parse complete..... netDefinisionInfo.OnParseComplete(); numErrors += errors; } if ( extendedDataMappings.Count > 0 ) //reassign data type for the elements that uses the extended types { #if UNITTEST Console.WriteLine( "Begin Modify Element Types -- Extended Types:" + DateTime.Now.ToShortTimeString() ); #endif foreach ( Element e1 in this.allElements.Values ) { List<string> checkedTypes = new List<string>(); SetBaseType(e1, checkedTypes ); } #if UNITTEST Console.WriteLine( "End Modify Element Types -- Extended Types:" + DateTime.Now.ToShortTimeString() ); #endif } foreach ( Taxonomy depTax in this.dependantTaxonomies ) { this.validationErrors.AddRange( depTax.validationErrors ); this.ValidationWarnings.AddRange(depTax.ValidationWarnings); foreach ( string key in depTax.customDataTypesHash.Keys ) { this.customDataTypesHash[key] = 1; } } if ( customDataTypesHash.Count > 0 ) { //need to xpath into the xml doucment and read the information related to the //custom data type so that typed domain refs works... foreach ( string name in new ArrayList( customDataTypesHash.Keys ) ) { this.customDataTypesHash[name] = LoadCustomDataType( name ); } } //we want to call close on dep tax only after we get a chance to call //load custom data types as .. as the extended tax might depend on //a custom type created in the base taxonomy... foreach ( Taxonomy depTax in this.dependantTaxonomies ) { depTax.Close(); } //this is required for extensions to get created properly. UpdateAllRelativeRoleRefs(); //fix substitution group #region good place to set the correct substitution group and type of the element //substitution group needs to point back to //item , tuple , dimenension, hypercube.... //type can be nested...and we need to get the base type .... //for each element.... foreach ( Element el in new ArrayList( AllElements.Values ) ) { if ( !el.IsBaseSubstGroup() ) { //recursvely walk up the chain till we find a base substitution group. Hashtable preventRecursion = new Hashtable(); el.SetSubstitutionGroup( AllElements, preventRecursion ); //the following code is commented out as //we have not been able to establish if this is a valid way to //configure tuples //the german taxonomy has elements that support this theory //and also elements that do not support this theory //so the code is being commented out until we can figure out the expected behaviour //look at unit test TestGermanCI_Presentation() #region move elements into tuples based on subst group //string otherElementId = el.OrigsubstGroup.Replace(":", "_"); //Element origEle = allElements[otherElementId] as Element; //if (origEle == null) continue; //ArrayList allClonesOfOrig = new ArrayList(); //allClonesOfOrig.Add(origEle); //allClonesOfOrig.AddRange(origEle.clonedElements); //foreach (Element master in allClonesOfOrig) //{ // if ( master.Parent != null) // { // Element child = el; // Element parent = master.Parent; // if (el.Parent != null) // { // if (el.Parent.Id == parent.Id) // { // //nothing to do here // continue; // } // else // { // child = (Element)el.Clone(); // } // } // parent.AddChild(child); // child.SetOccurances(master.MinOccurances, master.MaxOccurances); // if (master.IsChoice) // { // //orig is a choice item , need to add the current item to the parent choice list // parent.ChoiceContainer.TheChoices.Add( // new Choice(parent.ChoiceContainer, child, child.MinOccurances, child.MaxOccurances)); // } // // and remove this child from the hashtable // if (boundElements.ContainsKey(child.Id)) // { // boundElements.Remove(child.Id); // } // } //} #endregion } } #endregion //enums might exist in one dep tax //and it might get used in multiple other dep tax... //element enum information might not get populated ... //this might be a good place to correct it. RelinkEnumerationInformationWithElements(); //this is a good place to switch out all the titles in the linkbases to the //definition of the role refs.. ReplaceTitleWithRoleDefinition(); this.Close(); // and get rid of the dependant taxonomies if (!this.KeepInnerTaxonomies) { dependantTaxonomies.Clear(); } //load rivet extensions if any is available LoadRivetExtensions(); } }
/// <summary> /// A method to wrap the call to the event delegate for telling the outside world if /// which file is being processed on the load. It gets called to provide some progress status /// report of what is happening with the load. This wrapper checks if the ProcessingFileChanged /// event handler is not null and then calls the delegate. If it is null, nothing happens. /// </summary> /// <param name="tax"></param> /// <param name="e"></param> public static void OnProcessingFileChanged( Taxonomy tax, ProcessingFileChangedEventArgs e ) { if ( ProcessingFileChanged != null ) { ProcessingFileChanged( tax, e ); } }