Package org.drools.camel.component

Source Code of org.drools.camel.component.DroolsPolicy$DroolsProcess

/**
* Copyright 2010 JBoss Inc
*
* 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.drools.camel.component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.camel.Exchange;
import org.apache.camel.ExchangePattern;
import org.apache.camel.Message;
import org.apache.camel.Navigate;
import org.apache.camel.Processor;
import org.apache.camel.Route;
import org.apache.camel.component.cxf.CxfConstants;
import org.apache.camel.model.BeanDefinition;
import org.apache.camel.model.DataFormatDefinition;
import org.apache.camel.model.MarshalDefinition;
import org.apache.camel.model.PolicyDefinition;
import org.apache.camel.model.ProcessorDefinition;
import org.apache.camel.model.RouteDefinition;
import org.apache.camel.model.SendDefinition;
import org.apache.camel.model.ToDefinition;
import org.apache.camel.model.UnmarshalDefinition;
import org.apache.camel.model.dataformat.JaxbDataFormat;
import org.apache.camel.model.dataformat.JsonDataFormat;
import org.apache.camel.model.dataformat.XStreamDataFormat;
import org.apache.camel.processor.DelegateProcessor;
import org.apache.camel.processor.SendProcessor;
import org.apache.camel.spi.DataFormat;
import org.apache.camel.spi.Policy;
import org.apache.camel.spi.RouteContext;
import org.drools.command.runtime.BatchExecutionCommandImpl;
import org.drools.command.runtime.GetGlobalCommand;
import org.drools.command.runtime.SetGlobalCommand;
import org.drools.command.runtime.process.AbortWorkItemCommand;
import org.drools.command.runtime.process.CompleteWorkItemCommand;
import org.drools.command.runtime.process.SignalEventCommand;
import org.drools.command.runtime.process.StartProcessCommand;
import org.drools.command.runtime.rule.FireAllRulesCommand;
import org.drools.command.runtime.rule.GetObjectsCommand;
import org.drools.command.runtime.rule.InsertElementsCommand;
import org.drools.command.runtime.rule.InsertObjectCommand;
import org.drools.command.runtime.rule.ModifyCommand;
import org.drools.command.runtime.rule.QueryCommand;
import org.drools.command.runtime.rule.RetractCommand;
import org.drools.command.runtime.rule.ModifyCommand.SetterImpl;
import org.drools.common.DefaultFactHandle;
import org.drools.core.util.StringUtils;
import org.drools.runtime.CommandExecutor;
import org.drools.runtime.impl.ExecutionResultImpl;
import org.drools.runtime.rule.impl.FlatQueryResults;
import org.drools.xml.jaxb.util.JaxbListWrapper;
import org.mvel2.optimizers.impl.refl.nodes.ArrayLength;

public class DroolsPolicy
    implements
    Policy {
    private DroolsEndpoint dep;
   
    public void beforeWrap(RouteContext routeContext,
                           ProcessorDefinition processorDefinition) {
        augmentNodes( routeContext,
                      processorDefinition,
                      new HashSet() );
    }   

    public Processor wrap(RouteContext routeContext,
                          Processor processor) {
        RouteDefinition routeDef = routeContext.getRoute();
       
        ToDefinition toDrools = getDroolsNode( routeDef );

        Processor returnedProcessor;
        if ( toDrools != null ) {
            returnedProcessor = new DroolsProcess( toDrools.getUri(),
                                                   processor );
        } else {
            returnedProcessor =  processor;//new DroolsClientProcessor( processor );
        }
        return returnedProcessor;
    }

    private ToDefinition getDroolsNode(RouteDefinition routeDef) {
        ToDefinition toDrools = null;
        for ( ProcessorDefinition child : routeDef.getOutputs() ) {
            toDrools = getDroolsNode( child );
            if ( toDrools != null ) {
                break;
            }
        }
        return toDrools;
    }   
   
    public static void augmentNodes(RouteContext routeContext, ProcessorDefinition nav, Set visited) {
        if ( !nav.getOutputs().isEmpty() ) {

            List<ProcessorDefinition> outputs = nav.getOutputs();
            for ( int i = 0; i <  outputs.size(); i++  ) {
                ProcessorDefinition child = outputs.get( i );//it.next();
                if ( child instanceof ToDefinition) {
                    ToDefinition to = ( ToDefinition ) child;
                    if (to.getUri().startsWith( "cxfrs" ) && !visited.contains( to ) ) {                       
                        BeanDefinition beanDef = new BeanDefinition();
                        beanDef.setBeanType( PreCxfrs.class );
                        outputs.add( i, beanDef ); // insert before cxfrs
                        beanDef = new BeanDefinition();
                        beanDef.setBeanType( PostCxfrs.class );
                        outputs.add( i+2, beanDef ); // insert after cxfrs
                        i = i + 2;// adjust for the two inserts
                    }
                   
                } else if ( child instanceof MarshalDefinition ) {
                    MarshalDefinition m = (MarshalDefinition) child;

                    DataFormatDefinition dformatDefinition = m.getDataFormatType();   
                   
                    if ( dformatDefinition == null ) {
                        String ref = m.getRef();
                        if ( "json".equals( ref ) ) {
                            dformatDefinition = new XStreamDataFormat();
                            ((XStreamDataFormat)dformatDefinition).setDriver( "json" );                           
                        } else if ( "xstream".equals( ref ) ) {
                            dformatDefinition = new XStreamDataFormat();
                        } else if ( "jaxb".equals( ref ) ) {
                            dformatDefinition = new JaxbDataFormat();
                        } else {
                            dformatDefinition = routeContext.getCamelContext().resolveDataFormatDefinition(ref);
                        }
                    }
                   
                    // always clone before changing
                    dformatDefinition = new FastCloner().deepClone( dformatDefinition );                   
                   
                    if ( dformatDefinition instanceof JaxbDataFormat ) {
                        dformatDefinition = augmentJaxbDataFormatDefinition( (JaxbDataFormat) dformatDefinition );                   
                    } else if ( dformatDefinition instanceof XStreamDataFormat ) {
                        XStreamDataFormat xstreamDataFormat = ( XStreamDataFormat )dformatDefinition;
                        if ( "json".equals( xstreamDataFormat.getDriver() )) {
                            dformatDefinition =  XStreamJson.newJSonMarshaller( xstreamDataFormat );;   
                        } else {
                            dformatDefinition = XStreamXml.newXStreamMarshaller( (XStreamDataFormat) dformatDefinition );   
                        }
                       
                    }
                    m.setDataFormatType( dformatDefinition ); // repoint the marshaller, if it was cloned
                   
                   
                } else if ( child instanceof UnmarshalDefinition ) {
                    UnmarshalDefinition m = (UnmarshalDefinition) child;
                   
                    DataFormatDefinition dformatDefinition = m.getDataFormatType();
                   
                    if ( dformatDefinition == null ) {
                        String ref = m.getRef();
                        if ( "json".equals( ref ) ) {
                            dformatDefinition = new XStreamDataFormat();
                            ((XStreamDataFormat)dformatDefinition).setDriver( "json" );
                        } else if ( "xstream".equals( ref ) ) {
                            dformatDefinition = new XStreamDataFormat();
                        } else if ( "jaxb".equals( ref ) ) {
                            dformatDefinition = new JaxbDataFormat();
                        } else {
                            dformatDefinition = routeContext.getCamelContext().resolveDataFormatDefinition(ref);
                        }
                    }
                   
                    // always clone before changing
                    dformatDefinition = new FastCloner().deepClone( dformatDefinition );                                      
                   
                    // Augment the Jaxb DataFormatDefinition, but clone first so we don't alter the original.
                    if ( dformatDefinition instanceof JaxbDataFormat ) {
                        dformatDefinition = augmentJaxbDataFormatDefinition( (JaxbDataFormat) dformatDefinition );                   
                    } else if ( dformatDefinition instanceof XStreamDataFormat ) {
                        XStreamDataFormat xstreamDataFormat = ( XStreamDataFormat )dformatDefinition;
                        if ( "json".equals( xstreamDataFormat.getDriver() )) {
                            dformatDefinition =  XStreamJson.newJSonMarshaller( xstreamDataFormat );;   
                        } else {
                            dformatDefinition = XStreamXml.newXStreamMarshaller( (XStreamDataFormat) dformatDefinition );   
                        }
                    }
                    
                    m.setDataFormatType( dformatDefinition ); // repoint the marshaller, if it was cloned                   
                }
            }
           
            for ( Iterator<ProcessorDefinition> it = nav.getOutputs().iterator(); it.hasNext(); ) {
                ProcessorDefinition child = it.next();
                augmentNodes( routeContext,
                              child,
                              visited );
            }
        }       
    }

    private ToDefinition getDroolsNode(ProcessorDefinition nav) {
        if ( !nav.getOutputs().isEmpty() ) {
            List<ProcessorDefinition> children = nav.getOutputs();
            for ( ProcessorDefinition child : children ) {
                if ( child instanceof ToDefinition ) {
                    ToDefinition to = (ToDefinition) child;
                    if ( to.getUri().trim().startsWith( "drools:" ) ) {
                        return to;
                    }
                }
                getDroolsNode( child );
            }
        }
        return null;
    }
   
    /**
     * Clones the passed JaxbDataFormat and then augments it with with Drools related namespaces
     *
     * @param jaxbDataFormat
     * @return
     */
    public static JaxbDataFormat augmentJaxbDataFormatDefinition(JaxbDataFormat jaxbDataFormat) {
        Set<String> set = new HashSet<String>();

        for ( String clsName : JAXB_ANNOTATED_CMD ) {
            set.add( clsName.substring( 0,
                                        clsName.lastIndexOf( '.' ) ) );
        }

        StringBuilder sb = new StringBuilder();      
        sb.append( jaxbDataFormat.getContextPath() );
        sb.append( ":" );
        for ( String pkgName : set ) {
            sb.append( pkgName );
            sb.append( ':' );
        }

        jaxbDataFormat.setContextPath( sb.toString() );
        return jaxbDataFormat;
    }
   
    public static class DroolsClientProcessor
    implements
    Processor {
       
        private Processor processor;
       
       

        public DroolsClientProcessor(Processor processor) {
            this.processor = processor;
        }



        public void process(Exchange exchange) throws Exception {
            exchange.setPattern(ExchangePattern.InOut);
            Message inMessage = exchange.getIn();
            inMessage.setHeader(CxfConstants.CAMEL_CXF_RS_USING_HTTP_API, Boolean.TRUE);
            inMessage.setHeader(Exchange.HTTP_METHOD, "POST");
            inMessage.setHeader(Exchange.HTTP_PATH, "/execute");   
            inMessage.setHeader(Exchange.ACCEPT_CONTENT_TYPE, "text/plain");
            inMessage.setHeader(Exchange.CONTENT_TYPE, "text/plain");
           
            this.processor.process( exchange );
        }
       
    }
   
    public static class DroolsProcess
        implements
        Processor {

        private String         droolsUri;
        private DroolsEndpoint dep;
        private Processor      processor;

        public DroolsProcess(String droolsUri,
                             Processor processor) {
            this.droolsUri = droolsUri;
            this.processor = processor;
        }

        public void process(Exchange exchange) throws Exception {
            if ( dep == null ) {
                this.dep = exchange.getContext().getEndpoint( this.droolsUri,
                                                              DroolsEndpoint.class );
            }

            if ( dep == null ) {
                throw new RuntimeException( "Could not find DroolsEndPoint for uri=" + this.droolsUri );
            }

            ClassLoader originalClassLoader = null;
            try {
                originalClassLoader = Thread.currentThread().getContextClassLoader();
               
                CommandExecutor exec = dep.executor;
                if ( exec == null ) {
                    String lookup = exchange.getIn().getHeader( DroolsComponent.DROOLS_LOOKUP, String.class );
                    if ( StringUtils.isEmpty( lookup )  ) {
                        lookup = dep.getLookup( exchange.getIn().getBody( String.class ) );
                    }
                   
                    if ( StringUtils.isEmpty( lookup )  ) {
                        throw new RuntimeException( "No Executor defined and no lookup information available for uri " + this.dep.getEndpointUri()  );
                    }

                    exec = dep.getCommandExecutor( lookup );
                }


                if ( exec == null ) {
                    throw new RuntimeException( "CommandExecutor cannot be found for uri " + this.dep.getEndpointUri() );
                }

                ClassLoader localClassLoader = dep.getClassLoader( exec );
                if ( localClassLoader == null ) {
                    throw new RuntimeException( "CommandExecutor Classloader cannot be null for uri " + this.dep.getEndpointUri() );
                }

                // Set the classloader to the one used by the CommandExecutor
                Thread.currentThread().setContextClassLoader( localClassLoader );
                ExecutionNodePipelineContextImpl context = new ExecutionNodePipelineContextImpl( dep.node,
                                                                                                 localClassLoader );
                context.setCommandExecutor( exec );

                exchange.setProperty( "drools-context",
                                      context );

                processor.process( exchange );
            } finally {
                Thread.currentThread().setContextClassLoader( originalClassLoader );
            }
        }
    }

    public static final String[] JAXB_ANNOTATED_CMD = {BatchExecutionCommandImpl.class.getName(), SetGlobalCommand.class.getName(), GetGlobalCommand.class.getName(), FireAllRulesCommand.class.getName(), InsertElementsCommand.class.getName(),
            InsertObjectCommand.class.getName(), ModifyCommand.class.getName(), SetterImpl.class.getName(), QueryCommand.class.getName(), RetractCommand.class.getName(), AbortWorkItemCommand.class.getName(), SignalEventCommand.class.getName(),
            StartProcessCommand.class.getName(), BatchExecutionCommandImpl.class.getName(), ExecutionResultImpl.class.getName(), DefaultFactHandle.class.getName(), JaxbListWrapper.class.getName(),
            FlatQueryResults.class.getName(), CompleteWorkItemCommand.class.getName(), GetObjectsCommand.class.getName()};

}
TOP

Related Classes of org.drools.camel.component.DroolsPolicy$DroolsProcess

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.