Source Code Cross Referenced for ProcessOrderPlugin.java in  » Science » Cougaar12_4 » org » cougaar » pizza » plugin » 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 » Science » Cougaar12_4 » org.cougaar.pizza.plugin 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * <copyright>
003:         *  
004:         *  Copyright 1997-2004 BBNT Solutions, LLC
005:         *  under sponsorship of the Defense Advanced Research Projects
006:         *  Agency (DARPA).
007:         * 
008:         *  You can redistribute this software and/or modify it under the
009:         *  terms of the Cougaar Open Source License as published on the
010:         *  Cougaar Open Source Website (www.cougaar.org).
011:         * 
012:         *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013:         *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014:         *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015:         *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016:         *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017:         *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018:         *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019:         *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020:         *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021:         *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022:         *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023:         *  
024:         * </copyright>
025:         */
026:        package org.cougaar.pizza.plugin;
027:
028:        import org.cougaar.core.blackboard.IncrementalSubscription;
029:        import org.cougaar.core.plugin.ComponentPlugin;
030:        import org.cougaar.core.service.DomainService;
031:        import org.cougaar.core.service.LoggingService;
032:
033:        import org.cougaar.pizza.Constants;
034:        import org.cougaar.pizza.asset.KitchenAsset;
035:        import org.cougaar.pizza.asset.PizzaAsset;
036:
037:        import org.cougaar.planning.ldm.PlanningFactory;
038:        import org.cougaar.planning.ldm.plan.Allocation;
039:        import org.cougaar.planning.ldm.plan.AllocationResult;
040:        import org.cougaar.planning.ldm.plan.AspectType;
041:        import org.cougaar.planning.ldm.plan.AspectValue;
042:        import org.cougaar.planning.ldm.plan.Task;
043:        import org.cougaar.planning.ldm.plan.PlanElement;
044:        import org.cougaar.planning.plugin.util.PluginHelper;
045:
046:        import org.cougaar.util.UnaryPredicate;
047:
048:        import java.util.Collection;
049:        import java.util.Iterator;
050:
051:        /**
052:         * This plugin processes incoming pizza Order Tasks at the pizza provider 
053:         * agents. It matches the topping requirements (PropertyGroups on the 
054:         * DirectObject of the Task) with the capabilities of its Kitchen
055:         * (again, PropertyGroups on the Asset) to decide if it can
056:         * handle the Order.
057:         */
058:        public class ProcessOrderPlugin extends ComponentPlugin {
059:            private LoggingService logger;
060:            private DomainService domainService;
061:            private IncrementalSubscription tasksSubscription; // orders
062:            private IncrementalSubscription pesSubscription; // our responses
063:            private IncrementalSubscription kitchenAssetSubscription; // the kitchen
064:            private PlanningFactory planningFactory = null;
065:
066:            // local pointer to kitchen
067:            // Note that this is transient local state, that we must
068:            // re-initialize from our subscription any time the plugin re-starts,
069:            // which it may do on agent mobility or node restart for example
070:            private transient KitchenAsset kitchen = null;
071:
072:            /**
073:             * Used by the binding utility through introspection to set my DomainService
074:             * Services that are required for plugin usage should be set through reflection instead of explicitly
075:             * getting each service from your ServiceBroker in the load method. The setter methods are called after
076:             * the component is constructed but before the state methods such as initialize, load, setupSubscriptions, etc.
077:             * If the service is not available at that time the component will be unloaded.
078:             */
079:            public void setDomainService(DomainService aDomainService) {
080:                domainService = aDomainService;
081:            }
082:
083:            /**
084:             * Set up our services and our factory.
085:             */
086:            public void load() {
087:                super .load();
088:                logger = (LoggingService) getServiceBroker().getService(this ,
089:                        LoggingService.class, null);
090:
091:                planningFactory = (PlanningFactory) domainService
092:                        .getFactory("planning");
093:                getServiceBroker().releaseService(this , DomainService.class,
094:                        domainService);
095:            }
096:
097:            /**
098:             * Create the subscriptions to my Order Tasks, PlanElements for those, and Kitchen Asset
099:             */
100:            protected void setupSubscriptions() {
101:                tasksSubscription = (IncrementalSubscription) getBlackboardService()
102:                        .subscribe(ORDER_TASKS_PRED);
103:                // Subscribe to PlanElements handling the Order Tasks - 
104:                // to tell when we've processed a Task
105:                pesSubscription = (IncrementalSubscription) getBlackboardService()
106:                        .subscribe(ORDER_TASKS_PES_PRED);
107:                kitchenAssetSubscription = (IncrementalSubscription) getBlackboardService()
108:                        .subscribe(KITCHEN_ASSET_PRED);
109:            }
110:
111:            /**
112:             * Process the subscriptions: match topping PG on Order Tasks with
113:             * the PGs on the KitchenAsset, and if the Kitchen has the needed PGs,
114:             * respond with SUCCESS.
115:             */
116:            protected void execute() {
117:                // Make sure we have a kitchen asset before we allocate our tasks.
118:                // We only expect 1 kitchen asset so we'll exit if we don't have
119:                // one and set it when we do.
120:                if (kitchenAssetSubscription.isEmpty()) {
121:                    return;
122:                }
123:
124:                // If get here, the Kitchen asset has been created
125:                if (kitchen == null) {
126:                    // Need to get a pointer to Kitchen asset, and then
127:                    // try to Allocate any Tasks
128:                    kitchen = (KitchenAsset) kitchenAssetSubscription.first();
129:
130:                    // allocate all of the tasks on our subscription so far in case we
131:                    // missed some on the added list while our kitchen asset was null
132:                    allocateOrderTasks(tasksSubscription.getCollection());
133:                } else {
134:                    // if we had our kitchen asset already, process any new tasks
135:                    // Right now assume we only get new tasks and no changes
136:                    allocateOrderTasks(tasksSubscription.getAddedCollection());
137:                }
138:            }
139:
140:            /**
141:             * Allocate the new order tasks to the pizza kitchen asset
142:             *
143:             * @param newOrderTasks The tasks that are ordering pizzas from our kitchen.
144:             */
145:            private void allocateOrderTasks(Collection newOrderTasks) {
146:                for (Iterator i = newOrderTasks.iterator(); i.hasNext();) {
147:                    Task newTask = (Task) i.next();
148:
149:                    // Has this Order Task already been processed?
150:                    // This would happen if the agent restarted, for example.
151:                    // 2 approaches:
152:                    // 1: Check task.getPlanElement()
153:                    // -- quick, but mixes Subscription view with direct view, so
154:                    // frowned upon (may cause inconsistent state, errors)
155:                    // 1B: BlackBoard Query -- really just the same as the direct approach
156:                    // 2: Standing subscription to PEs
157:                    // -- Check if there's a PlanElement on our subscription that points to this Task
158:
159:                    // So we check to see if this Task was already planned, and avoid
160:                    // double-planning it
161:                    if (taskWasPlanned(newTask, pesSubscription)) {
162:                        // We apparently already handled this Task. Skip it for now
163:                        if (logger.isDebugEnabled())
164:                            logger.debug("Order already processed: " + newTask);
165:                        continue;
166:                    }
167:
168:                    // See if our kitchen can make the type of pizza requested and then
169:                    // make a successful or unsuccessful allocation result.
170:                    boolean kitchenCanMake = canMakePizza(newTask);
171:                    AllocationResult ar;
172:                    if (kitchenCanMake) {
173:                        // This helper method makes an allocation result containing all aspect values that match the current task's
174:                        // preferences.  Set the confidence value of the allocation result to 1.0 indicating a completed result and set
175:                        // isSuccess to true.
176:                        ar = PluginHelper.createEstimatedAllocationResult(
177:                                newTask, planningFactory, 1.0, true);
178:                    } else {
179:                        // Since we can't make the pizza we create a new aspect value to represent the zero quantity -- no pizzas provided
180:                        AspectValue qtyAspectValue = AspectValue
181:                                .newAspectValue(AspectType.QUANTITY, 0);
182:                        AspectValue[] aspectValueArray = { qtyAspectValue };
183:                        // Use the planning factory to create a new allocation result with a confidence of 1.0 and isSuccess is false.
184:                        ar = planningFactory.newAllocationResult(1.0, false,
185:                                aspectValueArray);
186:                    }
187:                    // Design choice:  The final processing of this task ends as an allocation to the kitchen asset.
188:                    // Another option would be to create a Disposition as the plan element instead of an
189:                    // allocation to an asset.
190:                    Allocation alloc = planningFactory.createAllocation(newTask
191:                            .getPlan(), newTask, kitchen, ar,
192:                            Constants.Roles.PIZZAPROVIDER);
193:                    getBlackboardService().publishAdd(alloc);
194:                }
195:            }
196:
197:            /**
198:             * Re-usable method to search a Collection (ie, Subscription) of
199:             * PlanElements to see if any handle the given Task. Use this
200:             * to decide whether a Task needs to be planned by this Plugin.
201:             * @param t Task for which to search for a PlanElement
202:             * @param planelements Collection of PlanElements to look through, typically a subscription
203:             * @return true if a PlanElement in the collection points to this Task
204:             */
205:            private boolean taskWasPlanned(Task t, Collection planelements) {
206:                if (t == null || planelements == null || planelements.isEmpty())
207:                    return false;
208:
209:                Iterator iter = pesSubscription.iterator();
210:                while (iter.hasNext()) {
211:                    PlanElement pe = (PlanElement) iter.next();
212:                    if (pe.getTask().equals(t)) {
213:                        if (logger.isDebugEnabled())
214:                            logger.debug("Order Task already planned. Task: "
215:                                    + t);
216:                        return true;
217:                    }
218:                } // end of while loop
219:
220:                // No PlanElement on our subscription handles this Task
221:                if (logger.isDebugEnabled())
222:                    logger.debug("Order Task not yet planned: " + t);
223:
224:                return false;
225:            }
226:
227:            /**
228:             * Check the kitchen asset to see if it has the toppings to make the requested type of pizza
229:             *
230:             * @param newTask The order task.
231:             * @return true If we can make the pizza
232:             */
233:            private boolean canMakePizza(Task newTask) {
234:                PizzaAsset directObject = (PizzaAsset) newTask
235:                        .getDirectObject();
236:                // Compare PGs on the pizza to PGs on the kitchen
237:                if (directObject.hasVeggiePG() && !kitchen.hasVeggiePG()) {
238:                    if (logger.isWarnEnabled()) {
239:                        logger
240:                                .warn("Can't make the VeggiePizza that was ordered!");
241:                    }
242:                    return false;
243:                }
244:
245:                if (directObject.hasMeatPG() && !kitchen.hasMeatPG()) {
246:                    if (logger.isWarnEnabled()) {
247:                        logger
248:                                .warn("Can't make the MeatPizza that was ordered!");
249:                    }
250:                    return false;
251:                }
252:                return true;
253:            }
254:
255:            /**
256:             * A predicate that filters for Verb.Order tasks
257:             */
258:            private final static UnaryPredicate ORDER_TASKS_PRED = new UnaryPredicate() {
259:                public boolean execute(Object o) {
260:                    if (o instanceof  Task) {
261:                        return ((Task) o).getVerb().equals(
262:                                Constants.Verbs.ORDER);
263:                    }
264:                    return false;
265:                }
266:            };
267:
268:            /**
269:             * A predicate that filters for PlanElements handling Verb.Order tasks
270:             */
271:            private final static UnaryPredicate ORDER_TASKS_PES_PRED = new UnaryPredicate() {
272:                public boolean execute(Object o) {
273:                    if (o instanceof  PlanElement) {
274:                        Task t = ((PlanElement) o).getTask();
275:                        return t.getVerb().equals(Constants.Verbs.ORDER);
276:                    }
277:                    return false;
278:                }
279:            };
280:
281:            /**
282:             * A predicate that filters for KitchenAsset objects
283:             */
284:            private final static UnaryPredicate KITCHEN_ASSET_PRED = new UnaryPredicate() {
285:                public boolean execute(Object o) {
286:                    return (o instanceof  KitchenAsset);
287:                }
288:            };
289:        } // end of ProcessOrderPlugin
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.