Java tutorial
/****************************************************************************** * Copyright (c) 2011-2013, Linagora * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Linagora - initial API and implementation *******************************************************************************/ package com.ebmwebsourcing.petals.components.drivers; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URI; import java.net.URL; import java.util.HashMap; import java.util.Map; import java.util.Properties; import org.eclipse.bpel.common.wsdl.helpers.UriAndUrlHelper; import org.eclipse.core.runtime.IStatus; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.ColumnWeightData; import org.eclipse.jface.viewers.ILabelProviderListener; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.TableLayout; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.window.Window; import org.eclipse.jface.wizard.IWizardPage; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.Text; import com.ebmwebsourcing.petals.common.internal.provisional.emf.InvalidJbiXmlException; import com.ebmwebsourcing.petals.common.internal.provisional.preferences.PreferencesManager; import com.ebmwebsourcing.petals.common.internal.provisional.utils.StringUtils; import com.ebmwebsourcing.petals.components.PetalsComponentsPlugin; import com.ebmwebsourcing.petals.components.utils.ArtifactArchiveUtils; /** * A wizard page to specify one or several SL to add to a component. * @author Vincent Zurczak - EBM WebSourcing */ public class ComponentConfigurationWizardPage extends WizardPage implements IWizardPage { private final static String NAME = "Name"; private final static String VERSION = "Version"; private boolean overwrite; private String componentUrl, updatedFileLocation; private final Map<String, String> slNameToVersion = new HashMap<String, String>(); /** * Constructor. */ protected ComponentConfigurationWizardPage() { super("Component Configuration Page"); } /* (non-Jsdoc) * @see org.eclipse.jface.dialogs.IDialogPage * #createControl(org.eclipse.swt.widgets.Composite) */ @Override public void createControl(Composite parent) { setTitle("Configured Component"); setMessage("Update a Petals component to use one or several shared libraries."); Composite container = new Composite(parent, SWT.NONE); container.setLayout(new GridLayout()); container.setLayoutData(new GridData(GridData.FILL_BOTH)); setControl(container); // Select the component's archive Composite subC = new Composite(container, SWT.NONE); GridLayout layout = new GridLayout(3, false); layout.marginWidth = 0; layout.marginHeight = 0; subC.setLayout(layout); subC.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); Label l = new Label(subC, SWT.NONE); l.setText("Component's URL:"); l.setToolTipText("The URL of the component's ZIP"); final Text componentUrlText = new Text(subC, SWT.SINGLE | SWT.BORDER); componentUrlText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); componentUrlText.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { ComponentConfigurationWizardPage.this.componentUrl = ((Text) e.widget).getText().trim(); validate(); } }); Button browseButton = new Button(subC, SWT.PUSH); browseButton.setText("Browse..."); browseButton.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { widgetDefaultSelected(e); } @Override public void widgetDefaultSelected(SelectionEvent e) { FileDialog dlg = new FileDialog(getShell(), SWT.SINGLE); dlg.setText("Select a zipped component file"); dlg.setFilterNames(new String[] { "ZIP (*.zip)" }); dlg.setFilterExtensions(new String[] { "*.zip" }); String path = PreferencesManager.getSavedLocation(); if (!StringUtils.isEmpty(path)) { try { File f = new File(path); dlg.setFilterPath(f.getParentFile().getAbsolutePath()); dlg.setFileName(f.getName()); } catch (Exception e1) { // nothing } } String fn = dlg.open(); if (fn != null) { PreferencesManager.setSavedLocation(fn); fn = convertFilePathToUrl(fn); componentUrlText.setText(fn); } } }); // Choose the output location l = new Label(subC, SWT.NONE); l.setText("Output Location:"); l.setToolTipText("The location of the component after configuration"); final Text outputLocationText = new Text(subC, SWT.SINGLE | SWT.BORDER); outputLocationText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); outputLocationText.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { ComponentConfigurationWizardPage.this.updatedFileLocation = ((Text) e.widget).getText().trim(); validate(); } }); browseButton = new Button(subC, SWT.PUSH); browseButton.setText("Browse..."); browseButton.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { widgetDefaultSelected(e); } @Override public void widgetDefaultSelected(SelectionEvent e) { FileDialog dlg = new FileDialog(getShell(), SWT.SINGLE | SWT.SAVE); dlg.setText("Select a zipped component file"); dlg.setFilterNames(new String[] { "ZIP (*.zip)" }); dlg.setFilterExtensions(new String[] { "*.zip" }); // File name String name = null; if (ComponentConfigurationWizardPage.this.componentUrl != null) { int index = Math.max(ComponentConfigurationWizardPage.this.componentUrl.lastIndexOf('/'), ComponentConfigurationWizardPage.this.componentUrl.lastIndexOf('\\')); if (index > 0 && index < ComponentConfigurationWizardPage.this.componentUrl.length() - 1) { name = ComponentConfigurationWizardPage.this.componentUrl.substring(index + 1); name = StringUtils.insertSuffixBeforeFileExtension(name, "--patched"); } } // Save location String path = PreferencesManager.getSavedLocation(); if (!StringUtils.isEmpty(path)) { try { File f = new File(path); dlg.setFilterPath(f.getParentFile().getAbsolutePath()); dlg.setFileName(name == null ? f.getName() : name); } catch (Exception e1) { // nothing } } else if (name != null) { dlg.setFileName(name); } String fn = dlg.open(); if (fn != null) outputLocationText.setText(fn); } }); new Label(subC, SWT.NO_FOCUS); final Button overwriteButton = new Button(subC, SWT.CHECK); overwriteButton.setText("Overwrite"); overwriteButton.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { widgetDefaultSelected(e); } @Override public void widgetDefaultSelected(SelectionEvent e) { ComponentConfigurationWizardPage.this.overwrite = overwriteButton.getSelection(); validate(); } }); // Add a table to display the shared libraries to add subC = new Composite(container, SWT.NONE); layout = new GridLayout(2, false); layout.marginWidth = 0; layout.marginHeight = 0; layout.marginTop = 18; subC.setLayout(layout); subC.setLayoutData(new GridData(GridData.FILL_BOTH)); l = new Label(subC, SWT.NONE); l.setText("Select or define the shared libraries this component must use."); GridData layoutData = new GridData(); layoutData.horizontalSpan = 2; l.setLayoutData(layoutData); final TableViewer slViewer = new TableViewer(subC, SWT.BORDER | SWT.HIDE_SELECTION | SWT.FULL_SELECTION | SWT.SINGLE); slViewer.setContentProvider(new ArrayContentProvider()); slViewer.setLabelProvider(new ITableLabelProvider() { @Override public void removeListener(ILabelProviderListener listener) { // nothing } @Override public boolean isLabelProperty(Object element, String property) { return false; } @Override public void dispose() { // nothing } @Override public void addListener(ILabelProviderListener listener) { // nothing } @Override public String getColumnText(Object element, int columnIndex) { Object key = ((Map.Entry<?, ?>) element).getKey(); Object value = ((Map.Entry<?, ?>) element).getValue(); String result = ""; ; if (columnIndex == 0) result = (String) key; else if (columnIndex == 1) result = (String) value; return result; } @Override public Image getColumnImage(Object element, int columnIndex) { return null; } }); slViewer.getTable().setLayoutData(new GridData(GridData.FILL_BOTH)); slViewer.getTable().setHeaderVisible(true); slViewer.getTable().setLinesVisible(true); TableLayout tlayout = new TableLayout(); tlayout.addColumnData(new ColumnWeightData(85, 300, true)); tlayout.addColumnData(new ColumnWeightData(15, 50, true)); slViewer.getTable().setLayout(tlayout); TableColumn column = new TableColumn(slViewer.getTable(), SWT.LEFT); column.setText(NAME); column = new TableColumn(slViewer.getTable(), SWT.CENTER); column.setText(VERSION); slViewer.setColumnProperties(new String[] { NAME, VERSION }); // Add some buttons Composite buttonsComposite = new Composite(subC, SWT.NONE); layout = new GridLayout(); layout.marginWidth = 0; layout.marginHeight = 0; buttonsComposite.setLayout(layout); buttonsComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, true)); Button addSlFileButton = new Button(buttonsComposite, SWT.PUSH); addSlFileButton.setText("Add a File..."); addSlFileButton.setToolTipText("Select a Shared Library file"); addSlFileButton.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false)); Button addSlUrlButton = new Button(buttonsComposite, SWT.PUSH); addSlUrlButton.setText("Add an URL..."); addSlUrlButton.setToolTipText("Add an URL pointing to a Shared Library"); addSlUrlButton.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false)); Button specifySlButton = new Button(buttonsComposite, SWT.PUSH); specifySlButton.setText("Specify Manually..."); specifySlButton.setToolTipText("Enter a shared library name and a shared library version manually"); specifySlButton.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false)); final Button editButton = new Button(buttonsComposite, SWT.PUSH); editButton.setText("Edit..."); editButton.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false)); final Button deleteButton = new Button(buttonsComposite, SWT.PUSH); deleteButton.setText("Delete"); deleteButton.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false)); // Button listeners addSlFileButton.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { openSlFileDialog(slViewer, null); } @Override public void widgetDefaultSelected(SelectionEvent e) { openSlFileDialog(slViewer, null); } }); addSlUrlButton.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { openSlUrlDialog(slViewer, null); } @Override public void widgetDefaultSelected(SelectionEvent e) { openSlUrlDialog(slViewer, null); } }); specifySlButton.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { openSlDialog(slViewer, null); } @Override public void widgetDefaultSelected(SelectionEvent e) { openSlDialog(slViewer, null); } }); editButton.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { widgetDefaultSelected(e); } @Override public void widgetDefaultSelected(SelectionEvent e) { if (!slViewer.getSelection().isEmpty()) { Object o = ((IStructuredSelection) slViewer.getSelection()).getFirstElement(); if (o instanceof Map.Entry<?, ?>) { o = ((Map.Entry<?, ?>) o).getKey(); if (o instanceof String) openSlDialog(slViewer, (String) o); } } } }); deleteButton.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { widgetDefaultSelected(e); } @Override public void widgetDefaultSelected(SelectionEvent e) { if (!slViewer.getSelection().isEmpty()) { Object o = ((IStructuredSelection) slViewer.getSelection()).getFirstElement(); ComponentConfigurationWizardPage.this.slNameToVersion.remove(o); slViewer.setInput(ComponentConfigurationWizardPage.this.slNameToVersion.entrySet()); slViewer.refresh(); } } }); // Other listeners slViewer.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { deleteButton.setEnabled(true); Object o = ((IStructuredSelection) slViewer.getSelection()).getFirstElement(); if (o instanceof Map.Entry<?, ?>) { o = ((Map.Entry<?, ?>) o).getKey(); boolean disabled = o instanceof File; editButton.setEnabled(!disabled); } } }); setPageComplete(false); } /** * @param slViewer the shared libraries viewer * @param name */ private void openSlDialog(final TableViewer slViewer, String name) { DuoInputDialog dlg = new DuoInputDialog(getShell()); dlg.setName(name); dlg.setVersion(this.slNameToVersion.get(name)); if (dlg.open() == Window.OK) { ComponentConfigurationWizardPage.this.slNameToVersion.put(dlg.getName(), dlg.getVersion()); slViewer.setInput(ComponentConfigurationWizardPage.this.slNameToVersion.entrySet()); slViewer.refresh(); validate(); } } /** * @param slViewer the shared libraries viewer * @param file */ private void openSlFileDialog(final TableViewer slViewer, File file) { FileDialog dlg = new FileDialog(getShell(), SWT.SINGLE); dlg.setText("Select a shared library file"); dlg.setFilterNames(new String[] { "ZIP (*.zip)" }); dlg.setFilterExtensions(new String[] { "*.zip" }); if (file != null) dlg.setFilterPath(file.getParentFile().getAbsolutePath()); String path = PreferencesManager.getSavedLocation(); if (!StringUtils.isEmpty(path)) { try { File f = new File(path); dlg.setFilterPath(f.getParentFile().getAbsolutePath()); dlg.setFileName(f.getName()); } catch (Exception e1) { // nothing } } String fn = dlg.open(); if (fn != null) { PreferencesManager.setSavedLocation(fn); File f = new File(fn); String version = null; String name = null; try { Properties prop = ArtifactArchiveUtils.getSharedLibraryVersion(f); version = prop.getProperty(ArtifactArchiveUtils.SL_VERSION); name = prop.getProperty(ArtifactArchiveUtils.SL_NAME); } catch (InvalidJbiXmlException e) { PetalsComponentsPlugin.log(e, IStatus.ERROR); } if (!StringUtils.isEmpty(name)) { ComponentConfigurationWizardPage.this.slNameToVersion.put(name, version); slViewer.setInput(ComponentConfigurationWizardPage.this.slNameToVersion.entrySet()); slViewer.refresh(); validate(); } } } /** * @param slViewer the shared libraries viewer * @param url */ private void openSlUrlDialog(final TableViewer slViewer, URL url) { ZipUrlInputDialog dlg = new ZipUrlInputDialog(getShell(), url); if (dlg.open() == Window.OK && !dlg.isCancelled() && !StringUtils.isEmpty(dlg.getName())) { ComponentConfigurationWizardPage.this.slNameToVersion.put(dlg.getName(), dlg.getVersion()); slViewer.setInput(ComponentConfigurationWizardPage.this.slNameToVersion.entrySet()); slViewer.refresh(); validate(); } } /** * Validates all the inputs. */ private void validate() { String msg = null; if (StringUtils.isEmpty(this.componentUrl)) msg = "You must indicate the location of a component archive."; else if ((msg = validateUrl(this.componentUrl)) == null) { if (StringUtils.isEmpty(this.updatedFileLocation)) msg = "You must indicate the location of the output archive."; else if (new File(this.updatedFileLocation).exists() && !this.overwrite) msg = "The output file already exists."; else if (this.componentUrl.equals(convertFilePathToUrl(this.updatedFileLocation))) msg = "The output component cannot overwrite the input component."; else if (this.slNameToVersion.isEmpty()) msg = "You must specify at least one shared library to use."; } setErrorMessage(msg); setPageComplete(msg == null); } /** * @return the componentUrl */ public String getComponentUrl() { return this.componentUrl; } /** * @return the updatedFileLocation */ public String getOutputLocation() { return this.updatedFileLocation; } /** * @return the slNameToVersion */ public Map<String, String> getSlNameToVersion() { return this.slNameToVersion; } /** * Builds an URL from a string and escapes illegal characters. * @param path the file path or file URL * @return an URL */ private static String convertFilePathToUrl(String path) { URL url; try { url = new URL(path); } catch (MalformedURLException e1) { try { URI uri = new File(path).toURI(); uri.normalize(); url = uri.toURL(); } catch (Exception e) { throw new IllegalArgumentException("Broken URL: " + path); } } return url.toString(); } /** * Checks that an URL points to an existing resource. * @param url an URL (not null) * @return null if everything is fine, an error message otherwise */ private static String validateUrl(String url) { String msg = null; InputStream is = null; try { is = UriAndUrlHelper.urlToUri(url).toURL().openStream(); } catch (MalformedURLException e) { msg = e.getMessage(); } catch (IOException e) { msg = e.getMessage(); } finally { if (is != null) { try { is.close(); } catch (IOException e) { PetalsComponentsPlugin.log(e, IStatus.WARNING); } } } return msg; } }