001: package org.drools.brms.client.packages;
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 org.drools.brms.client.common.AssetFormats;
020: import org.drools.brms.client.common.DirtyableComposite;
021: import org.drools.brms.client.common.DirtyableFlexTable;
022: import org.drools.brms.client.common.FormStyleLayout;
023: import org.drools.brms.client.common.GenericCallback;
024: import org.drools.brms.client.common.ImageButton;
025: import org.drools.brms.client.common.LoadingPopup;
026: import org.drools.brms.client.rpc.PackageConfigData;
027: import org.drools.brms.client.rpc.RepositoryServiceFactory;
028: import org.drools.brms.client.rpc.TableDataResult;
029: import org.drools.brms.client.ruleeditor.NewAssetWizard;
030: import org.drools.brms.client.rulelist.AssetItemListViewer;
031: import org.drools.brms.client.rulelist.EditItemEvent;
032:
033: import com.google.gwt.user.client.Command;
034: import com.google.gwt.user.client.DeferredCommand;
035: import com.google.gwt.user.client.Window;
036: import com.google.gwt.user.client.ui.Button;
037: import com.google.gwt.user.client.ui.ClickListener;
038: import com.google.gwt.user.client.ui.FlexTable;
039: import com.google.gwt.user.client.ui.HTML;
040: import com.google.gwt.user.client.ui.HasHorizontalAlignment;
041: import com.google.gwt.user.client.ui.HasVerticalAlignment;
042: import com.google.gwt.user.client.ui.HorizontalPanel;
043: import com.google.gwt.user.client.ui.Image;
044: import com.google.gwt.user.client.ui.Label;
045: import com.google.gwt.user.client.ui.StackPanel;
046: import com.google.gwt.user.client.ui.Tree;
047: import com.google.gwt.user.client.ui.TreeItem;
048: import com.google.gwt.user.client.ui.TreeListener;
049: import com.google.gwt.user.client.ui.VerticalPanel;
050: import com.google.gwt.user.client.ui.Widget;
051: import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter;
052:
053: /**
054: * Contains the explorer to view (and lazy load) the packages in a repository.
055: * This uses the explorer type motif, with a tree on the left, and a list or
056: * "panel" on the right.
057: *
058: * @author Michael Neale
059: */
060: public class PackageExplorerWidget extends DirtyableComposite {
061:
062: private final Tree exTree;
063: private final DirtyableFlexTable layout;
064: private final TreeListener treeListener;
065: private AssetItemListViewer listView;
066: private EditItemEvent editEvent;
067: private String uuid;
068: private String currentlySelectedPackage;
069:
070: /**
071: * This is for the generic and re-useable package explorer.
072: */
073: public PackageExplorerWidget(EditItemEvent edit) {
074: this (edit, null, null);
075: }
076:
077: /**
078: * This will open an explorer locked to one specific package.
079: *
080: * @param edit
081: * The edit event (action) when the user wants to open an item.
082: * @param uuid
083: * The package to lock this to.
084: */
085: public PackageExplorerWidget(EditItemEvent edit, String uuid,
086: String snapshotName) {
087:
088: this .editEvent = edit;
089: this .uuid = uuid;
090:
091: exTree = new Tree();
092: layout = new DirtyableFlexTable();
093:
094: treeListener = new TreeListener() {
095:
096: public void onTreeItemSelected(TreeItem selected) {
097: PackageTreeItem event = (PackageTreeItem) selected
098: .getUserObject();
099:
100: Command selectEvent = event.command;
101: LoadingPopup.showMessage("Please wait...");
102: DeferredCommand.add(selectEvent);
103: }
104:
105: public void onTreeItemStateChanged(TreeItem arg0) {
106: // ignore
107: }
108:
109: };
110:
111: exTree.addTreeListener(treeListener);
112: VerticalPanel left = new VerticalPanel();
113:
114: if (snapshotName == null) {
115: // only care about new buttons if its not read only
116: FlexTable buttons = new FlexTable();
117: buttons.getCellFormatter().setStyleName(0, 0,
118: "new-asset-Icons");
119: buttons.getCellFormatter().setAlignment(0, 0,
120: HasHorizontalAlignment.ALIGN_CENTER,
121: HasVerticalAlignment.ALIGN_MIDDLE);
122:
123: buttons.setWidget(0, 0, getNewWizardButtons());
124: left.add(buttons);
125: buttons.setWidth("100%");
126: }
127:
128: // ScrollPanel scroll = new ScrollPanel();
129: // scroll.add(exTree);
130: // scroll.setHeight("100%");
131: // left.add(scroll);
132: left.add(exTree);
133:
134: layout.setWidget(0, 0, left);
135: FlexCellFormatter formatter = layout.getFlexCellFormatter();
136: formatter.setVerticalAlignment(0, 0,
137: HasVerticalAlignment.ALIGN_TOP);
138: layout.getFlexCellFormatter().setRowSpan(0, 1, 2);
139: layout.getFlexCellFormatter().setAlignment(0, 1,
140: HasHorizontalAlignment.ALIGN_CENTER,
141: HasVerticalAlignment.ALIGN_TOP);
142:
143: refreshTreeView();
144:
145: TreeItem item = exTree.getItem(0);
146: if (item != null)
147: exTree.setSelectedItem(item);
148:
149: layout
150: .setWidget(
151: 0,
152: 1,
153: new HTML(
154: "<i>Please choose a package to edit, explore, or create a new package.</i>"));
155: layout.getFlexCellFormatter().setWidth(0, 0, "25%");
156: layout.getFlexCellFormatter().setAlignment(0, 1,
157: HasHorizontalAlignment.ALIGN_LEFT,
158: HasVerticalAlignment.ALIGN_TOP);
159: listView = new AssetItemListViewer(this .editEvent,
160: AssetItemListViewer.RULE_LIST_TABLE_ID);
161: initWidget(layout);
162: }
163:
164: /** Return all the new wizard buttons. */
165: private HorizontalPanel getNewWizardButtons() {
166: HorizontalPanel newWizards = new HorizontalPanel();
167:
168: Image newPackage = new Image("images/new_package.gif");
169: newPackage.setTitle("Create a new package");
170: newPackage.addClickListener(new ClickListener() {
171: public void onClick(Widget w) {
172: showNewPackage(w);
173: }
174: });
175:
176: Image uploadModel = new ImageButton("images/model_asset.gif");
177: uploadModel.addClickListener(new ClickListener() {
178: public void onClick(Widget w) {
179: launchWizard(AssetFormats.MODEL,
180: "Create a new model archive");
181: }
182: });
183: uploadModel
184: .setTitle("This creates a new model archive - models contain classes/types that rules use.");
185:
186: Image newRule = new ImageButton("images/new_rule.gif");
187: newRule.setTitle("Create new rule");
188:
189: newRule.addClickListener(new ClickListener() {
190:
191: public void onClick(Widget w) {
192: int left = 70;
193: int top = 100;
194:
195: NewAssetWizard pop = new NewAssetWizard(
196: new EditItemEvent() {
197: public void open(String key) {
198: editEvent.open(key);
199: }
200: }, true, null, "Create a new rule asset",
201: currentlySelectedPackage);
202:
203: pop.setPopupPosition(
204: (DirtyableComposite.getWidth() - pop
205: .getOffsetWidth()) / 2, 100);
206: pop.show();
207: }
208:
209: });
210:
211: final Image newFunction = new ImageButton(
212: "images/function_assets.gif");
213: newFunction.setTitle("Create a new function");
214: newFunction.addClickListener(new ClickListener() {
215: public void onClick(Widget w) {
216: launchWizard(AssetFormats.FUNCTION,
217: "Create a new function");
218: }
219: });
220:
221: final Image newDSL = new ImageButton("images/dsl.gif");
222: newDSL.setTitle("Create a new DSL (language configuration)");
223: newDSL.addClickListener(new ClickListener() {
224: public void onClick(Widget w) {
225: launchWizard(AssetFormats.DSL,
226: "Create a new language configuration");
227: }
228: });
229:
230: final Image newRuleflow = new ImageButton(
231: "images/ruleflow_small.gif");
232: newRuleflow.setTitle("Upload a new ruleflow.");
233: newRuleflow.addClickListener(new ClickListener() {
234: public void onClick(Widget w) {
235: launchWizard(AssetFormats.RULE_FLOW_RF,
236: "Create a new ruleflow");
237: }
238: });
239:
240: final Image newEnum = new ImageButton(
241: "images/new_enumeration.gif");
242: newEnum
243: .setTitle("Create a new data enumeration (drop down list)");
244: newEnum.addClickListener(new ClickListener() {
245:
246: public void onClick(Widget w) {
247: launchWizard(AssetFormats.ENUMERATION,
248: "Create a new enumeration (drop down mapping).");
249: }
250:
251: });
252:
253: newWizards.add(newPackage);
254: newWizards.add(uploadModel);
255: newWizards.add(newRule);
256: newWizards.add(newFunction);
257: newWizards.add(newDSL);
258: newWizards.add(newRuleflow);
259: newWizards.add(newEnum);
260: return newWizards;
261:
262: }
263:
264: public void refreshTreeView() {
265:
266: if (this .uuid == null) {
267: LoadingPopup.showMessage("Loading list of packages ...");
268: RepositoryServiceFactory.getService().listPackages(
269: new GenericCallback() {
270: public void onSuccess(Object data) {
271: PackageConfigData[] packages = (PackageConfigData[]) data;
272: exTree.clear();
273: for (int i = 0; i < packages.length; i++) {
274: if (i == 0) {
275: addPackage(packages[i], true);
276: } else {
277: addPackage(packages[i], false);
278: }
279: }
280: LoadingPopup.close();
281: }
282: });
283: } else {
284: LoadingPopup.showMessage("Loading package ...");
285: RepositoryServiceFactory.getService().loadPackageConfig(
286: uuid, new GenericCallback() {
287: public void onSuccess(Object data) {
288: PackageConfigData pack = (PackageConfigData) data;
289: exTree.clear();
290: addPackage(pack, true);
291:
292: LoadingPopup.close();
293: }
294: });
295: }
296:
297: }
298:
299: /**
300: * Pops up a new package wizard, and creates a new package should sir decide
301: * to create said package. Nice package sir.
302: */
303: private void showNewPackage(Widget w) {
304: NewPackageWizard pop = new NewPackageWizard(new Command() {
305: public void execute() {
306: refreshTreeView();
307: }
308: });
309: pop.setPopupPosition((DirtyableComposite.getWidth() - pop
310: .getOffsetWidth()) / 2, 100);
311: pop.show();
312: }
313:
314: /**
315: * Add a package to the tree.
316: *
317: * @param name
318: */
319: private void addPackage(final PackageConfigData conf,
320: boolean preSelect) {
321:
322: TreeItem pkg = makeItem(conf.name, "images/package.gif",
323: new PackageTreeItem(new Command() {
324:
325: public void execute() {
326:
327: if (isDirty()) {
328: if (Window.confirm("Discard Changes ? ")) {
329: resetDirty();
330: loadPackageConfig(conf.uuid);
331: }
332: } else {
333:
334: loadPackageConfig(conf.uuid);
335: }
336: }
337: }));
338:
339: pkg.addItem(makeItem("Business rule assets",
340: "images/rule_asset.gif", showListEvent(conf.uuid,
341: AssetFormats.BUSINESS_RULE_FORMATS)));
342: pkg
343: .addItem(makeItem("Technical rule assets",
344: "images/technical_rule_assets.gif",
345: showListEvent(conf.uuid,
346: AssetFormats.TECHNICAL_RULE_FORMATS)));
347: pkg.addItem(makeItem("Functions", "images/function_assets.gif",
348: showListEvent(conf.uuid,
349: new String[] { AssetFormats.FUNCTION })));
350: pkg.addItem(makeItem("DSL", "images/dsl.gif", showListEvent(
351: conf.uuid, new String[] { AssetFormats.DSL })));
352: pkg.addItem(makeItem("Model", "images/model_asset.gif",
353: showListEvent(conf.uuid,
354: new String[] { AssetFormats.MODEL })));
355:
356: exTree.addItem(pkg);
357: if (preSelect) {
358: exTree.setSelectedItem(pkg, true);
359: }
360: }
361:
362: /**
363: * This will create a "show list" event to be attached to the tree.
364: */
365: private PackageTreeItem showListEvent(final String uuid,
366: final String[] format) {
367:
368: final GenericCallback cb = new GenericCallback() {
369: public void onSuccess(Object data) {
370: final TableDataResult table = (TableDataResult) data;
371: listView.loadTableData(table);
372: listView.setWidth("100%");
373: layout.setWidget(0, 1, listView);
374: layout.getFlexCellFormatter().setAlignment(0, 1,
375: HasHorizontalAlignment.ALIGN_LEFT,
376: HasVerticalAlignment.ALIGN_TOP);
377: LoadingPopup.close();
378: }
379: };
380:
381: return new PackageTreeItem(new Command() {
382: public void execute() {
383: LoadingPopup
384: .showMessage("Loading list, please wait...");
385: RepositoryServiceFactory.getService().listAssets(uuid,
386: format, -1, -1, cb);
387: }
388: });
389: }
390:
391: /**
392: * Load up the package config data and display it.
393: */
394: private void loadPackageConfig(String uuid) {
395:
396: LoadingPopup.showMessage("Loading package information ...");
397:
398: RepositoryServiceFactory.getService().loadPackageConfig(uuid,
399: new GenericCallback() {
400:
401: public void onSuccess(Object data) {
402: final PackageConfigData conf = (PackageConfigData) data;
403:
404: StackPanel sp = new StackPanel();
405: currentlySelectedPackage = conf.name;
406:
407: FormStyleLayout infoLayout = new FormStyleLayout(
408: "images/package_large.png", conf.name);
409: infoLayout.setStyleName("package-Editor");
410: infoLayout.setWidth("100%");
411: infoLayout.addAttribute("Description:",
412: new Label(conf.description));
413: infoLayout.addAttribute("Date created:",
414: new Label(conf.dateCreated
415: .toLocaleString()));
416:
417: if (conf.isSnapshot) {
418: infoLayout.addAttribute(
419: "Snapshot created on:", new Label(
420: conf.lastModified
421: .toLocaleString()));
422: infoLayout.addAttribute(
423: "Snapshot comment:", new Label(
424: conf.checkinComment));
425: final String uri = PackageBuilderWidget
426: .getDownloadLink(conf);
427: // Button download = new Button("Download package");
428: // download.addClickListener( new ClickListener() {
429: // public void onClick(Widget arg0) {
430: // Window.open( uri, "downloading...",
431: // "resizable=no,scrollbars=yes,status=no" );
432: // }
433: // });
434:
435: HTML html = new HTML(
436: "<a href='"
437: + uri
438: + "' target='_blank'>Download binary package</a>");
439: infoLayout.addAttribute(
440: "Download package:", html);
441: infoLayout.addAttribute("Package URI:",
442: new Label(uri));
443: Button viewSource = new Button(
444: "View package source");
445: viewSource
446: .addClickListener(new ClickListener() {
447: public void onClick(Widget w) {
448: PackageBuilderWidget
449: .doBuildSource(
450: conf.uuid,
451: conf.name);
452: }
453: });
454: infoLayout.addAttribute(
455: "Show package source:", viewSource);
456: }
457:
458: if (!conf.isSnapshot) {
459: infoLayout
460: .addRow(new HTML(
461: "<i>Choose one of the options below</i>"));
462: }
463:
464: Command makeDirtyCommand = new Command() {
465: public void execute() {
466: makeDirty();
467: }
468:
469: };
470:
471: Command cleanDirtyCommand = new Command() {
472: public void execute() {
473: resetDirty();
474: }
475:
476: };
477:
478: sp
479: .add(
480: infoLayout,
481: "<img src='images/information.gif'/>Info",
482: true);
483: if (!conf.isSnapshot) {
484: sp
485: .add(
486: new PackageEditor(conf,
487: makeDirtyCommand,
488: cleanDirtyCommand,
489: refreshCommand),
490: "<img src='images/package.gif'/>Edit Package configuration",
491: true);
492: sp
493: .add(
494: new PackageBuilderWidget(
495: conf, editEvent),
496: "<img src='images/package_build.gif'/>Build, validate and deploy",
497: true);
498: } else {
499: sp
500: .add(
501: new PackageEditor(conf,
502: makeDirtyCommand,
503: cleanDirtyCommand,
504: refreshCommand),
505: "<img src='images/package.gif'/>View Package configuration",
506: true);
507:
508: }
509: sp.setWidth("100%");
510: layout.setWidget(0, 1, sp);
511: LoadingPopup.close();
512: }
513: });
514:
515: }
516:
517: Command refreshCommand = new Command() {
518: public void execute() {
519: refreshTreeView();
520: }
521: };
522:
523: private TreeItem makeItem(String name, String icon, Object command) {
524: TreeItem item = new TreeItem();
525: item.setHTML("<img src=\"" + icon + "\">" + name + "</a>");
526: item.setUserObject(command);
527: return item;
528: }
529:
530: private void launchWizard(String format, String title) {
531: int left = 70;
532: int top = 100;
533:
534: NewAssetWizard pop = new NewAssetWizard(new EditItemEvent() {
535: public void open(String key) {
536: editEvent.open(key);
537: }
538: }, false, format, title, currentlySelectedPackage);
539:
540: pop.setPopupPosition((DirtyableComposite.getWidth() - pop
541: .getOffsetWidth()) / 2, 100);
542: pop.show();
543: }
544:
545: static class PackageTreeItem {
546: Command command;
547:
548: public PackageTreeItem(Command com) {
549: this.command = com;
550:
551: }
552:
553: }
554: }
|