Source Code Cross Referenced for RuleAgent.java in  » Rule-Engine » drolls-Rule-Engine » org » drools » agent » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Rule Engine » drolls Rule Engine » org.drools.agent 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package org.drools.agent;
002:
003:        import java.io.IOException;
004:        import java.io.InputStream;
005:        import java.util.ArrayList;
006:        import java.util.Arrays;
007:        import java.util.Collections;
008:        import java.util.Date;
009:        import java.util.HashMap;
010:        import java.util.Iterator;
011:        import java.util.List;
012:        import java.util.Map;
013:        import java.util.Properties;
014:        import java.util.StringTokenizer;
015:        import java.util.Timer;
016:        import java.util.TimerTask;
017:
018:        import org.drools.RuleBase;
019:        import org.drools.RuleBaseConfiguration;
020:        import org.drools.RuleBaseFactory;
021:        import org.drools.RuntimeDroolsException;
022:        import org.drools.rule.Package;
023:
024:        /**
025:         * This manages a single rulebase, based on the properties given.
026:         * You should only have ONE instance of this agent per rulebase configuration.
027:         * You can get the rulebase from this agent repeatedly, as needed, or if you keep the rulebase, 
028:         * under most configurations it will be automatically updated. 
029:         * 
030:         * How this behaves depends on the properties that you pass into it (documented below)
031:         *
032:         * CONFIG OPTIONS (to be passed in as properties):
033:         *  <code>newInstance</code>: setting this to "true" means that each time the rules are changed
034:         *   a new instance of the rulebase is created (as opposed to updated in place)
035:         *   the default is to update in place. DEFAULT: false. If you set this to true, 
036:         *   then you will need to call getRuleBase() each time you want to use it. If it is false, 
037:         *   then it means you can keep your reference to the rulebase and it will be updated automatically
038:         *   (as well as any stateful sessions). 
039:         *
040:         *  <code>poll</code>The number of seconds to poll for changes. Polling 
041:         *  happens in a background thread. eg: poll=30 #30 second polling.
042:         *
043:         *  <code>file</code>: a space seperated listing of files that make up the 
044:         *  packages of the rulebase. Each package can only be in one file. You can't have 
045:         *  packages spread across files. eg: file=/your/dir/file1.pkg file=/your/dir/file2.pkg
046:         *  
047:         *  <code>dir</code>: a single file system directory to monitor for packages.
048:         *  As with files, each package must be in its own file.
049:         *  eg: dir=/your/dir
050:         *  
051:         *  <code>url</code>: A space seperated URL to a binary rulebase in the BRMS.
052:         *  eg: url=http://server/drools-jbrms/packages/somePakage/VERSION_1
053:         *  For URL you will also want a local cache directory setup:
054:         *  eg: localCacheDir=/some/dir/that/exists
055:         *  This is needed so that the runtime can startup and load packages even if the BRMS
056:         *  is not available (or the network).
057:         *  
058:         *  <code>name</code>
059:         *  the Name is used in any logging, so each agent can be differentiated (you may have one agent per rulebase
060:         *  that you need in your application).
061:         *  
062:         *  There is also an AgentEventListener interface which you can provide which will call back when lifecycle 
063:         *  events happen, or errors/warnings occur. As the updating happens in a background thread, this may be important.
064:         *  The default event listener logs to the System.err output stream.
065:         *  
066:         * @author Michael Neale
067:         */
068:        public class RuleAgent {
069:
070:            /**
071:             * Following are property keys to be used in the property
072:             * config file.
073:             */
074:            public static final String NEW_INSTANCE = "newInstance";
075:            public static final String FILES = "file";
076:            public static final String DIRECTORY = "dir";
077:            public static final String URLS = "url";
078:            public static final String POLL_INTERVAL = "poll";
079:            public static final String CONFIG_NAME = "name"; //name is optional
080:
081:            //this is needed for cold starting when BRMS is down (ie only for URL).
082:            public static final String LOCAL_URL_CACHE = "localCacheDir";
083:
084:            /**
085:             * Here is where we have a map of providers to the key that appears on the configuration.
086:             */
087:            public static Map PACKAGE_PROVIDERS = new HashMap() {
088:                {
089:                    put(FILES, FileScanner.class);
090:                    put(DIRECTORY, DirectoryScanner.class);
091:                    put(URLS, URLScanner.class);
092:                }
093:            };
094:
095:            /**
096:             * This is true if the rulebase is created anew each time.
097:             */
098:            private boolean newInstance;
099:
100:            /**
101:             * The rule base that is being managed.
102:             */
103:            private RuleBase ruleBase;
104:
105:            /**
106:             * the configuration for the RuleBase
107:             */
108:            private RuleBaseConfiguration ruleBaseConf;
109:
110:            /**
111:             * The timer that is used to monitor for changes and deal with them. 
112:             */
113:            private Timer timer;
114:
115:            /**
116:             * The providers that actually do the work.
117:             */
118:            List providers;
119:
120:            /**
121:             * This keeps the packages around that have been loaded.
122:             */
123:            Map packages = new HashMap();
124:
125:            /**
126:             * For logging events (important for stuff that happens in the background).
127:             */
128:            AgentEventListener listener = getDefaultListener();
129:
130:            /**
131:             * Polling interval value, in seconds, used in the Timer.
132:             */
133:            private int secondsToRefresh;
134:
135:            /**
136:             * Properties configured to load up packages into a rulebase (and monitor them
137:             * for changes).
138:             */
139:            public static RuleAgent newRuleAgent(Properties config) {
140:                return newRuleAgent(config, null, null);
141:            }
142:
143:            /**
144:             * Properties configured to load up packages into a rulebase with the provided
145:             * configuration (and monitor them for changes). 
146:             */
147:            public static RuleAgent newRuleAgent(Properties config,
148:                    RuleBaseConfiguration ruleBaseConf) {
149:                return newRuleAgent(config, null, ruleBaseConf);
150:            }
151:
152:            /**
153:             * This allows an optional listener to be passed in.
154:             * The default one prints some stuff out to System.err only when really needed.
155:             */
156:            public static RuleAgent newRuleAgent(Properties config,
157:                    AgentEventListener listener) {
158:                return newRuleAgent(config, listener, null);
159:            }
160:
161:            /**
162:             * This allows an optional listener to be passed in.
163:             * The default one prints some stuff out to System.err only when really needed.
164:             */
165:            public static RuleAgent newRuleAgent(Properties config,
166:                    AgentEventListener listener,
167:                    RuleBaseConfiguration ruleBaseConf) {
168:                RuleAgent agent = new RuleAgent(ruleBaseConf);
169:                if (listener != null) {
170:                    agent.listener = listener;
171:                }
172:                agent.init(config);
173:                return agent;
174:            }
175:
176:            void init(Properties config) {
177:
178:                boolean newInstance = Boolean.valueOf(
179:                        config.getProperty(NEW_INSTANCE, "false"))
180:                        .booleanValue();
181:                int secondsToRefresh = Integer.parseInt(config.getProperty(
182:                        POLL_INTERVAL, "-1"));
183:                final String name = config.getProperty(CONFIG_NAME, "default");
184:
185:                listener.setAgentName(name);
186:
187:                listener.info("Configuring with newInstance=" + newInstance
188:                        + ", secondsToRefresh=" + secondsToRefresh);
189:
190:                List provs = new ArrayList();
191:
192:                for (Iterator iter = config.keySet().iterator(); iter.hasNext();) {
193:                    String key = (String) iter.next();
194:                    PackageProvider prov = getProvider(key, config);
195:                    if (prov != null) {
196:                        listener.info("Configuring package provider : "
197:                                + prov.toString());
198:                        provs.add(prov);
199:                    }
200:                }
201:
202:                configure(newInstance, provs, secondsToRefresh);
203:            }
204:
205:            /**
206:             * Pass in the name and full path to a config file that is on the classpath. 
207:             */
208:            public static RuleAgent newRuleAgent(String propsFileName) {
209:                return newRuleAgent(loadFromProperties(propsFileName));
210:            }
211:
212:            /**
213:             * Pass in the name and full path to a config file that is on the classpath. 
214:             */
215:            public static RuleAgent newRuleAgent(String propsFileName,
216:                    RuleBaseConfiguration ruleBaseConfiguration) {
217:                return newRuleAgent(loadFromProperties(propsFileName),
218:                        ruleBaseConfiguration);
219:            }
220:
221:            /**
222:             * This takes in an optional listener. Listener must not be null in this case.
223:             */
224:            public static RuleAgent newRuleAgent(String propsFileName,
225:                    AgentEventListener listener) {
226:                return newRuleAgent(loadFromProperties(propsFileName), listener);
227:            }
228:
229:            /**
230:             * This takes in an optional listener and RuleBaseConfiguration. Listener must not be null in this case.
231:             */
232:            public static RuleAgent newRuleAgent(String propsFileName,
233:                    AgentEventListener listener,
234:                    RuleBaseConfiguration ruleBaseConfiguration) {
235:                return newRuleAgent(loadFromProperties(propsFileName),
236:                        listener, ruleBaseConfiguration);
237:            }
238:
239:            static Properties loadFromProperties(String propsFileName) {
240:                InputStream in = RuleAgent.class
241:                        .getResourceAsStream(propsFileName);
242:                Properties props = new Properties();
243:                try {
244:                    props.load(in);
245:                    return props;
246:
247:                } catch (IOException e) {
248:                    throw new RuntimeDroolsException(
249:                            "Unable to load properties. Needs to be the path and name of a config file on your classpath.",
250:                            e);
251:                }
252:            }
253:
254:            /**
255:             * Return a configured provider ready to go.
256:             */
257:            private PackageProvider getProvider(String key, Properties config) {
258:                if (!PACKAGE_PROVIDERS.containsKey(key)) {
259:                    return null;
260:                }
261:                Class clz = (Class) PACKAGE_PROVIDERS.get(key);
262:                try {
263:                    PackageProvider prov = (PackageProvider) clz.newInstance();
264:                    prov.setAgentListener(listener);
265:                    prov.configure(config);
266:                    return prov;
267:                } catch (InstantiationException e) {
268:                    throw new RuntimeDroolsException(
269:                            "Unable to load up a package provider for " + key,
270:                            e);
271:                } catch (IllegalAccessException e) {
272:                    throw new RuntimeDroolsException(
273:                            "Unable to load up a package provider for " + key,
274:                            e);
275:                }
276:            }
277:
278:            synchronized void configure(boolean newInstance, List provs,
279:                    int secondsToRefresh) {
280:                this .newInstance = newInstance;
281:                this .providers = provs;
282:
283:                //run it the first time for each.
284:                refreshRuleBase();
285:
286:                if (secondsToRefresh != -1) {
287:                    startPolling(secondsToRefresh);
288:                }
289:
290:            }
291:
292:            public void refreshRuleBase() {
293:
294:                List changedPackages = new ArrayList();
295:
296:                for (Iterator iter = providers.iterator(); iter.hasNext();) {
297:                    PackageProvider prov = (PackageProvider) iter.next();
298:                    Package[] changes = checkForChanges(prov);
299:                    if (changes != null && changes.length > 0) {
300:                        changedPackages.addAll(Arrays.asList(changes));
301:                    }
302:                }
303:
304:                if (changedPackages.size() > 0) {
305:                    listener.info("Applying changes to the rulebase.");
306:                    //we have a change
307:                    if (this .newInstance) {
308:                        listener
309:                                .info("Creating a new rulebase as per settings.");
310:                        //blow away old
311:                        this .ruleBase = RuleBaseFactory
312:                                .newRuleBase(this .ruleBaseConf);
313:
314:                        //need to store ALL packages
315:                        for (Iterator iter = changedPackages.iterator(); iter
316:                                .hasNext();) {
317:                            Package element = (Package) iter.next();
318:                            this .packages.put(element.getName(), element); //replace
319:                        }
320:                        //get packages from full name
321:                        PackageProvider.applyChanges(this .ruleBase, false,
322:                                this .packages.values(), this .listener);
323:                    } else {
324:                        PackageProvider.applyChanges(this .ruleBase, true,
325:                                changedPackages, this .listener);
326:                    }
327:                }
328:
329:            }
330:
331:            private synchronized Package[] checkForChanges(PackageProvider prov) {
332:                listener.debug("SCANNING FOR CHANGE " + prov.toString());
333:                if (this .ruleBase == null)
334:                    ruleBase = RuleBaseFactory.newRuleBase(this .ruleBaseConf);
335:                Package[] changes = prov.loadPackageChanges();
336:                return changes;
337:            }
338:
339:            /**
340:             * Convert a space seperated list into a List of stuff.
341:             * @param property
342:             * @return
343:             */
344:            static List list(String property) {
345:                if (property == null)
346:                    return Collections.EMPTY_LIST;
347:                StringTokenizer st = new StringTokenizer(property, "\n\r\t ");
348:                List list = new ArrayList();
349:                while (st.hasMoreTokens()) {
350:                    list.add(st.nextToken());
351:                }
352:                return list;
353:            }
354:
355:            /**
356:             * Return a current rulebase.
357:             * Depending on the configuration, this may be a new object each time
358:             * the rules are updated.
359:             *  
360:             */
361:            public synchronized RuleBase getRuleBase() {
362:                return this .ruleBase;
363:            }
364:
365:            RuleAgent(RuleBaseConfiguration ruleBaseConf) {
366:                if (ruleBaseConf == null) {
367:                    this .ruleBaseConf = new RuleBaseConfiguration();
368:                } else {
369:                    this .ruleBaseConf = ruleBaseConf;
370:                }
371:            }
372:
373:            /**
374:             * Stop the polling (if it is happening)
375:             */
376:            public synchronized void stopPolling() {
377:                if (this .timer != null)
378:                    timer.cancel();
379:                timer = null;
380:            }
381:
382:            /**
383:             * Will start polling. If polling is already running it does nothing.
384:             *
385:             */
386:            public synchronized void startPolling() {
387:                if (this .timer == null) {
388:                    startPolling(this .secondsToRefresh);
389:                }
390:            }
391:
392:            /**
393:             * Will start polling. If polling is already happening and of the same interval
394:             * it will do nothing, if the interval is different it will stop the current Timer
395:             * and create a new Timer for the new interval.
396:             * @param secondsToRefresh
397:             */
398:            public synchronized void startPolling(int secondsToRefresh) {
399:                if (this .timer != null) {
400:                    if (this .secondsToRefresh != secondsToRefresh) {
401:                        stopPolling();
402:                    } else {
403:                        // do nothing.
404:                        return;
405:                    }
406:                }
407:
408:                this .secondsToRefresh = secondsToRefresh;
409:                int interval = this .secondsToRefresh * 1000;
410:                //now schedule it for polling
411:                timer = new Timer(true);
412:                timer.schedule(new TimerTask() {
413:                    public void run() {
414:                        try {
415:
416:                            listener.debug("Checking for updates.");
417:                            refreshRuleBase();
418:
419:                        } catch (Exception e) {
420:                            //don't want to stop execution here.                                        
421:                            listener.exception(e);
422:                        }
423:                    }
424:                }, interval, interval);
425:            }
426:
427:            boolean isNewInstance() {
428:                return newInstance;
429:            }
430:
431:            public synchronized boolean isPolling() {
432:                return this .timer != null;
433:            }
434:
435:            /**
436:             * This should only be used once, on setup.
437:             * @return
438:             */
439:            private AgentEventListener getDefaultListener() {
440:
441:                return new AgentEventListener() {
442:
443:                    private String name;
444:
445:                    public String time() {
446:                        Date d = new Date();
447:                        return d.toString();
448:                    }
449:
450:                    public void exception(Exception e) {
451:                        System.err.println("RuleAgent(" + name
452:                                + ") EXCEPTION (" + time() + "): "
453:                                + e.getMessage()
454:                                + ". Stack trace should follow.");
455:                        e.printStackTrace(System.err);
456:                    }
457:
458:                    public void info(String message) {
459:                        System.err.println("RuleAgent(" + name + ") INFO ("
460:                                + time() + "): " + message);
461:                    }
462:
463:                    public void warning(String message) {
464:                        System.err.println("RuleAgent(" + name + ") WARNING ("
465:                                + time() + "): " + message);
466:                    }
467:
468:                    public void debug(String message) {
469:                        //do nothing...                
470:                    }
471:
472:                    public void setAgentName(String name) {
473:                        this.name = name;
474:
475:                    }
476:
477:                };
478:            }
479:
480:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.