Package org.springframework.ide.eclipse.boot.core.internal

Source Code of org.springframework.ide.eclipse.boot.core.internal.MavenSpringBootProject

/*******************************************************************************
* Copyright (c) 2013, 2014 Pivotal Software, Inc.
* 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:
* Pivotal Software, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.core.internal;

import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.ARTIFACT_ID;
import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.DEPENDENCIES;
import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.DEPENDENCY;
import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.GROUP_ID;
import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.findChild;
import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.findChilds;
import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.getChild;
import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.getTextValue;
import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.performOnDOMDocument;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.maven.model.Dependency;
import org.apache.maven.model.DependencyManagement;
import org.apache.maven.project.MavenProject;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.m2e.core.MavenPlugin;
import org.eclipse.m2e.core.project.IMavenProjectFacade;
import org.eclipse.m2e.core.project.IMavenProjectRegistry;
import org.eclipse.m2e.core.ui.internal.editing.PomEdits.Operation;
import org.eclipse.m2e.core.ui.internal.editing.PomEdits.OperationTuple;
import org.eclipse.m2e.core.ui.internal.editing.PomHelper;
import org.springframework.ide.eclipse.boot.core.BootActivator;
import org.springframework.ide.eclipse.boot.core.IMavenCoordinates;
import org.springframework.ide.eclipse.boot.core.MavenCoordinates;
import org.springframework.ide.eclipse.boot.core.SpringBootCore;
import org.springframework.ide.eclipse.boot.core.SpringBootStarter;
import org.springframework.ide.eclipse.boot.core.StarterId;
import org.springsource.ide.eclipse.commons.frameworks.core.ExceptionUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
* @author Kris De Volder
*/
@SuppressWarnings("restriction")
public class MavenSpringBootProject extends SpringBootProject {
 
  //TODO: all of the starter manipulation code completely ignores the version infos in SpringBootStarter objects.
  // This is ok assuming that versions always follow the 'managed' version in parent pom.
  // If that is not the case then... ??
 
  //TODO: the code adding raw maven deps has the oposite problem. It includes version numbers even
  //  when they are unnecessary (managed by parent pom).
 
  //TODO: properly handle pom manipulation when pom file is open / dirty in an editor.
  // minimum requirement: detect and prohibit by throwing an error.

  private static final List<SpringBootStarter> NO_STARTERS = Arrays
      .asList(new SpringBootStarter[0]);

  private static final boolean DEBUG = (""+Platform.getLocation()).contains("kdvolder");

  private IProject project;

  public MavenSpringBootProject(IProject project) {
    Assert.isNotNull(project);
    this.project = project;
  }

  @Override
  public IProject getProject() {
    return project;
  }

  /**
   * @return List of maven coordinates for known boot starters. These are
   *         discovered dynamically based on project contents. E.g. for maven
   *         projects we examine the 'dependencyManagement' section of the
   *         project's effective pom.
   *
   * @throws CoreException
   */
  @Override
  public List<SpringBootStarter> getKnownStarters() throws CoreException {
    MavenProject mp = getMavenProject();
    DependencyManagement depMan = mp.getDependencyManagement();
    if (depMan != null) {
      List<Dependency> deps = depMan.getDependencies();
      return getStarters(deps);
    }
    return NO_STARTERS;
  }

  private MavenProject getMavenProject() throws CoreException {
    IMavenProjectRegistry pr = MavenPlugin.getMavenProjectRegistry();
    IMavenProjectFacade mpf = pr.getProject(project);
    MavenProject mp = mpf.getMavenProject(new NullProgressMonitor());
    return mp;
  }

  private IFile getPomFile() {
    return project.getFile(new Path("pom.xml"));
  }

  @Override
  public List<SpringBootStarter> getBootStarters() throws CoreException {
    return getStarters(getMavenProject().getDependencies());
  }

  private List<SpringBootStarter> getStarters(List<Dependency> deps) {
    if (deps != null) {
      ArrayList<SpringBootStarter> starters = new ArrayList<SpringBootStarter>();
      for (Dependency _dep : deps) {
        IMavenCoordinates dep = new MavenCoordinates(_dep.getGroupId(),
            _dep.getArtifactId(), _dep.getVersion());
        if (SpringBootStarter.isStarter(dep)) {
          starters.add(new SpringBootStarter(dep));
        }
      }
      return starters;
    }
    return NO_STARTERS;
  }

  @Override
  public void removeStarter(final SpringBootStarter starter)
      throws CoreException {
    try {
      List<SpringBootStarter> starters = getBootStarters();
      boolean changed = starters.remove(starter);
      if (changed) {
        setStarters(starters);
      }
    } catch (Throwable e) {
      throw ExceptionUtil.coreException(e);
    }
  }

  @Override
  public void addStarter(final SpringBootStarter starter)
      throws CoreException {
    try {
      List<SpringBootStarter> starters = getBootStarters();
      boolean changed = starters.add(starter);
      if (changed) {
        setStarters(starters);
      }
    } catch (Throwable e) {
      throw ExceptionUtil.coreException(e);
    }
  }
 
  /**
   * Determine the 'managed' version, if any, associate with a given dependency.
   * @return Version string or null.
   */
  private String getManagedVersion(MavenCoordinates dep) {
    try {
      DependencyManagement managedDeps = getMavenProject().getDependencyManagement();
      if (managedDeps!=null) {
        List<Dependency> deps = managedDeps.getDependencies();
        if (deps!=null && !deps.isEmpty()) {
          for (Dependency d : deps) {
            if ("jar".equals(d.getType())) {
              if (dep.getArtifactId().equals(d.getArtifactId()) && dep.getGroupId().equals(d.getGroupId())) {
                return d.getVersion();
              }
            }
          }
        }
      }
    } catch (Exception e) {
      BootActivator.log(e);
    }
    return null;
  }
 
  private void debug(String string) {
    if (DEBUG) {
      System.out.println(string);
    }
  }

  @Override
  public void addMavenDependency(final MavenCoordinates dep, final boolean preferManagedVersion) throws CoreException {
    try {
      IFile file = getPomFile();
      performOnDOMDocument(new OperationTuple(file, new Operation() {
        public void process(Document document) {
          Element depsEl = getChild(
              document.getDocumentElement(), DEPENDENCIES);
          if (depsEl==null) {
            //TODO: handle this case
          } else {
            String version = dep.getVersion();
            String managedVersion = getManagedVersion(dep);
            if (managedVersion!=null) {
              //Decide whether we can/should inherit the managed version or override it.
              if (preferManagedVersion || managedVersion.equals(version)) {
                version = null;
              }
            } else {
              //No managed version. We have to include a version in xml added to the pom.
            }
            PomHelper.createDependency(depsEl,
                dep.getGroupId(),
                dep.getArtifactId(),
                version
            );
          }
        }
      }));
    } catch (Throwable e) {
      throw ExceptionUtil.coreException(e);
    }
  }
 
  @Override
  public void setStarters(Collection<SpringBootStarter> _starters) throws CoreException {
    try {
      final Set<StarterId> starters = new HashSet<StarterId>();
      for (SpringBootStarter s : _starters) {
        starters.add(s.getId());
      }
     
      IFile file = getPomFile();
      performOnDOMDocument(new OperationTuple(file, new Operation() {
        public void process(Document document) {
          Element depsEl = getChild(
              document.getDocumentElement(), DEPENDENCIES);
          List<Element> children = findChilds(depsEl, DEPENDENCY);
          for (Element c : children) {
            //We only care about 'starter' dependencies. Leave everything else alone.
            // Also... don't touch nodes that are already there, unless they are to
            // be removed. This way we don't mess up versions, comments or other stuff
            // that a user may have inserted via manual edits.
            String aid = getTextValue(findChild(c, ARTIFACT_ID));
            String gid = getTextValue(findChild(c, GROUP_ID));
            if (aid!=null && gid!=null) { //ignore invalid entries that don't have gid or aid
              if (aid.startsWith(SpringBootStarter.AID_PREFIX)) {
                StarterId id = new StarterId(gid, aid);
                boolean keep = starters.remove(id);
                if (!keep) {
                  depsEl.removeChild(c);
                }
              }
            }
          }
         
          //if 'starters' is not empty at this point, it contains remaining ids we have not seen
          // in the pom, so we need to add them.
          for (StarterId s : starters) {
            PomHelper.createDependency(depsEl,
                s.getGroupId(), s.getArtifactId(),
                null);           
          }
        }
      }));
    } catch (Throwable e) {
      throw ExceptionUtil.coreException(e);
    }
  }

  @Override
  public String getBootVersion() {
    try {
      return getBootVersion(getMavenProject().getDependencies());
    } catch (Exception e) {
      BootActivator.log(e);
      return SpringBootCore.getDefaultBootVersion();
    }
  }

  private String getBootVersion(List<Dependency> dependencies) {
    for (Dependency dep : dependencies) {
      if (dep.getArtifactId().startsWith("spring-boot") && dep.getGroupId().equals("org.springframework.boot")) {
        return dep.getVersion();
      }
    }
    return SpringBootCore.getDefaultBootVersion();
  }
}
TOP

Related Classes of org.springframework.ide.eclipse.boot.core.internal.MavenSpringBootProject

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.