/******************************************************************************* * Copyright (c) 2013, 2015 CEA LIST and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * E.D.Willink(CEA LIST) - Initial API and implementation *******************************************************************************/ package org.eclipse.ocl.examples.codegen.oclinecore; import java.util.List; import org.eclipse.emf.codegen.ecore.genmodel.GenParameter; import org.eclipse.emf.common.util.WrappedException; import org.eclipse.emf.ecore.EObject; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.ocl.examples.codegen.analyzer.AS2CGVisitor; import org.eclipse.ocl.examples.codegen.analyzer.CodeGenAnalyzer; import org.eclipse.ocl.examples.codegen.cgmodel.CGConstraint; import org.eclipse.ocl.examples.codegen.cgmodel.CGModelFactory; import org.eclipse.ocl.examples.codegen.cgmodel.CGParameter; import org.eclipse.ocl.examples.codegen.cgmodel.CGValuedElement; import org.eclipse.ocl.pivot.Constraint; import org.eclipse.ocl.pivot.ExpressionInOCL; import org.eclipse.ocl.pivot.LanguageExpression; import org.eclipse.ocl.pivot.NamedElement; import org.eclipse.ocl.pivot.OCLExpression; import org.eclipse.ocl.pivot.Parameter; import org.eclipse.ocl.pivot.Property; import org.eclipse.ocl.pivot.PropertyCallExp; import org.eclipse.ocl.pivot.TupleLiteralExp; import org.eclipse.ocl.pivot.TupleLiteralPart; import org.eclipse.ocl.pivot.Variable; import org.eclipse.ocl.pivot.internal.messages.PivotMessagesInternal; import org.eclipse.ocl.pivot.internal.prettyprint.PrettyPrinter; import org.eclipse.ocl.pivot.internal.utilities.EnvironmentFactoryInternal; import org.eclipse.ocl.pivot.internal.utilities.PivotUtilInternal; import org.eclipse.ocl.pivot.utilities.ClassUtil; import org.eclipse.ocl.pivot.utilities.NameUtil; import org.eclipse.ocl.pivot.utilities.ParserContext; import org.eclipse.ocl.pivot.utilities.ParserException; import org.eclipse.ocl.pivot.utilities.PivotConstants; import org.eclipse.ocl.pivot.utilities.PivotUtil; public final class OCLinEcoreAS2CGVisitor extends AS2CGVisitor { protected final @NonNull OCLinEcoreGlobalContext globalContext; public OCLinEcoreAS2CGVisitor(@NonNull CodeGenAnalyzer analyzer, @NonNull OCLinEcoreGlobalContext globalContext) { super(analyzer); this.globalContext = globalContext; createSeverityOperations(analyzer.getCodeGenerator().getEnvironmentFactory()); } private void createSeverityOperations(@NonNull EnvironmentFactoryInternal environmentFactory) { // TODO Auto-generated method stub } @Override protected void addParameter(@NonNull Variable aParameter, @NonNull CGParameter cgParameter) { super.addParameter(aParameter, cgParameter); Parameter representedParameter = aParameter.getRepresentedParameter(); if (representedParameter != null) { GenParameter genParameter = genModelHelper.getGenParameter(representedParameter); if (genParameter != null) { String name = ClassUtil.nonNullState(genParameter.getName()); cgParameter.setValueName(name); // reserve name } } } @Override public @NonNull CGParameter getParameter(@NonNull Variable aParameter, @Nullable String name) { CGParameter cgParameter = super.getParameter(aParameter, name); if (PivotConstants.SELF_NAME.equals(aParameter.getName())) { cgParameter.setValueName("this"); } return cgParameter; } @Override public @Nullable CGConstraint visitConstraint(@NonNull Constraint element) { CGConstraint cgConstraint = CGModelFactory.eINSTANCE.createCGConstraint(); setAst(cgConstraint, element); LanguageExpression specification = element.getOwnedSpecification(); if (specification != null) { String oclExpression = specification.getBody(); if (oclExpression != null) { try { EObject contextElement = ClassUtil.nonNullState(specification.eContainer()); // if ((specification instanceof ExpressionInOCL) && ((ExpressionInOCL)specification).getOwnedBody() != null) { // return (ExpressionInOCL)specification; // } ParserContext parserContext = metamodelManager.createParserContext(specification); if (parserContext == null) { throw new ParserException(PivotMessagesInternal.UnknownContextType_ERROR_, NameUtil.qualifiedNameFor(contextElement), PivotUtilInternal.getSpecificationRole(specification)); } parserContext.setRootElement(specification); if (specification instanceof ExpressionInOCL) { Variable diagnosticsVariable = PivotUtil.createVariable("diagnostics", metamodelManager.getStandardLibrary().getOclAnyType(), false, null); ((ExpressionInOCL)specification).getOwnedParameters().add(diagnosticsVariable); Variable contextVariable = PivotUtil.createVariable("context", metamodelManager.getStandardLibrary().getOclAnyType(), false, null); ((ExpressionInOCL)specification).getOwnedParameters().add(contextVariable); } String constraintName = element.getName(); if (constraintName.startsWith("validate")) { constraintName = constraintName.substring(8); // FIXME Use genModel/avoid wrong AS } EObject eContainer = element.eContainer(); if (eContainer instanceof NamedElement) { String containerName = ((NamedElement)eContainer).getName(); if (containerName != null) { constraintName = containerName + "::" + constraintName; } } @NonNull String statusExpression = oclExpression; String messageExpression = null; String severityExpression = null; ExpressionInOCL originalQuery = parserContext.parse(contextElement, oclExpression); OCLExpression ownedBody = originalQuery.getOwnedBody(); if (ownedBody instanceof PropertyCallExp) { PropertyCallExp asPropertyCallExp = (PropertyCallExp)ownedBody; OCLExpression asSource = asPropertyCallExp.getOwnedSource(); Property asReferredProperty = asPropertyCallExp.getReferredProperty(); if ((asReferredProperty != null) && PivotConstants.STATUS_PART_NAME.equals(asReferredProperty.getName()) && (asSource instanceof TupleLiteralExp)) { TupleLiteralExp asTupleLiteralExp = (TupleLiteralExp)asSource; List<TupleLiteralPart> asTupleParts = asTupleLiteralExp.getOwnedParts(); TupleLiteralPart asStatusPart = NameUtil.getNameable(asTupleParts, PivotConstants.STATUS_PART_NAME); if (asStatusPart != null) { OCLExpression asStatusInit = asStatusPart.getOwnedInit(); if (asStatusInit != null) { statusExpression = PrettyPrinter.print(asStatusInit); } TupleLiteralPart asMessagePart = NameUtil.getNameable(asTupleParts, PivotConstants.MESSAGE_PART_NAME); if (asMessagePart != null) { OCLExpression asMessageInit = asMessagePart.getOwnedInit(); if (asMessageInit != null) { messageExpression = PrettyPrinter.print(asMessageInit); } } TupleLiteralPart asSeverityPart = NameUtil.getNameable(asTupleParts, PivotConstants.SEVERITY_PART_NAME); if (asSeverityPart != null) { OCLExpression asSeverityInit = asSeverityPart.getOwnedInit(); if (asSeverityInit != null) { severityExpression = PrettyPrinter.print(asSeverityInit); } } } } } StringBuilder s = new StringBuilder(); if (severityExpression != null) { s.append("let severity : Integer = " + severityExpression + " in\n"); } else { s.append("let severity : Integer = '" + constraintName + "'.getSeverity() in\n" + "if severity <= 0 then true\n" + "else "); } s.append("let status : OclAny = " + statusExpression + " in\n"); if (messageExpression != null) { s.append("let message : String = if status <> true then " + messageExpression + " else null endif in\n"); } s.append("'" + constraintName + "'.logDiagnostic(self, null, diagnostics, context, "); s.append(messageExpression != null ? "message" : "null"); s.append(", severity, status, 0)\n"); if (severityExpression == null) { s.append("endif\n"); } String cgExpression = s.toString(); ExpressionInOCL query = parserContext.parse(contextElement, cgExpression); OCLinEcoreLocalContext localContext = (OCLinEcoreLocalContext) globalContext.getLocalContext(cgConstraint); Variable contextVariable = query.getOwnedContext(); if (contextVariable != null) { CGParameter cgParameter = getParameter(contextVariable, null); cgConstraint.getParameters().add(cgParameter); } for (@SuppressWarnings("null")@NonNull Variable parameterVariable : query.getOwnedParameters()) { String diagnosticsName = localContext != null ? localContext.getDiagnosticsName() : null; String contextName = localContext != null ? localContext.getContextName() : null; CGParameter cgParameter; if ((diagnosticsName != null) && diagnosticsName.equals(parameterVariable.getName())) { cgParameter = getParameter(parameterVariable, diagnosticsName); } else if ((contextName != null) && contextName.equals(parameterVariable.getName())) { cgParameter = getParameter(parameterVariable, contextName); } else { cgParameter = getParameter(parameterVariable, null); } cgConstraint.getParameters().add(cgParameter); } cgConstraint.setBody(doVisit(CGValuedElement.class, query.getOwnedBody())); } catch (ParserException e) { throw new WrappedException(e); } } } return cgConstraint; } }