Java tutorial
/* * (C) Copyright Factory4Solutions a.s. 2009 * * 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.fornax.cartridges.sculptor.framework.drools; /** * This advice should be used to wave Drools to service calls * * @author Ing. Pavel Tavoda */ import java.util.ArrayList; import java.util.Calendar; import java.util.HashMap; import java.util.Iterator; import java.util.List; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.drools.agent.KnowledgeAgent; import org.drools.agent.KnowledgeAgentFactory; import org.drools.command.Command; import org.drools.command.CommandFactory; import org.drools.io.ResourceChangeScannerConfiguration; import org.drools.io.ResourceFactory; import org.drools.runtime.StatelessKnowledgeSession; import org.fornax.cartridges.sculptor.framework.errorhandling.ServiceContext; import org.fornax.cartridges.sculptor.framework.errorhandling.ServiceContextStore; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; public class DroolsAdvice implements MethodInterceptor, ApplicationContextAware { private static final Logger log = LoggerFactory.getLogger(DroolsAdvice.class); private ApplicationContext appContext; private KnowledgeAgent kagent; int updateInterval = 300; // 5 min String ruleSet = "/CompanyPolicy.xml"; boolean catchAllExceptions = false; public Object invoke(MethodInvocation procJointpoint) throws Throwable { long startTimeExec = System.currentTimeMillis(); log.info("############# START DROOLS RULES"); RequestDescription req = new RequestDescription(procJointpoint); try { Object[] arguments = procJointpoint.getArguments(); ServiceContext ctx; int startArg; if (arguments[0] instanceof ServiceContext) { ctx = (ServiceContext) arguments[0]; startArg = 1; } else { ctx = ServiceContextStore.get(); startArg = 0; } HashMap<String, Object> objects = new HashMap<String, Object>(); for (int i = startArg; i < arguments.length; i++) { objects.put("arg" + i, arguments[i]); } objects.put("request", req); objects.put("service", procJointpoint.getThis()); objects.put("username", ServiceContextStore.getCurrentUser()); HashMap<String, Object> globals = new HashMap<String, Object>(); if (ctx != null) { globals.put("serviceContext", ctx); } globals.put("appContext", appContext); globals.put("log", log); Calendar curDate = Calendar.getInstance(); globals.put("currentDate", curDate); globals.put("currentTimestamp", curDate.getTimeInMillis()); applyCompanyPolicy(objects, globals); } catch (Throwable th) { if (catchAllExceptions) { while (th.getCause() != null) { th = th.getCause(); } log.warn("Applying company policy finished with error: " + th.getMessage(), th); } else { throw th; } } finally { log.info("############# END DROOLS RULES (" + (System.currentTimeMillis() - startTimeExec) + " ms)"); } if (req.wasProceed() && req.getLastResult() != null && req.getLastResult() instanceof Throwable) { throw (Throwable) req.getLastResult(); } else if (req.wasProceed()) { return req.getLastResult(); } else { return procJointpoint.proceed(); } } private void applyCompanyPolicy(HashMap<String, Object> objects, HashMap<String, Object> globals) { if (kagent == null) { synchronized (DroolsAdvice.class) { if (kagent == null) { KnowledgeAgent unconfigAgent = KnowledgeAgentFactory.newKnowledgeAgent("CompanyPolicyAgent"); unconfigAgent.applyChangeSet(ResourceFactory.newClassPathResource(getDroolsRuleSet())); ResourceChangeScannerConfiguration sconf = ResourceFactory.getResourceChangeScannerService() .newResourceChangeScannerConfiguration(); sconf.setProperty("drools.resource.scanner.interval", Integer.toString(getUpdateInterval())); ResourceFactory.getResourceChangeScannerService().configure(sconf); ResourceFactory.getResourceChangeNotifierService().start(); ResourceFactory.getResourceChangeScannerService().start(); kagent = unconfigAgent; } } } StatelessKnowledgeSession slSession = kagent.newStatelessKnowledgeSession(); List<Command<?>> cmds = new ArrayList<Command<?>>(); if (globals != null && globals.size() > 0) { for (Iterator<String> keys = globals.keySet().iterator(); keys.hasNext();) { String key = keys.next(); cmds.add(CommandFactory.newSetGlobal(key, globals.get(key))); } } if (objects != null && objects.size() > 0) { for (Iterator<String> keys = objects.keySet().iterator(); keys.hasNext();) { String key = keys.next(); cmds.add(CommandFactory.newInsert(objects.get(key), key)); } } // For stateless sesion is automatic // cmds.add(CommandFactory.newFireAllRules()); slSession.execute(CommandFactory.newBatchExecution(cmds)); } public int getUpdateInterval() { return updateInterval; } public void setUpdateInterval(int updateInterval) { this.updateInterval = updateInterval; } public String getDroolsRuleSet() { return ruleSet; } public void setDroolsRuleSet(String ruleSet) { this.ruleSet = ruleSet; } public boolean getCatchAllExceptions() { return catchAllExceptions; } public void setCatchAllExceptions(boolean catchAllExceptions) { this.catchAllExceptions = catchAllExceptions; } /** * Dependency injection, ApplicationContextAware. */ public void setApplicationContext(ApplicationContext appContext) throws BeansException { this.appContext = appContext; } }