/******************************************************************************* * Copyright (c) 2000, 2010 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 org.eclipse.jdt.ui.wizards; import java.lang.reflect.InvocationTargetException; import java.net.URI; 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.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.core.filesystem.EFS; import org.eclipse.core.filesystem.IFileStore; 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.NullProgressMonitor; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.ui.PlatformUI; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.JavaConventions; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.internal.corext.util.JavaConventionsUtil; import org.eclipse.jdt.internal.corext.util.Messages; import org.eclipse.jdt.internal.ui.IJavaHelpContextIds; import org.eclipse.jdt.internal.ui.JavaPlugin; import org.eclipse.jdt.internal.ui.dialogs.StatusInfo; import org.eclipse.jdt.internal.ui.dialogs.TextFieldNavigationHandler; import org.eclipse.jdt.internal.ui.wizards.NewWizardMessages; import org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField; import org.eclipse.jdt.internal.ui.wizards.dialogfields.IDialogFieldListener; import org.eclipse.jdt.internal.ui.wizards.dialogfields.LayoutUtil; import org.eclipse.jdt.internal.ui.wizards.dialogfields.StringDialogField; /** * Wizard page to create a new package. * * <p> * Note: This class is not intended to be subclassed, but clients can instantiate. * To implement a different kind of a new package wizard page, extend <code>NewContainerWizardPage</code>. * </p> * * @since 2.0 * * @noextend This class is not intended to be subclassed by clients. */ public class NewPackageWizardPage extends NewContainerWizardPage { private static final String PAGE_NAME= "NewPackageWizardPage"; //$NON-NLS-1$ private static final String PACKAGE= "NewPackageWizardPage.package"; //$NON-NLS-1$ private StringDialogField fPackageDialogField; /* * Status of last validation of the package field */ private IStatus fPackageStatus; private IPackageFragment fCreatedPackageFragment; /** * Creates a new <code>NewPackageWizardPage</code> */ public NewPackageWizardPage() { super(PAGE_NAME); setTitle(NewWizardMessages.NewPackageWizardPage_title); setDescription(NewWizardMessages.NewPackageWizardPage_description); fCreatedPackageFragment= null; PackageFieldAdapter adapter= new PackageFieldAdapter(); fPackageDialogField= new StringDialogField(); fPackageDialogField.setDialogFieldListener(adapter); fPackageDialogField.setLabelText(NewWizardMessages.NewPackageWizardPage_package_label); fPackageStatus= new StatusInfo(); } // -------- Initialization --------- /** * The wizard owning this page is responsible for calling this method with the * current selection. The selection is used to initialize the fields of the wizard * page. * * @param selection used to initialize the fields */ public void init(IStructuredSelection selection) { IJavaElement jelem= getInitialJavaElement(selection); initContainerPage(jelem); String pName= ""; //$NON-NLS-1$ if (jelem != null) { IPackageFragment pf= (IPackageFragment) jelem.getAncestor(IJavaElement.PACKAGE_FRAGMENT); if (pf != null && !pf.isDefaultPackage()) pName= pf.getElementName(); } setPackageText(pName, true); updateStatus(new IStatus[] { fContainerStatus, fPackageStatus }); } // -------- UI Creation --------- /* * @see WizardPage#createControl */ public void createControl(Composite parent) { initializeDialogUnits(parent); Composite composite= new Composite(parent, SWT.NONE); composite.setFont(parent.getFont()); int nColumns= 3; GridLayout layout= new GridLayout(); layout.numColumns= 3; composite.setLayout(layout); Label label= new Label(composite, SWT.WRAP); label.setText(NewWizardMessages.NewPackageWizardPage_info); GridData gd= new GridData(); gd.widthHint= convertWidthInCharsToPixels(60); gd.horizontalSpan= 3; label.setLayoutData(gd); createContainerControls(composite, nColumns); createPackageControls(composite, nColumns); setControl(composite); Dialog.applyDialogFont(composite); PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, IJavaHelpContextIds.NEW_PACKAGE_WIZARD_PAGE); } /** * @see org.eclipse.jface.dialogs.IDialogPage#setVisible(boolean) */ public void setVisible(boolean visible) { super.setVisible(visible); if (visible) { setFocus(); } } /** * Sets the focus to the package name input field. */ protected void setFocus() { fPackageDialogField.setFocus(); } private void createPackageControls(Composite composite, int nColumns) { fPackageDialogField.doFillIntoGrid(composite, nColumns - 1); Text text= fPackageDialogField.getTextControl(null); LayoutUtil.setWidthHint(text, getMaxFieldWidth()); LayoutUtil.setHorizontalGrabbing(text); DialogField.createEmptySpace(composite); TextFieldNavigationHandler.install(text); } // -------- PackageFieldAdapter -------- private class PackageFieldAdapter implements IDialogFieldListener { // --------- IDialogFieldListener public void dialogFieldChanged(DialogField field) { fPackageStatus= packageChanged(); // tell all others handleFieldChanged(PACKAGE); } } // -------- update message ---------------- /* * @see org.eclipse.jdt.ui.wizards.NewContainerWizardPage#handleFieldChanged(String) */ protected void handleFieldChanged(String fieldName) { super.handleFieldChanged(fieldName); if (fieldName == CONTAINER) { fPackageStatus= packageChanged(); } // do status line update updateStatus(new IStatus[] { fContainerStatus, fPackageStatus }); } // ----------- validation ---------- private IStatus validatePackageName(String text) { IJavaProject project= getJavaProject(); if (project == null || !project.exists()) { return JavaConventions.validatePackageName(text, JavaCore.VERSION_1_3, JavaCore.VERSION_1_3); } return JavaConventionsUtil.validatePackageName(text, project); } /* * Verifies the input for the package field. */ private IStatus packageChanged() { StatusInfo status= new StatusInfo(); String packName= getPackageText(); if (packName.length() > 0) { IStatus val= validatePackageName(packName); if (val.getSeverity() == IStatus.ERROR) { status.setError(Messages.format(NewWizardMessages.NewPackageWizardPage_error_InvalidPackageName, val.getMessage())); return status; } else if (val.getSeverity() == IStatus.WARNING) { status.setWarning(Messages.format(NewWizardMessages.NewPackageWizardPage_warning_DiscouragedPackageName, val.getMessage())); } } else { status.setError(NewWizardMessages.NewPackageWizardPage_error_EnterName); return status; } IPackageFragmentRoot root= getPackageFragmentRoot(); if (root != null && root.getJavaProject().exists()) { IPackageFragment pack= root.getPackageFragment(packName); try { IPath rootPath= root.getPath(); IPath outputPath= root.getJavaProject().getOutputLocation(); if (rootPath.isPrefixOf(outputPath) && !rootPath.equals(outputPath)) { // if the bin folder is inside of our root, don't allow to name a package // like the bin folder IPath packagePath= pack.getPath(); if (outputPath.isPrefixOf(packagePath)) { status.setError(NewWizardMessages.NewPackageWizardPage_error_IsOutputFolder); return status; } } if (pack.exists()) { if (pack.containsJavaResources() || !pack.hasSubpackages()) { status.setError(NewWizardMessages.NewPackageWizardPage_error_PackageExists); } else { status.setError(NewWizardMessages.NewPackageWizardPage_error_PackageNotShown); } } else { IResource resource= pack.getResource(); if (resource != null && !ResourcesPlugin.getWorkspace().validateFiltered(resource).isOK()) { status.setError(NewWizardMessages.NewPackageWizardPage_error_PackageNameFiltered); return status; } URI location= pack.getResource().getLocationURI(); if (location != null) { IFileStore store= EFS.getStore(location); if (store.fetchInfo().exists()) { status.setError(NewWizardMessages.NewPackageWizardPage_error_PackageExistsDifferentCase); } } } } catch (CoreException e) { JavaPlugin.log(e); } } return status; } /** * Returns the content of the package input field. * * @return the content of the package input field */ public String getPackageText() { return fPackageDialogField.getText(); } /** * Sets the content of the package input field to the given value. * * @param str the new package input field text * @param canBeModified if <code>true</code> the package input * field can be modified; otherwise it is read-only. */ public void setPackageText(String str, boolean canBeModified) { fPackageDialogField.setText(str); fPackageDialogField.setEnabled(canBeModified); } /** * Returns the resource handle that corresponds to the element to was created or * will be created. * @return A resource or null if the page contains illegal values. * @since 3.0 */ public IResource getModifiedResource() { IPackageFragmentRoot root= getPackageFragmentRoot(); if (root != null) { return root.getPackageFragment(getPackageText()).getResource(); } return null; } // ---- creation ---------------- /** * Returns a runnable that creates a package using the current settings. * * @return the runnable that creates the new package */ public IRunnableWithProgress getRunnable() { return new IRunnableWithProgress() { public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { try { createPackage(monitor); } catch (CoreException e) { throw new InvocationTargetException(e); } } }; } /** * Returns the created package fragment. This method only returns a valid value * after <code>getRunnable</code> or <code>createPackage</code> have been * executed. * * @return the created package fragment */ public IPackageFragment getNewPackageFragment() { return fCreatedPackageFragment; } /** * Creates the new package using the entered field values. * * @param monitor a progress monitor to report progress. The progress * monitor must not be <code>null</code> * @throws CoreException Thrown if creating the package failed. * @throws InterruptedException Thrown when the operation has been canceled. * @since 2.1 */ public void createPackage(IProgressMonitor monitor) throws CoreException, InterruptedException { if (monitor == null) { monitor= new NullProgressMonitor(); } IPackageFragmentRoot root= getPackageFragmentRoot(); String packName= getPackageText(); fCreatedPackageFragment= root.createPackageFragment(packName, true, monitor); if (monitor.isCanceled()) { throw new InterruptedException(); } } }