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