Java tutorial
/******************************************************************************* * Copyright (c) 2000, 2006 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 *******************************************************************************/ package descent.internal.ui.wizards.buildpaths; import java.io.File; import java.lang.reflect.InvocationTargetException; import java.util.List; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.ViewerFilter; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.DirectoryDialog; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.model.WorkbenchContentProvider; import org.eclipse.ui.model.WorkbenchLabelProvider; import descent.core.IClasspathEntry; import descent.core.IJavaProject; import descent.core.JavaCore; import descent.internal.corext.util.Messages; import descent.internal.ui.IJavaHelpContextIds; import descent.internal.ui.JavaPlugin; import descent.internal.ui.dialogs.StatusInfo; import descent.internal.ui.dialogs.StatusUtil; import descent.internal.ui.util.PixelConverter; import descent.internal.ui.wizards.IStatusChangeListener; import descent.internal.ui.wizards.NewWizardMessages; import descent.internal.ui.wizards.dialogfields.DialogField; import descent.internal.ui.wizards.dialogfields.IDialogFieldListener; import descent.internal.ui.wizards.dialogfields.IStringButtonAdapter; import descent.internal.ui.wizards.dialogfields.LayoutUtil; import descent.internal.ui.wizards.dialogfields.SelectionButtonDialogField; import descent.internal.ui.wizards.dialogfields.StringButtonDialogField; /** * UI to set the source attachment archive and root. * Same implementation for both setting attachments for libraries from * variable entries and for normal (internal or external) jar. */ public class SourceAttachmentBlock { private IStatusChangeListener fContext; private StringButtonDialogField fFileNameField; private SelectionButtonDialogField fWorkspaceButton; private SelectionButtonDialogField fExternalFolderButton; private IStatus fNameStatus; /** * The path to which the archive variable points. * Null if invalid path or not resolvable. Must not exist. */ private IPath fFileVariablePath; private IWorkspaceRoot fWorkspaceRoot; private Control fSWTWidget; private Label fFullPathResolvedLabel; private IJavaProject fProject; private IClasspathEntry fEntry; private IPath fContainerPath; /** * @param context listeners for status updates * @param entry The entry to edit */ public SourceAttachmentBlock(IStatusChangeListener context, IClasspathEntry entry) { Assert.isNotNull(entry); fContext = context; fEntry = entry; int kind = entry.getEntryKind(); Assert.isTrue(kind == IClasspathEntry.CPE_LIBRARY || kind == IClasspathEntry.CPE_VARIABLE); fWorkspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); fNameStatus = new StatusInfo(); SourceAttachmentAdapter adapter = new SourceAttachmentAdapter(); // create the dialog fields (no widgets yet) if (isVariableEntry()) { fFileNameField = new VariablePathDialogField(adapter); fFileNameField.setDialogFieldListener(adapter); fFileNameField.setLabelText(NewWizardMessages.SourceAttachmentBlock_filename_varlabel); fFileNameField.setButtonLabel(NewWizardMessages.SourceAttachmentBlock_filename_external_varbutton); ((VariablePathDialogField) fFileNameField) .setVariableButtonLabel(NewWizardMessages.SourceAttachmentBlock_filename_variable_button); } else { fFileNameField = new StringButtonDialogField(adapter); fFileNameField.setDialogFieldListener(adapter); fFileNameField.setLabelText(NewWizardMessages.SourceAttachmentBlock_filename_label); fFileNameField.setButtonLabel(NewWizardMessages.SourceAttachmentBlock_filename_externalfile_button); fWorkspaceButton = new SelectionButtonDialogField(SWT.PUSH); fWorkspaceButton.setDialogFieldListener(adapter); fWorkspaceButton.setLabelText(NewWizardMessages.SourceAttachmentBlock_filename_internal_button); fExternalFolderButton = new SelectionButtonDialogField(SWT.PUSH); fExternalFolderButton.setDialogFieldListener(adapter); fExternalFolderButton .setLabelText(NewWizardMessages.SourceAttachmentBlock_filename_externalfolder_button); } // set the old settings setDefaults(); } /** * @deprecated Use API {@link descent.ui.wizards.BuildPathDialogAccess#configureSourceAttachment(Shell, IClasspathEntry)} */ public SourceAttachmentBlock(IStatusChangeListener context, IClasspathEntry entry, IPath containerPath, IJavaProject project) { this(context, entry); fContainerPath = containerPath; fProject = project; } public void setDefaults() { if (fEntry.getSourceAttachmentPath() != null) { fFileNameField.setText(fEntry.getSourceAttachmentPath().toString()); } else { fFileNameField.setText(""); //$NON-NLS-1$ } } private boolean isVariableEntry() { return fEntry.getEntryKind() == IClasspathEntry.CPE_VARIABLE; } /** * Gets the source attachment path chosen by the user */ public IPath getSourceAttachmentPath() { if (fFileNameField.getText().length() == 0) { return null; } return getFilePath(); } /** * Gets the source attachment root chosen by the user * Returns null to let JCore automatically detect the root. */ public IPath getSourceAttachmentRootPath() { return null; } public IClasspathEntry getNewEntry() { CPListElement elem = CPListElement.createFromExisting(fEntry, fProject); elem.setAttribute(CPListElement.SOURCEATTACHMENT, getSourceAttachmentPath()); return elem.getClasspathEntry(); } /** * Creates the control */ public Control createControl(Composite parent) { PixelConverter converter = new PixelConverter(parent); fSWTWidget = parent; Composite composite = new Composite(parent, SWT.NONE); GridLayout layout = new GridLayout(); layout.marginHeight = 0; layout.marginWidth = 0; layout.numColumns = 4; composite.setLayout(layout); if (isVariableEntry()) { int widthHint = converter.convertWidthInCharsToPixels(50); Label message = new Label(composite, SWT.WRAP); GridData gd = new GridData(GridData.FILL, GridData.BEGINNING, false, false, 4, 1); gd.widthHint = widthHint; message.setLayoutData(gd); message.setText(Messages.format(NewWizardMessages.SourceAttachmentBlock_message, fEntry.getPath().lastSegment())); //DialogField.createEmptySpace(composite, 1); Label desc = new Label(composite, SWT.WRAP); gd = new GridData(GridData.FILL, GridData.BEGINNING, false, false, 4, 1); gd.widthHint = widthHint; desc.setLayoutData(gd); desc.setText(NewWizardMessages.SourceAttachmentBlock_filename_description); fFileNameField.doFillIntoGrid(composite, 4); LayoutUtil.setWidthHint(fFileNameField.getTextControl(null), widthHint); // label that shows the resolved path for variable jars //DialogField.createEmptySpace(composite, 1); fFullPathResolvedLabel = new Label(composite, SWT.WRAP); fFullPathResolvedLabel.setText(getResolvedLabelString()); gd = new GridData(GridData.FILL, GridData.BEGINNING, false, false, 4, 1); gd.widthHint = widthHint; fFullPathResolvedLabel.setLayoutData(gd); LayoutUtil.setHorizontalGrabbing(fFileNameField.getTextControl(null)); } else { int widthHint = converter.convertWidthInCharsToPixels(60); GridData gd = new GridData(GridData.FILL, GridData.BEGINNING, false, false, 3, 1); gd.widthHint = converter.convertWidthInCharsToPixels(50); Label message = new Label(composite, SWT.LEFT + SWT.WRAP); message.setLayoutData(gd); message.setText(Messages.format(NewWizardMessages.SourceAttachmentBlock_message, fEntry.getPath().lastSegment())); fWorkspaceButton.doFillIntoGrid(composite, 1); ((GridData) fWorkspaceButton.getSelectionButton(null).getLayoutData()).verticalAlignment = SWT.END; // archive name field fFileNameField.doFillIntoGrid(composite, 4); LayoutUtil.setWidthHint(fFileNameField.getTextControl(null), widthHint); LayoutUtil.setHorizontalGrabbing(fFileNameField.getTextControl(null)); // aditional 'browse workspace' button for normal jars DialogField.createEmptySpace(composite, 3); fExternalFolderButton.doFillIntoGrid(composite, 1); } fFileNameField.postSetFocusOnDialogField(parent.getDisplay()); Dialog.applyDialogFont(composite); PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, IJavaHelpContextIds.SOURCE_ATTACHMENT_BLOCK); return composite; } private class SourceAttachmentAdapter implements IStringButtonAdapter, IDialogFieldListener { // -------- IStringButtonAdapter -------- public void changeControlPressed(DialogField field) { attachmentChangeControlPressed(field); } // ---------- IDialogFieldListener -------- public void dialogFieldChanged(DialogField field) { attachmentDialogFieldChanged(field); } } private void attachmentChangeControlPressed(DialogField field) { if (field == fFileNameField) { IPath jarFilePath = isVariableEntry() ? chooseExtension() : chooseExtJarFile(); if (jarFilePath != null) { fFileNameField.setText(jarFilePath.toString()); } } } // ---------- IDialogFieldListener -------- private void attachmentDialogFieldChanged(DialogField field) { if (field == fFileNameField) { fNameStatus = updateFileNameStatus(); } else if (field == fWorkspaceButton) { IPath jarFilePath = chooseInternal(); if (jarFilePath != null) { fFileNameField.setText(jarFilePath.toString()); } return; } else if (field == fExternalFolderButton) { IPath folderPath = chooseExtFolder(); if (folderPath != null) { fFileNameField.setText(folderPath.toString()); } return; } doStatusLineUpdate(); } private void doStatusLineUpdate() { fFileNameField.enableButton(canBrowseFileName()); // set the resolved path for variable jars if (fFullPathResolvedLabel != null) { fFullPathResolvedLabel.setText(getResolvedLabelString()); } IStatus status = StatusUtil.getMostSevere(new IStatus[] { fNameStatus }); fContext.statusChanged(status); } private boolean canBrowseFileName() { if (!isVariableEntry()) { return true; } // to browse with a variable JAR, the variable name must point to a directory if (fFileVariablePath != null) { return fFileVariablePath.toFile().isDirectory(); } return false; } private String getResolvedLabelString() { IPath resolvedPath = getResolvedPath(getFilePath()); if (resolvedPath != null) { return resolvedPath.toOSString(); } return ""; //$NON-NLS-1$ } private IPath getResolvedPath(IPath path) { if (path != null) { String varName = path.segment(0); if (varName != null) { IPath varPath = JavaCore.getClasspathVariable(varName); if (varPath != null) { return varPath.append(path.removeFirstSegments(1)); } } } return null; } private IStatus updateFileNameStatus() { StatusInfo status = new StatusInfo(); fFileVariablePath = null; String fileName = fFileNameField.getText(); if (fileName.length() == 0) { // no source attachment return status; } else { if (!Path.EMPTY.isValidPath(fileName)) { status.setError(NewWizardMessages.SourceAttachmentBlock_filename_error_notvalid); return status; } IPath filePath = Path.fromOSString(fileName); IPath resolvedPath; if (isVariableEntry()) { if (filePath.getDevice() != null) { status.setError(NewWizardMessages.SourceAttachmentBlock_filename_error_deviceinpath); return status; } String varName = filePath.segment(0); if (varName == null) { status.setError(NewWizardMessages.SourceAttachmentBlock_filename_error_notvalid); return status; } fFileVariablePath = JavaCore.getClasspathVariable(varName); if (fFileVariablePath == null) { status.setError(NewWizardMessages.SourceAttachmentBlock_filename_error_varnotexists); return status; } resolvedPath = fFileVariablePath.append(filePath.removeFirstSegments(1)); if (resolvedPath.isEmpty()) { status.setWarning(NewWizardMessages.SourceAttachmentBlock_filename_warning_varempty); return status; } File file = resolvedPath.toFile(); if (!file.exists()) { String message = Messages.format( NewWizardMessages.SourceAttachmentBlock_filename_error_filenotexists, resolvedPath.toOSString()); status.setWarning(message); return status; } if (!resolvedPath.isAbsolute()) { String message = Messages.format( NewWizardMessages.SourceAttachmentBlock_filename_error_notabsolute, filePath.toString()); status.setError(message); return status; } } else { // JDT/Core only supports source attachments in archives on the // local file system. So using getLocation is save here. File file = filePath.toFile(); IResource res = fWorkspaceRoot.findMember(filePath); if (res != null && res.getLocation() != null) { file = res.getLocation().toFile(); } if (!file.exists()) { String message = Messages.format( NewWizardMessages.SourceAttachmentBlock_filename_error_filenotexists, filePath.toString()); status.setError(message); return status; } if (res == null) { if (!filePath.isAbsolute()) { String message = Messages.format( NewWizardMessages.SourceAttachmentBlock_filename_error_notabsolute, filePath.toString()); status.setError(message); return status; } } } } return status; } private IPath getFilePath() { return Path.fromOSString(fFileNameField.getText()).makeAbsolute(); } private IPath chooseExtension() { /* TODO JDT jar IPath currPath= getFilePath(); if (currPath.segmentCount() == 0) { currPath= fEntry.getPath(); } IPath resolvedPath= getResolvedPath(currPath); File initialSelection= resolvedPath != null ? resolvedPath.toFile() : null; String currVariable= currPath.segment(0); JARFileSelectionDialog dialog= new JARFileSelectionDialog(getShell(), false, true); dialog.setTitle(NewWizardMessages.SourceAttachmentBlock_extvardialog_title); dialog.setMessage(NewWizardMessages.SourceAttachmentBlock_extvardialog_description); dialog.setInput(fFileVariablePath.toFile()); dialog.setInitialSelection(initialSelection); if (dialog.open() == Window.OK) { File result= (File) dialog.getResult()[0]; IPath returnPath= Path.fromOSString(result.getPath()).makeAbsolute(); return modifyPath(returnPath, currVariable); } */ return null; } /* * Opens a dialog to choose a jar from the file system. */ private IPath chooseExtJarFile() { IPath currPath = getFilePath(); if (currPath.segmentCount() == 0) { currPath = fEntry.getPath(); } if (ArchiveFileFilter.isArchivePath(currPath)) { currPath = currPath.removeLastSegments(1); } FileDialog dialog = new FileDialog(getShell()); dialog.setText(NewWizardMessages.SourceAttachmentBlock_extjardialog_text); dialog.setFilterExtensions(new String[] { "*.jar;*.zip" }); //$NON-NLS-1$ dialog.setFilterPath(currPath.toOSString()); String res = dialog.open(); if (res != null) { return Path.fromOSString(res).makeAbsolute(); } return null; } private IPath chooseExtFolder() { IPath currPath = getFilePath(); if (currPath.segmentCount() == 0) { currPath = fEntry.getPath(); } if (ArchiveFileFilter.isArchivePath(currPath)) { currPath = currPath.removeLastSegments(1); } DirectoryDialog dialog = new DirectoryDialog(getShell()); dialog.setMessage(NewWizardMessages.SourceAttachmentBlock_extfolderdialog_message); dialog.setText(NewWizardMessages.SourceAttachmentBlock_extfolderdialog_text); dialog.setFilterPath(currPath.toOSString()); String res = dialog.open(); if (res != null) { return Path.fromOSString(res).makeAbsolute(); } return null; } /* * Opens a dialog to choose an internal jar. */ private IPath chooseInternal() { String initSelection = fFileNameField.getText(); ViewerFilter filter = new ArchiveFileFilter((List) null, false); ILabelProvider lp = new WorkbenchLabelProvider(); ITreeContentProvider cp = new WorkbenchContentProvider(); IResource initSel = null; if (initSelection.length() > 0) { initSel = fWorkspaceRoot.findMember(new Path(initSelection)); } if (initSel == null) { initSel = fWorkspaceRoot.findMember(fEntry.getPath()); } FolderSelectionDialog dialog = new FolderSelectionDialog(getShell(), lp, cp); dialog.setAllowMultiple(false); dialog.addFilter(filter); dialog.setTitle(NewWizardMessages.SourceAttachmentBlock_intjardialog_title); dialog.setMessage(NewWizardMessages.SourceAttachmentBlock_intjardialog_message); dialog.setInput(fWorkspaceRoot); dialog.setInitialSelection(initSel); if (dialog.open() == Window.OK) { IResource res = (IResource) dialog.getFirstResult(); return res.getFullPath(); } return null; } private Shell getShell() { if (fSWTWidget != null) { return fSWTWidget.getShell(); } return JavaPlugin.getActiveWorkbenchShell(); } /** * Takes a path and replaces the beginning with a variable name * (if the beginning matches with the variables value) */ private IPath modifyPath(IPath path, String varName) { if (varName == null || path == null) { return null; } if (path.isEmpty()) { return new Path(varName); } IPath varPath = JavaCore.getClasspathVariable(varName); if (varPath != null) { if (varPath.isPrefixOf(path)) { path = path.removeFirstSegments(varPath.segmentCount()); } else { path = new Path(path.lastSegment()); } } else { path = new Path(path.lastSegment()); } return new Path(varName).append(path); } /** * Creates a runnable that sets the source attachment by modifying the project's classpath. */ public static IRunnableWithProgress getRunnable(final Shell shell, final IClasspathEntry newEntry, final IJavaProject jproject, final IPath containerPath) { return new IRunnableWithProgress() { public void run(IProgressMonitor monitor) throws InvocationTargetException { try { String[] changedAttributes = { CPListElement.SOURCEATTACHMENT }; BuildPathSupport.modifyClasspathEntry(shell, newEntry, changedAttributes, jproject, containerPath, monitor); } catch (CoreException e) { throw new InvocationTargetException(e); } } }; } /** * @deprecated Use {@link #getRunnable(Shell, IClasspathEntry, IJavaProject, IPath)} */ public IRunnableWithProgress getRunnable(final Shell shell) { return getRunnable(shell, getNewEntry(), fProject, fContainerPath); } }