Package org.wso2.carbon.mediators.router.impl

Source Code of org.wso2.carbon.mediators.router.impl.Route

/**
*  Copyright (c) 2008, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*        http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
**/

package org.wso2.carbon.mediators.router.impl;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.synapse.MessageContext;
import org.apache.synapse.SynapseException;
import org.apache.synapse.SynapseLog;
import org.apache.synapse.endpoints.Endpoint;
import org.apache.synapse.mediators.base.SequenceMediator;
import org.apache.synapse.mediators.eip.Target;
import org.apache.synapse.util.xpath.SynapseXPath;
import org.jaxen.JaxenException;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* <p>Specifies the <code>Route</code> including the route conditions and the routing of a
* particular route for the <code>RouterMediator</code>. This stores the properties of a particular
* route and will be used by the <code>RouterMedaitor</code> in order to route the messages.</p>
*
* <p>This stores the routing path as a <code>Target</code> whihc can contain either a sequence or
* else and endpoint as the routing path and in the endpoint case the message will be delivered to
* the specified endpoint</p>
*
* @see RouterMediator
* @see org.apache.synapse.mediators.eip.Target
*/
public class Route {

    /**
     * <p>The state of the <code>Route</code> after calling the <code>doRoute</code> method is this
     * particular route over the specified message does not match the conditions specified in this
     * route.</p>
     *
     * @see Route#doRoute(org.apache.synapse.MessageContext, SynapseLog)
     */
    public static final int ROUTE_NOT_MACHING_STATE = 0;

    /**
     * <p>The state of the <code>Route</code> after calling the <code>doRoute</code> method is; this
     * particular route over the specified message matches the conditions specified in this
     * route and hence the message is routed, and the message should not go though any more routes
     * within this router.</p>
     *
     * @see Route#doRoute(org.apache.synapse.MessageContext, SynapseLog)
     */
    public static final int ROUTED_WITH_BREAK_STATE = 1;

    /**
     * <p>The state of the <code>Route</code> after calling the <code>doRoute</code> method is; this
     * particular route over the specified message matches the conditions specified in this
     * route and hence the message is routed, but the message may go through any other matching
     * routes within this router for further routing.</p>
     *
     * @see Route#doRoute(org.apache.synapse.MessageContext, SynapseLog)
     */
    public static final int ROUTED_WITH_CONTINUE_STATE = 2;

    /**
     * <p>The state of the <code>Route</code> after calling the <code>doRoute</code> method is; this
     * particular route over the specified message matches the conditions specified in this
     * route and hence the message is routed, at the same time the message must not go through any
     * other matching routes within this router.</p>
     *
     * @see Route#doRoute(org.apache.synapse.MessageContext, SynapseLog)
     */
    public static final int ROUTED_AND_DROPPED_STATE = 3;

    /**
     * <p>The state of the routing, when there is an error in routing after executing the
     * <code>doRoute</code> method.<p>
     *
     * @see Route#doRoute(org.apache.synapse.MessageContext, SynapseLog)
     */
    public static final int UNEXPECTED_ROUTING_STATE = 4;

    /**
     * <p>XPath describing the element or the attirbute of the message which will be matched
     * againset the <code>match</code> to check the matching. If there is no <code>match</code>
     * then the presence of this expression will be taken as the matching</p>
     *
     * @see org.apache.synapse.util.xpath.SynapseXPath
     */
    private SynapseXPath expression;

    /**
     * <p>Regular expression which will be evaluated to see the string value of the
     * <code>expression</code> evaluated over the current message to check whether that value is
     * matching to the specified pattern to check the matching</p>
     *
     * @see java.util.regex.Pattern
     */
    private Pattern match;

    /**
     * <p>Specifies whether to break the route or to continue on further routes on matching this
     * <code>route</code>. If the value is true, and if the <code>route</code> is matching then no
     * further routes will be evaluated inside the <code>router</code>, where as if the value is
     * false the next route will be evaluated to check the matching regardless of whether the
     * current route matches or not.</p>
     *
     * <p>Default value for the <code>breakRouter</code> is true implying that the router will be
     * breaked after the route. (i.e. no further routes will occur in this router)</p>
     */
    private boolean breakRouter = true;

    /**
     * <p>Represents the <code>target</code> of the route and it can specify a <code>sequence</code>
     * or an <code>endpoint</code> for the matching messages whihc needs to be routed to. At the
     * same time it can also specify the <code>to</code> address as well as <code>soapAction</code>
     * for the routing.</p>
     */
    private Target target;

    /**
     * <p>Holds the log4j based log for the loggin purposes</p>
     */
    private static final Log log = LogFactory.getLog(Route.class);

    /**
     * <p>Checks whether this route is matching for the given message or not. In general if the
     * <code>expression</code> is provided without a <code>match</code> then the presence of a
     * element or attribute in the message specified by the <code>expression</code> will be taken as
     * matching</p>
     *
     * <p>If both the <code>expression</code> and the <code>match</code> is provided then the
     * evaluated string value of the <code>expression</code> over the message will be matched
     * againset the given regular expression <code>match</code> to test whether the string value is
     * matching for the pattern or not</p>
     *
     * @param synCtx message to be matched to check the route condition
     * @return whether the route matches the given message or not
     */
    public boolean isMatching(MessageContext synCtx, SynapseLog synLog) {
        // expression is required to perform the match
        if (expression != null) {

            // if the match Pattern is not there then we consider the
            // existance of the xpath in the message
            if (match == null) {

                try {
                    // check whether the xpath is present in the message or not
                    return expression.booleanValueOf(synCtx.getEnvelope());
                } catch (JaxenException e) {
                    handleException("Error evaluating XPath expression : " + expression, e, synCtx);
                }

            } else {

                String sourceString = expression.stringValueOf(synCtx);

                if (sourceString == null) {
                    if (synLog.isTraceOrDebugEnabled()) {
                        synLog.traceOrDebug("Source String : " + expression + " evaluates to null");
                    }
                    return false;
                }

                Matcher matcher = match.matcher(sourceString);

                if (matcher == null) {
                    if (synLog.isTraceTraceEnabled()) {
                        synLog.traceOrDebug("Regex pattern matcher for : " + match.pattern() +
                                "against source : " + sourceString + " is null");
                    }
                    return false;
                }

                // matchese the string value of the xpath over the message and
                // evalutaes with the specifeid regEx
                return matcher.matches();
            }

        } else {
            handleException("Couldn't find the routing expression", synCtx);
        }

        return false; // never executes
    }

    /**
     * <p>Routes the message in to the specified <code>target</code> whihc can be one of the
     * <code>sequence</code> or else and <code>endpoint</code> after checking whether the conditions
     * specified in this route matches the provided message.</p>
     *
     * <p>Also if this particular router specifies the <code>breakRouter</code> to be false then the
     * specified status will be returned to not to break the route and route further matchings in
     * the router. Otherwise it will break the route</p>
     *
     * @param synCtx message to be routed
     * @return state of the routing and this can be one of the ROUTE_NOT_MACHING_STATE, or
     * ROUTED_WITH_BREAK_STATE, or ROUTED_WITH_CONTINUE state.
     *
     * @see Route#isMatching(org.apache.synapse.MessageContext, SynapseLog)
     */
    public int doRoute(MessageContext synCtx, SynapseLog synLog) {

        // first check whether this Route matches the specified conditions
        if (isMatching(synCtx, synLog)) {

            // route the messages to the specified target
            if (target != null) {

                boolean mediationResult = true;

                if (target.getSoapAction() != null) {
                    synCtx.setSoapAction(target.getSoapAction());
                }

                if (target.getSequence() != null) {
                    mediationResult = target.getSequence().mediate(synCtx);
                    sendToEndpoint(synCtx);

                } else if (target.getSequenceRef() != null) {
                    SequenceMediator refSequence
                        = (SequenceMediator) synCtx.getSequence(target.getSequenceRef());
                    if (refSequence != null) {
                        mediationResult = refSequence.mediate(synCtx);
                    }
                    sendToEndpoint(synCtx);

                } else {
                    sendToEndpoint(synCtx);
                }

                if (!mediationResult) {

                    return ROUTED_AND_DROPPED_STATE;

                } else {

                    // returns the state as break route or continue route depending on the
                    // breakRouter attribute
                    return breakRouter ? ROUTED_WITH_BREAK_STATE : ROUTED_WITH_CONTINUE_STATE;
                }
            } else {

                handleException("Couldn't find the route target for the message", synCtx);
            }

        } else {

            // the route conditions do not match the message
            return ROUTE_NOT_MACHING_STATE;
        }

        // does not execute under normal circumstances
        return UNEXPECTED_ROUTING_STATE;
    }

    private void sendToEndpoint(MessageContext synCtx) {
        if (target.getEndpoint() != null) {
            target.getEndpoint().send(synCtx);
        } else if (target.getEndpointRef() != null) {
            Endpoint epr = synCtx.getConfiguration().getEndpoint(target.getEndpointRef());
            if (epr != null) {
                epr.send(synCtx);
            }
        }
    }

    public Pattern getMatch() {
        return match;
    }

    public void setMatch(Pattern match) {
        this.match = match;
    }

    public SynapseXPath getExpression() {
        return expression;
    }

    public void setExpression(SynapseXPath expression) {
        this.expression = expression;
    }

    public boolean isBreakRouter() {
        return breakRouter;
    }

    public void setBreakRouter(boolean breakRouter) {
        this.breakRouter = breakRouter;
    }

    public Target getTarget() {
        return target;
    }

    public void setTarget(Target target) {
        this.target = target;
    }

    private void handleException(String msg, Exception e, MessageContext msgContext) {
        log.error(msg, e);
        if (msgContext.getServiceLog() != null) {
            msgContext.getServiceLog().error(msg, e);
        }
        throw new SynapseException(msg, e);
    }

    private void handleException(String msg, MessageContext msgContext) {
        log.error(msg);
        if (msgContext.getServiceLog() != null) {
            msgContext.getServiceLog().error(msg);
        }
        throw new SynapseException(msg);
    }
}
TOP

Related Classes of org.wso2.carbon.mediators.router.impl.Route

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.