public MappingFunctionStore(MapForceMapping mapForceMapping, TargetElementStore targetElementStore)
        {
            foreach (FunctionComponent functionComponent in mapForceMapping.FunctionComponents)
            {
                switch (functionComponent.FunctionType)
                {
                case "split":
                {
                    List <object> targetCcElements = new List <object>();

                    foreach (InputOutputKey outputKey in functionComponent.OutputKeys)
                    {
                        string targetElementKey = mapForceMapping.GetMappingTargetKey(outputKey.Value);
                        if (targetElementKey != null)
                        {
                            targetCcElements.Add(targetElementStore.GetTargetCc(targetElementKey));
                        }
                    }

                    MappingFunction mappingFunction = new MappingFunction(targetCcElements);

                    foreach (InputOutputKey inputKey in functionComponent.InputKeys)
                    {
                        mappingFunctions[inputKey.Value] = mappingFunction;
                    }
                }
                break;
                }
            }
        }
        /// <summary>
        /// Takes a MapForce mapping file as input and returns a <see cref="MapForceMapping"/> object.
        /// </summary>
        /// <param name="mappingFiles"></param>
        /// <returns></returns>
        public static MapForceMapping ImportFromFiles(params string[] mappingFiles)
        {
            numberOfEdges = 0;

            MapForceMapping mapForceMapping = new MapForceMapping(ImportSchemaComponents(mappingFiles), ImportConstantComponents(mappingFiles), ImportFunctionComponents(mappingFiles), ImportGraph(mappingFiles));

            Console.Out.WriteLine("Number of Edges specified in MapForce Mapping: " + numberOfEdges);

            // The following line of code was used for the CEC 2010 paper evaluation
            //Console.Out.WriteLine("Kennzahl 2 (explizite Mappings): " + numberOfEdges);

            return(mapForceMapping);
        }
        public TargetElementStore(MapForceMapping mapForceMapping, ICcLibrary ccLibrary, ICctsRepository cctsRepository)
        {
            cache = CcCache.GetInstance(cctsRepository);

            IEnumerable <SchemaComponent> targetSchemaComponents = mapForceMapping.GetTargetSchemaComponents();

            foreach (SchemaComponent component in targetSchemaComponents)
            {
                Entry entry = component.RootEntry;

                IAcc acc = cache.GetCcFromCcLibrary(ccLibrary.Name, entry.Name);

                if (acc == null)
                {
                    throw new MappingError("ACC '" + entry.Name + "' not found.");
                }
                AddToIndex(entry, acc);
                CreateChildren(entry, acc);
            }
        }
        /// <exception cref="ArgumentException">The MapForce mapping does not contain any input schema components.</exception>
        public MapForceSourceItemTree(MapForceMapping mapForceMapping, XmlSchemaSet xmlSchemaSet)
        {
            this.mapForceMapping = mapForceMapping;
            xmlSchemaSet.Compile();
            /// Retrieve the schema component containing the input schemas' root element.
            ///
            /// If there is only one input schema component, then this component is the root schema component.
            ///
            /// If there are more than one input schema components, we look for a constant component with value "Root: *", where "*" must
            /// be the name of the root XSD element of the input schemas. We then return the schema component containing this element as its root.

            var inputSchemaComponents = new List <SchemaComponent>(mapForceMapping.GetInputSchemaComponents());

            var schemaComponentTrees = new List <SourceItem>();

            foreach (SchemaComponent inputSchemaComponent in inputSchemaComponents)
            {
                XmlSchemaElement rootXsdElement = (XmlSchemaElement)xmlSchemaSet.GlobalElements[inputSchemaComponent.InstanceRoot];
                if (rootXsdElement == null)
                {
                    throw new MappingError("Root element of input schema component [" + inputSchemaComponent.InstanceRoot + "] not found in XSD global elements.");
                }
                SourceItem tree = CreateSourceItemTree(inputSchemaComponent.RootEntry, rootXsdElement);
                schemaComponentTrees.Add(tree);
            }

            if (schemaComponentTrees.Count == 0)
            {
                throw new MappingError("The MapForce mapping does not contain any input schema components.");
            }
            else if (schemaComponentTrees.Count == 1)
            {
                RootSourceItem = schemaComponentTrees[0];
            }
            else
            {
                var rootElementName = mapForceMapping.GetConstant("Root");
                if (string.IsNullOrEmpty(rootElementName))
                {
                    throw new MappingError("The MapForce mapping does not specify the root source element name.");
                }
                var nonRootElementTrees = new List <SourceItem>();
                foreach (SourceItem tree in schemaComponentTrees)
                {
                    if (tree.Name == rootElementName)
                    {
                        RootSourceItem = tree;
                    }
                    else
                    {
                        nonRootElementTrees.Add(tree);
                    }
                }
                if (RootSourceItem == null)
                {
                    throw new ArgumentException("The MapForce mapping does not contain an input schema component with the specified root element: " + rootElementName);
                }
                List <SourceItem> unattachedNonRootItemTrees = new List <SourceItem>(nonRootElementTrees);
                while (unattachedNonRootItemTrees.Count > 0)
                {
                    bool atLeastOneTreeAttached = false;
                    foreach (var nonRootElementTree in new List <SourceItem>(unattachedNonRootItemTrees))
                    {
                        // TODO iteratively attach trees until no attachable trees are left
                        if (AttachSubTree(nonRootElementTree, RootSourceItem))
                        {
                            atLeastOneTreeAttached = true;
                            unattachedNonRootItemTrees.Remove(nonRootElementTree);
                        }
                    }
                    if (!atLeastOneTreeAttached)
                    {
                        break;
                    }
                }
                if (unattachedNonRootItemTrees.Count > 0)
                {
                    List <string> itemTreeNames = new List <string>();
                    foreach (SourceItem tree in unattachedNonRootItemTrees)
                    {
                        itemTreeNames.Add(tree.Name);
                    }
                    throw new MappingError("The following schema components could not be attached to the source item tree: " + string.Join(", ", itemTreeNames.ToArray()));
                }
            }
        }
        public SchemaMapping(MapForceMapping mapForceMapping, XmlSchemaSet xmlSchemaSet, ICcLibrary ccLibrary, ICctsRepository cctsRepository)
        {
            sourceItemStore = new MapForceSourceItemTree(mapForceMapping, xmlSchemaSet);

            targetElementStore = new TargetElementStore(mapForceMapping, ccLibrary, cctsRepository);

            mappingFunctionStore = new MappingFunctionStore(mapForceMapping, targetElementStore);

            RootElementMapping = MapElement(sourceItemStore.RootSourceItem, "/" + sourceItemStore.RootSourceItem.Name, new Stack <XmlQualifiedName>());

            elementMappings.Add(RootElementMapping);

            elementMappings = new List <ElementMapping>(ResolveTypeMappings(elementMappings));

            foreach (KeyValuePair <string, List <ComplexTypeMapping> > pair in complexTypeMappings)
            {
                foreach (ComplexTypeMapping complexTypeMapping in pair.Value)
                {
                    complexTypeMapping.RemoveInvalidAsmaMappings();
                }
            }

            Dictionary <string, List <ComplexTypeMapping> > relevantComplexTypeMappings = new Dictionary <string, List <ComplexTypeMapping> >();

            foreach (KeyValuePair <string, List <ComplexTypeMapping> > pair in complexTypeMappings)
            {
                string             complexTypeName = pair.Key;
                ComplexTypeMapping relevantMapping = GetComplexTypeMappingWithMostChildren(pair.Value);
                if (relevantMapping is ComplexTypeToMaMapping)
                {
                    relevantMapping = CreateComplexTypeMappingForChildMappings(relevantMapping.Children, complexTypeName, relevantMapping.SourceElementName);
                }
                if (relevantMapping != null)
                {
                    relevantComplexTypeMappings[complexTypeName] = new List <ComplexTypeMapping> {
                        relevantMapping
                    };
                }
            }
            complexTypeMappings = relevantComplexTypeMappings;

            foreach (ElementMapping elementMapping in elementMappings)
            {
                if (elementMapping is AsmaMapping)
                {
                    AsmaMapping        asmaMapping        = (AsmaMapping)elementMapping;
                    ComplexTypeMapping complexTypeMapping = CreateComplexTypeMappingForChildMappings(asmaMapping.TargetMapping.Children, asmaMapping.TargetMapping.ComplexTypeName, asmaMapping.TargetMapping.SourceElementName);
                    asmaMapping.TargetMapping = complexTypeMapping;
                }
            }

            foreach (KeyValuePair <string, List <ComplexTypeMapping> > pair in complexTypeMappings)
            {
                foreach (ComplexTypeMapping complexTypeMapping in pair.Value)
                {
                    complexTypeMapping.RemoveInvalidAsmaMappings();
                }
            }


            // The following lines of code were used for the CEC 2010 paper evaluation.

            //Console.Out.WriteLine("Kennzahl 3 (implizite Mappings): haendisch");
            //Console.Out.WriteLine("Kennzahl 4 (Anzahl der gemappten Elemente)): " + (elementMappings.Count + simpleTypeMappings.Count + complexTypeMappings.Count));

            //Console.Out.WriteLine("Importer Kennzahl 3a (anhand elementMapping variable): " + elementMappings.Count);
            //Console.Out.WriteLine("Importer Kennzahl 3b (anhand simpleTypeMappings): " + simpleTypeMappings.Count);
            //Console.Out.WriteLine("Importer Kennzahl 3c (anhand complexTypeMappings): " + complexTypeMappings.Count);
        }