/******************************************************************************* * Copyright (c) 2007, 2011 IBM Corporation and others. * 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: * IBM Corporation - initial API and implementation * Ferenc Hechler, ferenc_hechler@users.sourceforge.net - 83258 [jar exporter] Deploy java application as executable jar *******************************************************************************/ package org.eclipse.jdt.internal.ui.jarpackager; import java.io.File; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Label; import org.eclipse.core.filesystem.URIUtil; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.dialogs.IMessageProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.ui.dialogs.WizardExportResourcesPage; import org.eclipse.jdt.ui.jarpackager.JarPackageData; import org.eclipse.jdt.internal.ui.util.SWTUtil; import org.eclipse.jdt.internal.ui.wizards.buildpaths.ArchiveFileFilter; /** * A wizard page containing a destination block for a jar file. Including * all required validation code. Clients should overwrite <code>createControl</code>. * * @since 3.4 */ public abstract class AbstractJarDestinationWizardPage extends WizardExportResourcesPage implements IJarPackageWizardPage { private final String fStoreDestinationNamesId; private Combo fDestinationNamesCombo; private Button fDestinationBrowseButton; private final JarPackageData fJarPackage; public AbstractJarDestinationWizardPage(String pageName, IStructuredSelection selection, JarPackageData jarPackage) { super(pageName, selection); fStoreDestinationNamesId= pageName + ".DESTINATION_NAMES_ID"; //$NON-NLS-1$ fJarPackage= jarPackage; } /* * Overrides method from WizardExportPage */ @Override protected void createDestinationGroup(Composite parent) { initializeDialogUnits(parent); // destination specification group Composite destinationSelectionGroup= new Composite(parent, SWT.NONE); GridLayout layout= new GridLayout(); layout.numColumns= 3; destinationSelectionGroup.setLayout(layout); destinationSelectionGroup.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL)); String label= getDestinationLabel(); if (label != null) { new Label(destinationSelectionGroup, SWT.NONE).setText(label); } else { layout.marginWidth= 0; layout.marginHeight= 0; } // destination name entry field fDestinationNamesCombo= new Combo(destinationSelectionGroup, SWT.SINGLE | SWT.BORDER); SWTUtil.setDefaultVisibleItemCount(fDestinationNamesCombo); fDestinationNamesCombo.addListener(SWT.Modify, this); fDestinationNamesCombo.addListener(SWT.Selection, this); GridData data= new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL); data.widthHint= SIZING_TEXT_FIELD_WIDTH; data.horizontalSpan= label == null ? 2 : 1; fDestinationNamesCombo.setLayoutData(data); if (label == null) { SWTUtil.setAccessibilityText(fDestinationNamesCombo, JarPackagerMessages.AbstractJarDestinationWizardPage_destinationCombo_AccessibilityText); } // destination browse button fDestinationBrowseButton= new Button(destinationSelectionGroup, SWT.PUSH); fDestinationBrowseButton.setText(JarPackagerMessages.JarPackageWizardPage_browseButton_text); fDestinationBrowseButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL)); SWTUtil.setButtonDimensionHint(fDestinationBrowseButton); fDestinationBrowseButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { handleDestinationBrowseButtonPressed(); } }); } /** * Open an appropriate destination browser so that the user can specify a source * to import from */ protected void handleDestinationBrowseButtonPressed() { FileDialog dialog= new FileDialog(getContainer().getShell(), SWT.SAVE); dialog.setFilterExtensions(ArchiveFileFilter.JAR_ZIP_FILTER_EXTENSIONS); String currentSourceString= getDestinationValue(); int lastSeparatorIndex= currentSourceString.lastIndexOf(File.separator); if (lastSeparatorIndex != -1) { dialog.setFilterPath(currentSourceString.substring(0, lastSeparatorIndex)); dialog.setFileName(currentSourceString.substring(lastSeparatorIndex + 1, currentSourceString.length())); } String selectedFileName= dialog.open(); if (selectedFileName != null) { IContainer[] findContainersForLocation= ResourcesPlugin.getWorkspace().getRoot().findContainersForLocationURI(URIUtil.toURI(new Path(selectedFileName).makeAbsolute())); if (findContainersForLocation.length > 0) { selectedFileName= findContainersForLocation[0].getFullPath().makeRelative().toString(); } fDestinationNamesCombo.setText(selectedFileName); } } /** * Answer the contents of the destination specification widget. If this * value does not have the required suffix then add it first. * * @return java.lang.String */ protected String getDestinationValue() { String destinationText= fDestinationNamesCombo.getText().trim(); if (destinationText.indexOf('.') < 0) destinationText+= getOutputSuffix(); return destinationText; } /** * Answer the string to display in self as the destination type * * @return java.lang.String */ protected String getDestinationLabel() { return JarPackagerMessages.JarPackageWizardPage_destination_label; } /** * Answer the suffix that files exported from this wizard must have. * If this suffix is a file extension (which is typically the case) * then it must include the leading period character. * * @return java.lang.String */ protected String getOutputSuffix() { return "." + JarPackagerUtil.JAR_EXTENSION; //$NON-NLS-1$ } @Override protected void restoreWidgetValues() { // destination if (fJarPackage.getJarLocation().isEmpty()) fDestinationNamesCombo.setText(""); //$NON-NLS-1$ else fDestinationNamesCombo.setText(fJarPackage.getJarLocation().toOSString()); IDialogSettings settings= getDialogSettings(); if (settings != null) { String[] directoryNames= settings.getArray(fStoreDestinationNamesId); if (directoryNames == null) return; // ie.- no settings stored if (!fDestinationNamesCombo.getText().equals(directoryNames[0])) fDestinationNamesCombo.add(fDestinationNamesCombo.getText()); for (int i= 0; i < directoryNames.length; i++) fDestinationNamesCombo.add(directoryNames[i]); } } protected void updateModel() { // destination String comboText= fDestinationNamesCombo.getText(); IPath path= Path.fromOSString(comboText); if (path.segmentCount() > 0 && ensureTargetFileIsValid(path.toFile()) && path.getFileExtension() == null) // append .jar path= path.addFileExtension(JarPackagerUtil.JAR_EXTENSION); fJarPackage.setJarLocation(path); } /** * Returns a boolean indicating whether the passed File handle is * is valid and available for use. * * @param targetFile the target * @return boolean */ protected boolean ensureTargetFileIsValid(File targetFile) { if (targetFile.exists() && targetFile.isDirectory() && fDestinationNamesCombo.getText().length() > 0) { setErrorMessage(JarPackagerMessages.JarPackageWizardPage_error_exportDestinationMustNotBeDirectory); fDestinationNamesCombo.setFocus(); return false; } if (targetFile.exists()) { if (!targetFile.canWrite()) { setErrorMessage(JarPackagerMessages.JarPackageWizardPage_error_jarFileExistsAndNotWritable); fDestinationNamesCombo.setFocus(); return false; } } return true; } /* * Overrides method from WizardDataTransferPage */ @Override protected boolean validateDestinationGroup() { if (fDestinationNamesCombo.getText().length() == 0) { // Clear error if (getErrorMessage() != null) setErrorMessage(null); if (getMessage() != null) setMessage(null); return false; } if (fJarPackage.getAbsoluteJarLocation().toString().endsWith("/")) { //$NON-NLS-1$ setErrorMessage(JarPackagerMessages.JarPackageWizardPage_error_exportDestinationMustNotBeDirectory); fDestinationNamesCombo.setFocus(); return false; } // Check if the Jar is put into the workspace and conflicts with the containers // exported. If the workspace isn't on the local files system we are fine since // the Jar is always created in the local file system IPath workspaceLocation= ResourcesPlugin.getWorkspace().getRoot().getLocation(); if (workspaceLocation != null && workspaceLocation.isPrefixOf(fJarPackage.getAbsoluteJarLocation())) { int segments= workspaceLocation.matchingFirstSegments(fJarPackage.getAbsoluteJarLocation()); IPath path= fJarPackage.getAbsoluteJarLocation().removeFirstSegments(segments); IResource resource= ResourcesPlugin.getWorkspace().getRoot().findMember(path); if (resource != null && resource.getType() == IResource.FILE) { // test if included if (JarPackagerUtil.contains(JarPackagerUtil.asResources(fJarPackage.getElements()), (IFile) resource)) { setErrorMessage(JarPackagerMessages.JarPackageWizardPage_error_cantExportJARIntoItself); return false; } } } // Inform user about relative directory String currentMessage= getMessage(); if (!(Path.fromOSString(fDestinationNamesCombo.getText()).isAbsolute())) { if (currentMessage == null) setMessage(JarPackagerMessages.JarPackageWizardPage_info_relativeExportDestination, IMessageProvider.INFORMATION); } else { if (currentMessage != null) setMessage(null); } return ensureTargetFileIsValid(fJarPackage.getAbsoluteJarLocation().toFile()); } /** * Set the current input focus to self's destination entry field */ protected void giveFocusToDestination() { fDestinationNamesCombo.setFocus(); } /** * {@inheritDoc} */ @Override protected void saveWidgetValues() { IDialogSettings settings= getDialogSettings(); if (settings != null) { String[] directoryNames= settings.getArray(fStoreDestinationNamesId); if (directoryNames == null) directoryNames= new String[0]; directoryNames= addToHistory(directoryNames, getDestinationValue()); settings.put(fStoreDestinationNamesId, directoryNames); } } /** * Initializes the JAR package from last used wizard page values. */ protected void initializeJarPackage() { IDialogSettings settings= getDialogSettings(); if (settings != null) { // destination String[] directoryNames= settings.getArray(fStoreDestinationNamesId); if (directoryNames == null) return; // ie.- no settings stored fJarPackage.setJarLocation(Path.fromOSString(directoryNames[0])); } } /* * Implements method from IJarPackageWizardPage. */ public void finish() { saveWidgetValues(); } /* * Implements method from Listener */ public void handleEvent(Event e) { if (getControl() == null) return; update(); } protected void update() { updateModel(); updateWidgetEnablements(); updatePageCompletion(); } @Override protected void updatePageCompletion() { boolean pageComplete= isPageComplete(); setPageComplete(pageComplete); if (pageComplete) setErrorMessage(null); } }