Package ccw.leiningen

Source Code of ccw.leiningen.NewLeiningenProjectWizard

/*******************************************************************************
* Copyright (c) 2000, 2008 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
*     Remy Chi Jian Suen <remy.suen@gmail.com>
*         - Bug 44162 [Wizards]  Define constants for wizard ids of new.file, new.folder, and new.project
*******************************************************************************/

package ccw.leiningen;

import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;

import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResourceStatus;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExecutableExtension;
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.core.runtime.Status;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.MessageDialogWithToggle;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.osgi.util.NLS;
import org.eclipse.ui.IPerspectiveDescriptor;
import org.eclipse.ui.IPerspectiveRegistry;
import org.eclipse.ui.IPluginContribution;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPreferenceConstants;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.WorkbenchException;
import org.eclipse.ui.activities.IActivityManager;
import org.eclipse.ui.activities.IIdentifier;
import org.eclipse.ui.activities.IWorkbenchActivitySupport;
import org.eclipse.ui.activities.WorkbenchActivityHelper;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.ide.undo.CreateProjectOperation;
import org.eclipse.ui.ide.undo.WorkspaceUndoUtil;
import org.eclipse.ui.internal.IPreferenceConstants;
import org.eclipse.ui.internal.WorkbenchPlugin;
import org.eclipse.ui.internal.ide.IDEInternalPreferences;
import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
import org.eclipse.ui.internal.ide.StatusUtil;
import org.eclipse.ui.internal.registry.PerspectiveDescriptor;
import org.eclipse.ui.internal.util.PrefUtil;
import org.eclipse.ui.internal.wizards.newresource.ResourceMessages;
import org.eclipse.ui.statushandlers.StatusAdapter;
import org.eclipse.ui.statushandlers.StatusManager;
import org.eclipse.ui.wizards.newresource.BasicNewResourceWizard;

import ccw.CCWPlugin;
import ccw.util.ClojureInvoker;

/**
* Standard workbench wizard that creates a new project resource in the
* workspace.
* <p>
* This class may be instantiated and used without further configuration; this
* class is not intended to be subclassed.
* </p>
* <p>
* Example:
*
* <pre>
* IWorkbenchWizard wizard = new BasicNewProjectResourceWizard();
* wizard.init(workbench, selection);
* WizardDialog dialog = new WizardDialog(shell, wizard);
* dialog.open();
* </pre>
*
* During the call to <code>open</code>, the wizard dialog is presented to
* the user. When the user hits Finish, a project resource with the
* user-specified name is created, the dialog closes, and the call to
* <code>open</code> returns.
* </p>
* @noextend This class is not intended to be subclassed by clients.
*/
public class NewLeiningenProjectWizard extends BasicNewResourceWizard
    implements IExecutableExtension {
 
  private static final String performFinish = "perform-finish";

  private final ClojureInvoker wizard = ClojureInvoker.newInvoker(
                                               CCWPlugin.getDefault(),
                                               "ccw.leiningen.wizard");
 
  /**
   * The wizard id for creating new projects in the workspace.
   * @since 3.4
   */
  public static final String WIZARD_ID = "org.eclipse.ui.wizards.new.project"; //$NON-NLS-1$
 
  private WizardNewLeiningenProjectTemplatePage mainPage;

  // cache of newly-created project
  private IProject newProject;

  /**
   * The config element which declares this wizard.
   */
  private IConfigurationElement configElement;

  private static String WINDOW_PROBLEMS_TITLE = ResourceMessages.NewProject_errorOpeningWindow;

  /**
   * Extension attribute name for final perspective.
   */
  private static final String FINAL_PERSPECTIVE = "finalPerspective"; //$NON-NLS-1$

  /**
   * Extension attribute name for preferred perspectives.
   */
  private static final String PREFERRED_PERSPECTIVES = "preferredPerspectives"; //$NON-NLS-1$

  /**
   * Creates a wizard for creating a new project resource in the workspace.
   */
  public NewLeiningenProjectWizard() {
    IDialogSettings workbenchSettings = IDEWorkbenchPlugin.getDefault()
        .getDialogSettings();
    IDialogSettings section = workbenchSettings
        .getSection("BasicNewProjectResourceWizard");//$NON-NLS-1$
    if (section == null) {
      section = workbenchSettings
          .addNewSection("BasicNewProjectResourceWizard");//$NON-NLS-1$
    }
    setDialogSettings(section);
  }

  public void addPages() {
    super.addPages();

    mainPage = new WizardNewLeiningenProjectTemplatePage(this, "basicNewProjectPage");

    this.addPage(mainPage);

    doLeinAddPagesPost();
  }
 
  private void doLeinAddPagesPost() {
    getStartingPage().setDescription("Leverages Leiningen 2.0, the recommended project management tool for Clojure."
        + "\n(Don't wanna use Leiningen? Then simply create a maven/gradle/whatever java project, and add Clojure in its classpath)");
        getStartingPage().setTitle("Clojure project");
        setWindowTitle("New Clojure project");
  }
 

  /**
   * Creates a new project resource with the selected name.
   * <p>
   * In normal usage, this method is invoked after the user has pressed Finish
   * on the wizard; the enablement of the Finish button implies that all
   * controls on the pages currently contain valid values.
   * </p>
   * <p>
   * Note that this wizard caches the new project once it has been
   * successfully created; subsequent invocations of this method will answer
   * the same project resource without attempting to create it again.
   * </p>
   *
   * @return the created project resource, or <code>null</code> if the
   *         project was not created
   */
  private IProject createNewProject() {
    if (newProject != null) {
      return newProject;
    }

    // get a project handle
    final IProject newProjectHandle = mainPage.getProjectHandle();

    // get a project descriptor
    URI location = mainPage.getLocationURI();
   
    // Fix before calling Eclipse CreateProjectOperation:
    // if the location manually selected by the user matches our project
    // location (or if she unchecked 'Create in:' and did not change the
    // default location), we must reset location to null
    if (location != null) {
      IPath defaultProjectPath = newProjectHandle.getWorkspace().getRoot().getLocation().append(newProjectHandle.getName());
      if (location.getPath().equals(defaultProjectPath.toOSString())) {
        location = null;
      }
    }

    IWorkspace workspace = ResourcesPlugin.getWorkspace();
    final IProjectDescription description = workspace
        .newProjectDescription(newProjectHandle.getName());
    description.setLocationURI(location);

    // create the new project operation
    IRunnableWithProgress op = new IRunnableWithProgress() {
      public void run(IProgressMonitor monitor)
          throws InvocationTargetException {
        CreateProjectOperation op = new CreateProjectOperation(
            description, ResourceMessages.NewProject_windowTitle);
        try {
          // see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=219901
          // directly execute the operation so that the undo state is
          // not preserved.  Making this undoable resulted in too many
          // accidental file deletions.
          op.execute(monitor, WorkspaceUndoUtil
            .getUIInfoAdapter(getShell()));
        } catch (ExecutionException e) {
          throw new InvocationTargetException(e);
        }
      }
    };

    // run the new project creation operation
    try {
      getContainer().run(true, true, op);
    } catch (InterruptedException e) {
      return null;
    } catch (InvocationTargetException e) {
      Throwable t = e.getTargetException();
      if (t instanceof ExecutionException
          && t.getCause() instanceof CoreException) {
        CoreException cause = (CoreException) t.getCause();
        StatusAdapter status;
        if (cause.getStatus().getCode() == IResourceStatus.CASE_VARIANT_EXISTS) {
          status = new StatusAdapter(
              StatusUtil
                  .newStatus(
                      IStatus.WARNING,
                      NLS
                          .bind(
                              ResourceMessages.NewProject_caseVariantExistsError,
                              newProjectHandle
                                  .getName()),
                      cause));
        } else {
          status = new StatusAdapter(StatusUtil.newStatus(cause
              .getStatus().getSeverity(),
              ResourceMessages.NewProject_errorMessage, cause));
        }
        status.setProperty(StatusAdapter.TITLE_PROPERTY,
            ResourceMessages.NewProject_errorMessage);
        StatusManager.getManager().handle(status, StatusManager.BLOCK);
      } else {
        StatusAdapter status = new StatusAdapter(new Status(
            IStatus.WARNING, IDEWorkbenchPlugin.IDE_WORKBENCH, 0,
            NLS.bind(ResourceMessages.NewProject_internalError, t
                .getMessage()), t));
        status.setProperty(StatusAdapter.TITLE_PROPERTY,
            ResourceMessages.NewProject_errorMessage);
        StatusManager.getManager().handle(status,
            StatusManager.LOG | StatusManager.BLOCK);
      }
      return null;
    }

    newProject = newProjectHandle;

    return newProject;
  }

  /**
   * Returns the newly created project.
   *
   * @return the created project, or <code>null</code> if project not
   *         created
   */
  public IProject getNewProject() {
    return newProject;
  }

  public void init(IWorkbench workbench, IStructuredSelection currentSelection) {
    super.init(workbench, currentSelection);
    setNeedsProgressMonitor(true);
    setWindowTitle(ResourceMessages.NewProject_windowTitle);
  }

  protected void initializeDefaultPageImageDescriptor() {
    ImageDescriptor desc = IDEWorkbenchPlugin
        .getIDEImageDescriptor("wizban/newprj_wiz.png");//$NON-NLS-1$
    setDefaultPageImageDescriptor(desc);
  }

  private static void openInNewWindow(IPerspectiveDescriptor desc) {

    // Open the page.
    try {
      PlatformUI.getWorkbench().openWorkbenchWindow(desc.getId(),
          ResourcesPlugin.getWorkspace().getRoot());
    } catch (WorkbenchException e) {
      IWorkbenchWindow window = PlatformUI.getWorkbench()
          .getActiveWorkbenchWindow();
      if (window != null) {
        ErrorDialog.openError(window.getShell(), WINDOW_PROBLEMS_TITLE,
            e.getMessage(), e.getStatus());
      }
    }
  }

  public boolean performFinish() {
    if (newProjectWizardPerformFinish()) {
      return doPerformFinish();
    } else {
      return false;
    }
  }

  private boolean doPerformFinish() {
    IProject project = getNewProject();

    try {
      wizard._(performFinish,
           mainPage.getLeiningenProjectName(),
           project,
           mainPage.computeTemplateName(),
           mainPage.computeTemplateArgs());
      return true;
    } catch (Exception e) {
      CCWPlugin.logError("Error while creating new project " + project.getName(), e);
      Throwable t = e;
      while (t.getCause() != null) t = t.getCause();
      ErrorDialog.openError(getShell(),
          "Exception while creating new project",
          t.getMessage(),
          CCWPlugin.createErrorStatus("Exception while creating new project", t));
      return false;
    }
  }

  private boolean newProjectWizardPerformFinish() {
    createNewProject();

    if (newProject == null) {
      return false;
    }
   
    // Add project to current WorkingSet
    IWorkingSet[] workingSets = getWorkbench().getWorkingSetManager().getWorkingSets();
    if (workingSets != null && workingSets.length > 0) {
      getWorkbench()
          .getWorkingSetManager()
          .addToWorkingSets(
              newProject,
          workingSets);
    }
       
    updatePerspective();
    selectAndReveal(newProject);

    return true;
  }

  private static void replaceCurrentPerspective(IPerspectiveDescriptor persp) {

    // Get the active page.
    IWorkbenchWindow window = PlatformUI.getWorkbench()
        .getActiveWorkbenchWindow();
    if (window == null) {
      return;
    }
    IWorkbenchPage page = window.getActivePage();
    if (page == null) {
      return;
    }

    // Set the perspective.
    page.setPerspective(persp);
  }

  /**
   * Stores the configuration element for the wizard. The config element will
   * be used in <code>performFinish</code> to set the result perspective.
   */
  public void setInitializationData(IConfigurationElement cfig,
      String propertyName, Object data) {
    configElement = cfig;
  }

  /**
   * Updates the perspective for the active page within the window.
   */
  protected void updatePerspective() {
    updatePerspective(configElement);
  }

  /**
   * Updates the perspective based on the current settings in the
   * Workbench/Perspectives preference page.
   *
   * Use the setting for the new perspective opening if we are set to open in
   * a new perspective.
   * <p>
   * A new project wizard class will need to implement the
   * <code>IExecutableExtension</code> interface so as to gain access to the
   * wizard's <code>IConfigurationElement</code>. That is the configuration
   * element to pass into this method.
   * </p>
   *
   * @param configElement -
   *            the element we are updating with
   *
   * @see IPreferenceConstants#OPM_NEW_WINDOW
   * @see IPreferenceConstants#OPM_ACTIVE_PAGE
   * @see IWorkbenchPreferenceConstants#NO_NEW_PERSPECTIVE
   */
  public static void updatePerspective(IConfigurationElement configElement) {
    // Do not change perspective if the configuration element is
    // not specified.
    if (configElement == null) {
      return;
    }

    // Retrieve the new project open perspective preference setting
    String perspSetting = PrefUtil.getAPIPreferenceStore().getString(
        IDE.Preferences.PROJECT_OPEN_NEW_PERSPECTIVE);

    String promptSetting = IDEWorkbenchPlugin.getDefault()
        .getPreferenceStore().getString(
            IDEInternalPreferences.PROJECT_SWITCH_PERSP_MODE);

    // Return if do not switch perspective setting and are not prompting
    if (!(promptSetting.equals(MessageDialogWithToggle.PROMPT))
        && perspSetting
            .equals(IWorkbenchPreferenceConstants.NO_NEW_PERSPECTIVE)) {
      return;
    }

    // Read the requested perspective id to be opened.
    String finalPerspId = configElement.getAttribute(FINAL_PERSPECTIVE);
    if (finalPerspId == null) {
      return;
    }

    // Map perspective id to descriptor.
    IPerspectiveRegistry reg = PlatformUI.getWorkbench()
        .getPerspectiveRegistry();

    // leave this code in - the perspective of a given project may map to
    // activities other than those that the wizard itself maps to.
    IPerspectiveDescriptor finalPersp = reg
        .findPerspectiveWithId(finalPerspId);
    if (finalPersp != null && finalPersp instanceof IPluginContribution) {
      IPluginContribution contribution = (IPluginContribution) finalPersp;
      if (contribution.getPluginId() != null) {
        IWorkbenchActivitySupport workbenchActivitySupport = PlatformUI
            .getWorkbench().getActivitySupport();
        IActivityManager activityManager = workbenchActivitySupport
            .getActivityManager();
        IIdentifier identifier = activityManager
            .getIdentifier(WorkbenchActivityHelper
                .createUnifiedId(contribution));
        Set idActivities = identifier.getActivityIds();

        if (!idActivities.isEmpty()) {
          Set enabledIds = new HashSet(activityManager
              .getEnabledActivityIds());

          if (enabledIds.addAll(idActivities)) {
            workbenchActivitySupport
                .setEnabledActivityIds(enabledIds);
          }
        }
      }
    } else {
      IDEWorkbenchPlugin.log("Unable to find perspective " //$NON-NLS-1$
          + finalPerspId
          + " in BasicNewProjectResourceWizard.updatePerspective"); //$NON-NLS-1$
      return;
    }

    // gather the preferred perspectives
    // always consider the final perspective (and those derived from it)
    // to be preferred
    ArrayList preferredPerspIds = new ArrayList();
    addPerspectiveAndDescendants(preferredPerspIds, finalPerspId);
    String preferred = configElement.getAttribute(PREFERRED_PERSPECTIVES);
    if (preferred != null) {
      StringTokenizer tok = new StringTokenizer(preferred, " \t\n\r\f,"); //$NON-NLS-1$
      while (tok.hasMoreTokens()) {
        addPerspectiveAndDescendants(preferredPerspIds, tok.nextToken());
      }
    }

    IWorkbenchWindow window = PlatformUI.getWorkbench()
        .getActiveWorkbenchWindow();
    if (window != null) {
      IWorkbenchPage page = window.getActivePage();
      if (page != null) {
        IPerspectiveDescriptor currentPersp = page.getPerspective();

        // don't switch if the current perspective is a preferred
        // perspective
        if (currentPersp != null
            && preferredPerspIds.contains(currentPersp.getId())) {
          return;
        }
      }

      // prompt the user to switch
      if (!confirmPerspectiveSwitch(window, finalPersp)) {
        return;
      }
    }

    int workbenchPerspectiveSetting = WorkbenchPlugin.getDefault()
        .getPreferenceStore().getInt(
            IPreferenceConstants.OPEN_PERSP_MODE);

    // open perspective in new window setting
    if (workbenchPerspectiveSetting == IPreferenceConstants.OPM_NEW_WINDOW) {
      openInNewWindow(finalPersp);
      return;
    }

    // replace active perspective setting otherwise
    replaceCurrentPerspective(finalPersp);
  }

  /**
   * Adds to the list all perspective IDs in the Workbench who's original ID
   * matches the given ID.
   *
   * @param perspectiveIds
   *            the list of perspective IDs to supplement.
   * @param id
   *            the id to query.
   * @since 3.0
   */
  private static void addPerspectiveAndDescendants(List perspectiveIds,
      String id) {
    IPerspectiveRegistry registry = PlatformUI.getWorkbench()
        .getPerspectiveRegistry();
    IPerspectiveDescriptor[] perspectives = registry.getPerspectives();
    for (int i = 0; i < perspectives.length; i++) {
      // @issue illegal ref to workbench internal class;
      // consider adding getOriginalId() as API on IPerspectiveDescriptor
      PerspectiveDescriptor descriptor = ((PerspectiveDescriptor) perspectives[i]);
      if (descriptor.getOriginalId().equals(id)) {
        perspectiveIds.add(descriptor.getId());
      }
    }
  }

  /**
   * Prompts the user for whether to switch perspectives.
   *
   * @param window
   *            The workbench window in which to switch perspectives; must not
   *            be <code>null</code>
   * @param finalPersp
   *            The perspective to switch to; must not be <code>null</code>.
   *
   * @return <code>true</code> if it's OK to switch, <code>false</code>
   *         otherwise
   */
  private static boolean confirmPerspectiveSwitch(IWorkbenchWindow window,
      IPerspectiveDescriptor finalPersp) {
    IPreferenceStore store = IDEWorkbenchPlugin.getDefault()
        .getPreferenceStore();
    String pspm = store
        .getString(IDEInternalPreferences.PROJECT_SWITCH_PERSP_MODE);
    if (!IDEInternalPreferences.PSPM_PROMPT.equals(pspm)) {
      // Return whether or not we should always switch
      return IDEInternalPreferences.PSPM_ALWAYS.equals(pspm);
    }
    String desc = finalPersp.getDescription();
    String message;
    if (desc == null || desc.length() == 0)
      message = NLS.bind(ResourceMessages.NewProject_perspSwitchMessage,
          finalPersp.getLabel());
    else
      message = NLS.bind(
          ResourceMessages.NewProject_perspSwitchMessageWithDesc,
          new String[] { finalPersp.getLabel(), desc });

    MessageDialogWithToggle dialog = MessageDialogWithToggle
        .openYesNoQuestion(window.getShell(),
            ResourceMessages.NewProject_perspSwitchTitle, message,
            null /* use the default message for the toggle */,
            false /* toggle is initially unchecked */, store,
            IDEInternalPreferences.PROJECT_SWITCH_PERSP_MODE);
    int result = dialog.getReturnCode();

    // If we are not going to prompt anymore propogate the choice.
    if (dialog.getToggleState()) {
      String preferenceValue;
      if (result == IDialogConstants.YES_ID) {
        // Doesn't matter if it is replace or new window
        // as we are going to use the open perspective setting
        preferenceValue = IWorkbenchPreferenceConstants.OPEN_PERSPECTIVE_REPLACE;
      } else {
        preferenceValue = IWorkbenchPreferenceConstants.NO_NEW_PERSPECTIVE;
      }

      // update PROJECT_OPEN_NEW_PERSPECTIVE to correspond
      PrefUtil.getAPIPreferenceStore().setValue(
          IDE.Preferences.PROJECT_OPEN_NEW_PERSPECTIVE,
          preferenceValue);
    }
    return result == IDialogConstants.YES_ID;
  }
 
  @Override
  public void setDefaultPageImageDescriptor(ImageDescriptor imageDescriptor) {
    ImageDescriptor d = ImageDescriptor.createFromURL(FileLocator.find(CCWPlugin.getDefault().getBundle(), new Path("icons/clojure64x64.png"), null));
    super.setDefaultPageImageDescriptor(d);
  }
}
TOP

Related Classes of ccw.leiningen.NewLeiningenProjectWizard

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.