/** * Bind an operation by copying the signature from the actual. * * @param copy the copier * @param actual the actual. If an operation, its signature is copied to the template * @param operation The operation template * @return */ public static Operation instantiateOperation( LazyCopier copy, Element actual, Operation operation) { try { Operation newOperation = copy.getCopy(operation); if (actual instanceof Operation) { for (Parameter parameter : ((Operation) actual).getOwnedParameters()) { Parameter newParam = EcoreUtil.copy(parameter); // copy parameter via EcoreUtil newParam.setType(copy.getCopy(parameter.getType())); newOperation.getOwnedParameters().add(newParam); } } TransformationContext.classifier = newOperation.getClass_(); if (actual instanceof Classifier) { bindOperation(newOperation, (Classifier) actual); } String newName = AcceleoDriverWrapper.evaluate(operation.getName(), actual, null); newOperation.setName(newName); return newOperation; } catch (TransformationException e) { // throw runtime exception throw new RuntimeException( String.format(Messages.TemplateInstantiationListener_TrafoException, e.getMessage())); } }
/** * Instantiate a behavior * * @param copy copier * @param actual actual in template instantiation * @param opaqueBehavior behavior with body in form of an Acceleo template. * @return instantiated (bound) behavior. * @throws TransformationException */ public static OpaqueBehavior instantiateBehavior( LazyCopier copy, Element actual, OpaqueBehavior opaqueBehavior) throws TransformationException { OpaqueBehavior newBehavior = copy.getCopy(opaqueBehavior); if (actual instanceof NamedElement) { String newName = AcceleoDriverWrapper.evaluate(opaqueBehavior.getName(), actual, null); newBehavior.setName(newName); } EList<String> bodyList = newBehavior.getBodies(); for (int i = 0; i < bodyList.size(); i++) { String body = bodyList.get(i); TransformationContext.classifier = (Classifier) newBehavior.getOwner(); // pass qualified operation name as template name. Used to identify script in case of an error String newBody = AcceleoDriverWrapper.evaluate(body, newBehavior.getQualifiedName(), actual, null); bodyList.set(i, newBody); } return newBehavior; }
/** * Bind a named element. Besides of binding the passed element, this operation will bind all * elements that are referenced (required) by the passed element. * * <p>In consequence, typically only a small part of a package template is actually created within * the bound package. We call this mechanism lazy instantiation/binding * * @param copier Source and target model * @param namedElement A member within the package template which should be bound, i.e. for which * template instantiation should be performed. * @param binding The binding between the bound package and the package template * @param args Acceleo arguments */ @SuppressWarnings("unchecked") public <T extends NamedElement> T bindNamedElement(T namedElement) throws TransformationException { if (namedElement == null) { // user should never see this exception throw new TransformationException(Messages.TemplateInstantiation_TemplateIsNull); } Package boundPackage = (Package) binding.getBoundElement(); EList<Namespace> path = TemplateUtils.relativePathWithMerge(namedElement, packageTemplate); Template template = UMLUtil.getStereotypeApplication(namedElement, Template.class); BindingHelper helper = (template != null) ? template.getHelper() : null; /* if((templateKind == TemplateKind.ACCUMULATE) || (templateKind == TemplateKind.LATE_EVALUATION)) { // TODO: not very clean yet path = TemplateUtils.relativePathWithMerge(namedElement, copy.source); if(path == null) { // element is imported path = namedElement.allNamespaces(); } boundPackage = copy.target; // CreationUtils.getAndCreate // (sat.target, "accumulate"); } */ if (path != null) { // register owning package template (template can be defined in // multiple packages) Element owner = TemplateUtils.getTemplateOwner(namedElement, signature); if (owner != null) { // note that we might overwrite an existing value copier.put(owner, boundPackage); } } else { // element is not part of the package template referenced by the // binding if (namedElement instanceof TemplateableElement) { // check whether the referenced element is part of another // package template, // (for which we allow for implicit binding with the first // template parameter) TemplateSignature signatureOfNE = TemplateUtils.getSignature((TemplateableElement) namedElement); if ((signatureOfNE != null) && (signature != signatureOfNE)) { TemplateBinding subBinding = TemplateUtils.getSubBinding( copier.target, (TemplateableElement) namedElement, binding); TemplateInstantiation ti = new TemplateInstantiation(copier, subBinding, args); NamedElement ret = ti.bindNamedElement(namedElement); return (T) ret; } } // => nothing to do with respect to template instantiation, but // since the template is potentially instantiated in another model, // the referenced element might need to be copied. return copier.getCopy(namedElement); } // element is contained in the template package, examine whether it // already exists in the // bound package. NamedElement existingMember = (NamedElement) copier.get(namedElement); /* if((existingMember != null) && (templateKind != TemplateKind.ACCUMULATE)) { // element is already existing (and thus bound), nothing to do // additional check, whether the ACCUMULATE information is unset) // however: if the element is a package, existence is not sufficient // since it might have been created via getAndCreate above //if(namedElement instanceof Package) { // bindPackage((Package)namedElement); //} return (T)existingMember; } */ if (existingMember == null) { FilterTemplate.getInstance().setActive(false); T copiedElement = copier.getCopy(namedElement); FilterTemplate.getInstance().setActive(true); copier.setPackageTemplate(null, null); return copiedElement; } return (T) existingMember; }