All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.faces.config.processor.FacesFlowDefinitionConfigProcessor Maven / Gradle / Ivy

Go to download

This is the master POM file for Oracle's Implementation of the JSF 2.2 Specification.

There is a newer version: 2.4.0
Show newest version
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 * 
 * Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
 * 
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 * 
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 * 
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 * 
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 * 
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.

 */
package com.sun.faces.config.processor;

import com.sun.faces.RIConstants;
import com.sun.faces.application.ApplicationAssociate;
import com.sun.faces.config.DocumentInfo;
import com.sun.faces.config.WebConfiguration;
import com.sun.faces.facelets.util.ReflectionUtil;
import com.sun.faces.flow.FlowImpl;
import com.sun.faces.flow.ParameterImpl;
import com.sun.faces.flow.builder.FlowBuilderImpl;
import com.sun.faces.util.FacesLogger;
import com.sun.faces.util.Util;
import java.net.MalformedURLException;
import java.net.URI;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.el.ELContext;
import javax.el.ExpressionFactory;
import javax.el.ValueExpression;
import javax.faces.FacesException;
import javax.faces.FactoryFinder;
import javax.faces.application.Application;
import javax.faces.context.FacesContext;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.PostConstructApplicationEvent;
import javax.faces.event.SystemEvent;
import javax.faces.event.SystemEventListener;
import javax.faces.flow.FlowHandler;
import javax.faces.flow.FlowHandlerFactory;
import javax.faces.flow.FlowNode;
import javax.faces.flow.Parameter;
import javax.faces.flow.builder.FlowBuilder;
import javax.faces.flow.builder.FlowCallBuilder;
import javax.faces.flow.builder.MethodCallBuilder;
import javax.faces.flow.builder.NavigationCaseBuilder;
import javax.faces.flow.builder.SwitchBuilder;
import javax.servlet.ServletContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Attr;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * 

* This ConfigProcessor handles all elements defined under * /faces-config/flow-definition. *

*/ public class FacesFlowDefinitionConfigProcessor extends AbstractConfigProcessor { private static final Logger LOGGER = FacesLogger.CONFIG.getLogger(); /** * /faces-config/flow-definition */ private static final String FACES_FLOW_DEFINITION = "flow-definition"; public FacesFlowDefinitionConfigProcessor() { } public static boolean uriIsFlowDefinition(URI uri) { boolean result = false; String path = uri.getPath(); String [] segments = path.split("/"); if (1 < segments.length) { String flowName = segments[segments.length-2]; String definingName = segments[segments.length-1]; result = definingName.equals(flowName + "-flow.xml"); } return result; } /* * Implement the requirements of 11.4.3.3 * * @param uri * @param toPopulate * @return */ public static Document synthesizeEmptyFlowDefinition(URI uri) throws ParserConfigurationException { Document newDoc = null; String path = uri.getPath(); String [] segments = path.split("/"); if (segments.length < 2) { return newDoc; } String flowName = segments[segments.length-2]; DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); DocumentBuilder builder = dbf.newDocumentBuilder(); DOMImplementation domImpl = builder.getDOMImplementation(); newDoc = domImpl.createDocument(RIConstants.JAVAEE_XMLNS, "faces-config", null); Node documentElement = newDoc.getDocumentElement(); Attr versionAttribute = newDoc.createAttribute("version"); versionAttribute.setValue("2.2"); documentElement.getAttributes().setNamedItem(versionAttribute); Node facesConfig = newDoc.getFirstChild(); Element flowDefinition = newDoc.createElementNS(RIConstants.JAVAEE_XMLNS, "flow-definition"); flowDefinition.setAttribute("id", flowName); facesConfig.appendChild(flowDefinition); final String flowReturnStr = flowName + "-return"; Element flowReturn = newDoc.createElementNS(RIConstants.JAVAEE_XMLNS, "flow-return"); flowReturn.setAttribute("id", flowReturnStr); flowDefinition.appendChild(flowReturn); Element fromOutcome = newDoc.createElementNS(RIConstants.JAVAEE_XMLNS, "from-outcome"); flowReturn.appendChild(fromOutcome); fromOutcome.setTextContent("/" + flowReturnStr); return newDoc; } @Override public void process(ServletContext sc, DocumentInfo[] documentInfos) throws Exception { WebConfiguration config = WebConfiguration.getInstance(sc); FacesContext context = FacesContext.getCurrentInstance(); for (int i = 0; i < documentInfos.length; i++) { URI definingDocumentURI = documentInfos[i].getSourceURI(); if (LOGGER.isLoggable(Level.FINE)) { LOGGER.log(Level.FINE, MessageFormat.format( "Processing factory elements for document: ''{0}''", definingDocumentURI)); } Document document = documentInfos[i].getDocument(); String namespace = document.getDocumentElement() .getNamespaceURI(); NodeList flowDefinitions = document.getDocumentElement() .getElementsByTagNameNS(namespace, FACES_FLOW_DEFINITION); if (flowDefinitions != null && flowDefinitions.getLength() > 0) { config.setHasFlows(true); saveFlowDefinition(context, definingDocumentURI, document); } } if (config.isHasFlows()) { String optionValue = config.getOptionValue(WebConfiguration.WebContextInitParameter.ClientWindowMode); boolean clientWindowNeedsEnabling = false; if ("none".equals(optionValue)) { clientWindowNeedsEnabling = true; String featureName = WebConfiguration.WebContextInitParameter.ClientWindowMode.getQualifiedName(); LOGGER.log(Level.WARNING, "{0} was set to none, but Faces Flows requires {0} is enabled. Setting to ''url''.", new Object[]{featureName}); } else if (null == optionValue) { clientWindowNeedsEnabling = true; } if (clientWindowNeedsEnabling) { config.setOptionValue(WebConfiguration.WebContextInitParameter.ClientWindowMode, "url"); } context.getApplication().subscribeToEvent(PostConstructApplicationEvent.class, Application.class, new PerformDeferredFlowProcessing()); } invokeNext(sc, documentInfos); } // private static final String flowDefinitionListKey = RIConstants.FACES_PREFIX + "FacesFlowDefinitions"; private void saveFlowDefinition(FacesContext context, URI definingDocumentURI, Document flowDefinitions) { Map appMap = context.getExternalContext().getApplicationMap(); List def = (List) appMap.get(flowDefinitionListKey); if (null == def) { def = new ArrayList(); appMap.put(flowDefinitionListKey, def); } def.add(new FlowDefinitionDocument(definingDocumentURI, flowDefinitions)); } private List getSavedFlowDefinitions(FacesContext context) { Map appMap = context.getExternalContext().getApplicationMap(); List def = (List) appMap.get(flowDefinitionListKey); return (null != def) ? def : Collections.EMPTY_LIST; } private void clearSavedFlowDefinitions(FacesContext context) { Map appMap = context.getExternalContext().getApplicationMap(); List def = (List) appMap.get(flowDefinitionListKey); if (null != def) { for (FlowDefinitionDocument cur : def) { cur.clear(); } def.clear(); appMap.remove(flowDefinitionListKey); } } private static class FlowDefinitionDocument { URI definingDocumentURI; Document flowDefinitions; public FlowDefinitionDocument(URI definingDocumentURI, Document flowDefinitions) { this.definingDocumentURI = definingDocumentURI; this.flowDefinitions = flowDefinitions; } public void clear() { this.definingDocumentURI = null; this.flowDefinitions = null; } } private class PerformDeferredFlowProcessing implements SystemEventListener { @Override public boolean isListenerForSource(Object source) { return source instanceof Application; } @Override public void processEvent(SystemEvent event) throws AbortProcessingException { FacesContext context = FacesContext.getCurrentInstance(); List flowDefinitions = FacesFlowDefinitionConfigProcessor.this.getSavedFlowDefinitions(context); for (FlowDefinitionDocument cur: flowDefinitions) { try { FacesFlowDefinitionConfigProcessor.this. processFacesFlowDefinitions(cur.definingDocumentURI, cur.flowDefinitions); } catch (XPathExpressionException ex) { throw new FacesException(ex); } } FacesFlowDefinitionConfigProcessor.this.clearSavedFlowDefinitions(context); } } // private void processFacesFlowDefinitions(URI definingDocumentURI, Document document) throws XPathExpressionException { String namespace = document.getDocumentElement() .getNamespaceURI(); NodeList flowDefinitions = document.getDocumentElement() .getElementsByTagNameNS(namespace, FACES_FLOW_DEFINITION); if (0 == flowDefinitions.getLength()) { return; } FacesContext context = FacesContext.getCurrentInstance(); Application app = context.getApplication(); FlowHandler flowHandler = app.getFlowHandler(); if (null == flowHandler) { FlowHandlerFactory flowHandlerFactory = (FlowHandlerFactory) FactoryFinder.getFactory(FactoryFinder.FLOW_HANDLER_FACTORY); app.setFlowHandler(flowHandler = flowHandlerFactory.createFlowHandler(context)); } XPath xpath = XPathFactory.newInstance().newXPath(); xpath.setNamespaceContext(new FacesConfigNamespaceContext()); String nameStr = ""; NodeList nameList = (NodeList) xpath.evaluate("./ns1:name/text()", document.getDocumentElement(), XPathConstants.NODESET); if (null != nameList && 1 < nameList.getLength()) { throw new XPathExpressionException(" must have at most one element."); } if (null != nameList && 1 == nameList.getLength()) { nameStr = nameList.item(0).getNodeValue().trim(); if (0 < nameStr.length()) { ApplicationAssociate associate = ApplicationAssociate.getInstance(context.getExternalContext()); try { associate.relateUrlToDefiningDocumentInJar(definingDocumentURI.toURL(), nameStr); } catch (MalformedURLException ex) { throw new XPathExpressionException(ex); } } } for (int c = 0, size = flowDefinitions.getLength(); c < size; c++) { Node flowDefinition = flowDefinitions.item(c); String flowId = getIdAttribute(flowDefinition); String uriStr = definingDocumentURI.toASCIIString(); if (uriStr.endsWith(RIConstants.FLOW_DEFINITION_ID_SUFFIX)) { nameStr = ""; } FlowBuilderImpl flowBuilder = new FlowBuilderImpl(context); flowBuilder.id(nameStr, flowId); processViews(xpath, flowDefinition, flowBuilder); processNavigationRules(xpath, flowDefinition, flowBuilder); processReturns(xpath, flowDefinition, flowBuilder); processInboundParameters(xpath, flowDefinition, flowBuilder); processFlowCalls(xpath, flowDefinition, flowBuilder); processSwitches(xpath, flowDefinition, flowBuilder); processMethodCalls(context, xpath, flowDefinition, flowBuilder); processInitializerFinalizer(xpath, flowDefinition, flowBuilder); String startNodeId = processStartNode(xpath, flowDefinition, flowBuilder); if (null != startNodeId) { FlowImpl toAdd = flowBuilder._getFlow(); FlowNode startNode = toAdd.getNode(startNodeId); if (null == startNode) { throw new XPathExpressionException("Unable to find flow node with id " + startNodeId + " to mark as start node"); } else { toAdd.setStartNodeId(startNodeId); } } else { flowBuilder.viewNode(flowId, "/" + flowId + "/" + flowId + ".xhtml").markAsStartNode(); } flowHandler.addFlow(context, flowBuilder.getFlow()); } } private void processNavigationRules(XPath xpath, Node flowDefinition, FlowBuilder flowBuilder) throws XPathExpressionException{ // NodeList navRules = (NodeList) xpath.evaluate(".//ns1:navigation-rule", flowDefinition, XPathConstants.NODESET); for (int i_navRule = 0; i_navRule < navRules.getLength(); i_navRule++) { Node navRule = navRules.item(i_navRule); NodeList fromViewIdList = (NodeList) xpath.evaluate(".//ns1:from-view-id/text()", navRule, XPathConstants.NODESET); if (1 != fromViewIdList.getLength()) { throw new XPathExpressionException("Within must have exactly one "); } String fromViewId = fromViewIdList.item(0).getNodeValue().trim(); NodeList navCases = (NodeList) xpath.evaluate(".//ns1:navigation-case", navRule, XPathConstants.NODESET); for (int i_navCase = 0; i_navCase < navCases.getLength(); i_navCase++) { Node navCase = navCases.item(i_navCase); NodeList toViewIdList = (NodeList) xpath.evaluate(".//ns1:to-view-id/text()", navCase, XPathConstants.NODESET); if (1 != toViewIdList.getLength()) { throw new XPathExpressionException("Within , must have exactly one "); } String toViewId = toViewIdList.item(0).getNodeValue().trim(); NavigationCaseBuilder ncb = flowBuilder.navigationCase(); ncb.fromViewId(fromViewId).toViewId(toViewId); { NodeList fromOutcomeList = (NodeList) xpath.evaluate(".//ns1:from-outcome/text()", navCase, XPathConstants.NODESET); if (null != fromOutcomeList && 1 < fromOutcomeList.getLength()) { throw new XPathExpressionException("Within , must have at most one "); } if (null != fromOutcomeList && 1 == fromOutcomeList.getLength()) { String fromOutcome = fromOutcomeList.item(0).getNodeValue().trim(); ncb.fromOutcome(fromOutcome); } } { NodeList fromActionList = (NodeList) xpath.evaluate(".//ns1:from-action/text()", navCase, XPathConstants.NODESET); if (null != fromActionList && 1 < fromActionList.getLength()) { throw new XPathExpressionException("Within , must have at most one "); } if (null != fromActionList && 1 == fromActionList.getLength()) { String fromAction = fromActionList.item(0).getNodeValue().trim(); ncb.fromAction(fromAction); } } { NodeList ifList = (NodeList) xpath.evaluate(".//ns1:if/text()", navCase, XPathConstants.NODESET); if (null != ifList && 1 < ifList.getLength()) { throw new XPathExpressionException("Within , must have zero or one "); } if (null != ifList && 1 == ifList.getLength()) { String ifStr = ifList.item(0).getNodeValue().trim(); ncb.condition(ifStr); } } { NodeList redirectList = (NodeList) xpath.evaluate(".//ns1:redirect", navCase, XPathConstants.NODESET); if (null != redirectList && 1 < redirectList.getLength()) { throw new XPathExpressionException("Within , must have zero or one "); } if (null != redirectList && 1 == redirectList.getLength()) { NavigationCaseBuilder.RedirectBuilder redirector = ncb.redirect(); Node redirectNode = redirectList.item(0); String includeViewParams = getAttribute(redirectNode, "include-view-params"); if (null != includeViewParams && "true".equalsIgnoreCase(includeViewParams)) { redirector.includeViewParams(); } NodeList viewParamList = (NodeList) xpath.evaluate(".//ns1:redirect-param", redirectNode, XPathConstants.NODESET); if (null != viewParamList) { for (int i_viewParam = 0; i_viewParam < viewParamList.getLength(); i_viewParam++) { Node viewParam = viewParamList.item(i_viewParam); NodeList nameList = (NodeList) xpath.evaluate(".//ns1:name/text()", viewParam, XPathConstants.NODESET); if (null == nameList || 1 != nameList.getLength()) { throw new XPathExpressionException("Within must have ."); } String nameStr = nameList.item(0).getNodeValue().trim(); NodeList valueList = (NodeList) xpath.evaluate(".//ns1:value/text()", viewParam, XPathConstants.NODESET); if (null == valueList || 1 != valueList.getLength()) { throw new XPathExpressionException("Within must have ."); } String valueStr = valueList.item(0).getNodeValue().trim(); redirector.parameter(nameStr, valueStr); } } } } } } // } private void processViews(XPath xpath, Node flowDefinition, FlowBuilder flowBuilder) throws XPathExpressionException{ // NodeList views = (NodeList) xpath.evaluate(".//ns1:view", flowDefinition, XPathConstants.NODESET); for (int i_view = 0; i_view < views.getLength(); i_view++) { Node viewNode = views.item(i_view); String viewNodeId = getIdAttribute(viewNode); NodeList vdlDocumentList = (NodeList) xpath.evaluate(".//ns1:vdl-document/text()", viewNode, XPathConstants.NODESET); if (1 != vdlDocumentList.getLength()) { throw new XPathExpressionException("Within exactly one child is allowed, and it must be a "); } String vdlDocumentStr = vdlDocumentList.item(0).getNodeValue().trim(); flowBuilder.viewNode(viewNodeId, vdlDocumentStr); } // } private void processReturns(XPath xpath, Node flowDefinition, FlowBuilder flowBuilder) throws XPathExpressionException{ // NodeList returns = (NodeList) xpath.evaluate(".//ns1:flow-return", flowDefinition, XPathConstants.NODESET); for (int i_return = 0; i_return < returns.getLength(); i_return++) { Node returnNode = returns.item(i_return); NodeList fromOutcomeList = (NodeList) xpath.evaluate(".//ns1:from-outcome/text()", returnNode, XPathConstants.NODESET); String id = getIdAttribute(returnNode); if (null != fromOutcomeList && 1 < fromOutcomeList.getLength()) { throw new XPathExpressionException("Within only one child is allowed, and it must be a "); } if (null != fromOutcomeList && 1 == fromOutcomeList.getLength()) { String fromOutcomeStr = fromOutcomeList.item(0).getNodeValue().trim(); flowBuilder.returnNode(id).fromOutcome(fromOutcomeStr); } } // } private void processInboundParameters(XPath xpath, Node flowDefinition, FlowBuilder flowBuilder) throws XPathExpressionException { // NodeList inboundParameters = (NodeList) xpath.evaluate(".//ns1:inbound-parameter", flowDefinition, XPathConstants.NODESET); for (int i_inbound = 0; i_inbound < inboundParameters.getLength(); i_inbound++) { Node inboundParamNode = inboundParameters.item(i_inbound); NodeList nameList = (NodeList) xpath.evaluate(".//ns1:name/text()", inboundParamNode, XPathConstants.NODESET); if (1 < nameList.getLength()) { throw new XPathExpressionException("Within only one child is allowed"); } String nameStr = nameList.item(0).getNodeValue().trim(); NodeList valueList = (NodeList) xpath.evaluate(".//ns1:value/text()", inboundParamNode, XPathConstants.NODESET); if (1 < valueList.getLength()) { throw new XPathExpressionException("Within only one child is allowed"); } String valueStr = valueList.item(0).getNodeValue().trim(); flowBuilder.inboundParameter(nameStr, valueStr); } // } private void processFlowCalls(XPath xpath, Node flowDefinition, FlowBuilder flowBuilder) throws XPathExpressionException { // NodeList flowCalls = (NodeList) xpath.evaluate(".//ns1:flow-call", flowDefinition, XPathConstants.NODESET); for (int i_flowCall = 0; i_flowCall < flowCalls.getLength(); i_flowCall++) { Node flowCallNode = flowCalls.item(i_flowCall); String flowCallId = getIdAttribute(flowCallNode); NodeList facesFlowRefList = (NodeList) xpath.evaluate(".//ns1:flow-reference", flowCallNode, XPathConstants.NODESET); if (null == facesFlowRefList || 1 != facesFlowRefList.getLength()) { throw new XPathExpressionException("Within must have exactly one "); } Node facesFlowRefNode = facesFlowRefList.item(0); NodeList facesFlowIdList = (NodeList) xpath.evaluate(".//ns1:flow-id/text()", facesFlowRefNode, XPathConstants.NODESET); if (null == facesFlowIdList || 1 != facesFlowIdList.getLength()) { throw new XPathExpressionException("Within must have exactly one "); } String destinationId = facesFlowIdList.item(0).getNodeValue().trim(); NodeList definingDocumentIdList = (NodeList) xpath.evaluate(".//ns1:flow-document-id/text()", facesFlowRefNode, XPathConstants.NODESET); if (null == definingDocumentIdList && 1 != definingDocumentIdList.getLength()) { throw new XPathExpressionException("Within must have at most one "); } String definingDocumentId = ""; if (null != definingDocumentIdList && 1 == definingDocumentIdList.getLength()) { definingDocumentId = definingDocumentIdList.item(0).getNodeValue().trim(); } FlowCallBuilder flowCallBuilder = flowBuilder.flowCallNode(flowCallId); flowCallBuilder.flowReference(definingDocumentId, destinationId); NodeList outboundParameters = (NodeList) xpath.evaluate(".//ns1:outbound-parameter", flowDefinition, XPathConstants.NODESET); if (null != outboundParameters) { for (int i_outbound = 0; i_outbound < outboundParameters.getLength(); i_outbound++) { Node outboundParamNode = outboundParameters.item(i_outbound); NodeList nameList = (NodeList) xpath.evaluate(".//ns1:name/text()", outboundParamNode, XPathConstants.NODESET); if (1 < nameList.getLength()) { throw new XPathExpressionException("Within only one child is allowed"); } String nameStr = nameList.item(0).getNodeValue().trim(); NodeList valueList = (NodeList) xpath.evaluate(".//ns1:value/text()", outboundParamNode, XPathConstants.NODESET); if (1 < valueList.getLength()) { throw new XPathExpressionException("Within only one child is allowed"); } String valueStr = valueList.item(0).getNodeValue().trim(); flowCallBuilder.outboundParameter(nameStr, valueStr); } } } // } private void processSwitches(XPath xpath, Node flowDefinition, FlowBuilder flowBuilder) throws XPathExpressionException { // NodeList switches = (NodeList) xpath.evaluate(".//ns1:switch", flowDefinition, XPathConstants.NODESET); if (null == switches) { return; } for (int i_switch = 0; i_switch < switches.getLength(); i_switch++) { Node switchNode = switches.item(i_switch); String switchId = getIdAttribute(switchNode); SwitchBuilder switchBuilder = flowBuilder.switchNode(switchId); NodeList cases = (NodeList) xpath.evaluate(".//ns1:case", switchNode, XPathConstants.NODESET); if (null != cases) { for (int i_case = 0; i_case < cases.getLength(); i_case++) { Node caseNode = cases.item(i_case); NodeList ifList = (NodeList) xpath.evaluate(".//ns1:if/text()", caseNode, XPathConstants.NODESET); if (1 < ifList.getLength()) { throw new XPathExpressionException("Within only one child is allowed"); } String ifStr = ifList.item(0).getNodeValue().trim(); NodeList fromOutcomeList = (NodeList) xpath.evaluate(".//ns1:from-outcome/text()", caseNode, XPathConstants.NODESET); if (1 < fromOutcomeList.getLength()) { throw new XPathExpressionException("Within only one child is allowed"); } String fromOutcomeStr = fromOutcomeList.item(0).getNodeValue().trim(); switchBuilder.switchCase().condition(ifStr).fromOutcome(fromOutcomeStr); } } NodeList defaultOutcomeList = (NodeList) xpath.evaluate(".//ns1:default-outcome/text()", switchNode, XPathConstants.NODESET); if (null != defaultOutcomeList && 1 < defaultOutcomeList.getLength()) { throw new XPathExpressionException("Within only one child is allowed"); } if (null != defaultOutcomeList) { Node defaultOutcomeNode = defaultOutcomeList.item(0); if (null != defaultOutcomeNode) { String defaultOutcomeStr = defaultOutcomeNode.getNodeValue().trim(); switchBuilder.defaultOutcome(defaultOutcomeStr); } } } // } private void processMethodCalls(FacesContext context, XPath xpath, Node flowDefinition, FlowBuilder flowBuilder) throws XPathExpressionException { // NodeList methodCalls = (NodeList) xpath.evaluate(".//ns1:method-call", flowDefinition, XPathConstants.NODESET); if (null == methodCalls) { return; } for (int i_methodCall = 0; i_methodCall < methodCalls.getLength(); i_methodCall++) { Node methodCallNode = methodCalls.item(i_methodCall); String methodCallId = getIdAttribute(methodCallNode); MethodCallBuilder methodCallBuilder = flowBuilder.methodCallNode(methodCallId); NodeList methodList = (NodeList) xpath.evaluate(".//ns1:method/text()", methodCallNode, XPathConstants.NODESET); if (1 != methodList.getLength()) { throw new XPathExpressionException("Within exactly one child is allowed"); } String methodStr = methodList.item(0).getNodeValue().trim(); NodeList params = (NodeList) xpath.evaluate(".//ns1:parameter", methodCallNode, XPathConstants.NODESET); if (null != params) { List paramTypes = Collections.emptyList(); if (0 < params.getLength()) { paramTypes = new ArrayList(); List paramList = new ArrayList(); Parameter toAdd = null; ExpressionFactory ef = context.getApplication().getExpressionFactory(); ELContext elContext = context.getELContext(); ValueExpression ve = null; for (int i_param = 0; i_param < params.getLength(); i_param++) { Node param = params.item(i_param); NodeList valueList = (NodeList) xpath.evaluate(".//ns1:value/text()", param, XPathConstants.NODESET); if (null == valueList || 1 != valueList.getLength()) { throw new XPathExpressionException("Within exactly one child is allowed"); } String valueStr = valueList.item(0).getNodeValue().trim(); String classStr = null; NodeList classList = (NodeList) xpath.evaluate(".//ns1:class/text()", param, XPathConstants.NODESET); if (null != classList && 1 < classList.getLength()) { throw new XPathExpressionException("Within at most one child is allowed"); } if (null != classList && 1 == classList.getLength()) { classStr = classList.item(0).getNodeValue().trim(); } Class clazz = String.class; if (null != classStr) { try { clazz = ReflectionUtil.forName(classStr); } catch (ClassNotFoundException e) { clazz = Object.class; } } ve = ef.createValueExpression(elContext, valueStr, clazz); toAdd = new ParameterImpl(classStr, ve); paramList.add(toAdd); paramTypes.add(clazz); } methodCallBuilder.parameters(paramList); } Class [] paramArray = new Class[paramTypes.size()]; paramTypes.toArray(paramArray); methodCallBuilder.expression(methodStr, paramArray); } NodeList defaultOutcomeList = (NodeList) xpath.evaluate(".//ns1:default-outcome/text()", methodCallNode, XPathConstants.NODESET); if (null != defaultOutcomeList && 1 < defaultOutcomeList.getLength()) { throw new XPathExpressionException("Within only one child is allowed"); } if (null != defaultOutcomeList) { String defaultOutcomeStr = defaultOutcomeList.item(0).getNodeValue().trim(); methodCallBuilder.defaultOutcome(defaultOutcomeStr); } } // } private void processInitializerFinalizer(XPath xpath, Node flowDefinition, FlowBuilder flowBuilder) throws XPathExpressionException { // NodeList initializerNodeList = (NodeList) xpath.evaluate(".//ns1:initializer/text()", flowDefinition, XPathConstants.NODESET); if (1 < initializerNodeList.getLength()) { throw new XPathExpressionException("At most one is allowed."); } if (1 == initializerNodeList.getLength()) { String initializerStr = initializerNodeList.item(0).getNodeValue().trim(); flowBuilder.initializer(initializerStr); } NodeList finalizerNodeList = (NodeList) xpath.evaluate(".//ns1:finalizer/text()", flowDefinition, XPathConstants.NODESET); if (1 < finalizerNodeList.getLength()) { throw new XPathExpressionException("At most one is allowed."); } if (1 == finalizerNodeList.getLength()) { String finalizerStr = finalizerNodeList.item(0).getNodeValue().trim(); flowBuilder.finalizer(finalizerStr); } // } private String processStartNode(XPath xpath, Node flowDefinition, FlowBuilder flowBuilder) throws XPathExpressionException { // String startNodeId = null; NodeList startNodeList = (NodeList) xpath.evaluate(".//ns1:start-node/text()", flowDefinition, XPathConstants.NODESET); if (1 < startNodeList.getLength()) { throw new XPathExpressionException("Within at most one is allowed"); } if (null != startNodeList && 1 == startNodeList.getLength()) { startNodeId = startNodeList.item(0).getNodeValue().trim(); } return startNodeId; // } protected String getAttribute(Node node, String attrName) { // Util.notNull("flow definition element", node); String result = null; NamedNodeMap attrs = node.getAttributes(); if (null != attrs) { Attr idAttr = (Attr) attrs.getNamedItem(attrName); if (null != idAttr) { result = idAttr.getValue(); } } return result; // } protected String getIdAttribute(Node node) throws XPathExpressionException { // Util.notNull("flow definition element", node); String result = null; NamedNodeMap attrs = node.getAttributes(); String localName = ""; boolean throwException = false; if (null != attrs) { Attr idAttr = (Attr) attrs.getNamedItem("id"); if (null != idAttr) { result = idAttr.getValue(); if (!idAttr.isId()) { if (LOGGER.isLoggable(Level.FINEST)) { LOGGER.log(Level.FINEST, "Element {0} has an id attribute, but it is not declared as type xsd:id", node.getLocalName()); } } } else { localName = node.getLocalName(); throwException = true; } } else { localName = node.getLocalName(); throwException = true; } if (throwException) { throw new XPathExpressionException("<" + localName + "> must have an \"id\" attribute."); } return result; // } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy