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.controls;
014:
015: import java.util.ArrayList;
016: import java.util.Iterator;
017: import java.util.List;
018:
019: import org.dom4j.Element;
020: import org.eclipse.jface.action.Action;
021: import org.eclipse.jface.action.IMenuListener;
022: import org.eclipse.jface.action.IMenuManager;
023: import org.eclipse.jface.action.MenuManager;
024: import org.eclipse.jface.viewers.IStructuredContentProvider;
025: import org.eclipse.jface.viewers.IStructuredSelection;
026: import org.eclipse.jface.viewers.LabelProvider;
027: import org.eclipse.jface.viewers.ListViewer;
028: import org.eclipse.jface.viewers.StructuredSelection;
029: import org.eclipse.jface.viewers.Viewer;
030: import org.eclipse.jface.viewers.ViewerDropAdapter;
031: import org.eclipse.swt.SWT;
032: import org.eclipse.swt.dnd.DND;
033: import org.eclipse.swt.dnd.Transfer;
034: import org.eclipse.swt.dnd.TransferData;
035: import org.eclipse.swt.widgets.Composite;
036: import org.eclipse.swt.widgets.Menu;
037: import org.pentaho.actionsequence.dom.AbstractActionIOElement;
038: import org.pentaho.actionsequence.dom.AbstractIOElement;
039: import org.pentaho.actionsequence.dom.ActionInput;
040: import org.pentaho.actionsequence.dom.ActionOutput;
041: import org.pentaho.actionsequence.dom.ActionSequenceInput;
042: import org.pentaho.actionsequence.dom.IActionInputVariable;
043: import org.pentaho.actionsequence.dom.actions.ActionDefinition;
044: import org.pentaho.designstudio.editors.actionsequence.pages.actions.IActionIOFilter;
045: import org.pentaho.designstudio.messages.Messages;
046:
047: /**
048: * Table viewer used for viewing and modifying the inputs and outputs of an action
049: * definition element.
050: *
051: * @author Angelo Rodriguez
052: */
053: public class SecureFilterInputsList extends ListViewer {
054:
055: class InputListDropAdapter extends ViewerDropAdapter {
056:
057: InputListDropAdapter() {
058: super (SecureFilterInputsList.this );
059: setFeedbackEnabled(true);
060: }
061:
062: public boolean performDrop(Object data) {
063: ActionInput input = null;
064: if (data instanceof IActionInputVariable) {
065: if ((filter == null)
066: || filter
067: .accept((AbstractActionIOElement) data)) {
068: input = addInput((AbstractIOElement) data);
069: }
070: }
071: return input != null;
072: }
073:
074: /*
075: * (non-Javadoc)
076: *
077: * @see org.eclipse.jface.viewers.ViewerDropAdapter#validateDrop(java.lang.Object,
078: * int, org.eclipse.swt.dnd.TransferData)
079: */
080: public boolean validateDrop(Object target, int op,
081: TransferData type) {
082: return canDrop(target, op, type);
083: }
084: }
085:
086: public class ContentProvider implements IStructuredContentProvider {
087:
088: public Object[] getElements(Object ioElement) {
089: ActionInput[] inputs = actionDefinition.getAllInputParams();
090: ArrayList inputsList = new ArrayList();
091: for (int i = 0; i < inputs.length; i++) {
092: if ((filter == null) || filter.accept(inputs[i])) {
093: inputsList.add(inputs[i]);
094: }
095: }
096: ArrayList elements = new ArrayList();
097: Element[] selections = actionDefinition
098: .getComponentDefElements("selections/*"); //$NON-NLS-1$
099: for (int i = 0; i < selections.length; i++) {
100: for (int j = 0; j < inputsList.size(); j++) {
101: ActionInput actionInput = (ActionInput) inputsList
102: .get(j);
103: if (selections[i].getName().equals(
104: actionInput.getName())) {
105: elements.add(actionInput);
106: }
107: }
108: }
109: return elements.toArray();
110: }
111:
112: public void dispose() {
113: }
114:
115: public void inputChanged(Viewer viewer, Object oldInput,
116: Object newInput) {
117: actionDefinition = (ActionDefinition) newInput;
118: }
119: }
120:
121: class AddInputAction extends Action {
122: AbstractIOElement actionSequenceIO;
123:
124: AddInputAction(ActionOutput actionOutput) {
125: super (actionOutput.getPublicName());
126: actionSequenceIO = actionOutput;
127: }
128:
129: AddInputAction(ActionSequenceInput actionSequenceInput) {
130: super (actionSequenceInput.getName());
131: actionSequenceIO = actionSequenceInput;
132: }
133:
134: public void run() {
135: addInput(actionSequenceIO);
136: }
137: }
138:
139: protected class DeleteInputAction extends Action {
140: public DeleteInputAction() {
141: super ("Delete"); //$NON-NLS-1$
142: }
143:
144: public void run() {
145: removeSelectedIOElement();
146: }
147: }
148:
149: ActionDefinition actionDefinition;
150:
151: protected DeleteInputAction deleteIOAction = new DeleteInputAction();
152:
153: IActionIOFilter filter;
154:
155: private InputListDropAdapter dropAdapter;
156:
157: private IStructuredContentProvider contentProvider;
158:
159: MenuManager addInputSubMenuManager;
160:
161: /**
162: * Creates an viewer
163: * @param parent the parent of this viewer.
164: * @param toolkit the form toolkit.
165: */
166: public SecureFilterInputsList(Composite parent) {
167: super (parent, SWT.V_SCROLL | SWT.BORDER);
168:
169: contentProvider = createContentProvider();
170: setContentProvider(contentProvider);
171: setLabelProvider(new LabelProvider() {
172: public String getText(Object element) {
173: String text = ""; //$NON-NLS-1$
174: if (element instanceof AbstractIOElement) {
175: AbstractIOElement ioElement = (AbstractIOElement) element;
176: text = ioElement.getName();
177: }
178: return text;
179: }
180: });
181: createPopupMenu();
182: int ops = DND.DROP_MOVE | DND.DROP_COPY;
183: Transfer[] transfers = new Transfer[] { ActionSequenceParamTransfer
184: .getInstance() };
185: dropAdapter = new InputListDropAdapter();
186: addDropSupport(ops, transfers, dropAdapter);
187:
188: }
189:
190: protected IStructuredContentProvider createContentProvider() {
191: return new ContentProvider();
192: }
193:
194: /**
195: * Creates the popup menu used by this viewer.
196: */
197: protected void createPopupMenu() {
198: MenuManager popupMenu = new MenuManager();
199:
200: addInputSubMenuManager = new MenuManager(
201: Messages
202: .getString("ActionsMasterDetailBlock.UI_INPUTS_MENU_ADD")); //$NON-NLS-1$
203: popupMenu.add(addInputSubMenuManager);
204:
205: popupMenu.add(deleteIOAction);
206: popupMenu.addMenuListener(new IMenuListener() {
207: public void menuAboutToShow(IMenuManager manager) {
208: updatePopupMenuState(manager);
209: }
210: });
211:
212: org.eclipse.swt.widgets.List list = getList();
213: Menu menu = popupMenu.createContextMenu(list);
214: list.setMenu(menu);
215: }
216:
217: /**
218: * Removes the selected inputs/ouputs from the action definition.
219: */
220: protected void removeSelectedIOElement() {
221: IStructuredSelection selection = (IStructuredSelection) getSelection();
222: for (Iterator iter = selection.iterator(); iter.hasNext();) {
223: ActionInput selectedElement = (ActionInput) iter.next();
224: Element filterElement = actionDefinition
225: .getComponentDefElement("selections/"
226: + selectedElement.getName() + "/filter");
227: String filterName = (filterElement != null ? filterElement
228: .getTextTrim() : null);
229: actionDefinition
230: .setComponentDefinition(
231: "selections/" + selectedElement.getName(), (String) null); //$NON-NLS-1$
232: if ((filterName != null) && (filterName.length() > 0)) {
233: boolean filterStillUsed = false;
234: Element[] usedFilters = actionDefinition
235: .getComponentDefElements("selections/*/filter");
236: for (int i = 0; (i < usedFilters.length)
237: && !filterStillUsed; i++) {
238: filterStillUsed = filterName.equals(usedFilters[i]
239: .getText());
240: }
241: if (!filterStillUsed) {
242: actionDefinition.removeInputParam(filterName);
243: }
244: }
245: }
246:
247: remove(selection.toArray());
248: List selections = selection.toList();
249: for (Iterator iter = selections.iterator(); iter.hasNext();) {
250: AbstractIOElement selectedElement = (AbstractIOElement) iter
251: .next();
252: actionDefinition
253: .removeInputParam(selectedElement.getName());
254:
255: }
256: refresh();
257: }
258:
259: protected void updatePopupMenuState(IMenuManager menuMgr) {
260: IStructuredSelection selection = (IStructuredSelection) getSelection();
261: deleteIOAction.setEnabled(selection.size() > 0);
262: }
263:
264: /* (non-Javadoc)
265: * @see org.eclipse.jface.viewers.Viewer#inputChanged(java.lang.Object, java.lang.Object)
266: */
267: protected void inputChanged(Object input, Object oldInput) {
268: actionDefinition = (ActionDefinition) input;
269: refreshPopupMenu();
270: super .inputChanged(input, oldInput);
271: }
272:
273: /**
274: * Adds a listener for XML document modifications to this detail page.
275: * @param listener a XML modification listener
276: */
277: public void setFilter(IActionIOFilter filter) {
278: this .filter = filter;
279: refresh();
280: }
281:
282: public IActionIOFilter getFilter() {
283: return filter;
284: }
285:
286: protected boolean canDrop(Object target, int op, TransferData type) {
287: return true;
288: }
289:
290: protected ActionInput addInput(AbstractIOElement actionSequenceIO) {
291: ActionInput actionInput = null;
292: if ((actionSequenceIO instanceof ActionSequenceInput)
293: && (actionDefinition.getDocument().getInput(
294: actionSequenceIO.getName()) != null)) {
295: actionInput = actionDefinition.addInputParam(
296: ((ActionSequenceInput) actionSequenceIO).getName(),
297: actionSequenceIO.getType());
298: refresh();
299: } else if (actionSequenceIO instanceof ActionOutput) {
300: ActionOutput droppedOutput = (ActionOutput) actionSequenceIO;
301: IActionInputVariable[] availInputs = actionDefinition
302: .getAvailInputVariables();
303: for (int i = 0; i < availInputs.length; i++) {
304: if (availInputs[i] instanceof ActionOutput) {
305: ActionOutput availInput = (ActionOutput) availInputs[i];
306: if (availInput.getName().equals(
307: droppedOutput.getName())
308: && availInput.getPublicName().equals(
309: droppedOutput.getPublicName())
310: && availInput.getType().equals(
311: droppedOutput.getType())) {
312: actionInput = actionDefinition.addInputParam(
313: droppedOutput.getPublicName(),
314: droppedOutput.getType());
315: refresh();
316: break;
317: }
318: }
319: }
320: }
321: if (actionDefinition
322: .getComponentDefinitionValue("selections/" + actionInput.getName()) == null) { //$NON-NLS-1$
323: actionDefinition.setComponentDefinition(
324: "selections/" + actionInput.getName(), ""); //$NON-NLS-1$ //$NON-NLS-2$
325: actionDefinition
326: .getComponentDefElement(
327: "selections/" + actionInput.getName()).addAttribute("filter", "none"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
328: }
329: refresh();
330: setSelection(new StructuredSelection(actionInput));
331: return actionInput;
332: }
333:
334: private void refreshPopupMenu() {
335: addInputSubMenuManager.removeAll();
336:
337: IActionInputVariable[] availInputs = actionDefinition
338: .getAvailInputVariables();
339: ArrayList availInputNames = new ArrayList();
340: for (int i = 0; i < availInputs.length; i++) {
341: IActionIOFilter actionIOFilter = getFilter();
342: if ((actionIOFilter == null)
343: || actionIOFilter
344: .accept((AbstractIOElement) availInputs[i])) {
345: if (availInputs[i] instanceof ActionOutput) {
346: ActionOutput actionOutput = (ActionOutput) availInputs[i];
347: if (!availInputNames.contains(actionOutput
348: .getPublicName())) {
349: addInputSubMenuManager.add(new AddInputAction(
350: actionOutput));
351: availInputNames.add(actionOutput
352: .getPublicName());
353: }
354: } else if (availInputs[i] instanceof ActionSequenceInput) {
355: ActionSequenceInput actionSequenceInput = (ActionSequenceInput) availInputs[i];
356: if (!availInputNames.contains(actionSequenceInput
357: .getName())) {
358: addInputSubMenuManager.add(new AddInputAction(
359: actionSequenceInput));
360: availInputNames.add(actionSequenceInput
361: .getName());
362: }
363: }
364: }
365: }
366: }
367:
368: public int indexForElement(Object element) {
369: return super.indexForElement(element);
370: }
371: }
|