Source Code Cross Referenced for Rete.java in  » Rule-Engine » drolls-Rule-Engine » org » drools » reteoo » 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.reteoo 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package org.drools.reteoo;
002:
003:        /*
004:         * Copyright 2005 JBoss Inc
005:         *
006:         * Licensed under the Apache License, Version 2.0 (the "License");
007:         * you may not use this file except in compliance with the License.
008:         * You may obtain a copy of the License at
009:         *
010:         *      http://www.apache.org/licenses/LICENSE-2.0
011:         *
012:         * Unless required by applicable law or agreed to in writing, software
013:         * distributed under the License is distributed on an "AS IS" BASIS,
014:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015:         * See the License for the specific language governing permissions and
016:         * limitations under the License.
017:         */
018:
019:        import java.io.IOException;
020:        import java.io.ObjectInputStream;
021:        import java.io.Serializable;
022:        import java.util.ArrayList;
023:        import java.util.Collection;
024:        import java.util.List;
025:        import java.util.Map;
026:
027:        import org.drools.FactException;
028:        import org.drools.RuleBaseConfiguration;
029:        import org.drools.RuntimeDroolsException;
030:        import org.drools.base.ClassObjectType;
031:        import org.drools.base.ShadowProxy;
032:        import org.drools.base.ShadowProxyFactory;
033:        import org.drools.common.BaseNode;
034:        import org.drools.common.DroolsObjectInputStream;
035:        import org.drools.common.InternalFactHandle;
036:        import org.drools.common.InternalRuleBase;
037:        import org.drools.common.InternalWorkingMemory;
038:        import org.drools.common.NodeMemory;
039:        import org.drools.facttemplates.Fact;
040:        import org.drools.facttemplates.FactImpl;
041:        import org.drools.facttemplates.FactTemplate;
042:        import org.drools.facttemplates.FactTemplateObjectType;
043:        import org.drools.objenesis.Objenesis;
044:        import org.drools.objenesis.ObjenesisStd;
045:        import org.drools.objenesis.instantiator.ObjectInstantiator;
046:        import org.drools.reteoo.builder.PatternBuilder;
047:        import org.drools.spi.ObjectType;
048:        import org.drools.spi.PropagationContext;
049:        import org.drools.util.FactEntry;
050:        import org.drools.util.FactHashTable;
051:        import org.drools.util.Iterator;
052:        import org.drools.util.ObjectHashMap;
053:        import org.drools.util.ObjectHashMap.ObjectEntry;
054:
055:        /**
056:         * The Rete-OO network.
057:         *
058:         * The Rete class is the root <code>Object</code>. All objects are asserted into
059:         * the Rete node where it propagates to all matching ObjectTypeNodes.
060:         *
061:         * The first time an  instance of a Class type is asserted it does a full
062:         * iteration of all ObjectTyppeNodes looking for matches, any matches are
063:         * then cached in a HashMap which is used for future assertions.
064:         *
065:         * While Rete  extends ObjectSource nad implements ObjectSink it nulls the
066:         * methods attach(), remove() and  updateNewNode() as this is the root node
067:         * they are no applicable
068:         *
069:         * @see ObjectTypeNode
070:         *
071:         * @author <a href="mailto:mark.proctor@jboss.com">Mark Proctor</a>
072:         * @author <a href="mailto:bob@werken.com">Bob McWhirter</a>
073:         */
074:        public class Rete extends ObjectSource implements  Serializable,
075:                ObjectSink, NodeMemory {
076:            // ------------------------------------------------------------
077:            // Instance members
078:            // ------------------------------------------------------------
079:
080:            /**
081:             *
082:             */
083:            private static final long serialVersionUID = 400L;
084:            /** The <code>Map</code> of <code>ObjectTypeNodes</code>. */
085:            private final ObjectHashMap objectTypeNodes;
086:
087:            private transient InternalRuleBase ruleBase;
088:
089:            // ------------------------------------------------------------
090:            // Constructors
091:            // ------------------------------------------------------------
092:
093:            public Rete(InternalRuleBase ruleBase) {
094:                super (0);
095:                this .objectTypeNodes = new ObjectHashMap();
096:                this .ruleBase = ruleBase;
097:            }
098:
099:            private void readObject(ObjectInputStream stream)
100:                    throws IOException, ClassNotFoundException {
101:                stream.defaultReadObject();
102:                this .ruleBase = ((DroolsObjectInputStream) stream)
103:                        .getRuleBase();
104:            }
105:
106:            // ------------------------------------------------------------
107:            // Instance methods
108:            // ------------------------------------------------------------
109:
110:            /**
111:             * This is the entry point into the network for all asserted Facts. Iterates a cache
112:             * of matching <code>ObjectTypdeNode</code>s asserting the Fact. If the cache does not
113:             * exist it first iteraes and builds the cache.
114:             *
115:             * @param handle
116:             *            The FactHandle of the fact to assert
117:             * @param context
118:             *            The <code>PropagationContext</code> of the <code>WorkingMemory</code> action
119:             * @param workingMemory
120:             *            The working memory session.
121:             */
122:            public void assertObject(final InternalFactHandle handle,
123:                    final PropagationContext context,
124:                    final InternalWorkingMemory workingMemory) {
125:                final ObjectHashMap memory = (ObjectHashMap) workingMemory
126:                        .getNodeMemory(this );
127:
128:                Object object = handle.getObject();
129:
130:                ObjectTypeConf ojectTypeConf;
131:                if (object instanceof  FactImpl) {
132:                    String key = ((Fact) object).getFactTemplate().getName();
133:                    ojectTypeConf = (ObjectTypeConf) memory.get(key);
134:                    if (ojectTypeConf == null) {
135:                        ojectTypeConf = new FactTemplateTypeConf(
136:                                ((Fact) object).getFactTemplate(),
137:                                this .ruleBase);
138:                        memory.put(key, ojectTypeConf, false);
139:                    }
140:                    object = key;
141:                } else {
142:                    Class cls = null;
143:                    if (object instanceof  ShadowProxy) {
144:                        cls = ((ShadowProxy) object).getShadowedObject()
145:                                .getClass();
146:                    } else {
147:                        cls = object.getClass();
148:                    }
149:
150:                    ojectTypeConf = (ObjectTypeConf) memory.get(cls);
151:                    if (ojectTypeConf == null) {
152:                        ojectTypeConf = new ClassObjectTypeConf(cls,
153:                                this .ruleBase);
154:                        memory.put(cls, ojectTypeConf, false);
155:                    }
156:
157:                    // checks if shadow is enabled
158:                    if (ojectTypeConf.isShadowEnabled()) {
159:                        // need to improve this
160:                        if (!(handle.getObject() instanceof  ShadowProxy)) {
161:                            // replaces the actual object by its shadow before propagating
162:                            handle.setObject(ojectTypeConf.getShadow(handle
163:                                    .getObject()));
164:                            handle.setShadowFact(true);
165:                        } else {
166:                            ((ShadowProxy) handle.getObject()).updateProxy();
167:                        }
168:                    }
169:                }
170:
171:                ObjectTypeNode[] cachedNodes = ojectTypeConf
172:                        .getObjectTypeNodes();
173:
174:                for (int i = 0, length = cachedNodes.length; i < length; i++) {
175:                    cachedNodes[i].assertObject(handle, context, workingMemory);
176:                }
177:            }
178:
179:            /**
180:             * Retract a fact object from this <code>RuleBase</code> and the specified
181:             * <code>WorkingMemory</code>.
182:             *
183:             * @param handle
184:             *            The handle of the fact to retract.
185:             * @param workingMemory
186:             *            The working memory session.
187:             */
188:            public void retractObject(final InternalFactHandle handle,
189:                    final PropagationContext context,
190:                    final InternalWorkingMemory workingMemory) {
191:                final ObjectHashMap memory = (ObjectHashMap) workingMemory
192:                        .getNodeMemory(this );
193:
194:                final Object object = handle.getObject();
195:
196:                ObjectTypeConf objectTypeConf;
197:                if (object instanceof  ShadowProxy) {
198:                    objectTypeConf = (ObjectTypeConf) memory
199:                            .get(((ShadowProxy) object).getShadowedObject()
200:                                    .getClass());
201:                } else {
202:                    objectTypeConf = (ObjectTypeConf) memory.get(object
203:                            .getClass());
204:                }
205:
206:                ObjectTypeNode[] cachedNodes = objectTypeConf
207:                        .getObjectTypeNodes();
208:
209:                if (cachedNodes == null) {
210:                    // it is  possible that there are no ObjectTypeNodes for an  object being retracted
211:                    return;
212:                }
213:
214:                for (int i = 0; i < cachedNodes.length; i++) {
215:                    cachedNodes[i]
216:                            .retractObject(handle, context, workingMemory);
217:                }
218:            }
219:
220:            /**
221:             * Adds the <code>TupleSink</code> so that it may receive
222:             * <code>Tuples</code> propagated from this <code>TupleSource</code>.
223:             *
224:             * @param tupleSink
225:             *            The <code>TupleSink</code> to receive propagated
226:             *            <code>Tuples</code>.
227:             */
228:            protected void addObjectSink(final ObjectSink objectSink) {
229:                final ObjectTypeNode node = (ObjectTypeNode) objectSink;
230:                this .objectTypeNodes.put(node.getObjectType(), node, true);
231:            }
232:
233:            protected void removeObjectSink(final ObjectSink objectSink) {
234:                final ObjectTypeNode node = (ObjectTypeNode) objectSink;
235:                this .objectTypeNodes.remove(node.getObjectType());
236:            }
237:
238:            public void attach() {
239:                throw new UnsupportedOperationException(
240:                        "cannot call attach() from the root Rete node");
241:            }
242:
243:            public void attach(final InternalWorkingMemory[] workingMemories) {
244:                throw new UnsupportedOperationException(
245:                        "cannot call attach() from the root Rete node");
246:            }
247:
248:            public void remove(final BaseNode node,
249:                    final InternalWorkingMemory[] workingMemories) {
250:                final ObjectTypeNode objectTypeNode = (ObjectTypeNode) node;
251:                removeObjectSink(objectTypeNode);
252:                for (int i = 0; i < workingMemories.length; i++) {
253:                    // clear the node memory for each working memory.
254:                    workingMemories[i].clearNodeMemory((NodeMemory) node);
255:                }
256:            }
257:
258:            public ObjectHashMap getObjectTypeNodes() {
259:                return this .objectTypeNodes;
260:            }
261:
262:            public Object createMemory(final RuleBaseConfiguration config) {
263:                return new ObjectHashMap();
264:            }
265:
266:            public InternalRuleBase getRuleBase() {
267:                return this .ruleBase;
268:            }
269:
270:            public int hashCode() {
271:                return this .objectTypeNodes.hashCode();
272:            }
273:
274:            public boolean equals(final Object object) {
275:                if (object == this ) {
276:                    return true;
277:                }
278:
279:                if (object == null || !(object instanceof  Rete)) {
280:                    return false;
281:                }
282:
283:                final Rete other = (Rete) object;
284:                return this .objectTypeNodes.equals(other.objectTypeNodes);
285:            }
286:
287:            public void updateSink(final ObjectSink sink,
288:                    final PropagationContext context,
289:                    final InternalWorkingMemory workingMemory) {
290:                // JBRULES-612: the cache MUST be invalidated when a new node type is added to the network, so iterate and reset all caches.
291:                final ObjectHashMap memory = (ObjectHashMap) workingMemory
292:                        .getNodeMemory(this );
293:                Iterator it = memory.iterator();
294:                final ObjectTypeNode node = (ObjectTypeNode) sink;
295:
296:                ObjectType newObjectType = node.getObjectType();
297:
298:                for (ObjectEntry entry = (ObjectEntry) it.next(); entry != null; entry = (ObjectEntry) it
299:                        .next()) {
300:                    ObjectTypeConf objectTypeConf = (ObjectTypeConf) entry
301:                            .getValue();
302:                    if (newObjectType.isAssignableFrom(objectTypeConf
303:                            .getConcreteObjectTypeNode().getObjectType())) {
304:                        objectTypeConf.resetCache();
305:                        ObjectTypeNode sourceNode = objectTypeConf
306:                                .getConcreteObjectTypeNode();
307:                        FactHashTable table = (FactHashTable) workingMemory
308:                                .getNodeMemory(sourceNode);
309:                        Iterator factIter = table.iterator();
310:                        for (FactEntry factEntry = (FactEntry) factIter.next(); factEntry != null; factEntry = (FactEntry) factIter
311:                                .next()) {
312:                            sink.assertObject(factEntry.getFactHandle(),
313:                                    context, workingMemory);
314:                        }
315:                    }
316:                }
317:
318:                //        ObjectType
319:                //        this.c
320:
321:                //        final ObjectTypeNode node = (ObjectTypeNode) sink;
322:                //        it = workingMemory.getFactHandleMap().iterator();
323:                //        for ( ObjectEntry entry = (ObjectEntry) it.next(); entry != null; entry = (ObjectEntry) it.next() ) {
324:                //            final InternalFactHandle handle = (InternalFactHandle) entry.getValue();
325:                //            if ( node.matches( handle.getObject() ) ) {
326:                //                node.assertObject( handle,
327:                //                                   context,
328:                //                                   workingMemory );
329:                //            }
330:                //        }
331:            }
332:
333:            public static interface ObjectTypeConf {
334:                public ObjectTypeNode[] getObjectTypeNodes();
335:
336:                public boolean isShadowEnabled();
337:
338:                public Object getShadow(final Object fact)
339:                        throws RuntimeDroolsException;
340:
341:                public ObjectTypeNode getConcreteObjectTypeNode();
342:
343:                public void resetCache();
344:
345:                public boolean isAssignableFrom(Object object);
346:            }
347:
348:            public static class FactTemplateTypeConf implements  ObjectTypeConf,
349:                    Serializable {
350:                private InternalRuleBase ruleBase;
351:                private FactTemplate factTemplate;
352:                private ObjectTypeNode concreteObjectTypeNode;
353:                private ObjectTypeNode[] cache;
354:
355:                public FactTemplateTypeConf(FactTemplate factTemplate,
356:                        InternalRuleBase ruleBase) {
357:                    this .ruleBase = ruleBase;
358:                    this .factTemplate = factTemplate;
359:                    ObjectType objectType = new FactTemplateObjectType(
360:                            factTemplate);
361:                    this .concreteObjectTypeNode = (ObjectTypeNode) ruleBase
362:                            .getRete().getObjectTypeNodes().get(objectType);
363:                    if (this .concreteObjectTypeNode == null) {
364:                        // there must exist an ObjectTypeNode for this concrete class                
365:                        this .concreteObjectTypeNode = PatternBuilder
366:                                .attachObjectTypeNode(ruleBase.getRete(),
367:                                        objectType);
368:                    }
369:                    this .cache = new ObjectTypeNode[] { this .concreteObjectTypeNode };
370:                }
371:
372:                public ObjectTypeNode getConcreteObjectTypeNode() {
373:                    return this .concreteObjectTypeNode;
374:                }
375:
376:                public ObjectTypeNode[] getObjectTypeNodes() {
377:                    if (this .cache == null) {
378:                        this .cache = new ObjectTypeNode[] { this .concreteObjectTypeNode };
379:                    }
380:                    return this .cache;
381:                }
382:
383:                public Object getShadow(Object fact)
384:                        throws RuntimeDroolsException {
385:                    return null;
386:                }
387:
388:                public boolean isShadowEnabled() {
389:                    return false;
390:                }
391:
392:                public boolean isAssignableFrom(Object object) {
393:                    return this .factTemplate.equals(object);
394:                }
395:
396:                public void resetCache() {
397:                    this .cache = null;
398:                }
399:
400:            }
401:
402:            public static class ClassObjectTypeConf implements  ObjectTypeConf,
403:                    Serializable {
404:                // Objenesis instance without cache (false)
405:                private static final Objenesis OBJENESIS = new ObjenesisStd(
406:                        false);
407:
408:                private final Class cls;
409:                private transient InternalRuleBase ruleBase;
410:                private ObjectTypeNode[] objectTypeNodes;
411:
412:                protected boolean shadowEnabled;
413:                protected Class shadowClass;
414:                protected transient ObjectInstantiator instantiator;
415:
416:                private ObjectTypeNode concreteObjectTypeNode;
417:
418:                public ClassObjectTypeConf(Class clazz,
419:                        InternalRuleBase ruleBase) {
420:                    this .cls = clazz;
421:                    this .ruleBase = ruleBase;
422:
423:                    ObjectType objectType = new ClassObjectType(clazz);
424:                    this .concreteObjectTypeNode = (ObjectTypeNode) ruleBase
425:                            .getRete().getObjectTypeNodes().get(objectType);
426:                    if (this .concreteObjectTypeNode == null) {
427:                        // there must exist an ObjectTypeNode for this concrete class
428:                        this .concreteObjectTypeNode = PatternBuilder
429:                                .attachObjectTypeNode(ruleBase.getRete(),
430:                                        objectType);
431:                    }
432:
433:                    defineShadowProxyData(clazz);
434:                }
435:
436:                public boolean isAssignableFrom(Object object) {
437:                    return this .cls.isAssignableFrom((Class) object);
438:                }
439:
440:                public ObjectTypeNode getConcreteObjectTypeNode() {
441:                    return this .concreteObjectTypeNode;
442:                }
443:
444:                private void defineShadowProxyData(Class clazz) {
445:                    Rete rete = this .ruleBase.getRete();
446:
447:                    if (!ruleBase.getConfiguration().isShadowProxy()
448:                            || clazz == null
449:                            || !ruleBase.getConfiguration().isShadowed(
450:                                    clazz.getName())) {
451:                        this .shadowEnabled = false;
452:                        this .shadowClass = null;
453:                        this .instantiator = null;
454:                        return;
455:                    }
456:
457:                    //String pkgName = (pkg != null) ? pkg.getName() : "";
458:                    String pkgName = getPackageName(clazz, clazz.getPackage());
459:                    if ("org.drools.reteoo".equals(pkgName)
460:                            || "org.drools.base".equals(pkgName)) {
461:                        // We don't shadow internal classes
462:                        this .shadowEnabled = false;
463:                        this .shadowClass = null;
464:                        this .instantiator = null;
465:                        return;
466:                    }
467:
468:                    // try to generate proxy for the actual class
469:                    Class shadowClass = loadOrGenerateProxy(clazz, rete);
470:
471:                    if (shadowClass == null) {
472:                        // if it failed, try to find a parent class
473:                        ObjectTypeNode[] nodes = this 
474:                                .getMatchingObjectTypes(clazz);
475:                        Class shadowClassRoot = clazz;
476:                        while (shadowClass == null
477:                                && (shadowClassRoot = this 
478:                                        .findAFeasibleSuperclassOrInterface(
479:                                                nodes, shadowClassRoot)) != null) {
480:                            shadowClass = loadOrGenerateProxy(shadowClassRoot,
481:                                    rete);
482:                        }
483:                    }
484:
485:                    if (shadowClass != null) {
486:                        this .shadowClass = shadowClass;
487:                        this .shadowEnabled = true;
488:                        setInstantiator();
489:                    }
490:                }
491:
492:                /**
493:                 * This will return the package name - if the package is null, it will
494:                 * work it out from the class name (this is in cases where funky classloading is used).
495:                 */
496:                public static String getPackageName(Class clazz, Package pkg) {
497:                    String pkgName = "";
498:                    if (pkg == null) {
499:                        int index = clazz.getName().lastIndexOf('.');
500:                        if (index != -1)
501:                            pkgName = clazz.getName().substring(0, index);
502:                    } else {
503:                        pkgName = pkg.getName();
504:                    }
505:                    return pkgName;
506:
507:                }
508:
509:                private Class loadOrGenerateProxy(Class clazz, Rete rete) {
510:                    Class shadowClass = null;
511:                    final String shadowProxyName = ShadowProxyFactory
512:                            .getProxyClassNameForClass(clazz);
513:                    try {
514:                        // if already loaded
515:                        shadowClass = rete.getRuleBase()
516:                                .getMapBackedClassLoader().loadClass(
517:                                        shadowProxyName);
518:                    } catch (final ClassNotFoundException cnfe) {
519:                        // otherwise, create and load
520:                        final byte[] proxyBytes = ShadowProxyFactory
521:                                .getProxyBytes(clazz);
522:                        if (proxyBytes != null) {
523:                            rete.getRuleBase().getMapBackedClassLoader()
524:                                    .addClass(shadowProxyName, proxyBytes);
525:                            try {
526:                                shadowClass = rete.getRuleBase()
527:                                        .getMapBackedClassLoader().loadClass(
528:                                                shadowProxyName);
529:                            } catch (ClassNotFoundException e) {
530:                                throw new RuntimeException(
531:                                        "Unable to find or generate the ShadowProxy implementation for '"
532:                                                + clazz + "'");
533:                            }
534:                        }
535:
536:                    }
537:                    return shadowClass;
538:                }
539:
540:                private Class findAFeasibleSuperclassOrInterface(
541:                        ObjectTypeNode[] nodes, Class clazz) {
542:
543:                    // check direct superclass
544:                    Class ret = clazz.getSuperclass();
545:                    boolean isOk = ret != null && ret != Object.class; // we don't want to shadow java.lang.Object
546:                    if (isOk) {
547:                        for (int i = 0; isOk && ret != null && i < nodes.length; i++) {
548:                            isOk = nodes[i].isAssignableFrom(ret);
549:                        }
550:                    }
551:
552:                    if (!isOk) {
553:                        // try the interfaces now...
554:                        Class[] interfaces = clazz.getInterfaces();
555:                        boolean notFound = true;
556:                        isOk = interfaces.length > 0;
557:                        for (int i = 0; notFound && i < interfaces.length; i++) {
558:                            ret = interfaces[i];
559:                            isOk = interfaces[i] != Serializable.class
560:                                    && interfaces[i] != Cloneable.class
561:                                    && interfaces[i] != Comparable.class;
562:                            for (int j = 0; isOk && j < nodes.length; j++) {
563:                                isOk = nodes[j].isAssignableFrom(ret);
564:                            }
565:                            notFound = !isOk;
566:                        }
567:                        if (notFound) {
568:                            ret = null;
569:                        }
570:                    }
571:
572:                    // ret now contains a superclass/interface that can be shadowed or null if none
573:                    return ret;
574:                }
575:
576:                private void readObject(ObjectInputStream stream)
577:                        throws IOException, ClassNotFoundException {
578:                    stream.defaultReadObject();
579:                    this .ruleBase = ((DroolsObjectInputStream) stream)
580:                            .getRuleBase();
581:                }
582:
583:                /**
584:                 *
585:                 */
586:                private void setInstantiator() {
587:                    this .instantiator = OBJENESIS
588:                            .getInstantiatorOf(this .shadowClass);
589:                }
590:
591:                public Object getShadow(final Object fact)
592:                        throws RuntimeDroolsException {
593:                    ShadowProxy proxy = null;
594:                    if (isShadowEnabled()) {
595:                        try {
596:                            if (Collection.class
597:                                    .isAssignableFrom(this .shadowClass)
598:                                    || Map.class
599:                                            .isAssignableFrom(this .shadowClass)) {
600:                                // if it is a collection, try to instantiate using constructor
601:                                try {
602:                                    proxy = (ShadowProxy) this .shadowClass
603:                                            .getConstructor(new Class[] { cls })
604:                                            .newInstance(new Object[] { fact });
605:                                } catch (Exception e) {
606:                                    // not possible to instantiate using constructor
607:                                }
608:                            }
609:                            if (proxy == null) {
610:                                if (this .instantiator == null) {
611:                                    this .setInstantiator();
612:                                }
613:                                proxy = (ShadowProxy) this .instantiator
614:                                        .newInstance();
615:                            }
616:                            proxy.setShadowedObject(fact);
617:                        } catch (final Exception e) {
618:                            throw new RuntimeDroolsException(
619:                                    "Error creating shadow fact for object: "
620:                                            + fact, e);
621:                        }
622:                    }
623:                    return proxy;
624:                }
625:
626:                public boolean isShadowEnabled() {
627:                    return this .shadowEnabled;
628:                }
629:
630:                public void resetCache() {
631:                    this .objectTypeNodes = null;
632:                    defineShadowProxyData(cls);
633:                }
634:
635:                public ObjectTypeNode[] getObjectTypeNodes() {
636:                    if (this .objectTypeNodes == null) {
637:                        this .objectTypeNodes = getMatchingObjectTypes(this .cls);
638:                    }
639:                    return this .objectTypeNodes;
640:                }
641:
642:                private ObjectTypeNode[] getMatchingObjectTypes(
643:                        final Class clazz) throws FactException {
644:                    final List cache = new ArrayList();
645:
646:                    final Iterator it = ruleBase.getRete().getObjectTypeNodes()
647:                            .newIterator();
648:                    for (ObjectEntry entry = (ObjectEntry) it.next(); entry != null; entry = (ObjectEntry) it
649:                            .next()) {
650:                        final ObjectTypeNode node = (ObjectTypeNode) entry
651:                                .getValue();
652:                        if (node.isAssignableFrom(clazz)) {
653:                            cache.add(node);
654:                        }
655:                    }
656:
657:                    return (ObjectTypeNode[]) cache
658:                            .toArray(new ObjectTypeNode[cache.size()]);
659:                }
660:            }
661:
662:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.