001: /*
002: * Copyright 2006 Pentaho Corporation. All rights reserved.
003: * This software was developed by Pentaho Corporation and is provided under the terms
004: * of the Mozilla Public License, Version 1.1, or any later version. You may not use
005: * this file except in compliance with the license. If you need a copy of the license,
006: * please go to http://www.mozilla.org/MPL/MPL-1.1.txt. The Original Code is the Pentaho
007: * BI Platform. The Initial Developer is Pentaho Corporation.
008: *
009: * Software distributed under the Mozilla Public License is distributed on an "AS IS"
010: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. Please refer to
011: * the license for the specific language governing your rights and limitations.
012: */
013: package org.pentaho.designstudio.editors.actionsequence.pages.parameters;
014:
015: import java.net.URI;
016: import java.net.URISyntaxException;
017: import java.util.ArrayList;
018: import java.util.Arrays;
019: import java.util.Iterator;
020:
021: import org.dom4j.Element;
022: import org.eclipse.jface.util.ListenerList;
023: import org.eclipse.jface.util.SafeRunnable;
024: import org.eclipse.jface.viewers.IStructuredSelection;
025: import org.eclipse.jface.viewers.ITreeContentProvider;
026: import org.eclipse.jface.viewers.TreeViewer;
027: import org.eclipse.jface.viewers.Viewer;
028: import org.eclipse.jface.window.Window;
029: import org.eclipse.swt.dnd.DND;
030: import org.eclipse.swt.dnd.DragSourceAdapter;
031: import org.eclipse.swt.dnd.DragSourceEvent;
032: import org.eclipse.swt.dnd.DragSourceListener;
033: import org.eclipse.swt.dnd.Transfer;
034: import org.eclipse.swt.widgets.Tree;
035: import org.eclipse.swt.widgets.Widget;
036: import org.pentaho.actionsequence.dom.AbstractIOElement;
037: import org.pentaho.actionsequence.dom.ActionControlStatement;
038: import org.pentaho.actionsequence.dom.ActionSequenceDocument;
039: import org.pentaho.actionsequence.dom.ActionSequenceInput;
040: import org.pentaho.actionsequence.dom.ActionSequenceResource;
041: import org.pentaho.actionsequence.dom.IActionSequenceDocumentListener;
042: import org.pentaho.actionsequence.dom.actions.ActionDefinition;
043: import org.pentaho.designstudio.controls.ActionSequenceParamTransfer;
044: import org.pentaho.designstudio.editors.actionsequence.pages.ActionSequenceLabelProvider;
045: import org.pentaho.designstudio.editors.actionsequence.pages.actions.IParamRenamedListener;
046: import org.pentaho.designstudio.messages.Messages;
047:
048: /**
049: * Tree viewer used for viewing and modifying the inputs, outputs, and resources in a
050: * component definition
051: *
052: * @author Angelo Rodriguez
053: */
054: public class ActionSequenceInputsTree extends TreeViewer implements
055: IActionSequenceDocumentListener {
056:
057: public class ContentProvider implements ITreeContentProvider {
058:
059: public ContentProvider() {
060: }
061:
062: /* (non-Javadoc)
063: * Method declared on ITreeContentProvider.
064: */
065: public Object[] getChildren(Object parent) {
066: ArrayList children = new ArrayList();
067: if (hasChildren(parent)) {
068: Element element = (Element) parent;
069: if (element.getPath().equals(
070: ActionSequenceDocument.DOC_INPUTS_PATH)) {
071: children.addAll(Arrays.asList(actionSequence
072: .getInputs()));
073: } else if (element.getPath().equals(
074: ActionSequenceDocument.DOC_RESOURCES_PATH)) {
075: children.addAll(Arrays.asList(actionSequence
076: .getResources()));
077: }
078: }
079: return children.toArray();
080: }
081:
082: /* (non-Javadoc)
083: * Method declared on ITreeContentProvider.
084: */
085: public Object getParent(Object child) {
086: Object parent = null;
087: if (child instanceof ActionSequenceInput) {
088: parent = getInputRoot();
089: } else if (child instanceof ActionSequenceResource) {
090: parent = getResourceRoot();
091: }
092: return parent;
093: }
094:
095: /* (non-Javadoc)
096: * Method declared on ITreeContentProvider.
097: */
098: public boolean hasChildren(Object node) {
099: boolean result = false;
100: if (node instanceof Element) {
101: Element element = (Element) node;
102: if (element.getPath().equals(
103: ActionSequenceDocument.DOC_INPUTS_PATH)) {
104: result = actionSequence.getInputs().length > 0;
105: } else if (element.getPath().equals(
106: ActionSequenceDocument.DOC_RESOURCES_PATH)) {
107: result = actionSequence.getResources().length > 0;
108: }
109: }
110: return result;
111: }
112:
113: /* (non-Javadoc)
114: * Method declared on ITreeContentProvider.
115: */
116: public Object[] getElements(Object inputElement) {
117: ArrayList elements = new ArrayList();
118: Element inputRoot = getInputRoot();
119: if (inputRoot != null) {
120: elements.add(inputRoot);
121: }
122: Element resourceRoot = getResourceRoot();
123: if (resourceRoot != null) {
124: elements.add(resourceRoot);
125: }
126: return elements.toArray();
127: }
128:
129: /* (non-Javadoc)
130: * Method declared on ITreeContentProvider.
131: */
132: public void dispose() {
133: actionSequence = null;
134: }
135:
136: /* (non-Javadoc)
137: * Method declared on ITreeContentProvider.
138: */
139: public void inputChanged(Viewer viewer, Object oldInput,
140: Object newInput) {
141: if (actionSequence != null) {
142: actionSequence
143: .removeListener(ActionSequenceInputsTree.this );
144: }
145: if (newInput instanceof ActionSequenceDocument) {
146: actionSequence = (ActionSequenceDocument) newInput;
147: actionSequence
148: .addListener(ActionSequenceInputsTree.this );
149: } else {
150: actionSequence = null;
151: }
152: }
153:
154: }
155:
156: class DragListener extends DragSourceAdapter {
157:
158: /* (non-Javadoc)
159: * @see org.eclipse.swt.dnd.DragSourceListener#dragFinished(org.eclipse.swt.dnd.DragSourceEvent)
160: */
161: public void dragFinished(DragSourceEvent event) {
162: draggedItem = null;
163: fireDragFinished(event);
164: }
165:
166: /* (non-Javadoc)
167: * @see org.eclipse.swt.dnd.DragSourceListener#dragSetData(org.eclipse.swt.dnd.DragSourceEvent)
168: */
169: public void dragSetData(DragSourceEvent event) {
170: if (ActionSequenceParamTransfer.getInstance()
171: .isSupportedType(event.dataType)) {
172: if ((draggedItem instanceof ActionSequenceInput)
173: || (draggedItem instanceof ActionSequenceResource)) {
174: event.data = draggedItem;
175: }
176: }
177: }
178:
179: /* (non-Javadoc)
180: * @see org.eclipse.swt.dnd.DragSourceListener#dragStart(org.eclipse.swt.dnd.DragSourceEvent)
181: */
182: public void dragStart(DragSourceEvent event) {
183: IStructuredSelection selection = (IStructuredSelection) getSelection();
184: if (selection.size() == 1) {
185: Object selectedItem = selection.getFirstElement();
186: if ((selectedItem instanceof ActionSequenceInput)
187: || (selectedItem instanceof ActionSequenceResource)) {
188: draggedItem = selection.getFirstElement();
189: event.doit = true;
190: fireDragStart(event);
191: } else {
192: draggedItem = null;
193: event.doit = false;
194: }
195: } else {
196: draggedItem = null;
197: event.doit = false;
198: }
199: }
200: }
201:
202: protected ActionSequenceDocument actionSequence;
203: Object draggedItem;
204: private DragListener dragListener;
205: private ListenerList dragSourceListeners = new ListenerList(1);
206: private ListenerList paramRenamedListeners = new ListenerList(3);
207:
208: /**
209: * Create an action sequence inputs, outputs, and resources viewer.
210: * @param parent the tree being managed by this viewer
211: */
212: public ActionSequenceInputsTree(Tree tree) {
213: super (tree);
214: init();
215: }
216:
217: private void init() {
218: setContentProvider(new ContentProvider());
219: setLabelProvider(new ActionSequenceLabelProvider(getTree()
220: .getDisplay()));
221:
222: int ops = DND.DROP_MOVE | DND.DROP_COPY;
223: Transfer[] transfers = new Transfer[] { ActionSequenceParamTransfer
224: .getInstance() };
225: dragListener = new DragListener();
226: addDragSupport(ops, transfers, dragListener);
227: }
228:
229: public void deleteSelectedInputs() {
230: IStructuredSelection selection = (IStructuredSelection) getSelection();
231: for (Iterator iter = selection.iterator(); iter.hasNext();) {
232: Object input = iter.next();
233: if (input instanceof ActionSequenceInput) {
234: actionSequence
235: .deleteInput(((ActionSequenceInput) input)
236: .getName());
237: } else if (input instanceof ActionSequenceResource) {
238: actionSequence
239: .deleteResource(((ActionSequenceResource) input)
240: .getName());
241: }
242: }
243: }
244:
245: public void renameSelectedInput() {
246: IStructuredSelection selection = (IStructuredSelection) getSelection();
247: if (selection.size() == 1) {
248: Object input = selection.getFirstElement();
249: if (input instanceof ActionSequenceInput) {
250: RenameParameterDialog renameActionSequenceInputDialog = new RenameParameterDialog(
251: getTree().getShell());
252: renameActionSequenceInputDialog
253: .setParamToRename((ActionSequenceInput) input);
254: if (renameActionSequenceInputDialog.open() == Window.OK) {
255: fireParamRenamed((ActionSequenceInput) input);
256: }
257: } else if (input instanceof ActionSequenceResource) {
258: RenameParameterDialog renameActionSequenceInputDialog = new RenameParameterDialog(
259: getTree().getShell());
260: renameActionSequenceInputDialog
261: .setParamToRename((ActionSequenceResource) input);
262: if (renameActionSequenceInputDialog.open() == Window.OK) {
263: fireParamRenamed((ActionSequenceResource) input);
264: }
265: }
266: }
267: }
268:
269: public ActionSequenceInput createNewInput(String inputType) {
270: String baseName = Messages
271: .getString("ParametersTreeViewer.UI_NEW_INPUT_NAME"); //$NON-NLS-1$
272: String variableName = baseName;
273: int variableIdx = 1;
274: while (actionSequence.getInput(variableName) != null) {
275: variableName = baseName + Integer.toString(variableIdx++);
276: }
277:
278: ActionSequenceInput newInput = actionSequence.createInput(
279: variableName, inputType);
280:
281: return newInput;
282: }
283:
284: /**
285: * Creates a new output element in the action sequence and adds it to this viewer.
286: * @return the created output element
287: */
288: public ActionSequenceResource createNewResource() {
289: String baseName = Messages
290: .getString("ParametersTreeViewer.UI_NEW_RESOURCE_NAME"); //$NON-NLS-1$
291: String variableName = baseName;
292: int variableIdx = 1;
293: while (actionSequence.getInput(baseName) != null) {
294: variableName = baseName + Integer.toString(variableIdx++);
295: }
296:
297: ActionSequenceResource newResource = null;
298: try {
299: newResource = actionSequence.setResourceUri(variableName,
300: new URI(ActionSequenceResource.SOLUTION_SCHEME,
301: " ", null), ""); //$NON-NLS-1$ //$NON-NLS-2$
302: } catch (URISyntaxException e) {
303: // URI is hardcoded in try block and is gauranteed to be valid.
304: }
305:
306: return newResource;
307: }
308:
309: private Element getInputRoot() {
310: Element inputRoot = null;
311: if (actionSequence != null) {
312: Element docRoot = actionSequence.getDocument()
313: .getRootElement();
314: if (docRoot != null) {
315: inputRoot = docRoot
316: .element(ActionSequenceDocument.DOC_INPUTS_NAME);
317: }
318: }
319: return inputRoot;
320: }
321:
322: private Element getResourceRoot() {
323: Element resourceRoot = null;
324: if (actionSequence != null) {
325: Element docRoot = actionSequence.getDocument()
326: .getRootElement();
327: if (docRoot != null) {
328: resourceRoot = docRoot
329: .element(ActionSequenceDocument.DOC_RESOURCES_NAME);
330: }
331: }
332: return resourceRoot;
333: }
334:
335: public void ioAdded(AbstractIOElement io) {
336: if (io instanceof ActionSequenceInput) {
337: Element inputElement = getInputRoot();
338: if (inputElement != null) {
339: Widget inputItem = findItem(inputElement);
340: if (inputItem == null) {
341: createTreeItem(getTree(), inputElement, -1);
342: } else {
343: refresh(inputElement);
344: }
345: }
346: }
347: }
348:
349: public void ioChanged(AbstractIOElement io) {
350: if (io instanceof ActionSequenceInput) {
351: update(io, null);
352: }
353: }
354:
355: public void ioRemoved(Object parent, AbstractIOElement io) {
356: if (io instanceof ActionSequenceInput) {
357: remove(io);
358: }
359: }
360:
361: public void ioRenamed(AbstractIOElement io) {
362: if (io instanceof ActionSequenceInput) {
363: update(io, null);
364: }
365: }
366:
367: public void resourceAdded(Object resource) {
368: if (resource instanceof ActionSequenceResource) {
369: Element resourceElement = getResourceRoot();
370: if (resourceElement != null) {
371: Widget resourceItem = findItem(resourceElement);
372: if (resourceItem == null) {
373: createTreeItem(getTree(), resourceElement, -1);
374: } else {
375: refresh(resourceElement);
376: }
377: }
378: }
379: }
380:
381: public void resourceChanged(Object resource) {
382: if (resource instanceof ActionSequenceResource) {
383: update(resource, null);
384: }
385: }
386:
387: public void resourceRemoved(Object parent, Object resource) {
388: if (resource instanceof ActionSequenceResource) {
389: remove(resource);
390: }
391: }
392:
393: public void resourceRenamed(Object resource) {
394: if (resource instanceof ActionSequenceResource) {
395: update(resource, null);
396: }
397: }
398:
399: public void controlStatementAdded(
400: ActionControlStatement controlStatement) {
401: }
402:
403: public void controlStatementChanged(
404: ActionControlStatement controlStatement) {
405: }
406:
407: public void controlStatementRemoved(Object parent,
408: ActionControlStatement controlStatement) {
409: }
410:
411: public void actionAdded(ActionDefinition action) {
412: }
413:
414: public void actionChanged(ActionDefinition action) {
415: }
416:
417: public void actionRemoved(Object parent, ActionDefinition action) {
418: }
419:
420: public void actionRenamed(ActionDefinition action) {
421: }
422:
423: public void headerChanged(
424: ActionSequenceDocument actionSequenceDocument) {
425: // TODO Auto-generated method stub
426:
427: }
428:
429: public void addDragSourceListener(DragSourceListener listener) {
430: dragSourceListeners.add(listener);
431: }
432:
433: public void removeDragSourceListener(DragSourceListener listener) {
434: dragSourceListeners.remove(listener);
435: }
436:
437: protected void fireDragStart(DragSourceEvent event) {
438: Object[] listeners = dragSourceListeners.getListeners();
439: for (int i = 0; i < listeners.length; ++i) {
440: DragSourceListener l = (DragSourceListener) listeners[i];
441: l.dragStart(event);
442: }
443: }
444:
445: protected void fireDragFinished(DragSourceEvent event) {
446: Object[] listeners = dragSourceListeners.getListeners();
447: for (int i = 0; i < listeners.length; ++i) {
448: DragSourceListener l = (DragSourceListener) listeners[i];
449: l.dragFinished(event);
450: }
451: }
452:
453: public void addParamRenamedListener(IParamRenamedListener listener) {
454: paramRenamedListeners.add(listener);
455: }
456:
457: protected void fireParamRenamed(
458: final AbstractIOElement actionSequenceParameter) {
459: Object[] listeners = paramRenamedListeners.getListeners();
460: for (int i = 0; i < listeners.length; ++i) {
461: final IParamRenamedListener l = (IParamRenamedListener) listeners[i];
462: SafeRunnable.run(new SafeRunnable() {
463: public void run() {
464: l.paramRenamed(actionSequenceParameter);
465: }
466: });
467: }
468: }
469:
470: public void removeParamRenamedListener(
471: IParamRenamedListener listener) {
472: paramRenamedListeners.remove(listener);
473: }
474: }
|