| /******************************************************************************* |
| * Copyright (c) 2006 Oracle Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Oracle Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.bpel.validator.rules; |
| |
| import java.util.List; |
| |
| import javax.xml.namespace.QName; |
| |
| |
| import org.eclipse.bpel.validator.model.ARule; |
| import org.eclipse.bpel.validator.model.Filter; |
| import org.eclipse.bpel.validator.model.Filters; |
| import org.eclipse.bpel.validator.model.IFilter; |
| import org.eclipse.bpel.validator.model.IModelQueryLookups; |
| import org.eclipse.bpel.validator.model.INode; |
| import org.eclipse.bpel.validator.model.IProblem; |
| import org.eclipse.bpel.validator.model.NodeNameFilter; |
| import org.eclipse.bpel.validator.model.ValueFilter; |
| |
| /** |
| * Dependency on the BPEL validation model only in here. |
| * Structurarily, the onEvent looks like this |
| * <pre> |
| <onEvent partnerLink="NCName" |
| portType="QName"? |
| operation="NCName" |
| ( messageType="QName" | element="QName" )? |
| variable="BPELVariableName"? |
| messageExchange="NCName"?>* |
| <correlations>? |
| <correlation set="NCName" initiate="yes|join|no"? />+ |
| </correlations> |
| <fromParts>? |
| <fromPart part="NCName" toVariable="BPELVariableName" />+ |
| </fromParts> |
| <scope ...>...</scope> |
| </onEvent> |
| </pre> |
| */ |
| |
| |
| |
| /** |
| * @author Michal Chmielewski (michal.chmielewski@oracle.com) |
| * @date Aug 28, 2008 |
| * |
| */ |
| |
| @SuppressWarnings( {"hiding","nls","boxing"} ) |
| public class OnEventValidator extends CPartnerActivityValidator { |
| |
| |
| protected INode fMyRoleNode; |
| |
| protected INode fVariable; |
| protected INode fPortTypeFromRole; |
| protected INode fAssociatedScope; |
| |
| protected String fCreateInstance; |
| |
| protected int fFromPartsCount; |
| |
| protected String fVariableName; |
| |
| private INode fVariableType; |
| |
| /** The parent nodes */ |
| static public IFilter<INode> PARENTS = new NodeNameFilter( ND_EVENT_HANDLERS ); |
| |
| |
| /** (non-Javadoc) |
| * @see org.eclipse.bpel.validator.rules.CValidator#checkChildren() |
| */ |
| @Override |
| public void checkChildren () { |
| super.checkChildren(); |
| fFromPartsCount = checkChild(ND_FROM_PARTS,0,1); |
| checkChild(ND_SCOPE, 1, 1); |
| } |
| |
| |
| /** |
| * |
| * @see org.eclipse.bpel.validator.model.Validator#start() |
| */ |
| |
| @Override |
| protected void start () { |
| super.start(); |
| |
| fAssociatedScope = mSelector.selectNode(mNode, ND_SCOPE); |
| |
| setValue("associated.scope",fAssociatedScope); |
| } |
| |
| |
| |
| /** |
| * @see org.eclipse.bpel.validator.rules.CActivityValidator#rule_CheckName_1() |
| */ |
| @Override |
| public void rule_CheckName_1() { |
| // we don't check the name, disable it here. |
| } |
| |
| /** |
| * @see org.eclipse.bpel.validator.rules.CActivityValidator#rule_CheckSuppressJoinFailure_1() |
| */ |
| @Override |
| public void rule_CheckSuppressJoinFailure_1() { |
| // we don't do anything here, disable it on OnMessage |
| } |
| |
| /** |
| * @see org.eclipse.bpel.validator.rules.CPartnerActivityValidator#rule_LookupPartnerLink_0() |
| * |
| * This method overrides the same method in the parent class. |
| */ |
| |
| @ARule( |
| sa = 84, |
| desc = "Partner Link resolution: associated scope first, then ancestor scopes", |
| author = "michal.chmielewski@oracle.com", |
| date = "03/15/2007", |
| errors = "BPELC_MISSING_ROLE" |
| ) |
| @Override |
| public void rule_LookupPartnerLink_0 () { |
| |
| INode context = fAssociatedScope; |
| |
| if (isUndefined(context)) { |
| context = mNode; |
| } |
| |
| fPartnerLinkNode = mModelQuery.lookup (context , |
| IModelQueryLookups.LOOKUP_NODE_PARTNER_LINK , |
| mNode.getAttribute( AT_PARTNER_LINK ) ); |
| |
| |
| markSAExecution(null); |
| } |
| |
| |
| |
| static IFilter<QName> TYPE_DEFS = new ValueFilter<QName>( |
| Filter.QNAME_COMPARATOR, |
| AT_MESSAGE_TYPE, AT_ELEMENT); |
| |
| |
| /** |
| * If the variable attribute is used in the <onEvent> element, either the |
| * messageType or the element attribute MUST be provided in the <onEvent> |
| * element. |
| */ |
| @ARule( |
| sa = 90, |
| desc = "Either messageType or element must be specified if variable variant is used", |
| date = "3/15/2007", |
| author = "michal.chmielewski@oracle.com", |
| errors="BPELC__UNSET_ATTRIBUTE,BPELC__UNRESOLVED_ATTRIBUTE,BPELC__INVALID_ATTRIBUTE_VALUE,BPELC__AT_LEAST_ONE,BPELC__AT_MOST_ONE,BPELC__SPECIFY_NONE" |
| ) |
| |
| public void rule_LookupVariable_5 () { |
| |
| fVariableName = getAttribute(mNode, AT_VARIABLE, KIND_ACTIVITY, Filters.NC_NAME, false); |
| |
| IProblem problem; |
| |
| // messageType or element must be used |
| String msgType = mNode.getAttribute(AT_MESSAGE_TYPE); |
| String elmDecl = mNode.getAttribute(AT_ELEMENT); |
| |
| boolean bMsgTypeEmpty = isEmptyOrWhitespace(msgType); |
| boolean bElmDeclEmpty = isEmptyOrWhitespace(elmDecl); |
| |
| |
| if (isEmpty(fVariableName) == false) { |
| |
| |
| // both empty |
| if ( bElmDeclEmpty && bMsgTypeEmpty) { |
| |
| problem = createError(); |
| problem.fill("BPELC__AT_LEAST_ONE", |
| toString(mNode.nodeName()), |
| KIND_ACTIVITY, |
| TYPE_DEFS, |
| KIND_ATTRIBUTE |
| ); |
| |
| return ; |
| } |
| |
| |
| // both specified |
| if ( !bElmDeclEmpty && !bMsgTypeEmpty) { |
| |
| problem = createError(); |
| problem.fill("BPELC__AT_MOST_ONE", |
| toString(mNode.nodeName()), |
| KIND_ACTIVITY, |
| TYPE_DEFS, |
| KIND_ATTRIBUTE |
| ); |
| } |
| |
| |
| if (!bElmDeclEmpty) { |
| // element is specified |
| fVariableType = mModelQuery.lookup(mNode, |
| IModelQueryLookups.LOOKUP_NODE_XSD_ELEMENT,elmDecl); |
| checkAttributeNode(mNode, fVariableType, AT_ELEMENT, KIND_ACTIVITY); |
| |
| } |
| |
| if (!bMsgTypeEmpty) { |
| // message type is specified |
| fVariableType = mModelQuery.lookup(mNode, |
| IModelQueryLookups.LOOKUP_NODE_MESSAGE_TYPE,msgType); |
| checkAttributeNode(mNode, fVariableType, AT_MESSAGE_TYPE, KIND_ACTIVITY); |
| } |
| |
| |
| } else { |
| |
| // the message type or element declaration must not be present |
| if (!bMsgTypeEmpty || !bElmDeclEmpty) { |
| problem = createError(); |
| problem.fill("BPELC__SPECIFY_NONE", |
| toString(mNode.nodeName()), |
| KIND_NODE, |
| TYPE_DEFS, |
| KIND_ATTRIBUTE); |
| } |
| } |
| |
| } |
| |
| |
| /** |
| * Check if the partner role is defined on this partner link. |
| */ |
| |
| @ARule( |
| sa = 84, |
| author = "michal.chmielewski@oracle.com", |
| date = "9/25/2006", |
| desc = "Checks if my role is defined in onMessage activity.", |
| errors = "BPELC_MISSING_ROLE" |
| ) |
| public void rule_CheckIfMyRoleIsDefined_5 () { |
| fMyRoleNode = lookupRoleNode ( fPartnerLinkNode , AT_MY_ROLE ); |
| } |
| |
| /** |
| * Check if the partnerLinkType derived port type and the port type present |
| * on the receive are one and the same. |
| */ |
| @ARule( |
| author = "michal.chmielewski@oracle.com", |
| date = "03/13/2007", |
| desc = "Checks portType and derived portType values on onEvent.", |
| sa = 5 , |
| errors="BPELC_MISMATCH_ROLE_PORT_TYPE" |
| ) |
| |
| public void rule_CheckRolePortTypeWithReceivePortType_10 () { |
| fPortTypeFromRole = verifyPortTypeFromRole ( fMyRoleNode, AT_MY_ROLE, fPortType ) ; |
| } |
| |
| /** |
| * 1) Receive needs myRole set. |
| * 2) myRole -> portType |
| * 3) portType (has operations) -> operation |
| * 4) operation -> "input" message must be set. |
| */ |
| |
| INode fInputMessage ; |
| |
| /** |
| * Checks the Input Message for the receive. This just makes |
| * sure that input message is defined in the WSDL. |
| * |
| */ |
| |
| |
| @ARule( |
| author = "michal.chmielewski@oracle.com", |
| date = "9/25/2006", |
| desc = "Checks if input message is defined for onEvent activity.", |
| errors="BPELC_PA__NO_MESSAGE,BPELC_PA__MSG_TYPE" |
| ) |
| public void rule_CheckInputMessage_12 () { |
| fInputMessage = findMessageType (fPortTypeFromRole, fOperation,WSDL_ND_INPUT, true ); |
| setValue("input.message.type", fInputMessage); |
| } |
| |
| |
| /** |
| * |
| */ |
| @ARule( |
| sa = 87, |
| desc = "Check message type compatability on onEvent", |
| author = "michal.chmielewski@oracle.com", |
| date = "03/15/2007", |
| errors="BPELC_PA__MESSAGE_TYPE_MISMATCH" |
| ) |
| public void rule_CheckVariableAndMessageStructureCompatibility_20 () |
| { |
| IProblem problem; |
| |
| if (isUndefined(fInputMessage) || isUndefined( fVariableType )) { |
| return ; |
| } |
| |
| // source -> destination |
| if (mModelQuery.check( IModelQueryLookups.TEST_COMPATIBLE_PARTNER_ACTIVITY_MESSAGE, fVariableType, fInputMessage ) == false) { |
| |
| problem = createError( ); |
| problem.fill( "BPELC_PA__MESSAGE_TYPE_MISMATCH", //$NON-NLS-1$ |
| toString(mNode.nodeName()), |
| AT_VARIABLE, |
| fVariableName, |
| fInputMessage, |
| fVariableType |
| ); |
| } |
| |
| markSAExecution(null); |
| } |
| |
| |
| /** |
| * Check the presence of fromParts. |
| */ |
| |
| |
| |
| @ARule( |
| sa = 85, |
| desc = "Check to see if fromPart is specified; if so then " + |
| " variable must not be used onEvent.", |
| author = "michal.chmielewski@oracle.com", |
| date = "03/20/2007", |
| errors="BPELC__PA_PARTS" |
| ) |
| public void rule_checkFromPartsPresence_50 () { |
| |
| List<INode> fFromParts; |
| |
| fFromParts = mSelector.selectNodes(mNode, ND_FROM_PARTS, ND_FROM_PART ); |
| |
| IProblem problem; |
| |
| boolean bNoVariable = isEmptyOrWhitespace(mNode.getAttribute(AT_VARIABLE)); |
| if (fFromParts.size() > 0 && !bNoVariable) { |
| problem = createError(); |
| problem.fill("BPELC__PA_PARTS", |
| toString(mNode.nodeName()), |
| ND_FROM_PART, |
| AT_VARIABLE, |
| KIND_ACTIVITY); |
| } |
| |
| |
| if (fFromParts.size() == 0 && bNoVariable) { |
| problem = createError(); |
| problem.fill("BPELC__PA_PARTS", |
| toString(mNode.nodeName()), |
| ND_FROM_PART, |
| AT_VARIABLE, |
| KIND_ACTIVITY); |
| } |
| } |
| |
| } |
| |