예제 #1
0
 public static ISet <IVariable> FindBindedVariables(IPropertyTemplateItem prop)
 {
     if (!prop.ReferredProperty.isMany())
     {
         IObjectTemplateExp nonManyPropObjectTemplate = prop.Value as IObjectTemplateExp;
         if (nonManyPropObjectTemplate != null)
         {
             return(new HashSet <IVariable>()
             {
                 nonManyPropObjectTemplate.BindsTo
             });
         }
         else
         {
             IVariableExp nonManyPropVar = prop.Value as IVariableExp;
             if (nonManyPropVar != null)
             {
                 return(new HashSet <IVariable>()
                 {
                     nonManyPropVar.ReferredVariable
                 });
             }
             else
             {
                 CSharpOpaqueExpression cast = prop.Value as CSharpOpaqueExpression;
                 if (cast != null)
                 {
                     return(new HashSet <IVariable>(cast.BindsTo));
                 }
             }
         }
     }
     return(new HashSet <IVariable>());
 }
            /// <summary>
            /// Adds the given element to the collection
            /// </summary>
            /// <param name="item">The item to add</param>
            public override void Add(IModelElement item)
            {
                IPropertyTemplateItem partCasted = item.As <IPropertyTemplateItem>();

                if ((partCasted != null))
                {
                    this._parent.Part.Add(partCasted);
                }
            }
            /// <summary>
            /// Removes the given item from the collection
            /// </summary>
            /// <returns>True, if the item was removed, otherwise False</returns>
            /// <param name="item">The item that should be removed</param>
            public override bool Remove(IModelElement item)
            {
                IPropertyTemplateItem propertyTemplateItemItem = item.As <IPropertyTemplateItem>();

                if (((propertyTemplateItemItem != null) &&
                     this._parent.Part.Remove(propertyTemplateItemItem)))
                {
                    return(true);
                }
                return(false);
            }
 public static bool AreEqual(IList <IPropertyTemplateItem> pp1, IList <IPropertyTemplateItem> pp2)
 {
     foreach (IPropertyTemplateItem pp1Item in pp1)
     {
         IPropertyTemplateItem pp2Item = pp2[pp1.IndexOf(pp1Item)];
         if (pp1Item != pp2Item)
         {
             return(false);
         }
     }
     return(true);
 }
            /// <summary>
            /// Adds the given element to the collection
            /// </summary>
            /// <param name="item">The item to add</param>
            public override void Add(IModelElement item)
            {
                IPropertyTemplateItem partCasted = item.As <IPropertyTemplateItem>();

                if ((partCasted != null))
                {
                    this._parent.Part.Add(partCasted);
                }
                if ((this._parent.ReferredClass == null))
                {
                    LL.MDE.Components.Qvt.Metamodel.EMOF.IClass referredClassCasted = item.As <LL.MDE.Components.Qvt.Metamodel.EMOF.IClass>();
                    if ((referredClassCasted != null))
                    {
                        this._parent.ReferredClass = referredClassCasted;
                        return;
                    }
                }
            }
        private static string GenerateAccess(string varname, IList <IPropertyTemplateItem> applicablePropertyPath)
        {
            string access = varname;

            foreach (IPropertyTemplateItem property in applicablePropertyPath)
            {
                access += "?." + property.ReferredProperty.Name;
            }
            IPropertyTemplateItem last = applicablePropertyPath.Last();

            if (last.ReferredProperty.Type is IDataType)
            {
                if (cSharpPrimitiveTypes.Contains(last.ReferredProperty.Type.GetRealTypeName()))
                {
                    access += "GetValueOrDefault()";
                }
            }
            return(access);
        }
        private static string GenerateFindValueWithKey(IPropertyTemplateItem propertyTemplateItem, IObjectTemplateExp objectTemplateExpression, string resultContainer, IList <IList <IPropertyTemplateItem> > applicablePropertyPaths, bool useMetamodelInterface)
        {
            StringBuilder  sb           = new StringBuilder();
            IList <string> conditions   = new List <string>();
            string         variableName = "var" + new Random().Next();

            foreach (IList <IPropertyTemplateItem> applicablePropertyPath in applicablePropertyPaths)
            {
                string access    = GenerateAccess(variableName, applicablePropertyPath);
                string condition = access + " == " + GenerateExpression(applicablePropertyPath.Last().Value, useMetamodelInterface);
                conditions.Add(condition);
            }
            string completeCondition = string.Join(" && ", conditions);

            // If the candidate is in a collection, we generate a query to find it
            if (propertyTemplateItem.ReferredProperty.isMany())
            {
                sb.AppendLine(objectTemplateExpression.BindsTo.Name + " = "
                              + resultContainer + "." + propertyTemplateItem.ReferredProperty.Name
                              + ".OfType<" + propertyTemplateItem.ReferredProperty.Type.GetRealTypeName() + ">()"
                              + ".FirstOrDefault(" + variableName + " => " + completeCondition + ");");
            }

            // If the candidate is in a ref, we generate a conditional to find it
            else
            {
                sb.AppendLine("{"
                              + propertyTemplateItem.ReferredProperty.Type.GetRealTypeName()
                              + variableName + "= " + resultContainer + "." + propertyTemplateItem.ReferredProperty.Name + ";"
                              + "if (" + completeCondition + ") {"
                              + objectTemplateExpression.BindsTo.Name + " = "
                              + variableName + ";"
                              + "}"
                              + "}");
            }
            return(sb.ToString());
        }
 /// <summary>
 /// Creates a new observable property access proxy
 /// </summary>
 /// <param name="modelElement">The model instance element for which to create the property access proxy</param>
 public IsOppositeProxy(IPropertyTemplateItem modelElement) :
     base(modelElement)
 {
 }
        private static string GenerateConditionnalProperty(IPropertyTemplateItem prop, bool useMetamodelInterface)
        {
            string right = GenerateExpression(prop.Value, useMetamodelInterface);

            return(prop.ObjContainer.BindsTo.Name + "." + prop.ReferredProperty.Name + " == " + right);
        }
 public static string GenerateBindingFreeNonMany(IPropertyTemplateItem prop, IVariable bindedVariable)
 {
     return(bindedVariable.Type.GetRealTypeName() + " " + bindedVariable.Name + " = (" + bindedVariable.Type.GetRealTypeName() + ")" + prop.ObjContainer.BindsTo.Name + "." + prop.ReferredProperty.Name + ";");
 }
        private static string GenerateSetValue(IPropertyTemplateItem propertyTemplateItem, string resultContainer, IRelation relation, bool useMetamodelInterface)
        {
            StringBuilder      sb = new StringBuilder();
            IObjectTemplateExp objectTemplateExpression = propertyTemplateItem.Value as IObjectTemplateExp;

            // Case ref value
            if (objectTemplateExpression != null)
            {
                IKey transformationKey = ((IRelationalTransformation)relation.Transformation).OwnedKey.FirstOrDefault(k => k.Identifies == objectTemplateExpression.ReferredClass);
                IList <IList <IPropertyTemplateItem> > propertyPathsTransformationKey = transformationKey != null?FindKeyApplicablePropertyPaths(objectTemplateExpression, transformationKey) : null;

                IKey relationKey = relation.Keys().FirstOrDefault(k => k.Identifies == objectTemplateExpression.ReferredClass);
                IList <IList <IPropertyTemplateItem> > propertyPathsRelationKey = relationKey != null?FindKeyApplicablePropertyPaths(objectTemplateExpression, relationKey) : null;

                // We always start by creating the empty variable that will contain the object
                sb.AppendLine(objectTemplateExpression.BindsTo.Type.GetRealTypeName() + " " + objectTemplateExpression.BindsTo.Name + " = null;");

                int nbBracketsOpened = 0;

                // If any part of a key applies, then we must generate a test to find a potential existing object
                if (propertyPathsTransformationKey != null || propertyPathsRelationKey != null)
                {
                    // We try to resolve globally and locally, if a global key applies here
                    if (propertyPathsTransformationKey != null)
                    {
                        sb.AppendLine();
                        sb.AppendLine("// Trying to resolve the object\'" + objectTemplateExpression.BindsTo.Name + "\' globally using the transformation key");
                        IList <string> tupleTypes      = propertyPathsTransformationKey.Select(pp => pp.Last().ReferredProperty.Type.GetRealTypeName()).Select(name => name + (cSharpPrimitiveTypes.Contains(name) ? "?" : "")).ToList();
                        IList <string> tupleValues     = propertyPathsTransformationKey.Select(pp => GenerateAccess(objectTemplateExpression.BindsTo.Name, pp)).ToList();
                        IList <string> tupleValuesRead = propertyPathsTransformationKey.Select(pp => GenerateExpression(pp.Last().Value, useMetamodelInterface)).ToList();

                        string tupleTypesCombined        = string.Join(",", tupleTypes);
                        string tupleValuesCombined       = string.Join(",", tupleValues);
                        string tupleValuesCombinedRead   = string.Join(",", tupleValuesRead);
                        string accessDictionnaryReadSafe = "transformation."
                                                           + QvtCodeGeneratorStrings.KeyDictionnaryName(transformationKey)
                                                           + ".TryGetValue(new Tuple<" + tupleTypesCombined + ">(" + tupleValuesCombinedRead + "), out " + objectTemplateExpression.BindsTo.Name + ")";
                        string accessDictionnaryWrite = "transformation."
                                                        + QvtCodeGeneratorStrings.KeyDictionnaryName(transformationKey)
                                                        + "[new Tuple<" + tupleTypesCombined + ">(" + tupleValuesCombined + ")]";
                        sb.AppendLine(accessDictionnaryReadSafe + ";");

                        // If not found globally with global key, we try to find locally with global key
                        sb.AppendLine("// If the object wasn't found globally, we try to find it locally");
                        sb.AppendLine("if (" + objectTemplateExpression.BindsTo.Name + "== null) {");
                        sb.AppendLine(GenerateFindValueWithKey(propertyTemplateItem, objectTemplateExpression, resultContainer, propertyPathsTransformationKey, useMetamodelInterface));
                        nbBracketsOpened++;

                        // If we found locally with global key, we add to the dictionnary
                        sb.AppendLine("// If the object was found locally, we add it to the global cache");
                        sb.AppendLine("if (" + objectTemplateExpression.BindsTo.Name + "!= null) {");
                        sb.AppendLine(accessDictionnaryWrite + " = " + objectTemplateExpression.BindsTo.Name + ";");

                        // Else we continue with other attempts (local key or object creation)
                        sb.AppendLine("}");
                    }

                    if (propertyPathsRelationKey != null)
                    {
                        sb.AppendLine("// Trying to resolve the object locally using the relation key");

                        if (propertyPathsTransformationKey != null)
                        {
                            sb.AppendLine("else {");
                            nbBracketsOpened++;
                        }

                        sb.AppendLine(GenerateFindValueWithKey(propertyTemplateItem, objectTemplateExpression, resultContainer, propertyPathsRelationKey, useMetamodelInterface));

                        // If we found something locally, once again we check in the dictionnary and try to update
                        sb.AppendLine("// If the object was found locally, we add it to the global cache");
                        sb.AppendLine("if (" + objectTemplateExpression.BindsTo.Name + "!= null) {");
                        sb.AppendLine(GenerateCheckAndAddDictionnary(propertyPathsTransformationKey, objectTemplateExpression.BindsTo.Name, transformationKey));
                        sb.AppendLine("}");
                    }

                    // In the end we generate a test if we found a candidate
                    sb.AppendLine("// If the object still doesn't exist, we create it");
                    sb.AppendLine("else {");
                    nbBracketsOpened++;
                }

                // In any case, we generate the code to create the object, even if it might end in the conditional due to the keys test
                string beginningCreation = objectTemplateExpression.BindsTo.Name + " = ";
                if (useMetamodelInterface)
                {
                    sb.AppendLine(beginningCreation + " (" + objectTemplateExpression.BindsTo.Type.GetRealTypeName() + ") editor." + nameof(IMetaModelInterface.CreateNewObjectInField) + "(" + resultContainer + ", \"" + propertyTemplateItem.ReferredProperty.Name + "\");");
                }
                else
                {
                    string res = beginningCreation;
                    res += "new " + objectTemplateExpression.BindsTo.Type.GetRealTypeName() + "();\n";
                    if (!propertyTemplateItem.ReferredProperty.isMany())
                    {
                        res += resultContainer + "." + propertyTemplateItem.ReferredProperty.Name + " = " + objectTemplateExpression.BindsTo.Name + ";";
                    }
                    else
                    {
                        res += resultContainer + "." + propertyTemplateItem.ReferredProperty.Name + ".Add(" + objectTemplateExpression.BindsTo.Name + ");";
                    }
                    sb.AppendLine(res);
                }

                if (propertyPathsTransformationKey != null)
                {
                    // TODO generate this all the time?
                    sb.AppendLine("// We add the created object to the global cache");
                    sb.AppendLine(GenerateCheckAndAddDictionnary(propertyPathsTransformationKey, objectTemplateExpression.BindsTo.Name, transformationKey));
                }
                // If we generated a conditional for the keys test, we close it now
                if (propertyPathsTransformationKey != null || propertyPathsRelationKey != null)
                {
                    sb.AppendLine("}");
                }

                for (int i = 0; i < nbBracketsOpened - 1; i++)
                {
                    sb.AppendLine("}");
                }
                return(sb.ToString());
            }
            // Case primitive value (variable use or c sharp expression)
            else
            {
                if (useMetamodelInterface)
                {
                    return("editor." + nameof(IMetaModelInterface.AddOrSetInField) + "(" + resultContainer + ", \"" + propertyTemplateItem.ReferredProperty.Name + "\", " + GenerateExpression(propertyTemplateItem.Value, true) + " );");
                }
                else
                {
                    return(resultContainer + "." + propertyTemplateItem.ReferredProperty.Name + "=" + GenerateExpression(propertyTemplateItem.Value, false) + ";");
                }
            }
        }
        private static IList <IList <IPropertyTemplateItem> > FindKeyApplicablePropertyPaths(IObjectTemplateExp objectTemplateExpression, IKey candidateKey)
        {
            // First, we try to find if some keys applies here
            IList <IList <IPropertyTemplateItem> > result = new List <IList <IPropertyTemplateItem> >();

            IList <IList <IPropertyTemplateItem> > candidateKeyPropertyPaths = new List <IList <IPropertyTemplateItem> >();

            bool isApplicable = true;

            foreach (IProperty property in candidateKey.Part)
            {
                IPropertyTemplateItem candidate = objectTemplateExpression.Part.FirstOrDefault(p => p.ReferredProperty == property);
                if (candidate != null)
                {
                    List <IPropertyTemplateItem> propertyPath = new List <IPropertyTemplateItem>()
                    {
                        candidate
                    };
                    candidateKeyPropertyPaths.Add(propertyPath);
                }
                else
                {
                    isApplicable = false;
                    break;
                }
            }

            if (isApplicable)
            {
                foreach (PropertyPath propertyPath in candidateKey.PropertyPaths())
                {
                    IObjectTemplateExp currentobjectTemplateExpression = objectTemplateExpression;
                    bool isPathApplicable = true;
                    List <IPropertyTemplateItem> concretePropertyPath = new List <IPropertyTemplateItem>();
                    foreach (IProperty property in propertyPath.Properties)
                    {
                        IEnumerable <IPropertyTemplateItem> nextObjectTemplate = currentobjectTemplateExpression.Part.Where(p => p.ReferredProperty == property).ToList();
                        if (!nextObjectTemplate.IsNullOrEmpty())
                        {
                            concretePropertyPath.Add(nextObjectTemplate.Single());
                            currentobjectTemplateExpression = (IObjectTemplateExp)nextObjectTemplate.Single().Value;
                        }
                        else
                        {
                            isPathApplicable = false;
                            break;
                        }
                    }
                    if (isPathApplicable)
                    {
                        candidateKeyPropertyPaths.Add(concretePropertyPath);
                    }
                    else
                    {
                        isApplicable = false;
                        break;
                    }
                }
            }
            // If this key is valid, we merge all its contents into the result
            if (isApplicable)
            {
                foreach (IList <IPropertyTemplateItem> candidateKeyPropertyPath in candidateKeyPropertyPaths)
                {
                    IList <IPropertyTemplateItem> existing = result.FirstOrDefault(pp => AreEqual(pp, candidateKeyPropertyPath));
                    if (existing.IsNullOrEmpty())
                    {
                        result.Add(candidateKeyPropertyPath);
                    }
                }
                return(result);
            }
            return(null);
        }