Package com.puppetlabs.geppetto.pp.dsl.ui.builder

Source Code of com.puppetlabs.geppetto.pp.dsl.ui.builder.ToggleNatureAction$ToggleJob

/**
* Copyright (c) 2013 Puppet Labs, Inc. and other contributors, as listed below.
* 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:
*   Puppet Labs
*/
package com.puppetlabs.geppetto.pp.dsl.ui.builder;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.log4j.Logger;
import com.puppetlabs.geppetto.pp.dsl.ui.PPUiConstants;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.IObjectActionDelegate;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.xtext.ui.XtextProjectHelper;

import com.google.common.collect.Lists;

public class ToggleNatureAction implements IObjectActionDelegate {
  private static class ToggleJob extends Job {
    final private boolean turnOn;

    final private List<IProject> projectsToToggle;

    public ToggleJob(boolean turnOn, List<IProject> projectsToToggle) {
      super("Building Puppet Projects");
      this.turnOn = turnOn;
      this.projectsToToggle = projectsToToggle;
      setPriority(Job.BUILD);
    }

    /**
     * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
     */
    @Override
    protected IStatus run(IProgressMonitor monitor) {
      try {
        final IWorkspace workspace = ResourcesPlugin.getWorkspace();

        // Run toggle followed by a full build as an atomic workspace operation so that things
        // are done in the right order
        workspace.run(new IWorkspaceRunnable() {
          @Override
          public void run(IProgressMonitor monitor) throws CoreException {
            for(IProject projectToToggle : projectsToToggle)
              toggleNature(projectToToggle, turnOn);
            workspace.build(IncrementalProjectBuilder.FULL_BUILD, monitor);
          }
        }, monitor);
        return Status.OK_STATUS;
      }
      catch(CoreException e) {
        return e.getStatus();
      }
    }
  }

  private final static Logger log = Logger.getLogger(ToggleNatureAction.class);

  private static void addNature(IProject project) {
    // Also add XtextNature if not already set
    boolean addXtextNature = !XtextProjectHelper.hasNature(project);

    try {
      IProjectDescription description = project.getDescription();
      String[] natures = description.getNatureIds();

      final int newCount = 1 + (addXtextNature
          ? 1
          : 0);
      // Add the nature
      String[] newNatures = new String[natures.length + newCount];
      System.arraycopy(natures, 0, newNatures, newCount, natures.length);
      newNatures[0] = PPUiConstants.PUPPET_NATURE_ID;
      if(addXtextNature)
        newNatures[1] = XtextProjectHelper.NATURE_ID;
      description.setNatureIds(newNatures);
      project.setDescription(description, null);
    }
    catch(CoreException e) {
      log.error("Failed adding Puppet Project Nature", e);
    }

  }

  protected static boolean hasNature(IProject project) {
    try {
      IProjectDescription description = project.getDescription();

      String[] natures = description.getNatureIds();

      for(int i = 0; i < natures.length; ++i)
        if(PPUiConstants.PUPPET_NATURE_ID.equals(natures[i]))
          return true;
    }
    catch(CoreException e) {
      log.error("Error while trying to obtain nature of project", e);
    }
    return false;
  }

  private static void removeNature(IProject project) {
    try {
      IProjectDescription description = project.getDescription();
      String[] natures = description.getNatureIds();

      for(int i = 0; i < natures.length; ++i) {
        if(PPUiConstants.PUPPET_NATURE_ID.equals(natures[i])) {
          // Remove the nature
          String[] newNatures = new String[natures.length - 1];
          System.arraycopy(natures, 0, newNatures, 0, i);
          System.arraycopy(natures, i + 1, newNatures, i, natures.length - i - 1);
          description.setNatureIds(newNatures);
          project.setDescription(description, null);
          return;
        }
      }
    }
    catch(CoreException e) {
      log.error("Failed adding Puppet Project Nature", e);
    }

  }

  protected static void toggleNature(IProject project, boolean on) {
    if(hasNature(project)) {
      if(!on)
        removeNature(project);
    }
    else if(on)
      addNature(project);

  }

  private ISelection selection;

  private boolean turnOn;

  /**
   * Returns selected accessible projects
   *
   * @param selection
   * @return
   */
  @SuppressWarnings("rawtypes")
  private List<IProject> getSelectedProjects(ISelection selection) {
    List<IProject> projects = Lists.newArrayList();
    if(selection instanceof IStructuredSelection) {
      for(Iterator it = ((IStructuredSelection) selection).iterator(); it.hasNext();) {
        Object element = it.next();
        IProject project = null;
        if(element instanceof IProject) {
          project = (IProject) element;
        }
        else if(element instanceof IAdaptable) {
          project = (IProject) ((IAdaptable) element).getAdapter(IProject.class);
        }
        if(project != null && project.isAccessible()) {
          projects.add(project);
        }
      }
    }
    return projects;
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
   */
  @SuppressWarnings("rawtypes")
  public void run(IAction action) {
    if(selection instanceof IStructuredSelection) {
      List<IProject> projectsToToggle = new ArrayList<IProject>();
      for(Iterator it = ((IStructuredSelection) selection).iterator(); it.hasNext();) {
        Object element = it.next();
        IProject project = null;
        if(element instanceof IProject) {
          project = (IProject) element;
        }
        else if(element instanceof IAdaptable) {
          project = (IProject) ((IAdaptable) element).getAdapter(IProject.class);
        }
        if(project != null) {
          projectsToToggle.add(project);
        }
      }
      if(!projectsToToggle.isEmpty())
        new ToggleJob(turnOn, projectsToToggle).schedule();
    }
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction,
   * org.eclipse.jface.viewers.ISelection)
   */
  public void selectionChanged(IAction action, ISelection selection) {
    this.selection = selection;
    List<IProject> projects = getSelectedProjects(selection);

    // enable the action if at least one project is selected
    action.setEnabled(projects.size() != 0);
    if(projects.size() == 0) {
      // Set a default text (for disabled state)
      action.setText("Toggle Puppet Project Nature");
    }
    else {
      // If one of the projects do not have the nature, then the action is a
      // set nature on all
      this.turnOn = false;
      for(IProject p : projects)
        if(!hasNature(p)) {
          turnOn = true;
          break;
        }
      if(turnOn)
        action.setText("Add Puppet Project Nature");
      else
        action.setText("Remove Puppet Project Nature");
    }
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.ui.IObjectActionDelegate#setActivePart(org.eclipse.jface.action.IAction,
   * org.eclipse.ui.IWorkbenchPart)
   */
  public void setActivePart(IAction action, IWorkbenchPart targetPart) {
  }

  /**
   * Toggles nature on a project
   *
   * @param project
   *            to have sample nature added or removed
   */
  protected void toggleNature(IProject project) {

    if(hasNature(project)) {
      if(!turnOn)
        removeNature(project);
    }
    else if(turnOn)
      addNature(project);
  }
}
TOP

Related Classes of com.puppetlabs.geppetto.pp.dsl.ui.builder.ToggleNatureAction$ToggleJob

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.