0001: /*
0002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003: *
0004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005: *
0006: * The contents of this file are subject to the terms of either the GNU
0007: * General Public License Version 2 only ("GPL") or the Common
0008: * Development and Distribution License("CDDL") (collectively, the
0009: * "License"). You may not use this file except in compliance with the
0010: * License. You can obtain a copy of the License at
0011: * http://www.netbeans.org/cddl-gplv2.html
0012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013: * specific language governing permissions and limitations under the
0014: * License. When distributing the software, include this License Header
0015: * Notice in each file and include the License file at
0016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
0017: * particular file as subject to the "Classpath" exception as provided
0018: * by Sun in the GPL Version 2 section of the License file that
0019: * accompanied this code. If applicable, add the following below the
0020: * License Header, with the fields enclosed by brackets [] replaced by
0021: * your own identifying information:
0022: * "Portions Copyrighted [year] [name of copyright owner]"
0023: *
0024: * Contributor(s):
0025: *
0026: * The Original Software is NetBeans. The Initial Developer of the Original
0027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
0028: * Microsystems, Inc. All Rights Reserved.
0029: *
0030: * If you wish your version of this file to be governed by only the CDDL
0031: * or only the GPL Version 2, indicate your decision by adding
0032: * "[Contributor] elects to include this software in this distribution
0033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034: * single choice of license, a recipient has the option to distribute
0035: * your version of this file under either the CDDL, the GPL Version 2 or
0036: * to extend the choice of license to its licensees as provided above.
0037: * However, if you add GPL Version 2 code and therefore, elected the GPL
0038: * Version 2 license, then the option applies only if the new code is
0039: * made subject to such option by the copyright holder.
0040: */
0041: package org.netbeans.modules.bpel.validation.statics;
0042:
0043: import java.net.URI;
0044: import java.net.URISyntaxException;
0045: import java.util.ArrayList;
0046: import java.util.Arrays;
0047: import java.util.Collection;
0048: import java.util.Collections;
0049: import java.util.HashMap;
0050: import java.util.HashSet;
0051: import java.util.LinkedList;
0052: import java.util.List;
0053: import java.util.Map;
0054: import java.util.Set;
0055: import java.util.Map.Entry;
0056:
0057: import java.util.ArrayList;
0058: import java.util.Arrays;
0059: import java.util.Collection;
0060: import java.util.HashMap;
0061: import java.util.LinkedList;
0062: import java.util.List;
0063: import java.util.Map;
0064:
0065: import org.netbeans.modules.bpel.model.api.BaseScope;
0066: import org.netbeans.modules.bpel.model.api.BpelContainer;
0067: import org.netbeans.modules.bpel.model.api.BpelModel;
0068: import org.netbeans.modules.bpel.model.api.Catch;
0069: import org.netbeans.modules.bpel.model.api.Compensate;
0070: import org.netbeans.modules.bpel.model.api.CompensateScope;
0071: import org.netbeans.modules.bpel.model.api.CompensationHandler;
0072: import org.netbeans.modules.bpel.model.api.CorrelationContainer;
0073: import org.netbeans.modules.bpel.model.api.CorrelationSet;
0074: import org.netbeans.modules.bpel.model.api.CorrelationSetContainer;
0075: import org.netbeans.modules.bpel.model.api.EventHandlers;
0076: import org.netbeans.modules.bpel.model.api.Extension;
0077: import org.netbeans.modules.bpel.model.api.FaultHandlers;
0078: import org.netbeans.modules.bpel.model.api.Flow;
0079: import org.netbeans.modules.bpel.model.api.ForEach;
0080: import org.netbeans.modules.bpel.model.api.From;
0081: import org.netbeans.modules.bpel.model.api.FromPart;
0082: import org.netbeans.modules.bpel.model.api.FromPartContainer;
0083: import org.netbeans.modules.bpel.model.api.Import;
0084: import org.netbeans.modules.bpel.model.api.Invoke;
0085: import org.netbeans.modules.bpel.model.api.Link;
0086: import org.netbeans.modules.bpel.model.api.LinkContainer;
0087: import org.netbeans.modules.bpel.model.api.OnEvent;
0088: import org.netbeans.modules.bpel.model.api.OnMessage;
0089: import org.netbeans.modules.bpel.model.api.OperationReference;
0090: import org.netbeans.modules.bpel.model.api.PartnerLink;
0091: import org.netbeans.modules.bpel.model.api.PartnerLinkContainer;
0092: import org.netbeans.modules.bpel.model.api.PatternedCorrelation;
0093: import org.netbeans.modules.bpel.model.api.PatternedCorrelationContainer;
0094: import org.netbeans.modules.bpel.model.api.Pick;
0095: import org.netbeans.modules.bpel.model.api.Process;
0096: import org.netbeans.modules.bpel.model.api.ReThrow;
0097: import org.netbeans.modules.bpel.model.api.Receive;
0098: import org.netbeans.modules.bpel.model.api.Reply;
0099: import org.netbeans.modules.bpel.model.api.Requester;
0100: import org.netbeans.modules.bpel.model.api.Responder;
0101: import org.netbeans.modules.bpel.model.api.Scope;
0102: import org.netbeans.modules.bpel.model.api.Source;
0103: import org.netbeans.modules.bpel.model.api.SourceContainer;
0104: import org.netbeans.modules.bpel.model.api.Target;
0105: import org.netbeans.modules.bpel.model.api.TargetContainer;
0106: import org.netbeans.modules.bpel.model.api.TerminationHandler;
0107: import org.netbeans.modules.bpel.model.api.Variable;
0108: import org.netbeans.modules.bpel.model.api.VariableContainer;
0109: import org.netbeans.modules.bpel.model.api.VariableDeclaration;
0110: import org.netbeans.modules.bpel.model.api.references.BpelReference;
0111: import org.netbeans.modules.bpel.model.api.references.SchemaReference;
0112: import org.netbeans.modules.bpel.model.api.references.WSDLReference;
0113: import org.netbeans.modules.bpel.model.api.support.ImportHelper;
0114: import org.netbeans.modules.bpel.model.api.support.Pattern;
0115: import org.netbeans.modules.bpel.model.api.support.Roles;
0116: import org.netbeans.modules.bpel.model.api.support.TBoolean;
0117: import org.netbeans.modules.bpel.model.impl.BpelModelImpl;
0118: import org.netbeans.modules.bpel.model.impl.ContainerIterator;
0119: import org.netbeans.modules.bpel.model.impl.Utils;
0120: import org.netbeans.modules.xml.schema.model.GlobalElement;
0121: import org.netbeans.modules.xml.schema.model.GlobalSimpleType;
0122: import org.netbeans.modules.xml.schema.model.GlobalType;
0123: import org.netbeans.modules.xml.wsdl.model.Input;
0124: import org.netbeans.modules.xml.wsdl.model.Message;
0125: import org.netbeans.modules.xml.wsdl.model.NotificationOperation;
0126: import org.netbeans.modules.xml.wsdl.model.OneWayOperation;
0127: import org.netbeans.modules.xml.wsdl.model.Operation;
0128: import org.netbeans.modules.xml.wsdl.model.Output;
0129: import org.netbeans.modules.xml.wsdl.model.Part;
0130: import org.netbeans.modules.xml.wsdl.model.PortType;
0131: import org.netbeans.modules.xml.wsdl.model.RequestResponseOperation;
0132: import org.netbeans.modules.xml.wsdl.model.SolicitResponseOperation;
0133: import org.netbeans.modules.xml.wsdl.model.WSDLModel;
0134: import org.netbeans.modules.xml.wsdl.model.WSDLModelFactory;
0135: import org.netbeans.modules.xml.wsdl.model.extensions.bpel.CorrelationProperty;
0136: import org.netbeans.modules.xml.wsdl.model.extensions.bpel.PropertyAlias;
0137: import org.netbeans.modules.xml.wsdl.model.Message;
0138: import org.netbeans.modules.xml.wsdl.model.OneWayOperation;
0139: import org.netbeans.modules.xml.wsdl.model.Operation;
0140: import org.netbeans.modules.xml.wsdl.model.RequestResponseOperation;
0141: import org.netbeans.modules.xml.wsdl.model.extensions.bpel.CorrelationProperty;
0142: import org.netbeans.modules.xml.xam.Component;
0143: import org.netbeans.modules.xml.xam.Model;
0144: import org.netbeans.modules.xml.xam.dom.NamedComponentReference;
0145: import org.netbeans.modules.bpel.validation.core.BpelValidator;
0146: import org.netbeans.modules.xml.xam.locator.CatalogModelException;
0147: import org.netbeans.modules.xml.xam.locator.CatalogModelFactory;
0148: import org.netbeans.modules.xml.schema.model.GlobalElement;
0149: import org.netbeans.modules.xml.schema.model.SchemaModel;
0150: import org.netbeans.modules.xml.schema.model.SchemaModelFactory;
0151: import org.netbeans.modules.bpel.model.api.BpelEntity;
0152: import org.netbeans.modules.bpel.model.api.Activity;
0153: import org.netbeans.modules.bpel.model.impl.Utils;
0154: import org.netbeans.modules.bpel.model.impl.Utils.Pair;
0155: import javax.xml.namespace.QName;
0156: import org.netbeans.modules.xml.xam.Model.State;
0157: import org.netbeans.modules.xml.xam.ModelSource;
0158: import org.netbeans.modules.bpel.model.api.support.Initiate;
0159: import org.netbeans.modules.bpel.model.api.NamedElement;
0160: import org.netbeans.modules.bpel.model.api.Empty;
0161: import org.netbeans.modules.bpel.model.api.CreateInstanceActivity;
0162: import org.netbeans.modules.bpel.model.api.Sequence;
0163: import org.netbeans.modules.bpel.model.api.ExtendableActivity;
0164: import org.netbeans.modules.bpel.model.api.CompositeActivity;
0165: import org.netbeans.modules.bpel.model.api.Correlation;
0166: import org.netbeans.modules.bpel.model.api.BaseCorrelation;
0167: import org.netbeans.modules.bpel.model.api.While;
0168: import org.netbeans.modules.bpel.model.api.ActivityHolder;
0169: import org.netbeans.modules.bpel.model.api.ToPart;
0170: import org.netbeans.modules.bpel.model.api.RepeatUntil;
0171: import org.netbeans.modules.bpel.model.api.PartnerLinkReference;
0172: import org.netbeans.modules.bpel.model.api.PortTypeReference;
0173: import static org.netbeans.modules.soa.ui.util.UI.*;
0174:
0175: /**
0176: * @author Vladimir Yaroslavskiy
0177: * @version 2007.05.03
0178: */
0179: public final class Validator extends BpelValidator {
0180:
0181: @Override
0182: public void visit(PartnerLink p) {
0183:
0184: // Rule: A partnerLink MUST specify the myRole or the partnerRole, or both.
0185: // This syntactic constraint MUST be statically enforced.
0186: if ((p.getMyRole() == null || p.getMyRole().equals(""))
0187: && (p.getPartnerRole() == null || p.getPartnerRole()
0188: .equals(""))) {
0189: addError(FIX_PARTNER_LINK_ERROR, p);
0190: }
0191:
0192: // Rule: The initializePartnerRole attribute MUST NOT be used on a partnerLink
0193: // that does not have a partner role; this restriction MUST be statically enforced.
0194: if (p.getPartnerRole() == null || p.getPartnerRole().equals("")) {
0195: if ((p.getInitializePartnerRole() != null)
0196: && (!p.getInitializePartnerRole().equals(
0197: TBoolean.INVALID))) {
0198: addError(FIX_INITIALISE_PARTNER_ROLE, p);
0199: }
0200: }
0201: }
0202:
0203: @Override
0204: public void visit(Invoke invoke) {
0205: // Rule: Porttype should not be solicit-response or Notification.
0206: checkSolicitResponsePortType(invoke, invoke.getPortType());
0207: checkNotificationPortType(invoke, invoke.getPortType());
0208:
0209: // Rule: PortType should not contain overloaded operation names.
0210: checkOverloadedPortTypeOperation(invoke, invoke.getPortType());
0211:
0212: //Rule: Input variable and toPart should not be used in combinatation.
0213: checkInputVariableToPartCombination(invoke);
0214:
0215: //Rule: Output variable and fromPart should not be used in combinatation.
0216: checkOutputVariableFromPartCombination(invoke);
0217:
0218: // Rule: FromPart element should have a valid part attribute.
0219: checkValidPartAttributeFromPartElement(invoke);
0220:
0221: // Rule: toPart element should have a valid part attribute.
0222: checkValidPartAttributeToPartElement(invoke);
0223:
0224: /*
0225: * Rule :If the portType attribute is included for readability,
0226: * in a <receive>, <reply>, <invoke>, <onEvent> or <onMessage>
0227: * element, the value of the portType attribute MUST match the
0228: * portType value implied by the combination of the specified
0229: * partnerLink and the role implicitly specified by the activity.
0230: */
0231: checkPortTypeCombinedPartnerLink(invoke);
0232:
0233: /*
0234: * Rule : For <invoke>, one-way invocation requires only the
0235: * inputVariable (or its equivalent <toPart>'s) since a response
0236: * is not expected as part of the operation. Request-response
0237: * invocation requires both an inputVariable
0238: * (or its equivalent <toPart>'s) and an outputVariable
0239: * (or its equivalent <fromPart>'s). If a WSDL message definition
0240: * does not contain any parts, then the associated attributes variable,
0241: * inputVariable or outputVariable, or the associated <fromParts> or
0242: * <toParts> elements MAY be omitted. The outputVariable (or its
0243: * equivalent <fromPart>'s) must be only specified for request-response
0244: * invocations.
0245: *
0246: * Rule : When the optional inputVariable and outputVariable
0247: * attributes are being used in an <invoke> activity,
0248: * the variables referenced by inputVariable and outputVariable
0249: * MUST be messageType variables whose QName matches the QName of the
0250: * input and output message type used in the operation, respectively,
0251: * except as follows: if the WSDL operation used in an <invoke>
0252: * activity uses a message containing exactly one part which itself is
0253: * defined using an element, then a variable of the same element type
0254: * as used to define the part MAY be referenced by the inputVariable
0255: * and outputVariable attributes respectively.
0256: */
0257: checkInputOutputVariableOperation(invoke);
0258:
0259: // Rule: All the WSDL message parts must be completely initialised
0260: // when using <toPart> element.
0261: checkAnyMissingToPartElementInInvoke(invoke);
0262:
0263: }
0264:
0265: @Override
0266: public void visit(Receive receive) {
0267: // Rule: Porttype should not be solicit-response or Notification.
0268: checkSolicitResponsePortType(receive, receive.getPortType());
0269: checkNotificationPortType(receive, receive.getPortType());
0270:
0271: // Rule: PortType should not contain overloaded operation names.
0272: checkOverloadedPortTypeOperation(receive, receive.getPortType());
0273:
0274: /*
0275: * Rule: On <receive> variable and <fromPart> must not be used at the same time.
0276: *
0277: * Rule : One-way invocation requires only the inputVariable (or its
0278: * equivalent <toPart> elements) since a response is not
0279: * expected as part of the operation (see section 10.4. Providing
0280: * Web Service Operations Receive and Reply in spec). Requestresponse
0281: * invocation requires both an inputVariable (or its
0282: * equivalent <toPart> elements) and an outputVariable (or
0283: * its equivalent <fromPart> elements). If a WSDL message
0284: * definition does not contain any parts, then the associated
0285: * attributes variable, inputVariable or outputVariable,
0286: * MAY be omitted,and the <fromParts> or <toParts>
0287: * construct MUST be omitted., IZ #87444
0288: */
0289: checkReceiveVariableFromPartCombination(receive);
0290:
0291: /*
0292: * Rule :If the portType attribute is included for readability,
0293: * in a <receive>, <reply>, <invoke>, <onEvent> or <onMessage>
0294: * element, the value of the portType attribute MUST match the
0295: * portType value implied by the combination of the specified
0296: * partnerLink and the role implicitly specified by the activity.
0297: */
0298: checkPortTypeCombinedPartnerLink(receive);
0299:
0300: /*
0301: * A "start activity" is a <receive> or <pick> activity that is
0302: * annotated with a createInstance="yes" attribute.
0303: * Activities other than the following: start activities, <scope>,
0304: * <flow>, <sequence>, and <empty> MUST NOT be performed prior to
0305: * or simultaneously with start activities.
0306: */
0307: checkOrderOfActivities(receive);
0308:
0309: }
0310:
0311: @Override
0312: public void visit(Reply reply) {
0313: // Rule: Porttype should not be solicit-response or Notification.
0314: checkSolicitResponsePortType(reply, reply.getPortType());
0315: checkNotificationPortType(reply, reply.getPortType());
0316:
0317: // Rule: PortType should not contain overloaded operation names.
0318: checkOverloadedPortTypeOperation(reply, reply.getPortType());
0319:
0320: /* Rule: On <reply> variable and <toPart> must not be used at the same time.
0321: *
0322: * Rule : One-way invocation requires only the inputVariable (or its
0323: * equivalent <toPart> elements) since a response is not
0324: * expected as part of the operation (see section 10.4. Providing
0325: * Web Service Operations Receive and Reply in spec). Requestresponse
0326: * invocation requires both an inputVariable (or its
0327: * equivalent <toPart> elements) and an outputVariable (or
0328: * its equivalent <fromPart> elements). If a WSDL message
0329: * definition does not contain any parts, then the associated
0330: * attributes variable, inputVariable or outputVariable,
0331: * MAY be omitted,and the <fromParts> or <toParts>
0332: * construct MUST be omitted., IZ #87444
0333:
0334: */
0335: checkReplyVariableToPartCombination(reply);
0336:
0337: /*
0338: * Rule :If the portType attribute is included for readability,
0339: * in a <receive>, <reply>, <invoke>, <onEvent> or <onMessage>
0340: * element, the value of the portType attribute MUST match the
0341: * portType value implied by the combination of the specified
0342: * partnerLink and the role implicitly specified by the activity.
0343: */
0344: checkPortTypeCombinedPartnerLink(reply);
0345:
0346: // Rule: All the WSDL message parts must be completely initialised
0347: // when using <toPart> element.
0348: checkAnyMissingToPartElementInReply(reply);
0349: }
0350:
0351: @Override
0352: public void visit(OnMessage onMessage) {
0353: // Rule: Porttype should not be solicit-response or Notification.
0354: checkSolicitResponsePortType(onMessage, onMessage.getPortType());
0355: checkNotificationPortType(onMessage, onMessage.getPortType());
0356:
0357: // Rule: PortType should not contain overloaded operation names.
0358: checkOverloadedPortTypeOperation(onMessage, onMessage
0359: .getPortType());
0360:
0361: /*
0362: * Rule :If the portType attribute is included for readability,
0363: * in a <receive>, <reply>, <invoke>, <onEvent> or <onMessage>
0364: * element, the value of the portType attribute MUST match the
0365: * portType value implied by the combination of the specified
0366: * partnerLink and the role implicitly specified by the activity.
0367: */
0368: checkPortTypeCombinedPartnerLink(onMessage);
0369:
0370: // Variable and <fromPart> must not be used at the simultaneously.
0371: checkOnMessageVariableFromPartCombination(onMessage);
0372: }
0373:
0374: @Override
0375: public void visit(ReThrow reThrow) {
0376: /*
0377: * Rule : The <rethrow> activity MUST only be used within a faultHandler
0378: * (i.e. <catch> and <catchAll> elements).
0379: */
0380: boolean isInsideFaultHandlers = Utils.hasAscendant(reThrow,
0381: FaultHandlers.class);
0382: if (!isInsideFaultHandlers) {
0383: addError(FIX_RETHROW_OCCURANCE, reThrow);
0384: }
0385: }
0386:
0387: @Override
0388: public void visit(Compensate compensate) {
0389: checkCompensateOccurance(compensate);
0390: }
0391:
0392: @Override
0393: public void visit(CompensateScope compensateScope) {
0394: checkCompensateOccurance(compensateScope);
0395: }
0396:
0397: @Override
0398: public void visit(From from) {
0399: Roles roles = from.getEndpointReference();
0400: if (Roles.MY_ROLE.equals(roles)) {
0401: BpelReference<PartnerLink> ref = from.getPartnerLink();
0402: boolean referenceHasMyRole = (ref != null)
0403: && (ref.get() != null)
0404: && (ref.get().getMyRole() != null);
0405: /*
0406: * Rule : In the from-spec of the partnerLink variant of <assign>
0407: * the value "myRole" for attribute endpointReference is only
0408: * permitted when the partnerLink specifies the attribute myRole.
0409: */
0410: if (!referenceHasMyRole) {
0411: addError(FIX_ENDPOINT_REFRENCE, from, Roles.MY_ROLE
0412: .toString());
0413: }
0414: } else if (Roles.PARTNER_ROLE.equals(roles)) {
0415: BpelReference<PartnerLink> ref = from.getPartnerLink();
0416: boolean referenceHasPartnerRole = (ref != null)
0417: && (ref.get() != null)
0418: && (ref.get().getPartnerRole() != null);
0419: /*
0420: * In the from-spec of the partnerLink variant of <assign> the
0421: * value "partnerRole" for attribute endpointReference is only
0422: * permitted when the partnerLink specifies the attribute
0423: * partnerRole.
0424: */
0425: if (!referenceHasPartnerRole) {
0426: addError(FIX_ENDPOINT_REFRENCE, from,
0427: Roles.PARTNER_ROLE.toString());
0428: }
0429: }
0430: }
0431:
0432: @Override
0433: public void visit(Process process) {
0434: visitBaseScope(process);
0435:
0436: /*
0437: * Rule : To be instantiated, an executable business process MUST contain at
0438: * least one <receive> or <pick> activity annotated with a
0439: * createInstance="yes" attribute.
0440: *
0441: * Rule : If a process has multiple start activities with
0442: * correlation sets then all such activities MUST share at
0443: * least one common correlationSet and all common correlationSets defined
0444: * on all the activities MUST have the value of the initiate
0445: * attribute be set to "join".
0446: */
0447: checkInstantiableActivities(process);
0448:
0449: /*
0450: * Rule : A WS-BPEL process definition MUST NOT be accepted for
0451: * processing if it defines two or more propertyAliases for the
0452: * same property name and WS-BPEL variable type.
0453: */
0454: checkPropertyAliasMultiplicity(process);
0455:
0456: /*
0457: * Rule :
0458: * Determine which languages are referenced by queryLanguage or
0459: * expressionLanguage attributes either in the WS-BPEL process
0460: * definition itself or in any WS-BPEL property definitions in
0461: * associated WSDLs and if any referenced language is unsupported by the
0462: * WS-BPEL processor then the processor MUST reject the submitted
0463: * WS-BPEL process definition.
0464: */
0465: String query = process.getQueryLanguage();
0466: String expression = process.getExpressionLanguage();
0467: if ((query != null && !SUPPORTED_LANGAGE.equals(query))
0468: || (expression != null && !SUPPORTED_LANGAGE
0469: .equals(expression))) {
0470: addError(FIX_SUPPORTED_LANGUAGE, process, SUPPORTED_LANGAGE);
0471: }
0472: }
0473:
0474: @Override
0475: public void visit(Scope scope) {
0476: visitBaseScope(scope);
0477:
0478: /*
0479: * Rule : A scope with the isolated attribute set to "yes" is called
0480: * an isolated scope. Isolated scopes MUST NOT contain other isolated scopes.
0481: */
0482: TBoolean isolated = scope.getIsolated();
0483: if (TBoolean.YES.equals(isolated)) {
0484: List<Component> collection = new LinkedList<Component>();
0485: collectIsolatedScopes(scope, collection);
0486:
0487: if (collection.size() > 0) {
0488: collection.add(scope);
0489:
0490: for (Component component : collection) {
0491: addError(FIX_ISOLATED_SCOPES, component);
0492: }
0493: }
0494: }
0495: }
0496:
0497: @Override
0498: public void visit(LinkContainer container) {
0499: /*
0500: * Rule : A links name MUST be unique amongst all link names
0501: * defined within the same immediately enclosing flow.
0502: * This requirement MUST be statically enforced.
0503: */
0504: Link[] links = container.getLinks();
0505: if (links == null) {
0506: return;
0507: }
0508: Map<String, Collection<Component>> map = new HashMap<String, Collection<Component>>();
0509: for (Link link : links) {
0510: addNamedToMap(link, map);
0511: }
0512:
0513: addErrorForNamed(map, FIX_MULTIPLE_NAMED_LINKS);
0514: }
0515:
0516: @Override
0517: public void visit(SourceContainer container) {
0518: /*
0519: * Rule : An activity MAY declare itself to be the source
0520: * of one or more links by including one or more <source> elements.
0521: * Each <source> element MUST use a distinct link name.
0522: */
0523: Source[] sources = container.getSources();
0524: if (sources == null) {
0525: return;
0526: }
0527: Map<String, Collection<Component>> map = new HashMap<String, Collection<Component>>();
0528: for (Source source : sources) {
0529: addNamedToMap(source, map,
0530: LazyHolder.SOURCE_LINK_NAME_ACCESS);
0531: }
0532: addErrorForNamed(map, FIX_MULTIPLE_SOURCE_LINK_REFERENCES);
0533: }
0534:
0535: @Override
0536: public void visit(TargetContainer container) {
0537: /*
0538: * Rule : An activity MAY declare itself to be the target of one or more
0539: * links by including one or more <target> elements. Each <target>
0540: * element associated with a given activity MUST use a link name distinct
0541: * from all other <target> elements at that activity.
0542: */
0543: Target[] targets = container.getTargets();
0544: if (targets == null) {
0545: return;
0546: }
0547: Map<String, Collection<Component>> map = new HashMap<String, Collection<Component>>();
0548: for (Target target : targets) {
0549: addNamedToMap(target, map,
0550: LazyHolder.TARGET_LINK_NAME_ACCESS);
0551: }
0552: addErrorForNamed(map, FIX_MULTIPLE_TARGET_LINK_REFERENCES);
0553: }
0554:
0555: @Override
0556: public void visit(ForEach forEach) {
0557: /*
0558: * Rule : For <forEach> the enclosed scope MUST NOT declare a variable
0559: * with the same name as specified in the counterName attribute of <forEach>.
0560: */
0561: String counterName = forEach.getCounterName();
0562: if (counterName == null) {
0563: return;
0564: }
0565: ContainerIterator<BaseScope> containerIterator = new ContainerIterator<BaseScope>(
0566: forEach, BaseScope.class);
0567: BaseScope scope = containerIterator.next();
0568: assert scope != null;
0569: VariableContainer container = scope.getVariableContainer();
0570: if (container == null) {
0571: return;
0572: }
0573: Variable[] variables = container.getVariables();
0574: if (variables == null) {
0575: return;
0576: }
0577: for (Variable variable : variables) {
0578: if (counterName.equals(variable.getName())) {
0579: Collection<Component> collection = new ArrayList<Component>(
0580: 2);
0581: collection.add(forEach);
0582: collection.add(variable);
0583:
0584: for (Component component : collection) {
0585: addError(FIX_DUPLICATE_COUNTER_NAME, component,
0586: counterName);
0587: }
0588: break;
0589: }
0590: }
0591:
0592: /*
0593: * Check Variable name
0594: */
0595: checkVariableName(forEach);
0596: }
0597:
0598: @Override
0599: public void visit(VariableContainer container) {
0600: checkVariableContainer(container);
0601: }
0602:
0603: @Override
0604: public void visit(OnEvent onEvent) {
0605: if (onEvent.getVariable() != null
0606: && onEvent.getMessageType() == null
0607: && onEvent.getElement() == null) {
0608: addError(FIX_ON_EVENT_VARAIBLE, onEvent);
0609: }
0610:
0611: /*
0612: * Rule :If the portType attribute is included for readability,
0613: * in a <receive>, <reply>, <invoke>, <onEvent> or <onMessage>
0614: * element, the value of the portType attribute MUST match the
0615: * portType value implied by the combination of the specified
0616: * partnerLink and the role implicitly specified by the activity.
0617: */
0618: checkPortTypeCombinedPartnerLink(onEvent);
0619:
0620: /*
0621: * Check variable name.
0622: */
0623: checkVariableName(onEvent);
0624:
0625: /*
0626: * Rule : For <onEvent>, the type of the variable (as specified by the
0627: * messageType attribute) MUST be the same as the type of the input
0628: * message defined by operation referenced by the operation attribute.
0629: * Optionally the messageType attribute may be omitted and instead the
0630: * element attribute substituted if the message to be received has a
0631: * single part and that part is defined with an element type.
0632: * That element type MUST be an exact match of the element type
0633: * referenced by the element attribute.
0634: */
0635: checkMessageType(onEvent);
0636:
0637: /*
0638: * For <onEvent>, variables referenced by the variable attribute of
0639: * <fromPart> elements or the variable attribute of an <onEvent> element
0640: * are implicitly declared in the associated scope of the event handler.
0641: * Variables of the same names MUST NOT be explicitly declared in the
0642: * associated scope. The variable references are resolved to the
0643: * associated scope only and MUST NOT be resolved to the ancestor
0644: * scopes.
0645: */
0646:
0647: checkImplicitlyDeclaredVars(onEvent);
0648:
0649: FromPartContainer fromParts = onEvent.getFromPartContaner();
0650: if (fromParts != null) {
0651: for (FromPart part : fromParts.getFromParts()) {
0652: checkVariableName(part);
0653: }
0654: }
0655: }
0656:
0657: @Override
0658: public void visit(EventHandlers handlers) {
0659: /*
0660: * Rule : An event handler MUST contain at least one <onEvent>
0661: * or <onAlarm> element.
0662: */
0663: if (handlers.sizeOfOnAlarms() == 0
0664: && handlers.sizeOfOnEvents() == 0) {
0665: addError(FIX_EVENT_HANDLERS, handlers);
0666: }
0667: }
0668:
0669: @Override
0670: public void visit(Catch catc) {
0671: /*
0672: * Rule : For the <catch> construct; to have a defined type
0673: * associated with the fault variable, the faultVariable
0674: * attribute MUST only be used if either the faultMessageType or
0675: * faultElement attributes, but not both, accompany it.
0676: * The faultMessageType and faultElement attributes MUST NOT be
0677: * used unless accompanied by faultVariable attribute.
0678: */
0679: String faultVariable = catc.getFaultVariable();
0680: SchemaReference<GlobalElement> element = catc.getFaultElement();
0681: WSDLReference<Message> message = catc.getFaultMessageType();
0682:
0683: if (faultVariable != null && element == null && message == null) {
0684: addError(FIX_FAULT_VARIABLE_TYPE, catc);
0685: }
0686: if (element != null && message != null) {
0687: addError(FIX_FAULT_VARIABLE_TYPE, catc);
0688: }
0689: if (faultVariable == null
0690: && (element != null || message != null)) {
0691: addError(FIX_ODD_FAULT_TYPE, catc);
0692: }
0693: // Check fault variable name
0694: checkVariableName(catc);
0695: }
0696:
0697: @Override
0698: public void visit(FaultHandlers handlers) {
0699: /*
0700: * Rule : There MUST be at least one <catch> or <catchAll> element
0701: * within a <faultHandlers> element.
0702: */
0703: if (handlers.sizeOfCathes() == 0
0704: && handlers.getCatchAll() == null) {
0705: addError(FIX_FAULT_HANDLERS, handlers);
0706: }
0707:
0708: /*
0709: * Rule : The root scope inside a FCT-handler MUST not have a compensation handler.
0710: */
0711: checkFCTScope(handlers);
0712: }
0713:
0714: @Override
0715: public void visit(Import imp) {
0716: final Model model = getImportModel(imp);
0717:
0718: /*
0719: * If the model is null -- skip all other checks, but DO NOT generate
0720: * a warning or an error, as it will be done by BPELImportsValidator.
0721: */
0722: if (model == null) {
0723: return;
0724: }
0725: final String namespace = imp.getNamespace();
0726: final String ns = getTargetNamespace(imp);
0727:
0728: if (namespace == null) {
0729: /*
0730: * If no namespace is specified then the imported definitions MUST NOT
0731: * contain a targetNamespace specification.
0732: * This requirement MUST be statically enforced.
0733: */
0734: if (ns != null) {
0735: addError(FIX_ABSENT_NAMESPACE_IN_IMPORT, imp);
0736: }
0737: } else {
0738: /*
0739: * If a namespace attribute is specified on an <import> then
0740: * the imported definitions MUST be in that namespace.
0741: * This requirement MUST be statically enforced.
0742: */
0743: if (!namespace.equals(ns)) {
0744: addError(FIX_BAD_NAMESPACE_IN_IMPORT, imp);
0745: }
0746: }
0747:
0748: /*
0749: * Rule: The value of the importType attribute of element <import>
0750: * MUST be set to http://www.w3.org/2001/XMLSchema when importing XML
0751: * Schema 1.0 documents, and to http://schemas.xmlsoap.org/wsdl/ when
0752: * importing WSDL 1.1 documents.
0753: */
0754: checkImportType(imp);
0755: }
0756:
0757: @Override
0758: public void visit(Variable variable) {
0759: checkVariableName(variable);
0760:
0761: /*
0762: * The messageType, type or element attributes are used to
0763: * specify the type of a variable. Exactly one of these attributes
0764: * MUST be used.
0765: */
0766: int count = variable.getType() == null ? 0 : 1;
0767: count += variable.getMessageType() == null ? 0 : 1;
0768: count += variable.getElement() == null ? 0 : 1;
0769: if (count != 1) {
0770: addError(FIX_VARIABLE_TYPES, variable);
0771: }
0772: }
0773:
0774: @Override
0775: public void visit(Pick pick) {
0776: if (TBoolean.YES.equals(pick.getCreateInstance())
0777: && pick.sizeOfOnAlarms() != 0) {
0778: Collection<Component> collection = Arrays
0779: .asList((Component[]) pick.getOnAlarms());
0780:
0781: for (Component component : collection) {
0782: addError(FIX_PICK_MESSAGES, component);
0783: }
0784: }
0785:
0786: /*
0787: * A "start activity" is a <receive> or <pick> activity that is
0788: * annotated with a createInstance="yes" attribute.
0789: * Activities other than the following: start activities, <scope>,
0790: * <flow>, <sequence>, and <empty> MUST NOT be performed prior to
0791: * or simultaneously with start activities.
0792: */
0793: checkOrderOfActivities(pick);
0794: }
0795:
0796: @Override
0797: public void visit(Flow flow) {
0798: /*
0799: * Rule : Every link declared within a <flow> activity MUST have exactly
0800: * one activity within the <flow> as its source and exactly
0801: * one activity within the <flow> as its target.
0802: *
0803: * and this method also peform one more rule :
0804: *
0805: * Rule : Two different links MUST NOT share the same source
0806: * and target activities; that is, at most one link may be used
0807: * to connect two activities.
0808: * ( check for this rule will be started only when previous rule
0809: * is succeeded).
0810: *
0811: *
0812: * Rule : A link that crosses a <faultHandlers> or <terminationHandler>
0813: * element boundary MUST be outbound only, that is, it MUST have its
0814: * source activity within the <faultHandlers> or <terminationHandler>,
0815: * and its target activity outside of the scope associated with the handler.
0816: *
0817: * Rule :A link MUST NOT cross the boundary of a repeatable construct or
0818: * the <compensationHandler> element. This means, a link used within a
0819: * repeatable construct (<while>, <repeatUntil>, <forEach>, <eventHandlers>)
0820: * or a <compensationHandler> MUST be declared in a <flow> that is itself
0821: * nested inside the repeatable construct or <compensationHandler>.
0822: */
0823: checkLinks(flow);
0824: }
0825:
0826: @Override
0827: public void visit(CompensationHandler handler) {
0828: /*
0829: * Rule : The root scope inside a FCT-handler MUST not have a compensation handler.
0830: */
0831: checkFCTScope(handler);
0832: }
0833:
0834: @Override
0835: public void visit(TerminationHandler handler) {
0836: /*
0837: * Rule : The root scope inside a FCT-handler MUST not have a compensation handler.
0838: */
0839: checkFCTScope(handler);
0840: }
0841:
0842: @Override
0843: public void visit(CorrelationSet set) {
0844: /*
0845: * Rule : Properties used in a <correlationSet> MUST be defined
0846: * using XML Schema simple types. This restriction MUST be statically
0847: * enforced.
0848: */
0849: List<WSDLReference<CorrelationProperty>> list = set
0850: .getProperties();
0851: if (list == null) {
0852: return;
0853: }
0854: for (WSDLReference<CorrelationProperty> reference : list) {
0855: CorrelationProperty property = reference.get();
0856: // if it null then reference validator will report about error
0857: if (property != null) {
0858: NamedComponentReference<GlobalType> typeRef = property
0859: .getType();
0860: if (typeRef == null
0861: || !(typeRef.get() instanceof GlobalSimpleType)) {
0862: addError(FIX_BAD_CORRELATION_PROPERTY_TYPE, set);
0863: }
0864: }
0865: }
0866: }
0867:
0868: @Override
0869: public void visit(PatternedCorrelation correlation) {
0870: /*
0871: * Rule : The pattern attribute used in <correlation> within
0872: * <invoke> is required for request-response operations, and
0873: * disallowed when a one-way operation is invoked.
0874: */
0875: Pattern pattern = correlation.getPattern();
0876:
0877: BpelContainer container = correlation.getParent().getParent();
0878: assert container instanceof Invoke;
0879: Invoke invoke = (Invoke) container;
0880:
0881: // If operation is absent or broken then other validators said about this.
0882:
0883: WSDLReference<Operation> operationRef = invoke.getOperation();
0884: if (operationRef == null) {
0885: return;
0886: }
0887: Operation operation = operationRef.get();
0888: if (operation == null) {
0889: return;
0890: }
0891: // # 84129
0892: boolean oneWayOperationPatternExist = pattern != null
0893: && operation instanceof OneWayOperation;
0894: boolean twoWayOperationPatternAbsent = pattern == null
0895: && operation instanceof RequestResponseOperation;
0896: boolean flag = oneWayOperationPatternExist
0897: || twoWayOperationPatternAbsent;
0898: if (flag) {
0899: addError(FIX_BAD_USAGE_PATTERN_ATTRIBUTE, invoke);
0900: }
0901: }
0902:
0903: @Override
0904: public void visit(CorrelationContainer container) {
0905: /*
0906: * Rule : Static analysis MUST detect property usages where
0907: * propertyAliases for the associated variable's type are not found
0908: * in any WSDL definitions directly imported by the WS-BPEL process.
0909: */
0910: BpelContainer parent = container.getParent();
0911: if (parent instanceof OperationReference
0912: && parent instanceof Responder) {
0913: checkPropertyUsageInInputMessage(
0914: (OperationReference) parent, container
0915: .getCorrelations());
0916: }
0917: if (parent instanceof OperationReference
0918: && parent instanceof Requester) {
0919: checkPropertyUsageInOutputMessage(
0920: (OperationReference) parent, container
0921: .getCorrelations());
0922: }
0923: }
0924:
0925: @Override
0926: public void visit(PatternedCorrelationContainer container) {
0927: /*
0928: * Rule : Static analysis MUST detect property usages where
0929: * propertyAliases for the associated variable's type are not found
0930: * in any WSDL definitions directly imported by the WS-BPEL process.
0931: */
0932: BpelContainer parent = container.getParent();
0933: if (parent instanceof OperationReference
0934: && parent instanceof Responder) {
0935: checkPropertyUsageInInputMessage(
0936: (OperationReference) parent, container
0937: .getPatternedCorrelations());
0938: }
0939: if (parent instanceof OperationReference
0940: && parent instanceof Requester) {
0941: checkPropertyUsageInOutputMessage(
0942: (OperationReference) parent, container
0943: .getPatternedCorrelations());
0944: }
0945: }
0946:
0947: @Override
0948: public void visit(CorrelationSetContainer container) {
0949: /*
0950: * The name of a <correlationSet> MUST be unique amongst the names of
0951: * all <correlationSet> defined within the same immediately
0952: * enclosing scope.
0953: */
0954: CorrelationSet[] correlations = container.getCorrelationSets();
0955: if (correlations == null) {
0956: return;
0957: }
0958: Map<String, Collection<Component>> map = new HashMap<String, Collection<Component>>();
0959: for (CorrelationSet correlation : correlations) {
0960: addNamedToMap(correlation, map);
0961: }
0962: addErrorForNamed(map, FIX_DUPLICATE_CORRELATION_SET_NAME);
0963: }
0964:
0965: @Override
0966: public void visit(PartnerLinkContainer container) {
0967: /*
0968: * The name of a partnerLink MUST be unique amongst the names of all
0969: * partnerLinks defined within the same immediately enclosing scope.
0970: * This requirement MUST be statically enforced.
0971: */
0972: PartnerLink[] links = container.getPartnerLinks();
0973: if (links == null) {
0974: return;
0975: }
0976: Map<String, Collection<Component>> map = new HashMap<String, Collection<Component>>();
0977: for (PartnerLink link : links) {
0978: addNamedToMap(link, map);
0979: }
0980: addErrorForNamed(map, FIX_DUPLICATE_PARTNER_LINK_NAME);
0981: }
0982:
0983: @Override
0984: public void visit(Extension extension) {
0985: /*
0986: * Rule : In the case of mandatory extensions declared in the
0987: * <extensions> element not supported by a WS-BPEL implementation, the
0988: * process definition MUST be rejected.
0989: */
0990: TBoolean mustUnderstand = extension.getMustUnderstand();
0991: if (TBoolean.YES.equals(mustUnderstand)) {
0992: BpelModel model = extension.getBpelModel();
0993: assert model instanceof BpelModelImpl;
0994: BpelModelImpl impl = (BpelModelImpl) model;
0995:
0996: if (!impl.isSupportedExpension(extension.getNamespace())) {
0997: String ns = extension.getNamespace();
0998: if (ns == null) {
0999: ns = "";
1000: }
1001: addError(FIX_UNSUPPORTED_EXTENSION, extension, ns);
1002: }
1003: }
1004: }
1005:
1006: private void checkVariableName(VariableDeclaration declaration) {
1007: String name = declaration.getVariableName();
1008: if (name != null && name.indexOf('.') != -1) {
1009: addError(FIX_BAD_VARIABLE_NAME, declaration);
1010: }
1011: }
1012:
1013: private Model getImportModel(Import imp) {
1014: if (Import.WSDL_IMPORT_TYPE.equals(imp.getImportType())) {
1015: return ImportHelper.getWsdlModel(imp, false);
1016: }
1017:
1018: if (Import.SCHEMA_IMPORT_TYPE.equals(imp.getImportType())) {
1019: return ImportHelper.getSchemaModel(imp, false);
1020: }
1021:
1022: return null;
1023: }
1024:
1025: public void checkNotificationPortType(BpelEntity bpelEntity,
1026: WSDLReference<PortType> portType) {
1027: if (portType == null || portType.get() == null) {
1028: return;
1029: }
1030: Collection<Operation> operations = portType.get()
1031: .getOperations();
1032: for (Operation operation : operations) {
1033: if (operation instanceof NotificationOperation) {
1034: addError(
1035: FIX_WSDLOPERATION_SOLICIT_RESPONSE_NOTIFICATION,
1036: bpelEntity);
1037: }
1038: }
1039: }
1040:
1041: public void checkSolicitResponsePortType(BpelEntity bpelEntity,
1042: WSDLReference<PortType> portType) {
1043: if (portType == null || portType.get() == null) {
1044: return;
1045: }
1046: Collection<Operation> operations = portType.get()
1047: .getOperations();
1048: for (Operation operation : operations) {
1049: if (operation instanceof SolicitResponseOperation) {
1050: addError(
1051: FIX_WSDLOPERATION_SOLICIT_RESPONSE_NOTIFICATION,
1052: bpelEntity);
1053: }
1054: }
1055: }
1056:
1057: public void checkOverloadedPortTypeOperation(BpelEntity bpelEntity,
1058: WSDLReference<PortType> portType) {
1059: if (portType == null || portType.get() == null)
1060: return;
1061:
1062: Collection<Operation> operations = portType.get()
1063: .getOperations();
1064: Set<String> operationsSet = new HashSet<String>();
1065:
1066: for (Operation operation : operations) {
1067: operationsSet.add(operation.getName());
1068: }
1069:
1070: if (operationsSet.size() != operations.size()) {
1071: addError(FIX_PORT_TYPE_OVERLOADED_OPERATION_NAME,
1072: bpelEntity);
1073: }
1074: }
1075:
1076: public void checkInputVariableToPartCombination(Invoke invoke) {
1077: if (invoke.getInputVariable() != null)
1078: if (invoke.getToPartContaner() != null
1079: && invoke.getToPartContaner().sizeOfToParts() != 0) {
1080: addError(FIX_INPUTVARIABLE_TOPART_COMBINATION, invoke);
1081: }
1082: }
1083:
1084: public void checkOutputVariableFromPartCombination(Invoke invoke) {
1085: if (invoke.getOutputVariable() != null)
1086: if (invoke.getFromPartContaner() != null
1087: && invoke.getFromPartContaner().sizeOfFromParts() != 0) {
1088: addError(FIX_OUTPUTVARIABLE_FROMPART_COMBINATION,
1089: invoke);
1090: }
1091: }
1092:
1093: public void checkValidPartAttributeFromPartElement(Invoke invoke) {
1094: // Only if one or more <fromPart> elements is defined.
1095: if (invoke.getFromPartContaner() != null
1096: && invoke.getFromPartContaner().sizeOfFromParts() != 0) {
1097: // For each <fromPart> element.
1098: FromPart[] fromParts = invoke.getFromPartContaner()
1099: .getFromParts();
1100: for (FromPart fromPart : fromParts) {
1101: boolean valid = false;
1102:
1103: if (fromPart == null || fromPart.getPart() == null) {
1104: return;
1105: }
1106: WSDLReference<Part> part = fromPart.getPart();
1107:
1108: Part partRef = part.get();
1109:
1110: if (partRef != null) {
1111: // This will be handled by another rule.
1112: if (invoke.getOperation() == null
1113: || invoke.getOperation().get() == null
1114: || invoke.getOperation().get().getOutput() == null
1115: || invoke.getOperation().get().getOutput()
1116: .getMessage() == null
1117: || invoke.getOperation().get().getOutput()
1118: .getMessage().get() == null
1119: || invoke.getOperation().get().getOutput()
1120: .getMessage().get().getParts() == null) {
1121: return;
1122: }
1123: for (Part wsdlPart : invoke.getOperation().get()
1124: .getOutput().getMessage().get().getParts()) {
1125: if (wsdlPart.equals(partRef)) {
1126: valid = true;
1127: break;
1128: }
1129: }
1130: }
1131:
1132: if (!valid) {
1133: addError(FIX_INVALID_FROMPART_PARTATTR, fromPart);
1134: }
1135: }
1136: }
1137: }
1138:
1139: public void checkValidPartAttributeToPartElement(Invoke invoke) {
1140: // Only if one or more <toPart> elements is defined.
1141: if (invoke.getToPartContaner() != null
1142: && invoke.getToPartContaner().sizeOfToParts() != 0) {
1143: // For each <toPart> element.
1144: ToPart[] toParts = invoke.getToPartContaner().getToParts();
1145: for (ToPart toPart : toParts) {
1146: boolean valid = false;
1147:
1148: if (toPart == null || toPart.getPart() == null) {
1149: return;
1150: }
1151: WSDLReference<Part> part = toPart.getPart();
1152:
1153: Part partRef = part.get();
1154: if (partRef != null) {
1155: // This will be handled by another rule.
1156: if (invoke.getOperation() == null
1157: || invoke.getOperation().get() == null
1158: || invoke.getOperation().get().getInput() == null
1159: || invoke.getOperation().get().getInput()
1160: .getMessage() == null
1161: || invoke.getOperation().get().getInput()
1162: .getMessage().get() == null
1163: || invoke.getOperation().get().getInput()
1164: .getMessage().get().getParts() == null) {
1165: return;
1166: }
1167: for (Part wsdlPart : invoke.getOperation().get()
1168: .getInput().getMessage().get().getParts()) {
1169: if (wsdlPart.equals(partRef)) {
1170: valid = true;
1171: break;
1172: }
1173: }
1174: }
1175:
1176: if (!valid) {
1177: addError(FIX_INVALID_TOPART_PARTATTR, toPart);
1178: }
1179: }
1180: }
1181: }
1182:
1183: /**
1184: * For toPart usage, check whether all parts in the WSDL message are
1185: * completely assigned.
1186: */
1187: public void checkAnyMissingToPartElementInInvoke(Invoke invoke) {
1188:
1189: // This will be handled by another rule.
1190: if (invoke.getOperation() == null
1191: || invoke.getOperation().get() == null
1192: || invoke.getOperation().get().getInput() == null
1193: || invoke.getOperation().get().getInput().getMessage() == null
1194: || invoke.getOperation().get().getInput().getMessage()
1195: .get() == null
1196: || invoke.getOperation().get().getInput().getMessage()
1197: .get().getParts() == null) {
1198: return;
1199: } else {
1200: if (invoke.getToPartContaner() == null
1201: || invoke.getToPartContaner().sizeOfToParts() == 0) {
1202: return;
1203: }
1204:
1205: for (Part wsdlPart : invoke.getOperation().get().getInput()
1206: .getMessage().get().getParts()) {
1207: // Each part in the wsdl message must be assigned via a <toPart>
1208: boolean assigned = false;
1209: ToPart[] toParts = invoke.getToPartContaner()
1210: .getToParts();
1211: for (ToPart toPart : toParts) {
1212: // # 84147
1213: WSDLReference<Part> partRef = toPart.getPart();
1214: if (partRef == null) {
1215: continue;
1216: }
1217: Part part = partRef.get();
1218: if (part != null && wsdlPart.equals(part)) {
1219: assigned = true;
1220: break;
1221: }
1222: }
1223: if (!assigned) {
1224: addError(
1225: FIX_WSDL_MESSAGE_NOT_COMPLETELY_INITIALISED,
1226: invoke);
1227: break;
1228: }
1229: }
1230: }
1231: }
1232:
1233: public void checkAnyMissingToPartElementInReply(Reply reply) {
1234: if (reply.getOperation() == null
1235: || reply.getOperation().get() == null
1236: || reply.getOperation().get().getOutput() == null
1237: || reply.getOperation().get().getOutput().getMessage() == null
1238: || reply.getOperation().get().getOutput().getMessage()
1239: .get() == null
1240: || reply.getOperation().get().getOutput().getMessage()
1241: .get().getParts() == null) {
1242: return;
1243: } else {
1244: if (reply.getToPartContaner() == null
1245: || reply.getToPartContaner().sizeOfToParts() == 0) {
1246: return;
1247: }
1248:
1249: for (Part wsdlPart : reply.getOperation().get().getOutput()
1250: .getMessage().get().getParts()) {
1251: // Each part in the wsdl message must be assigned via a <toPart>
1252: boolean assigned = false;
1253: ToPart[] toParts = reply.getToPartContaner()
1254: .getToParts();
1255:
1256: for (ToPart toPart : toParts) {
1257: WSDLReference<Part> partRef = toPart.getPart();
1258: if (partRef == null) {
1259: continue;
1260: }
1261: Part part = partRef.get();
1262: if (part != null && wsdlPart.equals(part)) {
1263: assigned = true;
1264: break;
1265: }
1266: }
1267: if (!assigned) {
1268: addError(
1269: FIX_WSDL_MESSAGE_NOT_COMPLETELY_INITIALISED,
1270: reply);
1271: break;
1272: }
1273: }
1274: }
1275: }
1276:
1277: public void checkReceiveVariableFromPartCombination(Receive receive) {
1278: if (receive == null) {
1279: return;
1280: }
1281: if (receive.getVariable() != null) {
1282: if (receive.getFromPartContaner() != null
1283: && receive.getFromPartContaner().sizeOfFromParts() != 0) {
1284: addError(FIX_RECEIVE_VARIABLE_FROMPART_COMBINATION,
1285: receive);
1286: }
1287: }
1288: // Rule SA00047
1289: WSDLReference<Operation> operationRef = receive.getOperation();
1290:
1291: if (operationRef == null) {
1292: return;
1293: }
1294: Operation operation = operationRef.get();
1295:
1296: if (operation == null) {
1297: return;
1298: }
1299: if (isAbsentOutputVaribale(receive, operation)) {
1300: addError(FIX_ABSENT_OUTPUT_VARIABLE, receive);
1301: }
1302: }
1303:
1304: public void checkOnMessageVariableFromPartCombination(
1305: OnMessage onMessage) {
1306: if (onMessage == null) {
1307: return;
1308: }
1309:
1310: if (onMessage.getVariable() != null) {
1311: if (onMessage.getFromPartContaner() != null
1312: && onMessage.getFromPartContaner()
1313: .sizeOfFromParts() != 0) {
1314: addError(FIX_ONMESSAGE_VARIABLE_FROMPART_COMBINATION,
1315: onMessage);
1316: }
1317: }
1318: }
1319:
1320: public void checkReplyVariableToPartCombination(Reply reply) {
1321: if (reply == null) {
1322: return;
1323: }
1324: if (reply.getVariable() != null) {
1325: if (reply.getToPartContaner() != null
1326: && reply.getToPartContaner().sizeOfToParts() != 0) {
1327: addError(FIX_REPLY_VARIABLE_TOPART_COMBINATION, reply);
1328: }
1329: }
1330:
1331: // Rule SA00047
1332: WSDLReference<Operation> operationRef = reply.getOperation();
1333:
1334: if (operationRef == null) {
1335: return;
1336: }
1337: Operation operation = operationRef.get();
1338:
1339: if (operation == null) {
1340: return;
1341: }
1342: if (isAbsentInputVaribale(reply, operation)) {
1343: addError(FIX_ABSENT_INPUT_VARIABLE, reply);
1344: }
1345: }
1346:
1347: void checkPortTypeCombinedPartnerLink(
1348: PortTypeReference portTypeReference) {
1349: if (portTypeReference instanceof PartnerLinkReference) {
1350: PartnerLinkReference partnerLinkReference = (PartnerLinkReference) portTypeReference;
1351: WSDLReference<PortType> portTypeDirectRef = portTypeReference
1352: .getPortType();
1353: if (portTypeDirectRef == null) {
1354: return;
1355: }
1356: BpelReference<PartnerLink> partnerLinkRef = partnerLinkReference
1357: .getPartnerLink();
1358: NamedComponentReference<PortType> portTypeRef = Utils
1359: .getPortTypeRef(partnerLinkRef,
1360: (Component) portTypeReference);
1361: if (portTypeRef == null
1362: || !Utils.equals(portTypeDirectRef.get(),
1363: portTypeRef.get())) {
1364: addError(FIX_DIFFERENT_PORT_TYPES,
1365: (BpelEntity) portTypeReference);
1366: }
1367: }
1368: }
1369:
1370: void addNamedToMap(BpelEntity named,
1371: Map<String, Collection<Component>> map) {
1372: addNamedToMap(named, map, DEFAULT_NAME_ACESS);
1373: }
1374:
1375: void addErrorForNamed(Map<String, Collection<Component>> map,
1376: String key) {
1377: for (Entry<String, Collection<Component>> entry : map
1378: .entrySet()) {
1379: String name = entry.getKey();
1380: assert name != null;
1381: Collection<Component> collection = entry.getValue();
1382:
1383: if (collection != null && collection.size() > 1) {
1384: for (Component component : collection) {
1385: addError(key, component);
1386: }
1387: }
1388: }
1389: }
1390:
1391: void addNamedToMap(BpelEntity entity,
1392: Map<String, Collection<Component>> map, NameAccess access) {
1393: String name = access.getName(entity);
1394:
1395: if (name == null) {
1396: return;
1397: }
1398: Collection<Component> collection = map.get(name);
1399:
1400: if (collection == null) {
1401: collection = new LinkedList<Component>();
1402: map.put(name, collection);
1403: }
1404: collection.add(entity);
1405: }
1406:
1407: void addCompensateError(Activity compensate) {
1408: addError(FIX_COMPENSATE_OCCURANCE, compensate, compensate
1409: .getPeer().getLocalName());
1410: }
1411:
1412: void checkCompensateOccurance(Activity compensate) {
1413: /*
1414: * Rule : The <compensate(Scope)> activity MUST only be used from within a faultHandler,
1415: * another compensationHandler, or a terminationHandler.
1416: */
1417: if (Utils.hasAscendant(compensate, FaultHandlers.class)) {
1418: return;
1419: }
1420: if (Utils.hasAscendant(compensate, CompensationHandler.class)) {
1421: return;
1422: }
1423: if (Utils.hasAscendant(compensate, TerminationHandler.class)) {
1424: return;
1425: }
1426: addCompensateError(compensate);
1427: }
1428:
1429: void addNamedActivity(BpelEntity entity,
1430: Map<String, Collection<Component>> map) {
1431: if (entity instanceof ExtendableActivity
1432: && entity instanceof NamedElement) {
1433: String name = ((NamedElement) entity).getName();
1434: if (name == null) {
1435: return;
1436: }
1437: Collection<Component> collection = map.get(name);
1438: if (collection == null) {
1439: collection = new LinkedList<Component>();
1440: map.put(name, collection);
1441: }
1442: collection.add((Component) entity);
1443: }
1444: }
1445:
1446: void collectIsolatedScopes(BpelContainer container,
1447: Collection<Component> collection) {
1448: List<BpelEntity> children = container.getChildren();
1449: for (BpelEntity entity : children) {
1450: if (entity instanceof Scope
1451: && TBoolean.YES.equals(((Scope) entity)
1452: .getIsolated())) {
1453: collection.add(entity);
1454: }
1455: if (entity instanceof BpelContainer) {
1456: collectIsolatedScopes((BpelContainer) entity,
1457: collection);
1458: }
1459: }
1460: }
1461:
1462: void checkOrderOfActivities(CreateInstanceActivity activity) {
1463: if (TBoolean.YES.equals(activity.getCreateInstance())) {
1464: /*
1465: * I will put into this set visited container ( sequence and flow )
1466: * for avoiding visiting them one more time while following up of tree.
1467: *
1468: * This will fix bug #85727
1469: */
1470: Set<CompositeActivity> set = new HashSet<CompositeActivity>();
1471: ExtendableActivity beforeOrSimultaneously = findPreviouslyPerformedActivities(
1472: (Activity) activity, set);
1473: if (beforeOrSimultaneously != null) {
1474: Collection<Component> collection = new ArrayList<Component>(
1475: 2);
1476: collection.add((Activity) activity);
1477: collection.add(beforeOrSimultaneously);
1478: addError(FIX_START_ACTIVITY_IS_NOT_FIRST_EXECUTED,
1479: collection);
1480: }
1481: }
1482: }
1483:
1484: void visitBaseScope(BaseScope baseScope) {
1485: /*
1486: * Rule : The name of a named activity MUST be unique amongst
1487: * all named activities present within the same immediately
1488: * enclosing scope. This requirement MUST be statically enforced.
1489: */
1490: Map<String, Collection<Component>> map = new HashMap<String, Collection<Component>>();
1491: collectActivitiesInScope(baseScope, map);
1492: addErrorForNamed(map, FIX_MULTIPLE_NAMED_ACTIVITIES);
1493:
1494: /*
1495: * Rule : If the value of exitOnStandardFault of a <scope> or <process>
1496: * is set to "yes", then a fault handler that explicitly targets the
1497: * WS-BPEL standard faults MUST NOT be used in that scope.
1498: * A process definition that violates this condition MUST be
1499: * detected and rejected by static analysis.
1500: */
1501: if (TBoolean.YES.equals(baseScope.getExitOnStandardFault())
1502: && baseScope.getFaultHandlers() != null) {
1503: Catch[] catches = baseScope.getFaultHandlers().getCatches();
1504: Collection<Component> collection = new LinkedList<Component>();
1505: for (Catch catc : catches) {
1506: QName qName = catc.getFaultName();
1507: if (qName != null
1508: && BpelEntity.BUSINESS_PROCESS_NS_URI
1509: .equals(qName.getNamespaceURI())) {
1510: /*
1511: * suggest that all qnames in bpws namespace are standart
1512: * faults ( may be this is wrong sugestion )
1513: */
1514: collection.add(catc);
1515: }
1516: }
1517: if (collection.size() > 0) {
1518: addError(FIX_EXIT_ON_STANDART_FAULT, collection);
1519: }
1520: }
1521: }
1522:
1523: void collectActivitiesInScope(BpelContainer container,
1524: Map<String, Collection<Component>> map) {
1525: List<BpelEntity> children = container.getChildren();
1526: for (BpelEntity entity : children) {
1527: addNamedActivity(entity, map);
1528: if (entity instanceof BaseScope) {
1529: // we do not need to go further in scope for searching activities with duplicate names.
1530: continue;
1531: }
1532: if (entity instanceof BpelContainer) {
1533: collectActivitiesInScope((BpelContainer) entity, map);
1534: }
1535: }
1536: }
1537:
1538: void checkImportType(Import imp) {
1539: String importType = imp.getImportType();
1540: if (!Import.WSDL_IMPORT_TYPE.equals(importType)
1541: && !Import.SCHEMA_IMPORT_TYPE.equals(importType)) {
1542: addError(FIX_BAD_IMPORT_TYPE, imp);
1543: }
1544: }
1545:
1546: void checkInstantiableActivities(Process process) {
1547: Collection<Activity> collection = getInstantiableActivities(process);
1548: if (collection.size() == 0) {
1549: addError(FIX_NO_PICK_OR_RECEIVE_WITH_CREATE_INSTANCE,
1550: process);
1551: }
1552:
1553: if (collection.size() > 0) {
1554: checkCorellations(collection);
1555: }
1556: }
1557:
1558: void checkMessageType(OnEvent onEvent) {
1559: WSDLReference<Message> messageRef = onEvent.getMessageType();
1560: WSDLReference<Operation> operationRef = onEvent.getOperation();
1561: if (operationRef == null || operationRef.get() == null) {
1562: return;
1563: }
1564: Operation operation = operationRef.get();
1565: if (messageRef != null) {
1566: if (!checkMessageTypeInOnEvent(messageRef, operation)) {
1567: addError(FIX_MESSAGE_TYPE_IN_ON_EVENT, onEvent);
1568: }
1569: } else {
1570: SchemaReference<GlobalElement> elementRef = onEvent
1571: .getElement();
1572: if (elementRef == null) {
1573: // do not need to do anything. Both messageType and element attributes could be absent.
1574: return;
1575: }
1576: if (!checkElementInOnEvent(elementRef, operation)) {
1577: addError(FIX_ELEMENT_IN_ON_EVENT, onEvent);
1578: }
1579: }
1580: }
1581:
1582: void checkLinks(Flow flow) {
1583: LinkContainer linkContainer = flow.getLinkContainer();
1584: if (linkContainer == null) {
1585: return;
1586: }
1587: Link[] links = linkContainer.getLinks();
1588: Set<Link> list = new HashSet<Link>(Arrays.asList(links));
1589: List<BpelEntity> children = flow.getChildren();
1590:
1591: Map<Link, Collection<Component>> sources = new HashMap<Link, Collection<Component>>();
1592:
1593: Map<Link, Collection<Component>> targets = new HashMap<Link, Collection<Component>>();
1594:
1595: for (BpelEntity child : children) {
1596: collectLinks(child, list, sources, targets);
1597: }
1598:
1599: Map<Pair<Component>, Collection<Link>> foundSourcesAndTargets = new HashMap<Pair<Component>, Collection<Link>>();
1600:
1601: for (Link link : list) {
1602: boolean isUsed = false;
1603: Collection<Component> collection = sources.get(link);
1604: isUsed = checkLink(link, collection,
1605: FIX_MILTIPLE_LINK_SOURCE);
1606: Component source = null;
1607: if (isUsed) {
1608: source = collection.iterator().next();
1609: }
1610:
1611: collection = targets.get(link);
1612: if (!isUsed
1613: || !checkLink(link, collection,
1614: FIX_MILTIPLE_LINK_TARGET)) {
1615: addError(FIX_LINK_IS_NOT_USED, link);
1616: } else {
1617: Component target = collection.iterator().next();
1618: /*
1619: * Here we perform one more check. It will be started only when
1620: * link appear between source and target ( from previous check )
1621: * for just ONE activity as source and ONE activity as target.
1622: */
1623: checkLinkSingleton(foundSourcesAndTargets, link,
1624: source, target);
1625:
1626: checkLinkBoundaries(link, (BpelEntity) source,
1627: (BpelEntity) target);
1628: }
1629: }
1630: }
1631:
1632: String getTargetNamespace(Import imp) {
1633: assert imp != null;
1634: String location = imp.getLocation();
1635: if (location == null) {
1636: return null;
1637: }
1638: try {
1639: URI uri = new URI(location);
1640: ModelSource source = CatalogModelFactory.getDefault()
1641: .getCatalogModel(imp.getModel().getModelSource())
1642: .getModelSource(uri,
1643: imp.getModel().getModelSource());
1644: if (Import.WSDL_IMPORT_TYPE.equals(imp.getImportType())) {
1645: WSDLModel model = WSDLModelFactory.getDefault()
1646: .getModel(source);
1647: if (model == null) {
1648: return null;
1649: }
1650: return model.getDefinitions() == null ? null : model
1651: .getDefinitions().getTargetNamespace();
1652: } else if (Import.SCHEMA_IMPORT_TYPE.equals(imp
1653: .getImportType())) {
1654: SchemaModel model = SchemaModelFactory.getDefault()
1655: .getModel(source);
1656: if (model == null) {
1657: return null;
1658: }
1659: if (model.getState() == Model.State.VALID) {
1660: return model.getSchema() == null ? null : model
1661: .getSchema().getTargetNamespace();
1662: }
1663: }
1664: } catch (URISyntaxException e) {
1665: return null;
1666: } catch (CatalogModelException e) {
1667: return null;
1668: }
1669: return null;
1670: }
1671:
1672: void checkInputOutputVariableOperation(Invoke invoke) {
1673: WSDLReference<Operation> operationRef = invoke.getOperation();
1674: if (operationRef == null) {
1675: return;
1676: }
1677: Operation operation = operationRef.get();
1678:
1679: if (operation instanceof RequestResponseOperation) {
1680: if (isAbsentInputVaribale(invoke, operation)
1681: || isAbsentOutputVaribale(invoke, operation)) {
1682: addError(FIX_ABSENT_INPUT_OUTPUT_VARIABLES, invoke);
1683: } else {
1684: /*
1685: * only if all is ok we start the next check - equality of
1686: * variable types and message type
1687: */
1688: checkInputVariable(invoke, operation);
1689: checkOutputVariable(invoke, operation);
1690: }
1691: } else if (operation instanceof OneWayOperation) {
1692: if (invoke.getOutputVariable() != null
1693: || (invoke.getFromPartContaner() != null && invoke
1694: .getFromPartContaner().sizeOfFromParts() > 0)) {
1695: addError(FIX_OUTPUT_VARIABLE_FOR_ONE_WAY_OP, invoke);
1696: }
1697: if (isAbsentInputVaribale(invoke, operation)) {
1698: addError(FIX_ABSENT_INPUT_VARIABLE_FOR_ONE_WAY_OP,
1699: invoke);
1700: } else {
1701: /*
1702: * only if all is ok we start the next check - equality of
1703: * variable types and message type
1704: */
1705: checkInputVariable(invoke, operation);
1706: }
1707: }
1708: }
1709:
1710: // vlv
1711: private void addError(String key, Collection<Component> collection) {
1712: for (Component component : collection) {
1713: addError(key, component);
1714: }
1715: }
1716:
1717: void checkFCTScope(BpelContainer container) {
1718: Collection<Scope> scopes = getScopes(container);
1719: for (Scope scope : scopes) {
1720: if (scope.getCompensationHandler() != null) {
1721: Collection<Component> collection = new ArrayList<Component>(
1722: 2);
1723: collection.add(container);
1724: collection.add(scope);
1725: addError(
1726: FIX_SCOPE_INSIDE_FCT_CONTAINS_COMPENSATION_HANDLER,
1727: collection);
1728: }
1729: }
1730: }
1731:
1732: void checkPropertyAliasMultiplicity(Process process) {
1733: Collection<PropertyAlias> aliases = getPropertyAliases(null,
1734: null, process.getBpelModel());
1735: Set<Pair<QName>> qNames = new HashSet<Pair<QName>>(); // # 80412
1736: for (PropertyAlias alias : aliases) {
1737: NamedComponentReference<CorrelationProperty> propRef = alias
1738: .getPropertyName();
1739: NamedComponentReference<Message> messageRef = alias
1740: .getMessageType();
1741: if (propRef != null && messageRef != null) {
1742: QName name = propRef.getQName();
1743: QName forCheckName = new QName(name.getNamespaceURI(),
1744: name.getLocalPart());
1745: QName message = messageRef.getQName(); // # 80412
1746: QName forCheckMessage = new QName(message
1747: .getNamespaceURI(), message.getLocalPart());
1748: Pair<QName> pair = new Pair<QName>(forCheckName,
1749: forCheckMessage); // # 80412
1750: if (qNames.contains(pair)) {
1751: addError(FIX_MULTIPLE_PROPERTY_ALIAS_FOR_PROPERTY,
1752: process);
1753: } else {
1754: qNames.add(pair);
1755: }
1756: }
1757: }
1758: }
1759:
1760: void checkPropertyUsageInInputMessage(OperationReference reference,
1761: BaseCorrelation[] correlations) {
1762: if (correlations.length == 0) {
1763: return;
1764: }
1765: WSDLReference<Operation> operationRef = reference
1766: .getOperation();
1767: if (operationRef == null) {
1768: return;
1769: }
1770: Operation operation = operationRef.get();
1771: if (operation == null) {
1772: return;
1773: }
1774: Message message = getInputMessage(operation);
1775: if (message == null) {
1776: return;
1777: }
1778: for (BaseCorrelation correlation : correlations) {
1779: boolean flag = true;
1780: if (correlation instanceof PatternedCorrelation) {
1781: Pattern pattern = ((PatternedCorrelation) correlation)
1782: .getPattern();
1783: flag = Pattern.isRequestApplicable(pattern);
1784: }
1785: if (flag) {
1786: checkPropertyList(correlation, message);
1787: }
1788: }
1789: }
1790:
1791: void checkPropertyUsageInOutputMessage(
1792: OperationReference reference, BaseCorrelation[] correlations) {
1793: if (correlations.length == 0) {
1794: return;
1795: }
1796: WSDLReference<Operation> operationRef = reference
1797: .getOperation();
1798: if (operationRef == null) {
1799: return;
1800: }
1801: Operation operation = operationRef.get();
1802: if (operation == null) {
1803: return;
1804: }
1805: Message message = getOutputMessage(operation);
1806: if (message == null) {
1807: return;
1808: }
1809: for (BaseCorrelation correlation : correlations) {
1810: boolean flag = true;
1811: if (correlation instanceof PatternedCorrelation) {
1812: Pattern pattern = ((PatternedCorrelation) correlation)
1813: .getPattern();
1814: flag = Pattern.isResponseApplicable(pattern);
1815: }
1816: if (flag) {
1817: checkPropertyList(correlation, message);
1818: }
1819: }
1820: }
1821:
1822: void checkVariableContainer(VariableContainer container) {
1823: /*
1824: * Rule : The name of a variable MUST be unique amongst the names of all
1825: * variables defined within the same immediately enclosing scope. This
1826: * requirement MUST be statically enforced.
1827: */
1828: Variable[] variables = container.getVariables();
1829: if (variables == null) {
1830: return;
1831: }
1832:
1833: Map<String, Collection<Component>> map = new HashMap<String, Collection<Component>>();
1834:
1835: for (Variable variable : variables) {
1836: addNamedToMap(variable, map);
1837: }
1838:
1839: addErrorForNamed(map, FIX_DUPLICATE_VARIABLE_NAME);
1840:
1841: }
1842:
1843: void checkImplicitlyDeclaredVars(OnEvent onEvent) {
1844: FromPartContainer parts = onEvent.getFromPartContaner();
1845: if (parts == null || parts.getFromParts() == null) {
1846: return;
1847: }
1848: /*
1849: * This map is used for collecting duplicate variable declarations in
1850: * fromParts.
1851: */
1852: Map<String, Collection<Component>> map = new HashMap<String, Collection<Component>>();
1853: /*
1854: * This map is used for collecting all fromParts names. It will be used
1855: * for checking absence of duplicate varaible names.
1856: */
1857: Map<String, Component> mapVarsInScope = new HashMap<String, Component>();
1858: for (VariableDeclaration decl : parts.getFromParts()) {
1859: addNamedToMap(decl, map, LazyHolder.VAR_DECL_NAME_ACCESS);
1860: mapVarsInScope.put(decl.getVariableName(), decl);
1861: }
1862:
1863: addNamedToMap(onEvent, map, LazyHolder.VAR_DECL_NAME_ACCESS);
1864: mapVarsInScope.put(onEvent.getVariableName(), onEvent);
1865:
1866: Scope scope = onEvent.getScope();
1867: if (scope != null && scope.getVariableContainer() != null) {
1868: VariableContainer container = scope.getVariableContainer();
1869: Variable[] variables = container.getVariables();
1870: for (Variable variable : variables) {
1871: String name = variable.getName();
1872: if (mapVarsInScope.containsKey(name)) {
1873: addNamedToMap(variable, map,
1874: LazyHolder.VAR_DECL_NAME_ACCESS);
1875: }
1876: }
1877: }
1878:
1879: addErrorForNamed(map, FIX_DUPLICATE_VARIABLE_NAME_ON_EVENT);
1880: }
1881:
1882: private void checkCorellations(Collection<Activity> collection) {
1883: Set<CorrelationSet> sharedCorrelations = new HashSet<CorrelationSet>();
1884: boolean first = true;
1885: Collection<Component> components = new ArrayList<Component>(
1886: collection.size());
1887: for (Activity activity : collection) {
1888: components.add(activity);
1889: Collection<CorrelationSet> correlations = getJoinedCorrelationSets(activity);
1890: if (first) {
1891: first = false;
1892: sharedCorrelations.addAll(correlations);
1893: } else {
1894: sharedCorrelations.retainAll(correlations);
1895: checEmptySet(sharedCorrelations, components);
1896: }
1897: }
1898: }
1899:
1900: private void checEmptySet(Set<CorrelationSet> sharedCorrelations,
1901: Collection<Component> components) {
1902: if (sharedCorrelations.size() == 0) {
1903: addError(FIX_ABSENT_SHARED_JOINED_CORRELATION_SET,
1904: components);
1905: }
1906: }
1907:
1908: @SuppressWarnings("unchecked")
1909: private Collection<CorrelationSet> getJoinedCorrelationSets(
1910: Activity activity) {
1911: if (activity.getElementType().equals(Receive.class)) {
1912: Receive receive = (Receive) activity;
1913: return getJoinedCorrelationSets(receive
1914: .getCorrelationContainer());
1915: } else if (activity.getElementType().equals(Pick.class)) {
1916: Pick pick = (Pick) activity;
1917: OnMessage[] onMessages = pick.getOnMessages();
1918: Collection<CorrelationSet> collection = null;
1919: for (OnMessage onMessage : onMessages) {
1920: if (collection == null) {
1921: collection = getJoinedCorrelationSets(onMessage
1922: .getCorrelationContainer());
1923: } else {
1924: collection
1925: .addAll(getJoinedCorrelationSets(onMessage
1926: .getCorrelationContainer()));
1927: }
1928: }
1929: // # 83773
1930: if (collection == null) {
1931: collection = Collections.EMPTY_LIST;
1932: }
1933: return collection;
1934: }
1935: return Collections.EMPTY_LIST;
1936: }
1937:
1938: private void checkPropertyList(BaseCorrelation correlation,
1939: Message message) {
1940: BpelReference<CorrelationSet> setRef = correlation.getSet();
1941: if (setRef == null) {
1942: return;
1943: }
1944: CorrelationSet set = setRef.get();
1945:
1946: if (set == null) {
1947: return;
1948: }
1949: List<WSDLReference<CorrelationProperty>> list = set
1950: .getProperties();
1951: if (list == null) {
1952: return; // # 80696
1953: }
1954: for (WSDLReference<CorrelationProperty> reference : list) {
1955: if (reference == null) {
1956: continue;
1957: }
1958: Collection<PropertyAlias> collection = getPropertyAliases(
1959: reference.getQName(), message, correlation
1960: .getBpelModel());
1961:
1962: if (collection.size() == 0) {
1963: addError("FIX_AbsentPropertyAliasForMessage",
1964: correlation, reference.get().getName(), set
1965: .getName());
1966: }
1967: }
1968: }
1969:
1970: @SuppressWarnings("unchecked")
1971: private Set<PropertyAlias> getPropertyAliases(QName name,
1972: Message message, BpelModel model) {
1973: Import[] imports = model.getProcess().getImports();
1974: if (imports.length == 0) {
1975: return Collections.EMPTY_SET;
1976: } else {
1977: Set<PropertyAlias> list = new HashSet<PropertyAlias>();
1978: for (Import imp : imports) {
1979: collectPropertyAliases(name, message, imp, list);
1980: }
1981: return list;
1982: }
1983: }
1984:
1985: private void collectPropertyAliases(QName name, Message message,
1986: Import imp, Set<PropertyAlias> list) {
1987: WSDLModel model = ImportHelper.getWsdlModel(imp);
1988:
1989: if (model == null) {
1990: return;
1991: }
1992: if (model.getState() != State.VALID) {
1993: return;
1994: }
1995: List<PropertyAlias> properties = model.getDefinitions()
1996: .getExtensibilityElements(PropertyAlias.class);
1997: for (PropertyAlias alias : properties) {
1998: NamedComponentReference<CorrelationProperty> propRef = alias
1999: .getPropertyName();
2000: if (propRef == null) {
2001: continue;
2002: }
2003: if (name != null && !Utils.equals(propRef.getQName(), name)) {
2004: continue;
2005: }
2006: if (message == null) {
2007: list.add(alias);
2008: continue;
2009: }
2010: NamedComponentReference<Message> messageRef = alias
2011: .getMessageType();
2012: if (messageRef == null) {
2013: continue;
2014: } else if (messageRef.references(message)) {
2015: list.add(alias);
2016: }
2017: }
2018: }
2019:
2020: @SuppressWarnings("unchecked")
2021: private Collection<CorrelationSet> getJoinedCorrelationSets(
2022: CorrelationContainer container) {
2023: Collection<CorrelationSet> collection = new LinkedList<CorrelationSet>();
2024: if (container == null) {
2025: return Collections.EMPTY_LIST;
2026: }
2027: Correlation[] correlations = container.getCorrelations();
2028: for (Correlation correlation : correlations) {
2029: if (Initiate.JOIN.equals(correlation.getInitiate())) {
2030: BpelReference<CorrelationSet> setRef = correlation
2031: .getSet();
2032: if (setRef != null && setRef.get() != null) {
2033: collection.add(setRef.get());
2034: }
2035: }
2036: }
2037: return collection;
2038: }
2039:
2040: private Message getInputMessage(Operation operation) {
2041: Input input = operation.getInput();
2042: if (input == null) {
2043: return null;
2044: }
2045: NamedComponentReference<Message> messageRef = input
2046: .getMessage();
2047: if (messageRef == null) {
2048: return null;
2049: }
2050: return messageRef.get();
2051: }
2052:
2053: private Message getOutputMessage(Operation operation) {
2054: Output output = operation.getOutput();
2055: if (output == null) {
2056: return null;
2057: }
2058: NamedComponentReference<Message> messageRef = output
2059: .getMessage();
2060: if (messageRef == null) {
2061: return null;
2062: }
2063: return messageRef.get();
2064: }
2065:
2066: private void checkInputVariable(Invoke invoke, Operation operation) {
2067: BpelReference<VariableDeclaration> varRef = invoke
2068: .getInputVariable();
2069: Message message = getInputMessage(operation);
2070: checkVariable(invoke, varRef, message);
2071: }
2072:
2073: private void checkOutputVariable(Invoke invoke, Operation operation) {
2074: BpelReference<VariableDeclaration> varRef = invoke
2075: .getOutputVariable();
2076: Message message = getOutputMessage(operation);
2077: checkVariable(invoke, varRef, message);
2078: }
2079:
2080: private void checkVariable(Invoke invoke,
2081: BpelReference<VariableDeclaration> varRef, Message message) {
2082: if (varRef == null) {
2083: return;
2084: }
2085: VariableDeclaration variable = varRef.get();
2086: if (variable == null) {
2087: return;
2088: }
2089: if (message == null) {
2090: return;
2091: }
2092: WSDLReference<Message> messageRef = variable.getMessageType();
2093: if (messageRef != null) {
2094: if (!messageRef.references(message)) {
2095: addError(FIX_BAD_VARIABLE_MESSAGE_TYPE, invoke);
2096: }
2097: } else if (variable.getElement() != null) {
2098: SchemaReference<GlobalElement> varElement = variable
2099: .getElement();
2100: if (!checkElementType(message, varElement)) {
2101: addError(FIX_BAD_VARIABLE_ELEMENT_TYPE, invoke);
2102: }
2103: }
2104: }
2105:
2106: private boolean checkElementType(Message message,
2107: SchemaReference<GlobalElement> varElement) {
2108: if (message.getParts().size() != 1) {
2109: return false;
2110: }
2111: Part part = message.getParts().iterator().next();
2112: NamedComponentReference<GlobalElement> elementRef = part
2113: .getElement();
2114: if (elementRef == null) {
2115: return false;
2116: }
2117: GlobalElement element = elementRef.get();
2118: if (element == null) {
2119: return false;
2120: }
2121: if (varElement.references(element)) {
2122: return true;
2123: }
2124: return false;
2125: }
2126:
2127: private boolean isAbsentInputVaribale(Invoke invoke,
2128: Operation operation) {
2129: Message message = getInputMessage(operation);
2130:
2131: if (message == null) {
2132: return false;
2133: }
2134: // # 109292
2135: if (message.getParts().size() == 0
2136: && invoke.getInputVariable() != null) {
2137: addWarning("FIX_MentionedInputVariableForOneWayOp", invoke); // NOI18N
2138: return false;
2139: }
2140: if (message.getParts().size() != 0
2141: && invoke.getInputVariable() == null
2142: && (invoke.getToPartContaner() == null || invoke
2143: .getToPartContaner().sizeOfToParts() == 0)) {
2144: return true;
2145: } else if (message.getParts().size() == 0) {
2146: return invoke.getToPartContaner() == null
2147: || invoke.getToPartContaner().sizeOfToParts() == 0;
2148: }
2149: return false;
2150: }
2151:
2152: private boolean isAbsentInputVaribale(Reply reply,
2153: Operation operation) {
2154: Message message = getInputMessage(operation);
2155:
2156: if (message == null) {
2157: return false;
2158: }
2159: // # 109292
2160: if (message.getParts().size() == 0
2161: && reply.getVariable() != null) {
2162: addWarning("FIX_MentionedInputVariable", reply); // NOI18N
2163: return false;
2164: }
2165: if (message.getParts().size() != 0
2166: && reply.getVariable() == null
2167: && (reply.getToPartContaner() == null || reply
2168: .getToPartContaner().sizeOfToParts() == 0)) {
2169: return true;
2170: } else if (message.getParts().size() == 0) {
2171: return reply.getToPartContaner() == null
2172: || reply.getToPartContaner().sizeOfToParts() == 0;
2173: }
2174: return false;
2175: }
2176:
2177: private boolean isAbsentOutputVaribale(Invoke invoke,
2178: Operation operation) {
2179: Message message = getOutputMessage(operation);
2180:
2181: if (message == null) {
2182: return false;
2183: }
2184: // # 109292
2185: if (message.getParts().size() == 0
2186: && invoke.getOutputVariable() != null) {
2187: addWarning("FIX_MentionedInputOutputVariables", invoke); // NOI18N
2188: return false;
2189: }
2190: if (message.getParts().size() != 0
2191: && invoke.getOutputVariable() == null
2192: && (invoke.getFromPartContaner() == null || invoke
2193: .getFromPartContaner().sizeOfFromParts() == 0)) {
2194: return true;
2195: } else if (message.getParts().size() == 0) {
2196: return invoke.getFromPartContaner() == null
2197: || invoke.getFromPartContaner().sizeOfFromParts() == 0;
2198: }
2199: return false;
2200: }
2201:
2202: private boolean isAbsentOutputVaribale(Receive receive,
2203: Operation operation) {
2204: Message message = getOutputMessage(operation);
2205:
2206: if (message == null) {
2207: return false;
2208: }
2209: // # 109292
2210: if (message.getParts().size() == 0
2211: && receive.getVariable() != null) {
2212: addWarning("FIX_MentionedOutputVariable", receive); // NOI18N
2213: return false;
2214: }
2215: if (message.getParts().size() != 0
2216: && receive.getVariable() == null
2217: && (receive.getFromPartContaner() == null || receive
2218: .getFromPartContaner().sizeOfFromParts() == 0)) {
2219: return true;
2220: } else if (message.getParts().size() == 0) {
2221: return receive.getFromPartContaner() == null
2222: || receive.getFromPartContaner().sizeOfFromParts() == 0;
2223: }
2224: return false;
2225: }
2226:
2227: private boolean checkElementInOnEvent(
2228: SchemaReference<GlobalElement> ref, Operation operation) {
2229: GlobalElement element = ref.get();
2230: if (element == null) {
2231: return false;
2232: }
2233: NamedComponentReference<Message> messageOperation = getMessageRef(operation);
2234: if (messageOperation == null) {
2235: return false;
2236: }
2237: Message message = messageOperation.get();
2238: if (message == null) {
2239: return false;
2240: }
2241: Collection<Part> parts = message.getParts();
2242: if (parts.size() != 1) {
2243: return false;
2244: }
2245: Part part = parts.iterator().next();
2246: NamedComponentReference<GlobalElement> elementOperationRef = part
2247: .getElement();
2248: if (elementOperationRef == null) {
2249: return false;
2250: }
2251: return elementOperationRef.references(element);
2252: }
2253:
2254: private boolean checkMessageTypeInOnEvent(
2255: WSDLReference<Message> messageRef, Operation operation) {
2256: Message message = messageRef.get();
2257: if (message == null) {
2258: return false;
2259: }
2260:
2261: NamedComponentReference<Message> messageOperation = getMessageRef(operation);
2262: if (messageOperation == null) {
2263: return false;
2264: }
2265: return messageOperation.references(message);
2266: }
2267:
2268: private NamedComponentReference<Message> getMessageRef(
2269: Operation operation) {
2270: Input input = operation.getInput();
2271: if (input == null) {
2272: return null;
2273: }
2274: return input.getMessage();
2275: }
2276:
2277: private Collection<Scope> getScopes(BpelContainer container) {
2278: Collection<Scope> collection = new LinkedList<Scope>();
2279: collectScopes(container, collection);
2280: return collection;
2281: }
2282:
2283: private void collectScopes(BpelEntity container,
2284: Collection<Scope> collection) {
2285: if (container instanceof Scope) {
2286: collection.add((Scope) container);
2287: } else {
2288: List<BpelEntity> children = container.getChildren();
2289: for (BpelEntity child : children) {
2290: collectScopes(child, collection);
2291: }
2292: }
2293: }
2294:
2295: private void checkLinkSingleton(
2296: Map<Pair<Component>, Collection<Link>> map, Link link,
2297: Component source, Component target) {
2298: Pair<Component> pair = new Pair<Component>(source, target);
2299: Collection<Link> linkCollection = map.get(pair);
2300: if (linkCollection == null) {
2301: linkCollection = new HashSet<Link>();
2302: map.put(pair, linkCollection);
2303: }
2304: if (linkCollection.size() > 0) {
2305: Collection<Component> components = new LinkedList<Component>(
2306: linkCollection);
2307: components.add(link);
2308: components.add(source);
2309: components.add(target);
2310: addError(FIX_MULTIPLE_LINKS_WITH_SAME_SOURCE_AND_TARGET,
2311: components);
2312: } else {
2313: linkCollection.add(link);
2314: }
2315: }
2316:
2317: private boolean checkLink(Link link,
2318: Collection<Component> collection, String bundleKey) {
2319: if (collection != null && collection.size() > 1) {
2320: collection.add(link);
2321: addError(bundleKey, collection);
2322: }
2323: return collection != null && collection.size() > 0;
2324: }
2325:
2326: private Collection<Activity> getInstantiableActivities(
2327: BpelContainer container) {
2328: Collection<Activity> collection = new LinkedList<Activity>();
2329: collectInstantiableActivities(container, collection);
2330: return collection;
2331: }
2332:
2333: private void collectInstantiableActivities(BpelContainer container,
2334: Collection<Activity> collection) {
2335: List<BpelEntity> list = container.getChildren();
2336: for (BpelEntity entity : list) {
2337: if (entity.getElementType().equals(Receive.class)
2338: || entity.getElementType().equals(Pick.class)) {
2339: TBoolean isInstance = ((CreateInstanceActivity) entity)
2340: .getCreateInstance();
2341: if (TBoolean.YES.equals(isInstance)) {
2342: collection.add((Activity) entity);
2343: }
2344: } else if (entity instanceof BpelContainer) {
2345: collectInstantiableActivities((BpelContainer) entity,
2346: collection);
2347: }
2348: }
2349: }
2350:
2351: private void collectLinks(BpelEntity entity, Set<Link> set,
2352: Map<Link, Collection<Component>> sourcesMap,
2353: Map<Link, Collection<Component>> targetsMap) {
2354: if (entity instanceof Activity) {
2355: collectLinkInTargets((Activity) entity, set, targetsMap);
2356: collectLinkInSources((Activity) entity, set, sourcesMap);
2357: }
2358:
2359: List<BpelEntity> children = entity.getChildren();
2360: for (BpelEntity child : children) {
2361: collectLinks(child, set, sourcesMap, targetsMap);
2362: }
2363: }
2364:
2365: private void collectLinkInTargets(Activity activity, Set<Link> set,
2366: Map<Link, Collection<Component>> targetsMap) {
2367: TargetContainer targetContainer = activity.getTargetContainer();
2368: if (targetContainer != null) {
2369: Target[] targets = targetContainer.getTargets();
2370: for (Target target : targets) {
2371: BpelReference<Link> ref = target.getLink();
2372: collectLinks(activity, set, targetsMap, ref);
2373: }
2374: }
2375: }
2376:
2377: private void collectLinkInSources(Activity activity, Set<Link> set,
2378: Map<Link, Collection<Component>> sourcesMap) {
2379: SourceContainer sourceContainer = activity.getSourceContainer();
2380: if (sourceContainer != null) {
2381: Source[] sources = sourceContainer.getSources();
2382: for (Source source : sources) {
2383: BpelReference<Link> ref = source.getLink();
2384: collectLinks(activity, set, sourcesMap, ref);
2385: }
2386: }
2387: }
2388:
2389: private void collectLinks(Activity activity, Set<Link> set,
2390: Map<Link, Collection<Component>> targetsMap,
2391: BpelReference<Link> reference) {
2392: if (reference == null) {
2393: return;
2394: }
2395: Link link = reference.get();
2396: if (set.contains(link)) {
2397: Collection<Component> collection = targetsMap.get(link);
2398: if (collection == null) {
2399: collection = new LinkedList<Component>();
2400: targetsMap.put(link, collection);
2401: }
2402: collection.add(activity);
2403: }
2404: }
2405:
2406: private void checkLinkBoundaries(Link link, BpelEntity source,
2407: BpelEntity target) {
2408: checkFTBoundaries(link, source, target);
2409:
2410: checkRepeatableConstract(link, source, target);
2411: }
2412:
2413: private void checkRepeatableConstract(Link link, BpelEntity source,
2414: BpelEntity target) {
2415: /*
2416: * Rule :A link MUST NOT cross the boundary of a repeatable construct or
2417: * the <compensationHandler> element. This means, a link used within a
2418: * repeatable construct (<while>, <repeatUntil>, <forEach>, <eventHandlers>)
2419: * or a <compensationHandler> MUST be declared in a <flow> that is itself
2420: * nested inside the repeatable construct or <compensationHandler>.
2421: */
2422: BpelContainer flow = link.getParent().getParent();
2423: Class[] containers = new Class[] { While.class,
2424: RepeatUntil.class, ForEach.class, EventHandlers.class,
2425: CompensationHandler.class };
2426: boolean targetInside = getContainer(target, flow, containers) != null;
2427: boolean sourceInside = getContainer(source, flow, containers) != null;
2428: Collection<Component> collection = new ArrayList<Component>(3);
2429: if (targetInside) {
2430: collection.add(target);
2431: }
2432: if (sourceInside) {
2433: collection.add(source);
2434: }
2435: if (collection.size() > 0) {
2436: collection.add(link);
2437: addError(FIX_LINK_CROSS_BOUNDARY_REPEATABLE_CONSTRUCT,
2438: collection);
2439: }
2440: }
2441:
2442: private void checkFTBoundaries(Link link, BpelEntity source,
2443: BpelEntity target) {
2444: BpelContainer flow = link.getParent().getParent();
2445: /*
2446: * Rule : A link that crosses a <faultHandlers> or <terminationHandler>
2447: * element boundary MUST be outbound only, that is, it MUST have its
2448: * source activity within the <faultHandlers> or <terminationHandler>,
2449: * and its target activity outside of the scope associated with the handler.
2450: *
2451: */
2452: boolean badHandlersBoundaries = true;
2453: Class[] containers = new Class[] { FaultHandlers.class,
2454: TerminationHandler.class };
2455: BpelContainer targetParentHandler = getContainer(target, flow,
2456: containers);
2457:
2458: if (targetParentHandler == null
2459: || hasParent(source, targetParentHandler, flow)) {
2460: // source should be inside the same FT container as target
2461: // otherwise link will be inbound
2462: badHandlersBoundaries = false;
2463: }
2464: if (!badHandlersBoundaries) {
2465: BpelContainer sourceParentHandler = getContainer(source,
2466: flow, containers);
2467: if (sourceParentHandler != null) {
2468: BpelContainer scope = sourceParentHandler.getParent();
2469: if (hasParent(target, scope, flow)
2470: && !hasParent(target, sourceParentHandler, flow)) {
2471: badHandlersBoundaries = true;
2472: }
2473: }
2474: }
2475: if (badHandlersBoundaries) {
2476: Collection<Component> collection = new ArrayList<Component>(
2477: 3);
2478: collection.add(target);
2479: collection.add(source);
2480: collection.add(link);
2481: addError(FIX_BAD_HANDLERS_LINK_BOUNDARIES, collection);
2482: }
2483: }
2484:
2485: @SuppressWarnings("unchecked")
2486: private BpelContainer getContainer(BpelEntity child,
2487: BpelContainer parent, Class... classes) {
2488: BpelContainer container = child.getParent();
2489: while (container != null && !container.equals(parent)) {
2490: for (Class clazz : classes) {
2491: if (clazz.isAssignableFrom(container.getClass())) {
2492: return container;
2493: }
2494: }
2495: container = container.getParent();
2496: }
2497: return null;
2498: }
2499:
2500: private boolean hasParent(BpelEntity entity,
2501: BpelContainer container, BpelContainer parent) {
2502: BpelEntity child = entity;
2503: while (child != null && child != parent) {
2504: if (child == container) {
2505: return true;
2506: }
2507: child = child.getParent();
2508: }
2509: return false;
2510: }
2511:
2512: private ExtendableActivity findPreviouslyPerformedActivities(
2513: ExtendableActivity activity, Set<CompositeActivity> set) {
2514:
2515: if (!isAcceptableActivity(activity)) {
2516: return activity;
2517: }
2518: BpelContainer container = activity.getParent();
2519: if (!(container instanceof ExtendableActivity)) {
2520: return null;
2521: }
2522: if (container instanceof ActivityHolder) {
2523: return findPreviouslyPerformedActivities(
2524: (ExtendableActivity) container, set);
2525: }
2526: if (container instanceof CompositeActivity) {
2527: ExtendableActivity found = findExecutableActivity(
2528: (CompositeActivity) container, activity, set);
2529:
2530: if (found == null) {
2531: found = findPreviouslyPerformedActivities(
2532: (ExtendableActivity) container, set);
2533: }
2534: return found;
2535: }
2536: return null;
2537: }
2538:
2539: private ExtendableActivity findExecutableActivity(
2540: CompositeActivity container, ExtendableActivity activity,
2541: Set<CompositeActivity> set) {
2542: // # 85727
2543: set.add(container);
2544: if (container instanceof Sequence) {
2545: Sequence sequence = (Sequence) container;
2546: int i = sequence
2547: .indexOf(ExtendableActivity.class, activity);
2548: return findExecutableActivityInSequence(sequence, i, set);
2549: } else if (container instanceof Flow) {
2550: return findExecutableActivityInFlow((Flow) container,
2551: activity, set);
2552: } else {
2553: assert false;
2554: }
2555: return null;
2556: }
2557:
2558: private ExtendableActivity findExecutableActivityInFlow(Flow flow,
2559: ExtendableActivity activity,
2560: Set<CompositeActivity> compositeActivities) {
2561: Set<ExtendableActivity> set = getLogicallyPreceding(activity);
2562: ExtendableActivity found = findDescendantActivity(set);
2563: if (found != null) {
2564: return found;
2565: }
2566: return getUntargetedUnacceptableActivity(flow,
2567: compositeActivities);
2568: }
2569:
2570: private ExtendableActivity getUntargetedUnacceptableActivity(
2571: Activity activity, Set<CompositeActivity> set) {
2572: /*
2573: * We are trying to find here unacceptable activity inside flow that
2574: * do not have target at all.
2575: * If there is some activity with target then it precede some other
2576: * activity ( may be situated inside ascendant flow, not this flow ),
2577: * so when we appear in appropriate flow we find this preceding
2578: * activity. If it has "acceptable" activity then all ok, because
2579: * all following ( by links order ) activity will be after
2580: * "acceptable". If it does not have acceptable activity then we will
2581: * find it on this step.
2582: */
2583: List<Activity> children = activity.getChildren(Activity.class);
2584: for (Activity child : children) {
2585: if (set.contains(child)) {
2586: continue;
2587: }
2588: TargetContainer container = child.getTargetContainer();
2589: if (container == null || container.getTargets().length == 0) {
2590: if (!isAcceptableActivity(child)) {
2591: return child;
2592: }
2593: ExtendableActivity found = getUntargetedUnacceptableActivity(
2594: child, set);
2595: if (found != null) {
2596: return found;
2597: }
2598: }
2599: }
2600: return null;
2601: }
2602:
2603: private ExtendableActivity findDescendantActivity(
2604: Set<ExtendableActivity> set) {
2605: for (ExtendableActivity preceding : set) {
2606: ExtendableActivity found = findDescendantActivity(preceding);
2607: if (found != null) {
2608: return found;
2609: }
2610: }
2611: return null;
2612: }
2613:
2614: @SuppressWarnings("unchecked")
2615: private Set<ExtendableActivity> getLogicallyPreceding(
2616: ExtendableActivity activity) {
2617: /*
2618: * This method collect all preceding activities for activity.
2619: * So resulting set will contain activities that are source
2620: * for some links and those links have activity as target.
2621: * Then we put on the place "activity" found source activities
2622: * and search sources for them. And so on.
2623: */
2624: if (!(activity instanceof Activity)) {
2625: return Collections.EMPTY_SET;
2626: }
2627: Set<ExtendableActivity> set = new HashSet<ExtendableActivity>();
2628: collectPreceding((Activity) activity, set);
2629: return set;
2630: }
2631:
2632: private void collectPreceding(Activity activity,
2633: Set<ExtendableActivity> set) {
2634: if (set.contains(activity)) {
2635: return;
2636: }
2637: TargetContainer container = activity.getTargetContainer();
2638: if (container == null) {
2639: return;
2640: }
2641: Target[] targets = container.getTargets();
2642: for (Target target : targets) {
2643: BpelReference<Link> linkRef = target.getLink();
2644: if (linkRef == null) {
2645: continue;
2646: }
2647: Link link = linkRef.get();
2648: if (link == null) {
2649: continue;
2650: }
2651: BpelContainer flow = link.getParent().getParent();
2652: Activity source = findSource(flow, link);
2653: if (source != null) {
2654: set.add(source);
2655: collectPreceding(source, set);
2656: }
2657: }
2658: }
2659:
2660: private Activity findSource(BpelContainer container, Link link) {
2661: List<Activity> children = container.getChildren(Activity.class);
2662: for (Activity child : children) {
2663: SourceContainer sourceContainer = child
2664: .getSourceContainer();
2665: if (sourceContainer != null
2666: && checkSource(link, sourceContainer)) {
2667: return child;
2668: }
2669: if (child instanceof BpelContainer) {
2670: Activity found = findSource((BpelContainer) child, link);
2671: if (found != null) {
2672: return found;
2673: }
2674: }
2675: }
2676: return null;
2677: }
2678:
2679: private boolean checkSource(Link link,
2680: SourceContainer sourceContainer) {
2681: Source[] sources = sourceContainer.getSources();
2682: for (Source source : sources) {
2683: BpelReference<Link> linkRef = source.getLink();
2684: if (linkRef != null && linkRef.references(link)) {
2685: return true;
2686: }
2687: }
2688: return false;
2689: }
2690:
2691: private ExtendableActivity findExecutableActivityInSequence(
2692: Sequence sequence, int i, Set<CompositeActivity> set) {
2693: ExtendableActivity[] children = sequence.getActivities();
2694: for (int j = 0; j < i; j++) {
2695: if (set.contains(children[j])) {
2696: continue;
2697: }
2698: ExtendableActivity found = findDescendantActivity(children[j]);
2699: if (found != null) {
2700: return found;
2701: }
2702: }
2703: return null;
2704: }
2705:
2706: private ExtendableActivity findDescendantActivity(
2707: ExtendableActivity activity) {
2708: if (!isAcceptableActivity(activity)) {
2709: return activity;
2710: }
2711: List<ExtendableActivity> children = activity
2712: .getChildren(ExtendableActivity.class);
2713: for (ExtendableActivity child : children) {
2714: ExtendableActivity found = findDescendantActivity(child);
2715: if (found != null) {
2716: return found;
2717: }
2718: }
2719: return null;
2720: }
2721:
2722: private boolean isAcceptableActivity(ExtendableActivity activity) {
2723: if (activity instanceof CreateInstanceActivity) {
2724: if (TBoolean.YES.equals(((CreateInstanceActivity) activity)
2725: .getCreateInstance())) {
2726: return true;
2727: }
2728: }
2729: Class clazz = activity.getElementType();
2730: return clazz.equals(Scope.class) || clazz.equals(Flow.class)
2731: || clazz.equals(Sequence.class)
2732: || clazz.equals(Empty.class);
2733: }
2734:
2735: static class DefaultNameAccess implements NameAccess {
2736:
2737: public String getName(BpelEntity entity) {
2738: if (entity instanceof NamedElement) {
2739: return ((NamedElement) entity).getName();
2740: }
2741: return null;
2742: }
2743: }
2744:
2745: /**
2746: * This class allow collect instances that needs to be lazy initialized
2747: * ( this is the safe way to do this if we care about thread-safe ,
2748: * but may be here we do not need to care about thread-safety ).
2749: * @author ads
2750: *
2751: */
2752: static final class LazyHolder {
2753:
2754: static final NameAccess SOURCE_LINK_NAME_ACCESS = new NameAccess() {
2755: public String getName(BpelEntity entity) {
2756: if (entity instanceof Source) {
2757: BpelReference<Link> ref = ((Source) entity)
2758: .getLink();
2759: if (ref != null && ref.getRefString() != null) {
2760: return ref.getRefString();
2761: }
2762: }
2763: return null;
2764: }
2765: };
2766:
2767: static final NameAccess TARGET_LINK_NAME_ACCESS = new NameAccess() {
2768: public String getName(BpelEntity entity) {
2769: if (entity instanceof Target) {
2770: BpelReference<Link> ref = ((Target) entity)
2771: .getLink();
2772: if (ref != null && ref.getRefString() != null) {
2773: return ref.getRefString();
2774: }
2775: }
2776: return null;
2777: }
2778: };
2779:
2780: static final NameAccess VAR_DECL_NAME_ACCESS = new NameAccess() {
2781: public String getName(BpelEntity entity) {
2782: if (entity instanceof VariableDeclaration) {
2783: return ((VariableDeclaration) entity)
2784: .getVariableName();
2785: }
2786: return null;
2787: }
2788: };
2789: }
2790:
2791: static interface NameAccess {
2792: String getName(BpelEntity entity);
2793: }
2794:
2795: private static final String FIX_PORT_TYPE_OVERLOADED_OPERATION_NAME = "FIX_PortTypeOverloadedOperationName"; // NOI18N
2796: private static final String FIX_WSDLOPERATION_SOLICIT_RESPONSE_NOTIFICATION = "FIX_WSDLOperationSolicitResponseNotification"; // NOI18N
2797: private static final String FIX_INPUTVARIABLE_TOPART_COMBINATION = "FIX_InputVariableToPartCombination"; // NOI18N
2798: private static final String FIX_OUTPUTVARIABLE_FROMPART_COMBINATION = "FIX_OutputVariableFromPartCombination"; // NOI18N
2799: private static final String FIX_INVALID_FROMPART_PARTATTR = "FIX_InvalidFromPartPartAttribute"; // NOI18N
2800: private static final String FIX_INVALID_TOPART_PARTATTR = "FIX_InvalidToPartPartAttribute"; // NOI18N
2801: private static final String FIX_RECEIVE_VARIABLE_FROMPART_COMBINATION = "FIX_ReceiveVariableFromPartCombination"; // NOI18N
2802: private static final String FIX_REPLY_VARIABLE_TOPART_COMBINATION = "FIX_ReplyVariableToPartCombination"; // NOI18N
2803: private static final String FIX_COMPENSATE_OCCURANCE = "FIX_CompensateOccurance"; // NOI18N
2804: private static final String FIX_MULTIPLE_NAMED_ACTIVITIES = "FIX_MultipleNamedActivities"; // NOI18N
2805: private static final String FIX_EXIT_ON_STANDART_FAULT = "FIX_ExitOnStandartFault"; // NOI18N
2806: private static final String FIX_DIFFERENT_PORT_TYPES = "FIX_DifferentPortTypes"; // NOI18N
2807: private static final String FIX_BAD_IMPORT_TYPE = "FIX_BadImportType"; // NOI18N
2808: private static final String FIX_NO_PICK_OR_RECEIVE_WITH_CREATE_INSTANCE = "FIX_NoPickReceiveWithCreateInstance"; // NOI18N
2809: private static final String FIX_MILTIPLE_LINK_SOURCE = "FIX_MultipleLinkSource"; // NOI18N
2810: private static final String FIX_MILTIPLE_LINK_TARGET = "FIX_MultipleLinkTarget"; // NOI18N
2811: private static final String FIX_LINK_IS_NOT_USED = "FIX_LinkIsNotUsed"; // NOI18N
2812: private static final String FIX_MULTIPLE_LINKS_WITH_SAME_SOURCE_AND_TARGET = "FIX_MultipleLinksWithSameSourceAndTarget"; // NOI18N
2813: private static final String FIX_SCOPE_INSIDE_FCT_CONTAINS_COMPENSATION_HANDLER = "FIX_ScopeWithCompenstationHandlerInsideFCT"; // NOI18N
2814: private static final String FIX_MESSAGE_TYPE_IN_ON_EVENT = "FIX_MessageTypeInOnEvent"; // NOI18N
2815: private static final String FIX_ELEMENT_IN_ON_EVENT = "FIX_ElementInOnEvent"; // NOI18N
2816: private static final String FIX_LINK_CROSS_BOUNDARY_REPEATABLE_CONSTRUCT = "FIX_LinkCrossBoundaryRepeatableConstract"; // NOI18N
2817: private static final String FIX_BAD_HANDLERS_LINK_BOUNDARIES = "FIX_BadHandlersLinkBoundaries"; // NOI18N
2818: private static final String FIX_WSDL_MESSAGE_NOT_COMPLETELY_INITIALISED = "FIX_WSDL_Message_Not_Completely_Initialised"; // NOI18N
2819: private static final String FIX_ONMESSAGE_VARIABLE_FROMPART_COMBINATION = "FIX_OnMessage_Variable_FromPart_Combination"; // NOI18N
2820: private static final String FIX_OUTPUT_VARIABLE_FOR_ONE_WAY_OP = "FIX_OutputVariableForOneWayOperation"; // NOI18N
2821: private static final String FIX_ABSENT_INPUT_VARIABLE_FOR_ONE_WAY_OP = "FIX_AbsentInputVariableForOneWayOp"; // NOI18N
2822: private static final String FIX_ABSENT_INPUT_OUTPUT_VARIABLES = "FIX_AbsentInputOutputVariables"; // NOI18N
2823: private static final String FIX_BAD_VARIABLE_MESSAGE_TYPE = "FIX_BadVariableMessageType"; // NOI18N
2824: private static final String FIX_BAD_VARIABLE_ELEMENT_TYPE = "FIX_BadVariableElementType"; // NOI18N
2825: private static final String FIX_START_ACTIVITY_IS_NOT_FIRST_EXECUTED = "FIX_StartActivityHasPreceding"; // NOI18N
2826: private static final String FIX_ABSENT_SHARED_JOINED_CORRELATION_SET = "FIX_AbsentSharedJoinedCorrelationSet"; // NOI18N
2827: private static final String FIX_MULTIPLE_PROPERTY_ALIAS_FOR_PROPERTY = "FIX_MultiplePropertyAliasForProperty"; // NOI18N
2828: private static final String FIX_ABSENT_OUTPUT_VARIABLE = "FIX_AbsentOutputVariable"; // NOI18N
2829: private static final String FIX_ABSENT_INPUT_VARIABLE = "FIX_AbsentInputVariable"; // NOI18N
2830: private static final String FIX_DUPLICATE_VARIABLE_NAME = "FIX_DUPLICATE_VARIABLE_NAME"; // NOI18N
2831: private static final String FIX_DUPLICATE_VARIABLE_NAME_ON_EVENT = "FIX_DuplicateVariableNameOnEvent"; // NOI18N
2832: private static final String SUPPORTED_LANGAGE = "urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0";
2833: private static final String FIX_INITIALISE_PARTNER_ROLE = "FIX_InitialisePartnerRole";
2834: private static final String FIX_PARTNER_LINK_ERROR = "FIX_PartnerLinkError";
2835: private static final String FIX_RETHROW_OCCURANCE = "FIX_RethrowOccurance";
2836: private static final String FIX_ENDPOINT_REFRENCE = "FIX_EndpointReference";
2837: private static final String FIX_MULTIPLE_NAMED_LINKS = "FIX_MultipleNamedLinks";
2838: private static final String FIX_MULTIPLE_SOURCE_LINK_REFERENCES = "FIX_MultipleSourceLinkReferences";
2839: private static final String FIX_MULTIPLE_TARGET_LINK_REFERENCES = "FIX_MultipleTargetLinkReferences";
2840: private static final String FIX_DUPLICATE_COUNTER_NAME = "FIX_DuplicateCounterName";
2841: private static final String FIX_ISOLATED_SCOPES = "FIX_IsolatedScopes";
2842: private static final String FIX_ON_EVENT_VARAIBLE = "FIX_OnEventVariable";
2843: private static final String FIX_EVENT_HANDLERS = "FIX_EventHandlers";
2844: private static final String FIX_FAULT_VARIABLE_TYPE = "FIX_FaultVariableType";
2845: private static final String FIX_ODD_FAULT_TYPE = "FIX_OddFaultType";
2846: private static final String FIX_FAULT_HANDLERS = "FIX_FaultHandlers";
2847: private static final String FIX_ABSENT_NAMESPACE_IN_IMPORT = "FIX_AbsentNamespaceInImport";
2848: private static final String FIX_BAD_NAMESPACE_IN_IMPORT = "FIX_BadNamespaceInImport";
2849: private static final String FIX_BAD_VARIABLE_NAME = "FIX_BadVariableName";
2850: private static final String FIX_PICK_MESSAGES = "FIX_PickMessages";
2851: private static final String FIX_BAD_CORRELATION_PROPERTY_TYPE = "FIX_BadCorrelationPropertyType";
2852: private static final String FIX_BAD_USAGE_PATTERN_ATTRIBUTE = "FIX_BadUsagePatternAttribute";
2853: private static final String FIX_DUPLICATE_CORRELATION_SET_NAME = "FIX_DuplicateCorrelationSetName";
2854: private static final String FIX_DUPLICATE_PARTNER_LINK_NAME = "FIX_DuplicatePartnerLinkName";
2855: private static final String FIX_VARIABLE_TYPES = "FIX_VariableTypes";
2856: private static final String FIX_SUPPORTED_LANGUAGE = "FIX_SupportedLanguage";
2857: private static final String FIX_UNSUPPORTED_EXTENSION = "FIX_UnsupportedExtension";
2858: private static final DefaultNameAccess DEFAULT_NAME_ACESS = new DefaultNameAccess();
2859: }
|