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.actions.details.kettle;
014:
015: import java.net.URI;
016: import java.net.URISyntaxException;
017: import java.text.MessageFormat;
018: import java.util.ArrayList;
019: import java.util.Arrays;
020:
021: import org.eclipse.core.runtime.IPath;
022: import org.eclipse.core.runtime.Path;
023: import org.eclipse.swt.SWT;
024: import org.eclipse.swt.custom.StackLayout;
025: import org.eclipse.swt.events.SelectionEvent;
026: import org.eclipse.swt.events.SelectionListener;
027: import org.eclipse.swt.layout.GridData;
028: import org.eclipse.swt.layout.GridLayout;
029: import org.eclipse.swt.widgets.Button;
030: import org.eclipse.swt.widgets.Composite;
031: import org.eclipse.swt.widgets.FileDialog;
032: import org.eclipse.swt.widgets.Text;
033: import org.pentaho.actionsequence.dom.AbstractIOElement;
034: import org.pentaho.actionsequence.dom.ActionInputConstant;
035: import org.pentaho.actionsequence.dom.ActionResource;
036: import org.pentaho.actionsequence.dom.ActionSequenceDocument;
037: import org.pentaho.actionsequence.dom.ActionSequenceResource;
038: import org.pentaho.actionsequence.dom.IActionSequenceElement;
039: import org.pentaho.actionsequence.dom.actions.ActionDefinition;
040: import org.pentaho.actionsequence.dom.actions.KettleJobAction;
041: import org.pentaho.designstudio.controls.ActionInputCombo;
042: import org.pentaho.designstudio.controls.ActionInputsList;
043: import org.pentaho.designstudio.controls.ActionInputsListToolbar;
044: import org.pentaho.designstudio.controls.ActionResourceText;
045: import org.pentaho.designstudio.controls.NewActionInputCombo;
046: import org.pentaho.designstudio.controls.WidgetFactory;
047: import org.pentaho.designstudio.editors.actionsequence.pages.actions.IActionIOFilter;
048: import org.pentaho.designstudio.editors.actionsequence.pages.actions.details.ActionDetailsPage;
049: import org.pentaho.designstudio.messages.Messages;
050: import org.pentaho.designstudio.util.SolutionHelper;
051:
052: public class KettleJobDetailsPage extends ActionDetailsPage implements
053: SelectionListener, IActionIOFilter {
054:
055: ActionResourceText kettleResourceFilePath;
056: NewActionInputCombo kettleRepositoryFile;
057: NewActionInputCombo kettleRepositoryDir;
058: Button useKettleRepositoryBtn;
059:
060: Button browseKettleTransformBtn;
061:
062: IPath basePath;
063:
064: ActionInputsList inputParameters;
065: ActionInputsListToolbar inputParametersToolbar;
066: StackLayout stackLayout = new StackLayout();
067: Composite stackedComposite;
068: Composite resourceFileComposite;
069: Composite repositoryFileComposite;
070:
071: public KettleJobDetailsPage(IPath basePath) {
072: this .basePath = basePath;
073: }
074:
075: public String getComponentName() {
076: return KettleJobAction.COMPONENT_NAME;
077: }
078:
079: public void createDetailsComposite(Composite parent) {
080: Composite actionConfigComposite = parent;
081:
082: GridLayout gridLayout = new GridLayout(2, true);
083: gridLayout.horizontalSpacing = 20;
084: actionConfigComposite.setLayout(gridLayout);
085:
086: useKettleRepositoryBtn = WidgetFactory
087: .createButton(
088: actionConfigComposite,
089: Messages
090: .getString("KettleJobDetailsPage.USE_KETTLE_REPOS"), SWT.CHECK); //$NON-NLS-1$
091: useKettleRepositoryBtn.addSelectionListener(this );
092:
093: Composite composite = WidgetFactory
094: .createComposite(actionConfigComposite);
095: gridLayout = new GridLayout(2, false);
096: gridLayout.marginWidth = 0;
097: gridLayout.marginHeight = 0;
098: composite.setLayout(gridLayout);
099: composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
100: WidgetFactory.createLabel(composite, Messages
101: .getString("KettleJobDetailsPage.KETTLE_JOB_INPUTS")); //$NON-NLS-1$
102:
103: stackedComposite = WidgetFactory
104: .createComposite(actionConfigComposite);
105: stackedComposite.setLayoutData(new GridData(
106: GridData.FILL_HORIZONTAL));
107: stackedComposite.setLayout(stackLayout);
108:
109: repositoryFileComposite = WidgetFactory
110: .createComposite(stackedComposite);
111: gridLayout = new GridLayout();
112: gridLayout.marginWidth = 1;
113: gridLayout.marginHeight = 1;
114: repositoryFileComposite.setLayout(gridLayout);
115: WidgetFactory.createLabel(repositoryFileComposite, "Directory"); //$NON-NLS-1$
116: kettleRepositoryDir = new NewActionInputCombo(
117: repositoryFileComposite, new GridData(
118: GridData.FILL_HORIZONTAL));
119: kettleRepositoryDir.setRemoveInputWhenNoValue(false);
120: WidgetFactory.createLabel(repositoryFileComposite, Messages
121: .getString("KettleJobDetailsPage.KETTLE_JOB_FILE")); //$NON-NLS-1$
122: kettleRepositoryFile = new NewActionInputCombo(
123: repositoryFileComposite, new GridData(
124: GridData.FILL_HORIZONTAL));
125: kettleRepositoryFile.setRemoveInputWhenNoValue(false);
126:
127: resourceFileComposite = WidgetFactory
128: .createComposite(stackedComposite);
129: gridLayout = new GridLayout();
130: gridLayout.marginWidth = 1;
131: gridLayout.marginHeight = 1;
132: resourceFileComposite.setLayout(gridLayout);
133: GridData gridData = new GridData();
134: gridData.grabExcessVerticalSpace = true;
135: gridData.verticalAlignment = SWT.END;
136: WidgetFactory
137: .createLabel(
138: resourceFileComposite,
139: Messages
140: .getString("KettleJobDetailsPage.KETTLE_JOB_FILE")).setLayoutData(gridData); //$NON-NLS-1$
141: kettleResourceFilePath = new ActionResourceText(
142: resourceFileComposite, new GridData(
143: GridData.FILL_HORIZONTAL));
144: kettleResourceFilePath.setBasePath(basePath);
145: browseKettleTransformBtn = WidgetFactory
146: .createButton(
147: resourceFileComposite,
148: Messages
149: .getString("JFreeReportDetailsPage.UI_BROWSE_LABEL"), SWT.FLAT); //$NON-NLS-1$
150: browseKettleTransformBtn.addSelectionListener(this );
151: gridData = new GridData();
152: gridData.horizontalAlignment = GridData.END;
153: gridData.verticalAlignment = SWT.BEGINNING;
154: browseKettleTransformBtn.setLayoutData(gridData);
155:
156: inputParameters = new ActionInputsList(actionConfigComposite);
157: gridData = new GridData();
158: gridData.grabExcessHorizontalSpace = true;
159: gridData.horizontalAlignment = SWT.FILL;
160: gridData.verticalAlignment = SWT.FILL;
161: inputParameters.getControl().setLayoutData(gridData);
162: inputParameters.setFilter(this );
163:
164: inputParametersToolbar = new ActionInputsListToolbar(composite,
165: inputParameters);
166: gridData = new GridData(GridData.FILL_HORIZONTAL);
167: gridData.horizontalAlignment = GridData.END;
168: inputParametersToolbar.getControl().setLayoutData(gridData);
169: }
170:
171: public void refresh() {
172: super .refresh();
173: useKettleRepositoryBtn.removeSelectionListener(this );
174: kettleResourceFilePath.setTargetResource(actionDefinition,
175: KettleJobAction.JOB_FILE_ELEMENT);
176: kettleRepositoryFile.setTargetInput(actionDefinition,
177: KettleJobAction.REPOSITORY_JOB,
178: ActionSequenceDocument.STRING_TYPE);
179: kettleRepositoryDir.setTargetInput(actionDefinition,
180: KettleJobAction.REPOSITORY_DIRECTORY,
181: ActionSequenceDocument.STRING_TYPE);
182: inputParameters.setInput(actionDefinition);
183: inputParametersToolbar.refresh();
184: ActionResource actionResource = actionDefinition
185: .getResourceParam(KettleJobAction.JOB_FILE_ELEMENT);
186: if (actionResource == null) {
187: useKettleRepositoryBtn.setSelection(true);
188: stackLayout.topControl = repositoryFileComposite;
189: } else {
190: useKettleRepositoryBtn.setSelection(false);
191: stackLayout.topControl = resourceFileComposite;
192: }
193: stackedComposite.layout();
194: useKettleRepositoryBtn.addSelectionListener(this );
195: }
196:
197: private void setResourcePath(String fileName, Text text) {
198: String fileSolution = SolutionHelper.getSolutionName(fileName);
199: Path filePath = new Path(fileName);
200: String baseSolution = SolutionHelper.getSolutionName(basePath
201: .toString());
202: String solutionRoot = SolutionHelper.getSolutionRoot(basePath
203: .toString());
204:
205: if ((baseSolution != null) && baseSolution.equals(fileSolution)) {
206: if (filePath.matchingFirstSegments(basePath) == basePath
207: .segmentCount()) {
208: IPath relativeFilePath = filePath
209: .removeFirstSegments(basePath.segmentCount());
210: text.setText(relativeFilePath.setDevice(
211: ActionSequenceResource.SOLUTION_SCHEME + ":")
212: .toString());
213: } else {
214: Path solutionPath = new Path(solutionRoot);
215: IPath relativePath = filePath
216: .removeFirstSegments(solutionPath
217: .segmentCount());
218: IPath absPath = relativePath.makeAbsolute().setDevice(
219: ActionSequenceResource.SOLUTION_SCHEME + ":"); //$NON-NLS-1$
220: text.setText(absPath.toString());
221: }
222: } else {
223: text.setText(ActionSequenceResource.FILE_SCHEME + ":"
224: + fileName);
225: }
226: }
227:
228: public boolean checkResourceReferences(
229: ActionDefinition actionDefinition) {
230: return (actionDefinition
231: .getResourceParam(KettleJobAction.JOB_FILE_ELEMENT) != null)
232: || (actionDefinition.getDocument().getResource(
233: KettleJobAction.JOB_FILE_ELEMENT) == null);
234: }
235:
236: public void fixResourceReferences(ActionDefinition actionDefinition) {
237: if ((actionDefinition
238: .getResourceParam(KettleJobAction.JOB_FILE_ELEMENT) == null)
239: && (actionDefinition.getDocument().getResource(
240: KettleJobAction.JOB_FILE_ELEMENT) != null)) {
241: actionDefinition
242: .addResourceParam(KettleJobAction.JOB_FILE_ELEMENT);
243: }
244: }
245:
246: public String getName() {
247: return Messages.getString("KettleJobDetailsPage.KETTLE_JOB"); //$NON-NLS-1$
248: }
249:
250: public boolean accepts(IActionSequenceElement actionDef) {
251: return actionDef instanceof KettleJobAction;
252: }
253:
254: public void widgetDefaultSelected(SelectionEvent e) {
255: // TODO Auto-generated method stub
256:
257: }
258:
259: private void setUseKettleRepository(boolean useKettleRepository) {
260: KettleJobAction kettleJobAction = (KettleJobAction) actionDefinition;
261: if (useKettleRepository) {
262: ActionResource actionResource = actionDefinition
263: .getResourceParam(KettleJobAction.JOB_FILE_ELEMENT);
264: if (actionResource != null) {
265: String logicalName = actionResource.getPublicName();
266: actionDefinition
267: .removeResourceParam(KettleJobAction.JOB_FILE_ELEMENT);
268: ActionSequenceResource actionSequenceResource = actionDefinition
269: .getDocument().getResource(logicalName);
270: if ((actionSequenceResource != null)
271: && (actionDefinition
272: .getDocument()
273: .getReferencesTo(actionSequenceResource).length == 0)) {
274: actionSequenceResource.delete();
275: }
276: }
277: kettleJobAction.setDirectory(new ActionInputConstant("")); //$NON-NLS-1$
278: kettleJobAction.setJob(new ActionInputConstant(""));
279: stackLayout.topControl = repositoryFileComposite;
280: } else {
281: try {
282: actionDefinition.setResourceUri(
283: KettleJobAction.JOB_FILE_ELEMENT, new URI(
284: ActionSequenceResource.FILE_SCHEME,
285: " ", null), "text/plain");
286: } catch (URISyntaxException e) {
287: // Hard coded URI in try block is always valid.
288: }
289: kettleJobAction.setDirectory(null); //$NON-NLS-1$
290: kettleJobAction.setJob(null);
291: stackLayout.topControl = resourceFileComposite;
292: }
293: kettleRepositoryFile.refresh();
294: kettleRepositoryDir.refresh();
295: kettleResourceFilePath.refresh();
296: stackedComposite.layout();
297: }
298:
299: private void selectKettleJob() {
300: FileDialog fileChooser = new FileDialog(
301: browseKettleTransformBtn.getShell(), SWT.OPEN);
302: fileChooser
303: .setText(MessageFormat
304: .format(
305: Messages
306: .getString("AbstractKettleDetailsPage.FILE_CHOOSER_TITLE"), new Object[] { Messages.getString("KettleJobDetailsPage.KETTLE_JOB_FILE") })); //$NON-NLS-1$ //$NON-NLS-2$
307: fileChooser
308: .setFilterExtensions(new String[] { "*.kjb", "*.*" }); //$NON-NLS-1$ //$NON-NLS-2$
309: fileChooser
310: .setFilterNames(new String[] {
311: "Kettle Job", Messages.getString("JFreeReportDetailsPage.ALL_FILES") }); //$NON-NLS-2$
312: String filename = fileChooser.open();
313: if (filename != null) {
314: setResourcePath(filename, (Text) kettleResourceFilePath
315: .getControl());
316: }
317: }
318:
319: public void widgetSelected(SelectionEvent e) {
320: if (e.getSource() == useKettleRepositoryBtn) {
321: setUseKettleRepository(useKettleRepositoryBtn
322: .getSelection());
323: } else if (e.getSource() == browseKettleTransformBtn) {
324: selectKettleJob();
325: }
326: }
327:
328: public boolean accept(AbstractIOElement ioElement) {
329: ArrayList expectedInputs = new ArrayList();
330: if (actionDefinition != null) {
331: expectedInputs.addAll(Arrays.asList(actionDefinition
332: .getReservedInputNames()));
333: }
334: return (!expectedInputs.contains(ioElement.getName()));
335: }
336:
337: }
|