<%@ jet package="org.eclipse.uml2.codegen.ecore.templates.model" imports="org.eclipse.emf.codegen.ecore.genmodel.* org.eclipse.uml2.codegen.ecore.genmodel.util.UML2GenModelUtil" class="OperationsClass" version="$Id: OperationsClass.javajet,v 1.16 2011/05/09 03:33:03 khussey Exp $" %>
<%
/**
 * <copyright>
 *
 * Copyright (c) 2005, 2018 IBM Corporation, Embarcadero Technologies, and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 *
 * Contributors:
 *   IBM - initial API and implementation
 *   Kenn Hussey (Embarcadero Technologies) - 206636, 224693
 *	 Lutz Wrage - 242726
 *   Kenn Hussey - 344908, 284810, 345083, 535301
 *   Kenn Hussey (CEA) - 451350, 480509
 *
 * </copyright>
 */
%>
<%GenClass genClass = (GenClass)argument; GenPackage genPackage = genClass.getGenPackage(); GenModel genModel=genPackage.getGenModel();%>
<%@ include file="../Header.jetinc"%>
package <%=UML2GenModelUtil.getOperationsPackageName(genPackage)%>;

<%genModel.markImportLocation(stringBuffer, genPackage);%>

/**
 * <!-- begin-user-doc -->
 * A static utility class that provides operations related to '<em><b><%=genClass.getFormattedName()%></b></em>' model objects.
 * <!-- end-user-doc -->
 *
<%if (!UML2GenModelUtil.getOperationsClassGenOperations(genClass).isEmpty()) { boolean first = true;%>
  <%for (GenOperation genOperation : UML2GenModelUtil.getOperationsClassGenOperations(genClass)) {%>
    <%if (first) { first = false;%>
 * <p>
 * The following operations are supported:
 * </p>
 * <ul>
    <%}%>
 *   <li>{@link <%=genOperation.getGenClass().getQualifiedInterfaceName()%>#<%=genOperation.getName()%>(<%=genOperation.getParameterTypes(", ")%>) <em><%=genOperation.getFormattedName()%></em>}</li>
  <%}%>
  <% if (!first) {%>
 * </ul>
  <%}%>
<%}%>
 *
 * @generated
 */
public class <%=UML2GenModelUtil.getOperationsClassName(genClass)%><%=UML2GenModelUtil.getOperationsClassExtends(genClass)%>
{
<%if (genModel.hasCopyrightField()) {%>
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public static final <%=genModel.getImportedName("java.lang.String")%> copyright = <%=genModel.getCopyrightFieldLiteral()%>;<%=genModel.getNonNLS()%>

<%}%>
<%if (UML2GenModelUtil.hasOCLOperationBodies(genClass) && (!UML2GenModelUtil.hasOCLOperationBodies(genClass.getClassExtendsGenClass()) || !UML2GenModelUtil.isOperationsClasses(genClass.getClassExtendsGenClass().getGenPackage()))) {%>
	/**
	 * The cached environment for evaluating OCL expressions.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 * @ordered
	 */
	protected static final <%=genModel.getImportedName("org.eclipse.ocl.ecore.OCL")%> EOCL_ENV = <%=genModel.getImportedName("org.eclipse.ocl.ecore.OCL")%>.newInstance();

<%}%>
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected <%=UML2GenModelUtil.getOperationsClassName(genClass)%>() {
		super();
	}

<%for (GenOperation genOperation : UML2GenModelUtil.getOperationsClassGenOperations(genClass)) {%>
<%@ include file="Operations/genOperation.override.javajetinc" fail="alternative" %>
<%@ start %>
<%if (UML2GenModelUtil.hasOCLBody(genOperation)) {%>
	/**
	 * The cached OCL expression body for the '{@link #<%=genOperation.getName()%>(<%=genClass.getImportedInterfaceName()%><%if (!genOperation.getGenParameters().isEmpty()) {%>, <%}%><%=genOperation.getParameterTypes(", ")%>) <em><%=genOperation.getFormattedName()%></em>}' operation.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #<%=genOperation.getName()%>(<%=genClass.getImportedInterfaceName()%><%if (!genOperation.getGenParameters().isEmpty()) {%>, <%}%><%=genOperation.getParameterTypes(", ")%>)
	 * @generated
	 * @ordered
	 */
	protected static final <%=genModel.getImportedName("java.lang.String")%> <%=UML2GenModelUtil.getUpperName(genOperation.getName())%><%=genOperation.getGenParameters().size() == 0 ? "" : "__" + UML2GenModelUtil.getUpperName(genOperation.getParameterTypes("_", false))%>__EOCL_EXP = "<%=UML2GenModelUtil.getOCLBody(genOperation)%>";<%=genModel.getNonNLS()%>

  <%if (genOperation.isInvariant()) {%>
	/**
	 * The cached OCL invariant for the '{@link #<%=genOperation.getName()%>(<%=genClass.getImportedInterfaceName()%><%if (!genOperation.getGenParameters().isEmpty()) {%>, <%}%><%=genOperation.getParameterTypes(", ")%>) <em><%=genOperation.getFormattedName()%></em>}' invariant operation.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #<%=genOperation.getName()%>(<%=genClass.getImportedInterfaceName()%><%if (!genOperation.getGenParameters().isEmpty()) {%>, <%}%><%=genOperation.getParameterTypes(", ")%>)
	 * @generated
	 * @ordered
	 */
	protected static <%=genModel.getImportedName("org.eclipse.ocl.ecore.Constraint")%> <%=UML2GenModelUtil.getUpperName(genOperation.getName())%><%=genOperation.getGenParameters().size() == 0 ? "" : "__" + UML2GenModelUtil.getUpperName(genOperation.getParameterTypes("_", false))%>__EOCL_INV;

  <%} else {%>
	/**
	 * The cached OCL query for the '{@link #<%=genOperation.getName()%>(<%=genClass.getImportedInterfaceName()%><%if (!genOperation.getGenParameters().isEmpty()) {%>, <%}%><%=genOperation.getParameterTypes(", ")%>) <em><%=genOperation.getFormattedName()%></em>}' query operation.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #<%=genOperation.getName()%>(<%=genClass.getImportedInterfaceName()%><%if (!genOperation.getGenParameters().isEmpty()) {%>, <%}%><%=genOperation.getParameterTypes(", ")%>)
	 * @generated
	 * @ordered
	 */
	protected static <%=genModel.getImportedName("org.eclipse.ocl.expressions.OCLExpression")%><%if (genModel.getComplianceLevel().getValue() >= GenJDKLevel.JDK50) {%><<%=genModel.getImportedName("org.eclipse.emf.ecore.EClassifier")%>><%}%> <%=UML2GenModelUtil.getUpperName(genOperation.getName())%><%=genOperation.getGenParameters().size() == 0 ? "" : "__" + UML2GenModelUtil.getUpperName(genOperation.getParameterTypes("_", false))%>__EOCL_QRY;

  <%}%>
<%}%>
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
  <%if (genOperation.hasDocumentation() || genOperation.hasParameterDocumentation()) {%>
	 * <!-- begin-model-doc -->
    <%if (genOperation.hasDocumentation()) {%>
	 * <%=genOperation.getDocumentation(genModel.getIndentation(stringBuffer))%>
    <%}%>
	 * @param <%=genClass.safeName(genClass.getUncapName())%> The receiving '<em><b><%=genClass.getFormattedName()%></b></em>' model object.
    <%for (GenParameter genParameter : genOperation.getGenParameters()) {%>
      <%if (genParameter.hasDocumentation()) { String documentation = genParameter.getDocumentation("");%>
        <%if (documentation.contains("\n") || documentation.contains("\r")) {%>
	 * @param <%=genParameter.getName()%>
	 *   <%=genParameter.getDocumentation(genModel.getIndentation(stringBuffer))%>
        <%} else {%>
	 * @param <%=genParameter.getName()%> <%=genParameter.getDocumentation(genModel.getIndentation(stringBuffer))%>
        <%}%>
      <%}%>
    <%}%>
	 * <!-- end-model-doc -->
  <%}%>
	 * @generated
	 */
	public static <%=genClass.getTypeParameters().length() > 0 && genOperation.getTypeParameters(genClass).length() > 0 ? genClass.getTypeParameters().substring(0, genClass.getTypeParameters().length() - 2) + ", " + genOperation.getTypeParameters(genClass).trim().substring(1) : genClass.getTypeParameters().trim() + genOperation.getTypeParameters(genClass).trim()%> <%=genOperation.getImportedType(genClass)%> <%=genOperation.getName()%>(<%=genClass.getImportedInterfaceName()%><%=genClass.getInterfaceTypeArguments().trim()%> <%=genClass.safeName(genClass.getUncapName())%><%if (!genOperation.getGenParameters().isEmpty()) {%>, <%}%><%=genOperation.getParameters(genClass)%>)<%=genOperation.getThrows(genClass)%>
	{
  <%if (genOperation.isInvariant()) {GenClass opClass = genOperation.getGenClass(); String diagnostics = genOperation.getGenParameters().get(0).getName(); String context = genOperation.getGenParameters().get(1).getName();%>
      <%if (UML2GenModelUtil.hasOCLBody(genOperation)) { String oclInv = UML2GenModelUtil.getUpperName(genOperation.getName()) + (genOperation.getGenParameters().size() == 0 ? "" : "__" + UML2GenModelUtil.getUpperName(genOperation.getParameterTypes("_", false))) + "__EOCL_INV";%>
		if (<%=oclInv%> == null)
		{
			<%=genModel.getImportedName("org.eclipse.ocl.ecore.OCL")%>.Helper helper = EOCL_ENV.createOCLHelper();
			helper.setContext(<%=opClass.getQualifiedClassifierAccessor()%>);
			try
			{
				<%=oclInv%> = helper.createInvariant(<%=UML2GenModelUtil.getUpperName(genOperation.getName())%><%=genOperation.getGenParameters().size() == 0 ? "" : "__" + UML2GenModelUtil.getUpperName(genOperation.getParameterTypes("_", false))%>__EOCL_EXP);
			}
			catch (<%=genModel.getImportedName("org.eclipse.ocl.ParserException")%> pe)
			{
				throw new UnsupportedOperationException(pe.getLocalizedMessage());
			}
		}
		if (!EOCL_ENV.createQuery(<%=oclInv%>).check(<%=genClass.safeName(genClass.getUncapName())%>))
      <%} else {%>
		// TODO: implement this method
		// -> specify the condition that violates the invariant
		// -> verify the details of the diagnostic, including severity and message
		// Ensure that you remove @generated or mark it @generated NOT
		if (false)
      <%}%>
		{
			if (<%=diagnostics%> != null)
			{
<%@ include file="Operations/genOperation.diagnostics.override.javajetinc" fail="alternative" %>
<%@ start %>
				<%=diagnostics%>.add
					(new <%=genModel.getImportedName("org.eclipse.emf.common.util.BasicDiagnostic")%>
						(<%=genModel.getImportedName("org.eclipse.emf.common.util.Diagnostic")%>.ERROR,
						 <%=opClass.getGenPackage().getImportedValidatorClassName()%>.DIAGNOSTIC_SOURCE,
						 <%=opClass.getGenPackage().getImportedValidatorClassName()%>.<%=opClass.getOperationID(genOperation)%>,
						 org.eclipse.emf.ecore.plugin.EcorePlugin.INSTANCE.getString("_UI_GenericInvariant_diagnostic", new Object[] { "<%=genOperation.getName()%>", org.eclipse.emf.ecore.util.EObjectValidator.getObjectLabel(<%=genClass.safeName(genClass.getUncapName())%>, <%=context%>) }),<%=genModel.getNonNLS()%><%=genModel.getNonNLS(2)%>
						 new Object [] { <%=genClass.safeName(genClass.getUncapName())%> }));
<%@ end %><%//Operations/genOperation.diagnostics.override.javajetinc%>
			}
			return false;
		}
		return true;
    <%} else if (UML2GenModelUtil.hasOCLBody(genOperation)) { String oclQry = UML2GenModelUtil.getUpperName(genOperation.getName()) + (genOperation.getGenParameters().size() == 0 ? "" : "__" + UML2GenModelUtil.getUpperName(genOperation.getParameterTypes("_", false))) + "__EOCL_QRY";
		GenOperation redefinedGenOperation = genOperation;
		while (UML2GenModelUtil.isDuplicate(redefinedGenOperation)) {
			java.util.List<GenOperation> redefinedGenOperations = UML2GenModelUtil.getRedefinedGenOperations(redefinedGenOperation);
			if (redefinedGenOperations.size() > 0) {
				redefinedGenOperation = redefinedGenOperations.get(0);
			} else {
				break;
			}
		}
		int index = genOperation.getGenClass().getAllGenOperations().indexOf(redefinedGenOperation);%>
		if (<%=oclQry%> == null)
		{
			<%=genModel.getImportedName("org.eclipse.ocl.ecore.OCL")%>.Helper helper = EOCL_ENV.createOCLHelper();
			helper.setOperationContext(<%=genOperation.getGenClass().getQualifiedClassifierAccessor()%>, <%=genOperation.getGenClass().getQualifiedClassifierAccessor()%>.getEAllOperations().get(<%=index%>));
			try
			{
				<%=oclQry%> = helper.createQuery(<%=UML2GenModelUtil.getUpperName(genOperation.getName())%><%=genOperation.getGenParameters().size() == 0 ? "" : "__" + UML2GenModelUtil.getUpperName(genOperation.getParameterTypes("_", false))%>__EOCL_EXP);
			}
			catch (<%=genModel.getImportedName("org.eclipse.ocl.ParserException")%> pe)
			{
				throw new UnsupportedOperationException(pe.getLocalizedMessage());
			}
		}
		<%=genModel.getImportedName("org.eclipse.ocl.ecore.OCL")%>.Query query = EOCL_ENV.createQuery(<%=oclQry%>);
      <%if (!genOperation.getGenParameters().isEmpty()) {%>
		<%=genModel.getImportedName("org.eclipse.ocl.EvaluationEnvironment")%><%if (genModel.getComplianceLevel().getValue() >= GenJDKLevel.JDK50) {%><?, ?, ?, ?, ?><%}%> environment = query.getEvaluationEnvironment();
        <%for (GenParameter genParameter : genOperation.getGenParameters()) {%>
		environment.add("<%=genParameter.getName()%>", <%=genParameter.getName()%>);<%=genModel.getNonNLS()%>
        <%}%>
      <%}%>
      <%if (genOperation.isListType()) {%>
        <%if (genModel.getComplianceLevel().getValue() >= GenJDKLevel.JDK50) {%>
		@SuppressWarnings("unchecked")
        <%}%>
		<%=genModel.getImportedName("java.util.Collection")%><<%=genOperation.getListItemType(null)%>> result = (<%=genModel.getImportedName("java.util.Collection")%><<%=genOperation.getListItemType(null)%>>) query.evaluate(<%=genClass.safeName(genClass.getUncapName())%>);
		return new <%=genModel.getImportedName("org.eclipse.emf.common.util.BasicEList")%>.UnmodifiableEList<<%=genOperation.getListItemType(null)%>>(result.size(), result.toArray());
      <%} else if (genOperation.isPrimitiveType()) {%>
		return ((<%=genOperation.getObjectType(null)%>) query.evaluate(<%=genClass.safeName(genClass.getUncapName())%>)).<%=genOperation.getPrimitiveValueFunction()%>();
      <%} else {%>
		return (<%=genOperation.getImportedType(null)%>) query.evaluate(<%=genClass.safeName(genClass.getUncapName())%>);
      <%}%>
  <%} else {%>
<%@ include file="Operations/genOperation.TODO.override.javajetinc" fail="alternative" %>
<%@ start %>
		// TODO: implement this method
		// Ensure that you remove @generated or mark it @generated NOT
		throw new UnsupportedOperationException();
<%@ end %><%//Operations/genOperation.todo.override.javajetinc%>
  <%}%>
	}

<%@ include file="Operations/genOperation.insert.javajetinc" fail="silent" %>
<%@ end %><%//Operations/genOperation.override.javajetinc%>
<%}%>
} // <%=UML2GenModelUtil.getOperationsClassName(genClass)%>
<%genModel.emitSortedImports();%>