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:
027: package org.cougaar.mlm.plugin.generic;
028:
029: import java.awt.Color;
030: import java.awt.GridBagConstraints;
031: import java.awt.GridBagLayout;
032: import java.awt.GridLayout;
033: import java.awt.LayoutManager;
034: import java.awt.event.ActionEvent;
035: import java.awt.event.ActionListener;
036: import java.util.Enumeration;
037:
038: import javax.swing.JButton;
039: import javax.swing.JFrame;
040: import javax.swing.JLabel;
041: import javax.swing.JPanel;
042:
043: import org.cougaar.glm.ldm.asset.Organization;
044: import org.cougaar.planning.ldm.asset.Asset;
045: import org.cougaar.planning.ldm.plan.Allocation;
046: import org.cougaar.planning.ldm.plan.AllocationResult;
047: import org.cougaar.planning.ldm.plan.PlanElement;
048: import org.cougaar.planning.ldm.plan.Preference;
049: import org.cougaar.planning.ldm.plan.Role;
050: import org.cougaar.planning.ldm.plan.Task;
051:
052: /**
053: * Allocate to sink until user presses button (like UniversalAllocator),
054: * then remove the allocation and actually allocate to an organization
055: * (like GenericTablePlugin). Need a GUI to control the button and
056: * special checks for subscription added/all.
057: * <p>
058: * @see GenericTablePlugin for XML input usage
059: * @see org.cougaar.mlm.plugin.sample.UniversalAllocatorPlugin for sink info
060: */
061: public class GenericBufferedTablePlugin extends GenericTablePlugin {
062:
063: // Create a single dummy asset to which to allocate all appropriate tasks
064: private Asset sink_asset = null;
065:
066: protected void setupSubscriptions() {
067: super .setupSubscriptions();
068: sink_asset = theLDMF.createPrototype("AbstractAsset",
069: "GenericSink");
070: publishAdd(sink_asset);
071: createGUI();
072: }
073:
074: protected void initializeSubscriptions() {
075: // want subscriptions running
076: makeSubscriptions();
077: }
078:
079: public synchronized void execute() {
080: // allocate to sink until button pressed
081: int sinkAllocCounter = 0;
082: for (int i = 0; i < tasksSub.length; i++) {
083: if (!(tasksSub[i].hasChanged()))
084: continue;
085: Enumeration eTasks = tasksSub[i].getAddedList();
086: if (!(eTasks.hasMoreElements()))
087: continue;
088: CommandInfo c = allCommands[i];
089: if (c.type_id == CommandInfo.TYPE_ALLOCATE) {
090: // allocate to sink for now
091: do {
092: Task theTask = (Task) eTasks.nextElement();
093: if (getTaskPlanElement(theTask, allocationsSub[i]) == null) {
094: AllocationResult allocation_result = computeAllocationResult(theTask);
095: Allocation allocation = theLDMF
096: .createAllocation(theLDMF
097: .getRealityPlan(), theTask,
098: sink_asset, allocation_result,
099: Role.BOGUS);
100: publishAdd(allocation);
101: sinkAllocCounter++;
102: }
103: } while (eTasks.hasMoreElements());
104: } else if (c.type_id == CommandInfo.TYPE_EXPAND) {
105: // expand as usual
106: TaskInfo[] toTasks = ((ExpandCommandInfo) c).expandTasks;
107: do {
108: Task theTask = (Task) eTasks.nextElement();
109: // Need a sub to expansions to do this....
110: // if (getTaskPlanElement(theTask, allocationsSub[i]) == null) {
111: if (theTask.getPlanElement() == null) {
112: for (int j = 0; j < toTasks.length; j++) {
113: doExpansion(toTasks[j], theTask);
114: }
115: }
116: } while (eTasks.hasMoreElements());
117: } else {
118: // no other commands!
119: }
120: }
121:
122: for (int i = 0; i < allocationsSub.length; i++) {
123: if (allocationsSub[i].hasChanged()) {
124: updateAllocationResult(allocationsSub[i]);
125: }
126: }
127:
128: // update GUI
129: incrementSinkAllocCounter(sinkAllocCounter);
130: }
131:
132: public synchronized void buttonExecute() {
133: // unallocate tasks allocated to sink and reallocate
134: int orgAllocCounter = 0;
135: for (int i = 0; i < tasksSub.length; i++) {
136: Enumeration eTasks = tasksSub[i].elements();
137: if (!(eTasks.hasMoreElements()))
138: continue;
139: CommandInfo c = allCommands[i];
140: if (c.type_id == CommandInfo.TYPE_ALLOCATE) {
141: // allocate
142: Organization capableOrg = null;
143: do {
144: Task theTask = (Task) eTasks.nextElement();
145: PlanElement pe = getTaskPlanElement(theTask,
146: allocationsSub[i]);
147: if ((pe instanceof Allocation)
148: && (((Allocation) pe).getAsset() == sink_asset)) {
149: // find capable org
150: if (capableOrg == null) {
151: capableOrg = findCapableOrganization((AllocateCommandInfo) c);
152: if (capableOrg == null) {
153: // no capable org found!
154: break;
155: }
156: }
157: // unallocate from sink
158: publishRemove(pe);
159: // allocate to org
160: doAllocation(capableOrg, theTask);
161: orgAllocCounter++;
162: }
163: } while (eTasks.hasMoreElements());
164: } else if (c.type_id == CommandInfo.TYPE_EXPAND) {
165: // expand as usual
166: TaskInfo[] toTasks = ((ExpandCommandInfo) c).expandTasks;
167: do {
168: Task theTask = (Task) eTasks.nextElement();
169: if (theTask.getPlanElement() == null) {
170: // if (getTaskPlanElement(theTask, allocationsSub[i]) == null) {
171: for (int j = 0; j < toTasks.length; j++) {
172: doExpansion(toTasks[j], theTask);
173: }
174: }
175: } while (eTasks.hasMoreElements());
176: } else {
177: // no other commands!
178: }
179: }
180:
181: for (int i = 0; i < allocationsSub.length; i++) {
182: updateAllocationResult(allocationsSub[i]);
183: }
184:
185: // update GUI
186: decrementSinkAllocCounter(orgAllocCounter);
187: }
188:
189: protected void executeCommands() {
190: // Have to do this transaction boundary
191: openTransaction();
192: buttonExecute();
193: closeTransactionDontReset();
194: }
195:
196: // Return an allocation result that gives back a successful/optimistic answer
197: // consisting of the best value for every aspect
198: private AllocationResult computeAllocationResult(Task task) {
199: int num_prefs = 0;
200: Enumeration prefs = task.getPreferences();
201: while (prefs.hasMoreElements()) {
202: prefs.nextElement();
203: num_prefs++;
204: }
205: int[] types = new int[num_prefs];
206: double[] results = new double[num_prefs];
207: prefs = task.getPreferences();
208:
209: int index = 0;
210: while (prefs.hasMoreElements()) {
211: Preference pref = (Preference) prefs.nextElement();
212: types[index] = pref.getAspectType();
213: results[index] = pref.getScoringFunction().getBest()
214: .getValue();
215: index++;
216: }
217:
218: AllocationResult result = theLDMF.newAllocationResult(1.0, // Rating,
219: true, // Success,
220: types, results);
221: return result;
222: }
223:
224: JButton executeButton;
225: JLabel sinkAllocCounterLabel;
226: int sinkAllocCounter = 0;
227:
228: /** called by synchronized method! **/
229: protected void incrementSinkAllocCounter(int nMoreAllocs) {
230: if (nMoreAllocs > 0) {
231: sinkAllocCounter += nMoreAllocs;
232: sinkAllocCounterLabel.setText(Integer
233: .toString(sinkAllocCounter));
234: }
235: }
236:
237: /** called by synchronized method! **/
238: protected void decrementSinkAllocCounter(int nFewerAllocs) {
239: if (nFewerAllocs > 0) {
240: sinkAllocCounter -= nFewerAllocs;
241: sinkAllocCounterLabel.setText(Integer
242: .toString(sinkAllocCounter));
243: }
244: }
245:
246: /**
247: * An ActionListener that listens to the button.
248: */
249: class MyListener implements ActionListener {
250: public void actionPerformed(ActionEvent e) {
251: JButton button = (JButton) e.getSource();
252: if (button == executeButton) {
253: try {
254: executeCommands();
255: } catch (Exception exc) {
256: System.err.println("Could not execute button: "
257: + e.getActionCommand());
258: }
259: }
260: }
261: }
262:
263: protected String getClusterID() {
264: String s;
265: try {
266: s = getAgentIdentifier().toString();
267: } catch (Exception e) {
268: s = "UNKNOWN";
269: }
270: int beginIdx = 0;
271: if (s.startsWith("<")) {
272: beginIdx++;
273: }
274: int endIdx = s.length();
275: if (s.endsWith(">")) {
276: endIdx--;
277: }
278: // substring notices when indexes are (0, len)
279: return s.substring(beginIdx, endIdx);
280: }
281:
282: protected void createGUI() {
283: executeButton = new JButton("Execute");
284: executeButton.addActionListener(new MyListener());
285: sinkAllocCounterLabel = new JLabel("< >", JLabel.RIGHT);
286: sinkAllocCounterLabel.setText("0");
287:
288: String clusterID = getClusterID();
289:
290: JFrame frame = new JFrame("GenericBufferedTablePlugin "
291: + clusterID);
292: frame.setLocation(0, 0);
293: JPanel rootPanel = new JPanel((LayoutManager) null);
294: GridBagLayout gbl = new GridBagLayout();
295: GridBagConstraints gbc = new GridBagConstraints();
296: //gbc.insets = new Insets(10, 10, 10, 10);
297: gbc.fill = GridBagConstraints.BOTH;
298: rootPanel.setLayout(gbl);
299:
300: JLabel titleLabel = new JLabel("Buffer Allocator for "
301: + clusterID);
302: titleLabel.setForeground(Color.blue);
303: gbc.gridy = 1;
304: gbl.setConstraints(titleLabel, gbc);
305: rootPanel.add(titleLabel);
306:
307: JPanel sinkPanel = new JPanel();
308: sinkPanel.setLayout(new GridLayout(1, 2));
309: JLabel sinkLabel = new JLabel(
310: "Number of tasks allocated to sink: ");
311: sinkLabel.setForeground(Color.blue);
312: sinkPanel.add(sinkLabel);
313: sinkPanel.add(sinkAllocCounterLabel);
314: gbc.gridy = 2;
315: gbl.setConstraints(sinkPanel, gbc);
316: rootPanel.add(sinkPanel);
317:
318: JLabel instructionsLabel = new JLabel(
319: "Press button to send buffered " + clusterID + " tasks");
320: instructionsLabel.setForeground(Color.blue);
321: gbc.gridy = 3;
322: gbl.setConstraints(instructionsLabel, gbc);
323: rootPanel.add(instructionsLabel);
324:
325: JPanel buttonPanel = new JPanel();
326: buttonPanel.add(executeButton);
327: gbc.gridy = 4;
328: gbl.setConstraints(buttonPanel, gbc);
329: rootPanel.add(buttonPanel);
330:
331: frame.setContentPane(rootPanel);
332: frame.pack();
333: frame.setVisible(true);
334: }
335: }
|