package com.sap.furcas.parsergenerator.util; import java.util.Iterator; import java.util.List; import com.sap.furcas.metamodel.FURCAS.TCS.QualifiedNamedElement; import com.sap.furcas.metamodel.FURCAS.TCS.SequenceElement; import com.sap.furcas.parsergenerator.tcs.t2m.grammar.RuleBodyStringBuffer; import com.sap.furcas.parsergenerator.tcs.t2m.grammar.constraints.PropertyInstanceOfConstraint; import com.sap.furcas.parsergenerator.tcs.t2m.grammar.constraints.RuleBodyPropertyConstraint; import com.sap.furcas.runtime.common.exceptions.MetaModelLookupException; import com.sap.furcas.runtime.common.exceptions.NameResolutionFailedException; import com.sap.furcas.runtime.common.exceptions.SyntaxElementException; import com.sap.furcas.runtime.common.interfaces.IMetaModelLookup; import com.sap.furcas.runtime.common.interfaces.ResolvedNameAndReferenceBean; import com.sap.furcas.runtime.tcs.MessageHelper; import com.sap.furcas.runtime.tcs.MetaModelElementResolutionHelper; public class TcsUtil { // /** // * Gets the type of the referenced property. // * Allows to have a dotted navigation within the properties // * reference name. For example: refersTo='subElement.name' will first // * resolve the subElement Property and then the property "name" of the // type // * of this property. // * // * @param <Type> // * @param prop // * @param buffer // * @param name // * @param propertyOwnerTypeTemplate // * @param resolutionHelper // * @param metaLookup // * @return // * @throws MetaModelLookupException // * @throws SyntaxElementException // */ // public static <Type> ResolvedNameAndReferenceBean<Type> // getReferencedTypeWithNavigation(SequenceElement prop, // ResolvedNameAndReferenceBean<Type> metaModelTypeOfPropertyReference, // String name, // MetaModelElementResolutionHelper<Type> resolutionHelper, // IMetaModelLookup<Type> metaLookup) // throws MetaModelLookupException, SyntaxElementException { // if(name.indexOf('.') > 0) { // String[] navigation = name.split("\\."); // ResolvedNameAndReferenceBean<Type> navigationStep = // metaModelTypeOfPropertyReference; // for (int i = 0; i < navigation.length-1; i++) { // navigationStep = metaLookup.getFeatureClassReference(navigationStep , // navigation[i]); // } // return navigationStep; // } else { // return // metaLookup.getFeatureClassReference(metaModelTypeOfPropertyReference , // name); // } // // } /** * util method that looks up the type of a referenced object, and also * considers the context of the current template sequence. * * @param prop * @param buffer * @param propertyName * @param propertyOwnerTypeTemplate * @param resolutionHelper * @param metaLookup * @return * @throws MetaModelLookupException * @throws SyntaxElementException */ public static <Type> ResolvedNameAndReferenceBean<Type> getReferencedType(SequenceElement prop, RuleBodyStringBuffer buffer, String propertyName, QualifiedNamedElement propertyOwnerTypeTemplate, MetaModelElementResolutionHelper<Type> resolutionHelper, IMetaModelLookup<Type> metaLookup) throws MetaModelLookupException, SyntaxElementException { // check for instanceof constraint context in current buffer ResolvedNameAndReferenceBean<Type> substitutePropertyType = null; if (buffer != null) { List<RuleBodyPropertyConstraint> constraints = buffer.getCurrentConstraints(); for (Iterator<RuleBodyPropertyConstraint> iterator = constraints.iterator(); iterator.hasNext();) { RuleBodyPropertyConstraint ruleBodyPropertyConstraint = iterator.next(); if (ruleBodyPropertyConstraint instanceof PropertyInstanceOfConstraint) { PropertyInstanceOfConstraint instOfConst = (PropertyInstanceOfConstraint) ruleBodyPropertyConstraint; if (instOfConst.getPropertyName().equals(propertyName)) { List<String> substitutePropertyTypeName = instOfConst.getTypename(); substitutePropertyType = resolutionHelper.resolve(substitutePropertyTypeName); // the last in the list wins, that's fine, since they // can overrule each other. } } } } ResolvedNameAndReferenceBean<Type> metaElementRef; try { metaElementRef = resolutionHelper.resolve(propertyOwnerTypeTemplate); } catch (NameResolutionFailedException e) { throw new SyntaxElementException(e.getMessage(), prop, e); } ResolvedNameAndReferenceBean<Type> realMetaModelTypeOfPropertyTemplate = metaLookup.getFeatureClassReference( metaElementRef, propertyName); // realMetaModelTypeOfPropertyTemplate = // syntaxLookup.getTCSTemplate(propertyTypeName); if (realMetaModelTypeOfPropertyTemplate == null) { throw new SyntaxElementException("Type " + MessageHelper.getTemplateName(propertyOwnerTypeTemplate) + " has no feature " + propertyName, prop); } ResolvedNameAndReferenceBean<Type> metaModelTypeOfProperty; if (substitutePropertyType != null) { // check in Metamodel that new ownername is subclass of previous // one, else error if (metaLookup.isSubTypeOf(substitutePropertyType, realMetaModelTypeOfPropertyTemplate)) { metaModelTypeOfProperty = substitutePropertyType; } else { throw new SyntaxElementException("Conditional subtype " + substitutePropertyType + " of feature " + propertyName + " is not a subtype of expected type " + realMetaModelTypeOfPropertyTemplate, prop); } } else { metaModelTypeOfProperty = realMetaModelTypeOfPropertyTemplate; } return metaModelTypeOfProperty; } public static String escapeMultiLineOclQuery(String value) { String javaQuery = value.replaceAll("\\\\", "\\\\\\\\"); javaQuery = javaQuery.replaceAll("\\\"", "\\\\\""); javaQuery = javaQuery.replaceAll("\r\n", "\n"); javaQuery = javaQuery.replaceAll("\n", "\"+\n\""); return javaQuery; } }