/******************************************************************************* * Copyright (c) 2006 Oracle Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Oracle Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.bpel.validator.rules; import java.util.List; import javax.xml.namespace.QName; import org.eclipse.bpel.validator.model.Filters; import org.eclipse.bpel.validator.model.IFilter; import org.eclipse.bpel.validator.model.IModelQueryLookups; import org.eclipse.bpel.validator.model.INode; import org.eclipse.bpel.validator.model.IProblem; import org.eclipse.bpel.validator.model.ARule; import org.eclipse.bpel.validator.model.IValue; import org.eclipse.bpel.validator.model.NodeNameFilter; import org.eclipse.bpel.validator.model.RuleFactory; import org.eclipse.bpel.validator.model.Validator; /** * Validates From nodes. * * Variants: Part/Query * <from variable="BPELVariableName" part="NCName"?> <query queryLanguage="anyURI"?>? queryContent </query> </from> * Partner link <from partnerLink="NCName" endpointReference="myRole|partnerRole" /> * Variable property <from variable="BPELVariableName" property="QName" /> * Expression <from expressionLanguage="anyURI"?>expression</from> * Literal <from><literal>literal value</literal></from> * Empty <from/> * * @author Michal Chmielewski (michal.chmielewski@oracle.com) * @date Oct 10, 2006 * */ @SuppressWarnings( {"nls","boxing"} ) public class FromValidator extends CValidator { static QName [] ENDPOINT_REFRENCE = { AT_MY_ROLE , AT_PARTNER_ROLE }; /** Can be part of variable too */ static public IFilter<INode> PARENTS = new NodeNameFilter( ND_VARIABLE, ND_COPY ) ; protected INode fVariableNode ; protected INode fQueryNode; protected INode fLiteralNode; protected INode fPartnerLinkNode; protected INode fPartNode; protected INode fPropertyNode; protected String fEndpointReference; protected Validator fExprValidator; protected String fExpressionLanguage; protected String fPropertyName; protected String fPartName; protected String fHeaderName; /** * */ @Override protected void start () { super.start(); fVariableNode = mModelQuery.lookup(mNode, IModelQueryLookups.LOOKUP_NODE_VARIABLE, mNode.getAttribute(AT_VARIABLE)); fPartName = mNode.getAttribute(AT_PART); // fix Bug 323945 fHeaderName = mNode.getAttribute(AT_HEADER); fQueryNode = mNode.getNode(ND_QUERY); fPartnerLinkNode = mModelQuery.lookup(mNode, IModelQueryLookups.LOOKUP_NODE_PARTNER_LINK, mNode.getAttribute(AT_PARTNER_LINK)); fEndpointReference = mNode.getAttribute(AT_ENDPOINT_REFERENCE); fPropertyName = mNode.getAttribute(AT_PROPERTY); fExpressionLanguage = getLanguage(mNode,AT_EXPRESSIONLANGUAGE); fLiteralNode = mNode.getNode(ND_LITERAL); } /** * Checks the from variant. It must be exactly one of * the variants */ @SuppressWarnings("boxing") @ARule( author = "michal.chmielewski@oracle.com", desc = "Checks the allowed formats of the <from> element", date = "01/15/2007", sa = 32 , errors="BPELC__UNSET_ATTRIBUTE,BPELC__UNRESOLVED_ATTRIBUTE,BPELC__INVALID_ATTRIBUTE_VALUE,BPELC_FROM__VARIANT", warnings="BPELC_REF_NODE_PROBLEMS" ) public void rule_CheckFromVariant_10 () { IProblem problem; int variant = 0; if (fLiteralNode != null) { variant += 1; } // fix Bug 323945 if(!isEmpty(fHeaderName)){ setValue("header", fHeaderName); } if (fVariableNode != null) { variant += 1; // if this is bad, disable all rules if (checkValidator(mNode, fVariableNode, AT_VARIABLE, KIND_NODE) == false || checkAttributeNode(mNode, fVariableNode, AT_VARIABLE, KIND_NODE) == false) { disableRules(); } } if (fPartnerLinkNode != null) { variant += 1; // if this is bad, disable all rules if (checkValidator(mNode, fPartnerLinkNode, AT_PARTNER_LINK, KIND_NODE) == false || checkAttributeNode(mNode, fPartnerLinkNode, AT_PARTNER_LINK, KIND_NODE) == false) { disableRules(); } fEndpointReference = getAttribute(mNode, AT_ENDPOINT_REFERENCE, KIND_NODE, Filters.ENDPOINT_FILTER, true); if (isEmpty(fEndpointReference)) { disableRules(); } } // if nothing else, it must be the expression variant. if (variant == 0) { variant += 1; } // if (variant == 0) { problem = createError(); problem.fill("BPELC_FROM__VARIANT", //$NON-NLS-1$ toString(mNode.nodeName()), variant); disableRules(); } else if (variant > 1) { problem = createError(); problem.fill("BPELC_FROM__VARIANT", //$NON-NLS-1$ toString(mNode.nodeName()), variant); disableRules(); } } /** * Check the variable variant. */ @ARule( desc = "Variables used in <from> must not have part set if they are schema types. " + " (part must not be set) ", author = "michal.chmielewski@oracle.com", date = "01/15/2007", sa = 34 , errors="BPELC_FROM__VARIABLE_PART,BPELC__PA_NO_PART" ) public void rule_CheckVariableVariant_18 () { IProblem problem ; // variable is not specified. if (isUndefined(fVariableNode) || isDefined(fPropertyNode)) { return ; } // The variable has a certain type. Get it from the variable validator. INode varTypeNode = getValue(fVariableNode,"type",null); if (isUndefined(varTypeNode)) { return ; } // type-of from is the variable type setValue("type", varTypeNode); // Not a WSDL message if (WSDL_ND_MESSAGE.equals(varTypeNode.nodeName()) == false) { // not a WSDL message type if (isEmpty(fPartName) == false) { problem = createError(); problem.fill("BPELC_FROM__VARIABLE_PART", //$NON-NLS-1$ toString(mNode.nodeName()), AT_VARIABLE, fVariableNode.getAttribute(AT_NAME) ); } } else if (isEmpty(fPartName) == false ) { // it is a message type, figure out the part type INode partNode = mModelQuery.lookup(varTypeNode, IModelQueryLookups.LOOKUP_NODE_MESSAGE_PART,fPartName); if (isUndefined(partNode)) { problem = createError(); problem.fill("BPELC__PA_NO_PART", toString(mNode.nodeName()), fPartName, varTypeNode); return ; } INode partType = mModelQuery.lookup(partNode, IModelQueryLookups.LOOKUP_NODE_TYPE_OF_PART,fPartName); if (isDefined(partType)) { setValue("type",partType); } } } /** * Check to make sure that if endpointReference is set to myRole * the partner link specifies the attribute myRole. */ @SuppressWarnings({"boxing", "nls"}) @ARule( author = "michal.chmielewski@oracle.com", desc = "A partner link referenced in a <from> spec with endpoint " + " reference of 'myRole' must have myRole set.", date = "01/10/2007", sa = 35 , errors="BPELC_FROM__PARTNER_LINK" ) public void rule_CheckPartnerLinkVariantMyRole_21 () { if ( isUndefined(fPartnerLinkNode) ) { return ; } IProblem problem; if (AT_MY_ROLE.equals(fEndpointReference)) { String myRole = fPartnerLinkNode.getAttribute(AT_MY_ROLE); if (isEmptyOrWhitespace(myRole) ) { problem = createError(); problem.fill("BPELC_FROM__PARTNER_LINK", //$NON-NLS-1$ toString(mNode.nodeName()), fPartnerLinkNode.getAttribute(AT_NAME), fEndpointReference ); } else { // the effective "type" of this is portType. INode portType = getValue(fPartnerLinkNode,"role.portType." + myRole, null); setValue("type", portType); } } } /** * Check to make sure that if endpointReference is set to partnerRole * the partner link specifies the attribute partnerRole. */ @SuppressWarnings("nls") @ARule( author = "michal.chmielewski@oracle.com", desc = "A partner link referenced in a <from> spec with endpoint " + " reference of 'partnerRole' must have partnerRole set.", date = "01/10/2007", sa = 36 , errors="BPELC_FROM__PARTNER_LINK" ) public void rule_CheckPartnerLinkVariantPartnerRole_22 () { if ( isUndefined(fPartnerLinkNode) ) { return ; } IProblem problem; if (AT_PARTNER_ROLE.equals(fEndpointReference)) { String partnerRole = fPartnerLinkNode.getAttribute(AT_PARTNER_ROLE); if (isEmptyOrWhitespace(partnerRole) ) { problem = createError(); problem.fill("BPELC_FROM__PARTNER_LINK", //$NON-NLS-1$ toString(mNode.nodeName()), fPartnerLinkNode.getAttribute(AT_NAME), fEndpointReference ); } else { // effective type is the portType INode portType = getValue(fPartnerLinkNode,"role.portType." + partnerRole, null); setValue("type", portType); } } } /** * Check the literal variant. Here, an XML literal is * being used as the source. * */ @SuppressWarnings({ "nls", "boxing" }) @ARule( author = "michal.chmielewski@oracle.com", desc = "The literal <from> spec must return a EII or a TII only", date = "01/10/2007", sa = 38 , errors="BPELC_FROM__LITERAL" ) public void rule_CheckLiteralVariant_30 () { if (isUndefined(fLiteralNode)) { return ; } IProblem problem; List<INode> children = fLiteralNode.children(); if (children.size() > 1) { problem = createError(); problem.fill("BPELC_FROM__LITERAL", toString(mNode.nodeName()), fLiteralNode.nodeName(), children.size() ); } // Compute the type of this literal in this <from> if (children.size() > 0) { INode first = children.get(0); // literal } } /** * Check the expression variant. * */ @ARule( author = "michal.chmielewski@oracle.com", desc = "Checks the actual expression using the expression language validator.", date = "10/2/2006", sa = 1000 , warnings="BPELC__NO_EXPRESSION_VALIDATOR" ) public void rule_CheckExpressionVariant_50 () { // not this variant. if (fVariableNode != null || fPropertyNode != null || fPartnerLinkNode != null || fPartName != null || fLiteralNode != null || fQueryNode != null ) { return ; } /** * How to dynamically add an validator to the chain. * * 1. Have we been through here before ? */ if (fExprValidator == null) { /** 2. If no, then create the validator. We use the normal factory mechanism for */ QName qname = new QName( fExpressionLanguage, mNode.nodeName().getLocalPart() ); fExprValidator = RuleFactory.INSTANCE.createValidator ( qname ); IProblem problem; if (fExprValidator == null) { problem = createWarning(); problem.fill("BPELC__NO_EXPRESSION_VALIDATOR", //$NON-NLS-1$ toString(mNode.nodeName()), fExpressionLanguage ); return ; } /** * 3. Add this validator to my chain. Some points to follow below ... * a) add() will check against instance equality, but not against anything else. * b) because this is a "dynamic" addition, (validation is already running), * the code there will not be executed until all the rules here are done. */ attach (fExprValidator); } // "expression.type" is not computed until that validator is run. // this does not happen until we are done, to the IValue binding mechanism // is used. setValue("type", new IValue<Object>() { public Object get() { return fExprValidator.getValue("expression.type"); } } ); } /** * Check the expression variant. * */ @ARule( author = "michal.chmielewski@oracle.com", desc = "Query variant checking.", date = "07/07/2007", sa = 1000 ) public void rule_CheckQueryVariant_55 () { if (fQueryNode == null) { return ; } } /** End of public rule methods. * * Other methods are support methods for this class to perform its * validation function. * */ }