Source Code Cross Referenced for SDPlaceOrderPlugin.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 2002-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.blackboard.Subscription;
030:        import org.cougaar.pizza.Constants;
031:        import org.cougaar.planning.ldm.asset.Asset;
032:        import org.cougaar.planning.ldm.asset.Entity;
033:        import org.cougaar.planning.ldm.plan.Allocation;
034:        import org.cougaar.planning.ldm.plan.Disposition;
035:        import org.cougaar.planning.ldm.plan.Expansion;
036:        import org.cougaar.planning.ldm.plan.NewPrepositionalPhrase;
037:        import org.cougaar.planning.ldm.plan.NewTask;
038:        import org.cougaar.planning.ldm.plan.PrepositionalPhrase;
039:        import org.cougaar.planning.ldm.plan.Relationship;
040:        import org.cougaar.planning.ldm.plan.RelationshipSchedule;
041:        import org.cougaar.planning.ldm.plan.SubTaskResult;
042:        import org.cougaar.planning.ldm.plan.Task;
043:        import org.cougaar.util.Filters;
044:        import org.cougaar.util.UnaryPredicate;
045:
046:        import java.util.Collection;
047:        import java.util.Iterator;
048:        import java.util.Vector;
049:
050:        /**
051:         * The SDPlaceOrderPlugin extends the {@link PlaceOrderPlugin} to use Service Discovery
052:         * to find pizza providers dynamically. Once the plugin receives the {@link PizzaPreferences}
053:         * object, it publishes a {@link org.cougaar.pizza.Constants.Verbs#FIND_PROVIDERS} task with a Role of {@link org.cougaar.pizza.Constants.Roles#PIZZAPROVIDER}. This task
054:         * will be handled by Service Discovery.  The plugin then creates and expands the {@link org.cougaar.pizza.Constants.Verbs#ORDER}
055:         * Task as done in the super class.  However, unlike the super class, this plugin waits
056:         * until Service Discovery has finished finding a pizza provider and has added a
057:         * Disposition on the FindProviders task before it can allocate the pizza subtasks.
058:         * <p/>
059:         * ServiceDiscovery will find a provider, creating a PizzaProvider relationship. Then
060:         * the plugin continues as in the PlaceOrderPlugin.
061:         * <p/>
062:         * If the Expansion on the order task fails, i.e., the provider could not complete the
063:         * pizza order, then the plugin will remove the Allocations on the subtasks of the Expansion and
064:         * request a new provider from Service Discovery.  To exclude the provider that
065:         * previously failed, the plugin adds a prepositional phrase of {@link org.cougaar.pizza.Constants.Prepositions#NOT} with the name of the
066:         * provider as the indirect object on the FindProviders task.  Once a new provider is
067:         * found the tasks will be reallocated -- hopefully more succesfully!
068:         */
069:        public class SDPlaceOrderPlugin extends PlaceOrderPlugin {
070:            // Subscription to Dispositions on FindProviders tasks
071:            private IncrementalSubscription fpDispositionSub;
072:            // Subscription to Order tasks, entire collection not just incremental changes
073:            private Subscription taskSub;
074:
075:            /**
076:             * Overrides the super class method. Adds additional subscriptions
077:             * to Dispositions of the FindProviders Task and our original Order Tasks.
078:             */
079:            protected void setupSubscriptions() {
080:                // Initialize subscriptions in the super class.n
081:                super .setupSubscriptions();
082:                // Subscribe to the Disposition of the FindProviders task
083:                fpDispositionSub = (IncrementalSubscription) blackboard
084:                        .subscribe(FP_DISPOSITION_PRED);
085:                // Subscribe to our Order tasks.
086:                taskSub = blackboard.subscribe(TASK_PRED);
087:            }
088:
089:            /**
090:             * When we get the PizzaPreferences object (that subscription is changed), ask ServiceDiscovery to find a provider.
091:             * Meanwhile, create the root order Task and its expansions - but not yet allocated.
092:             * <p/>
093:             * When the FindProviders task is Disposed (a different subscription change),
094:             * we have a provider. Allocate the Order sub-tasks to that provider.
095:             * <p/>
096:             * As in the base class, update the AllocationResults as they come in from our provider.
097:             * <p/>
098:             * Finally, when the Expansion of the root Order Task changes, see if we got all
099:             * our pizza. If not, remove the old Allocations to the old provider, and ask
100:             * ServiceDiscovery to find another (different) provider. When that FindProviders
101:             * is disposed, we'll try again...
102:             */
103:            protected void execute() {
104:                // The PizzaPreferences object contains the party invitation responses,
105:                // and indicates we should start.
106:                // Get any just added PizzaPreferences object.
107:                PizzaPreferences pizzaPrefs = getPizzaPreferences();
108:                if (pizzaPrefs != null) {
109:                    // We get in here only when a PizzaPreferences object has just been added. So
110:                    // in our application, this should happen exactly once.
111:
112:                    // Use service discovery to find a provider, null means do not exclude any providers
113:                    publishFindProvidersTask(null);
114:                    // Create the parent order task.
115:                    Task orderTask = createOrderTask();
116:                    // Create a subtask for each pizza preference.
117:                    Collection pizzaSubtasks = createPizzaSubtasks(pizzaPrefs,
118:                            orderTask);
119:                    // Expand the order task and add the subtasks to the workflow.
120:                    makeExpansion(orderTask, pizzaSubtasks);
121:                }
122:
123:                // Service Discovery adds a Disposition to the FindProviders task when it is done.
124:                Disposition disposition = getDisposedFindProvider();
125:                if (disposition != null) {
126:                    /**
127:                     * Overrides super method.  Uses the Disposition to get to the FindProviders task to
128:                     * check for excluded providers.  An excluded provider is one that was previously
129:                     * unable to complete an order task.
130:                     */
131:                    Entity pizzaProvider = getProvider(disposition);
132:                    if (pizzaProvider != null) {
133:                        // Allocate all pizza subtasks to this single pizza provider.
134:                        allocateSubtasks(getUnallocatedSubtasks(),
135:                                pizzaProvider);
136:                    }
137:                }
138:
139:                // Update changes to the results of the allocation.
140:                updateOrderAllocationResults();
141:
142:                // Check for changes on the Expansion
143:                Expansion exp = getChangedExpansion();
144:                if (exp != null) {
145:                    if (logger.isDebugEnabled()) {
146:                        logger.debug(" Change received on the expansion "
147:                                + printExpansionResults(exp));
148:                    }
149:
150:                    // If the Expansion is confident, then we are done. Print the results.
151:                    if (exp.getReportedResult().getConfidenceRating() == 1.0) {
152:                        logExpansionResults(exp);
153:
154:                        // But this is using servicediscovery, so we could try again.
155:                        if (!exp.getReportedResult().isSuccess()) {
156:                            /**
157:                             * Publish remove the Allocations on all subtasks in the Expansion and return the
158:                             * provider that failed.  The subtasks will get reallocated when a new provider is
159:                             * found.
160:                             */
161:                            Entity failedProvider = processFailedSubtasks(exp);
162:
163:                            // Request a new provider from Service Discovery, excluding the one that failed.
164:                            // We do so by publishing a new FindProviders task. When ServiceDiscovery
165:                            // Disposes that Task, this plugin will run again, and re-allocate
166:                            // the Order Tasks....
167:                            publishFindProvidersTask(failedProvider);
168:                            logger
169:                                    .shout("Initial Expansion FAILed. Redo Service Discovery.");
170:                        }
171:                    }
172:                }
173:            }
174:
175:            /**
176:             * Publishes a FindProviders task, indicating to Service Discovery
177:             * the desired Role for which you want a relationship (PizzaProvider),
178:             * and possibly a known provider to ignore.
179:             * <p/>
180:             * The Task is created with the Verb
181:             * FindProviders and the direct object is set to the agent's self entity.  The type of
182:             * provider is defined by creating an "As" Preposition with the indirect object set to a
183:             * PizzaProvider Role.  If the failedProvider is not null, a "Not" Preposition is also
184:             * created and the indirect object is set to the failed provider asset.  The "Not"
185:             * Preposition represents a provider to be excluded from Service Discovery.  The
186:             * task is then published to the blackboard.
187:             *
188:             * @param failedProvider the provider to exclude in service discovery.  Can be null if
189:             *                       there is no provider to exclude.
190:             */
191:            private void publishFindProvidersTask(Asset failedProvider) {
192:                NewTask newTask = makeTask(Constants.Verbs.FIND_PROVIDERS,
193:                        getSelfEntity());
194:                Vector prepPhrases = new Vector();
195:
196:                // Indicate we want an Agent to act AS a PizzaProvider
197:                NewPrepositionalPhrase pp = planningFactory
198:                        .newPrepositionalPhrase();
199:                pp
200:                        .setPreposition(org.cougaar.planning.Constants.Preposition.AS);
201:                pp.setIndirectObject(Constants.Roles.PIZZAPROVIDER);
202:                prepPhrases.add(pp);
203:
204:                if (failedProvider != null) {
205:                    // Indicate we want to exclude this known provider
206:                    NewPrepositionalPhrase excludePhrase = planningFactory
207:                            .newPrepositionalPhrase();
208:                    excludePhrase.setPreposition(Constants.Prepositions.NOT);
209:                    excludePhrase.setIndirectObject(failedProvider);
210:                    prepPhrases.add(excludePhrase);
211:                }
212:                newTask.setPrepositionalPhrases(prepPhrases.elements());
213:                getBlackboardService().publishAdd(newTask);
214:            }
215:
216:            /**
217:             * Find a PizzaProvider to try using, avoiding the provider on the given
218:             * Disposition if any.
219:             * First, retrieve the excluded provider from the
220:             * FindProviders task of the Disposition.  Get all relationships that match the Role
221:             * of PizzaProvider from the RelationshipSchedule. Return the first provider found that
222:             * is not the excluded provider.  Returns null if a provider is not found.
223:             * <p/>
224:             * Note that only one failed provider can be avoided with this implementation.
225:             *
226:             * @param disposition whose previous Provider to avoid
227:             * @return a pizza provider Entity to try
228:             */
229:            protected Entity getProvider(Disposition disposition) {
230:                // Get the excluded provider from the FindProviders task of the disposition.
231:                Entity excludeProvider = null;
232:                if (disposition != null)
233:                    excludeProvider = getExcludedProvider(disposition.getTask());
234:
235:                // Get the RelationshipSchedule for this agent.
236:                RelationshipSchedule relSched = getSelfEntity()
237:                        .getRelationshipSchedule();
238:
239:                // Find all Relationships matching the Role of PizzaProvider.
240:                Collection relationships = relSched
241:                        .getMatchingRelationships(Constants.Roles.PIZZAPROVIDER);
242:
243:                Entity provider = null;
244:                for (Iterator iterator = relationships.iterator(); iterator
245:                        .hasNext();) {
246:                    Relationship r = (Relationship) iterator.next();
247:                    provider = (Entity) relSched.getOther(r);
248:                    // Return the first provider found that is not the excluded provider
249:                    if (!provider.equals(excludeProvider)) {
250:                        return provider;
251:                    }
252:                }
253:                return null;
254:            }
255:
256:            /**
257:             * Return the succesful Disposition of the FindProviders task, if it is there.
258:             *
259:             * @return the FindProviders Disposition, null if it is not sucessful and confident
260:             */
261:            private Disposition getDisposedFindProvider() {
262:                for (Iterator i = fpDispositionSub.getAddedCollection()
263:                        .iterator(); i.hasNext();) {
264:                    Disposition disposition = (Disposition) i.next();
265:                    if (disposition.isSuccess()
266:                            && disposition.getEstimatedResult()
267:                                    .getConfidenceRating() == 1.0) {
268:                        return disposition;
269:                    }
270:                }
271:                return null;
272:            }
273:
274:            /**
275:             * Returns a collection of tasks that do not have PlanElements.  Filters the
276:             * task subscription by applying the "tasks with no PlanElement" Predicate.
277:             * The point of this being that only tasks without PlanElements are the
278:             * subtasks that need to be allocated.
279:             *
280:             * @return a collection of Tasks that do not have Allocation PlanElements.
281:             */
282:            private Collection getUnallocatedSubtasks() {
283:                return Filters.filter((Collection) taskSub, TASK_NO_PE_PRED);
284:            }
285:
286:            /**
287:             * Processes the subtasks of the failed Expansion and returns the provider that failed.
288:             * If any of the subtasks in the expansion are failed by the provider, the subtask
289:             * Allocations are publishRemoved so that they can be reallocated to a new provider.
290:             * Returns the provider that failed (so we can avoid it in future).
291:             * <p/>
292:             * Note that the assumption is that there is only one failed provider. All the
293:             * Allocations will be removed, but only the last failed provider is returned,
294:             * to be excluded.
295:             *
296:             * @param exp order task expansion that contains our pizza orders.
297:             * @return PizzaProvider that failed to satisfy our order
298:             */
299:            private Entity processFailedSubtasks(Expansion exp) {
300:                Asset failedProvider = null;
301:                for (Iterator resultsIt = exp.getWorkflow().getSubtaskResults()
302:                        .iterator(); resultsIt.hasNext();) {
303:                    SubTaskResult result = (SubTaskResult) resultsIt.next();
304:                    // Grab the provider to be excluded
305:                    failedProvider = ((Allocation) result.getTask()
306:                            .getPlanElement()).getAsset();
307:                    // Rescind all task allocations
308:                    getBlackboardService().publishRemove(
309:                            result.getTask().getPlanElement());
310:                }
311:                return (Entity) failedProvider;
312:            }
313:
314:            /**
315:             * Returns the excluded provider Entity.  Looks for the "Not" Preposition on the
316:             * FindProviders task and gets the indirect object which is the provider entity.
317:             * Presumably this provider is unable to satisfy previous pizza orders. Returns null if
318:             * the FindProviders task does not contain the "Not" Preposition.
319:             *
320:             * @param findProvidersTask the task to look at.
321:             * @return The entity (provider) to exclude.
322:             */
323:            private Entity getExcludedProvider(Task findProvidersTask) {
324:                Entity excludedEntity = null;
325:                PrepositionalPhrase notPP = findProvidersTask
326:                        .getPrepositionalPhrase(Constants.Prepositions.NOT);
327:                if (notPP != null) {
328:                    excludedEntity = (Entity) notPP.getIndirectObject();
329:                }
330:                return excludedEntity;
331:            }
332:
333:            /**
334:             * This predicate matches Dispositions on FindProviders tasks.
335:             */
336:            private static final UnaryPredicate FP_DISPOSITION_PRED = new UnaryPredicate() {
337:                public boolean execute(Object o) {
338:                    if (o instanceof  Disposition) {
339:                        Task task = ((Disposition) o).getTask();
340:                        return task.getVerb().equals(
341:                                Constants.Verbs.FIND_PROVIDERS);
342:                    }
343:                    return false;
344:                }
345:            };
346:
347:            /**
348:             * This predicate matches Order tasks.
349:             */
350:            private static final UnaryPredicate TASK_PRED = new UnaryPredicate() {
351:                public boolean execute(Object o) {
352:                    if (o instanceof  Task) {
353:                        Task task = (Task) o;
354:                        return (task.getVerb().equals(Constants.Verbs.ORDER));
355:                    }
356:                    return false;
357:                }
358:            };
359:
360:            /**
361:             * This predicate matches tasks without PlanElements.  It is used on a local collection
362:             * of order tasks.  It should be noted that this predicate is testing a mutable attribute
363:             * on a task and is therefore not recommended for use with blackboard subscriptions.
364:             */
365:            private static final UnaryPredicate TASK_NO_PE_PRED = new UnaryPredicate() {
366:                public boolean execute(Object o) {
367:                    return (((Task) o).getPlanElement() == null);
368:                }
369:            };
370:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.