/// <inheritdoc /> public override CdmObject Copy(ResolveOptions resOpt = null, CdmObject host = null) { if (resOpt == null) { resOpt = new ResolveOptions(this, this.Ctx.Corpus.DefaultResolutionDirectives); } CdmImport copy; if (host == null) { copy = new CdmImport(this.Ctx, this.CorpusPath, this.Moniker); } else { copy = host as CdmImport; copy.Ctx = this.Ctx; copy.CorpusPath = this.CorpusPath; copy.Moniker = this.Moniker; } copy.Document = this.Document?.Copy(resOpt) as CdmDocumentDefinition; copy.PreviousOwner = this.Owner; return(copy); }
public override CdmObject Copy(ResolveOptions resOpt = null) { if (resOpt == null) { resOpt = new ResolveOptions(this); } CdmImport copy = new CdmImport(this.Ctx, this.CorpusPath, this.Moniker); copy.Doc = this.Doc; return(copy); }
/// <inheritdoc /> public override CdmObject Copy(ResolveOptions resOpt = null, CdmObject host = null) { if (resOpt == null) { resOpt = new ResolveOptions(this); } CdmImport copy; if (host == null) { copy = new CdmImport(this.Ctx, this.CorpusPath, this.Moniker); } else { copy = host as CdmImport; copy.Ctx = this.Ctx; copy.CorpusPath = this.CorpusPath; copy.Moniker = this.Moniker; } copy.Doc = this.Doc; return(copy); }
/// <summary> /// finds any relative corpus paths that are held within this document and makes them relative to the new folder instead /// </summary> internal bool LocalizeCorpusPaths(CdmFolderDefinition newFolder) { bool allWentWell = true; bool wasBlocking = this.Ctx.Corpus.blockDeclaredPathChanges; this.Ctx.Corpus.blockDeclaredPathChanges = true; // shout into the void Logger.Info(nameof(CdmDocumentDefinition), (ResolveContext)this.Ctx, $"Localizing corpus paths in document '{this.Name}'", nameof(LocalizeCorpusPaths)); // find anything in the document that is a corpus path this.Visit("", new VisitCallback { Invoke = (iObject, path) => { // i don't like that document needs to know a little about these objects // in theory, we could create a virtual function on cdmObject that localizes properties // but then every object would need to know about the documents and paths and such ... // also, i already wrote this code. switch (iObject.ObjectType) { case CdmObjectType.Import: { CdmImport typeObj = iObject as CdmImport; typeObj.CorpusPath = LocalizeCorpusPath(typeObj.CorpusPath, newFolder, ref allWentWell) ?? typeObj.CorpusPath; break; } case CdmObjectType.LocalEntityDeclarationDef: case CdmObjectType.ReferencedEntityDeclarationDef: { CdmEntityDeclarationDefinition typeObj = iObject as CdmEntityDeclarationDefinition; typeObj.EntityPath = LocalizeCorpusPath(typeObj.EntityPath, newFolder, ref allWentWell) ?? typeObj.EntityPath; break; } case CdmObjectType.DataPartitionDef: { CdmDataPartitionDefinition typeObj = iObject as CdmDataPartitionDefinition; typeObj.Location = LocalizeCorpusPath(typeObj.Location, newFolder, ref allWentWell) ?? typeObj.Location; typeObj.SpecializedSchema = LocalizeCorpusPath(typeObj.SpecializedSchema, newFolder, ref allWentWell) ?? typeObj.SpecializedSchema; break; } case CdmObjectType.DataPartitionPatternDef: { CdmDataPartitionPatternDefinition typeObj = iObject as CdmDataPartitionPatternDefinition; typeObj.RootLocation = LocalizeCorpusPath(typeObj.RootLocation, newFolder, ref allWentWell) ?? typeObj.RootLocation; typeObj.SpecializedSchema = LocalizeCorpusPath(typeObj.SpecializedSchema, newFolder, ref allWentWell) ?? typeObj.SpecializedSchema; break; } case CdmObjectType.E2ERelationshipDef: { CdmE2ERelationship typeObj = iObject as CdmE2ERelationship; typeObj.ToEntity = LocalizeCorpusPath(typeObj.ToEntity, newFolder, ref allWentWell) ?? typeObj.ToEntity; typeObj.FromEntity = LocalizeCorpusPath(typeObj.FromEntity, newFolder, ref allWentWell) ?? typeObj.FromEntity; break; } case CdmObjectType.ManifestDeclarationDef: { CdmManifestDeclarationDefinition typeObj = iObject as CdmManifestDeclarationDefinition; typeObj.Definition = LocalizeCorpusPath(typeObj.Definition, newFolder, ref allWentWell) ?? typeObj.Definition; break; } } return(false); } }, null); this.Ctx.Corpus.blockDeclaredPathChanges = wasBlocking; return(allWentWell); }
private int PrioritizeImports(HashSet <CdmDocumentDefinition> processedSet, IDictionary <CdmDocumentDefinition, int> priorityMap, int sequence, IDictionary <string, CdmDocumentDefinition> monikerMap, bool skipMonikered = false) { // goal is to make a map from the reverse order of imports (breadth first) to the first (aka last) sequence number in that list. // This gives the semantic that the 'last/shallowest' definition for a duplicate symbol wins, // the lower in this list a document shows up, the higher priority its definitions are for resolving conflicts. // for 'moniker' imports, keep track of the 'last/shallowest' use of each moniker tag. // if already in list, don't do this again if (processedSet.Contains(this)) { return(sequence); } processedSet.Add(this); if (this.Imports != null) { // first add the imports done at this level only int l = this.Imports.Count; // reverse order for (int i = l - 1; i >= 0; i--) { CdmImport imp = this.Imports.AllItems[i]; CdmDocumentDefinition impDoc = imp.ResolvedDocument as CdmDocumentDefinition; // don't add the moniker imports to the priority list bool isMoniker = !string.IsNullOrWhiteSpace(imp.Moniker); if (imp.ResolvedDocument != null && !isMoniker) { if (priorityMap.ContainsKey(impDoc) == false) { // add doc priorityMap.Add(impDoc, sequence); sequence++; } } } // now add the imports of the imports for (int i = l - 1; i >= 0; i--) { CdmImport imp = this.Imports.AllItems[i]; CdmDocumentDefinition impDoc = imp.ResolvedDocument as CdmDocumentDefinition; // don't add the moniker imports to the priority list bool isMoniker = !string.IsNullOrWhiteSpace(imp.Moniker); if (impDoc?.ImportPriorities != null) { // lucky, already done so avoid recursion and copy ImportPriorities impPriSub = impDoc.GetImportPriorities(); impPriSub.ImportPriority.Remove(impDoc); // because already added above foreach (var ip in impPriSub.ImportPriority) { if (priorityMap.ContainsKey(ip.Key) == false) { // add doc priorityMap.Add(ip.Key, sequence); sequence++; } } if (!isMoniker) { foreach (var mp in impPriSub.MonikerPriorityMap) { monikerMap[mp.Key] = mp.Value; } } } else if (impDoc != null) { // skip the monikered imports from here if this is a monikered import itself and we are only collecting the dependencies sequence = impDoc.PrioritizeImports(processedSet, priorityMap, sequence, monikerMap, isMoniker); } } // skip the monikered imports from here if this is a monikered import itself and we are only collecting the dependencies if (!skipMonikered) { // moniker imports are prioritized by the 'closest' use of the moniker to the starting doc. so last one found in this recursion for (int i = 0; i < l; i++) { CdmImport imp = this.Imports.AllItems[i]; if (imp.ResolvedDocument != null && imp.Moniker != null) { monikerMap[imp.Moniker] = imp.ResolvedDocument as CdmDocumentDefinition; } } } } return(sequence); }