Support maven 3

This commit is contained in:
Sergey Evdokimov
2012-09-26 19:26:58 +04:00
parent 777cfbbb56
commit 4233e02354
5 changed files with 287 additions and 32 deletions
+1
View File
@@ -54,6 +54,7 @@
<orderEntry type="module" module-name="testFramework-java" exported="" scope="TEST" />
<orderEntry type="module" module-name="jetgroovy" />
<orderEntry type="module" module-name="maven2-server-impl" scope="RUNTIME" />
<orderEntry type="module" module-name="maven3-server-impl" scope="RUNTIME" />
<orderEntry type="library" name="Guava" level="project" />
<orderEntry type="module" module-name="lang-impl" />
</component>
@@ -16,7 +16,19 @@
package org.jetbrains.idea.maven.server;
import com.intellij.util.SystemProperties;
import gnu.trove.THashSet;
import org.apache.maven.cli.MavenCli;
import org.apache.maven.model.Activation;
import org.apache.maven.model.Model;
import org.apache.maven.model.Profile;
import org.apache.maven.model.profile.DefaultProfileInjector;
import org.apache.maven.profiles.activation.*;
import org.apache.maven.project.DefaultProjectBuilderConfiguration;
import org.apache.maven.project.ProjectBuilderConfiguration;
import org.apache.maven.project.interpolation.AbstractStringBasedModelInterpolator;
import org.apache.maven.project.interpolation.ModelInterpolationException;
import org.apache.maven.project.path.DefaultPathTranslator;
import org.apache.maven.project.path.PathTranslator;
import org.apache.maven.settings.Settings;
import org.apache.maven.settings.building.DefaultSettingsBuildingRequest;
import org.apache.maven.settings.building.SettingsBuilder;
@@ -25,11 +37,15 @@ import org.apache.maven.settings.building.SettingsBuildingRequest;
import org.codehaus.plexus.DefaultPlexusContainer;
import org.codehaus.plexus.PlexusContainer;
import org.codehaus.plexus.classworlds.ClassWorld;
import org.codehaus.plexus.context.ContextException;
import org.codehaus.plexus.context.DefaultContext;
import org.codehaus.plexus.logging.BaseLoggerManager;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.maven.model.*;
import org.jetbrains.idea.maven.server.embedder.CustomMaven3ModelInterpolator;
import org.jetbrains.idea.maven.server.embedder.FieldAccessor;
import java.io.File;
@@ -65,34 +81,27 @@ public class Maven3ServerEmbedderImpl extends MavenRemoteObject implements Maven
}
};
List<String> methods = Arrays.asList("initialize",
"cli",
"properties",
"container");
Class cliRequestClass = null;
Class[] classes = MavenCli.class.getDeclaredClasses();
for (Class<?> each : classes) {
if (each.getSimpleName().equals("CliRequest")) {
cliRequestClass = each;
break;
}
try {
cliRequestClass = MavenCli.class.getClassLoader().loadClass("org.apache.maven.cli.MavenCli$CliRequest");
}
catch (ClassNotFoundException e) {
throw new RuntimeException("Class \"org.apache.maven.cli.MavenCli$CliRequest\" not found");
}
if (cliRequestClass == null) throw new RuntimeException("'CliRequest' class not found among '" + Arrays.toString(classes) + "'");
Object cliRequest;
try {
List<String> commandLineOptions = new ArrayList<String>(settings.getUserProperties().size());
String[] commandLineOptions = new String[settings.getUserProperties().size()];
int idx = 0;
for (Map.Entry<Object, Object> each : settings.getUserProperties().entrySet()) {
commandLineOptions.add("-D" + each.getKey() + "=" + each.getValue());
commandLineOptions[idx++] = "-D" + each.getKey() + "=" + each.getValue();
}
String[] commandLineOptionsArray = commandLineOptions.toArray(new String[commandLineOptions.size()]);
Constructor constructor = cliRequestClass.getDeclaredConstructor(String[].class, ClassWorld.class);
constructor.setAccessible(true);
cliRequest = constructor.newInstance(commandLineOptionsArray, classWorld);
cliRequest = constructor.newInstance(commandLineOptions, classWorld);
for (String each : methods) {
for (String each : new String[]{"initialize", "cli", "properties", "container"}) {
Method m = MavenCli.class.getDeclaredMethod(each, cliRequestClass);
m.setAccessible(true);
m.invoke(cli, cliRequest);
@@ -112,7 +121,7 @@ public class Maven3ServerEmbedderImpl extends MavenRemoteObject implements Maven
}
// reset threshold
myContainer = FieldAccessor.<DefaultPlexusContainer>get(MavenCli.class, cli, "container");
myContainer = FieldAccessor.get(MavenCli.class, cli, "container");
myContainer.getLoggerManager().setThreshold(settings.getLoggingLevel());
myMavenSettings = buildSettings(FieldAccessor.<SettingsBuilder>get(MavenCli.class, cli, "settingsBuilder"),
@@ -169,6 +178,13 @@ public class Maven3ServerEmbedderImpl extends MavenRemoteObject implements Maven
@Override
public MavenArtifact resolve(@NotNull MavenArtifactInfo info, @NotNull List<MavenRemoteRepository> remoteRepositories)
throws RemoteException, MavenServerProcessCanceledException {
//DependencyTreeResolutionListener listener = new DependencyTreeResolutionListener(myConsoleWrapper);
//
//MavenExecutionResult result = myImpl.resolveProject(file,
// new ArrayList<String>(activeProfiles),
// Arrays.<ResolutionListener>asList(listener));
//return createExecutionResult(file, result, listener.getRootNode());
throw new UnsupportedOperationException();
}
@@ -204,18 +220,22 @@ public class Maven3ServerEmbedderImpl extends MavenRemoteObject implements Maven
myContainer.dispose();
}
@Override
public void clearCaches() throws RemoteException {
throw new UnsupportedOperationException();
// do nothing
}
@Override
public void clearCachesFor(MavenId projectId) throws RemoteException {
throw new UnsupportedOperationException();
public void clearCachesFor(final MavenId projectId) throws RemoteException {
// do nothing
}
public static MavenModel interpolateAndAlignModel(MavenModel model, File basedir) {
throw new UnsupportedOperationException();
public static MavenModel interpolateAndAlignModel(MavenModel model, File basedir) throws RemoteException {
Model result = MavenModelConverter.toNativeModel(model);
result = doInterpolate(result, basedir);
PathTranslator pathTranslator = new DefaultPathTranslator();
pathTranslator.alignToBaseDirectory(result, basedir);
return MavenModelConverter.convertModel(result, null);
}
public static MavenModel assembleInheritance(MavenModel model, MavenModel parentModel) {
@@ -225,8 +245,111 @@ public class Maven3ServerEmbedderImpl extends MavenRemoteObject implements Maven
public static ProfileApplicationResult applyProfiles(MavenModel model,
File basedir,
Collection<String> explicitProfiles,
Collection<String> alwaysOnProfiles) {
throw new UnsupportedOperationException();
Collection<String> alwaysOnProfiles) throws RemoteException {
Model nativeModel = MavenModelConverter.toNativeModel(model);
List<Profile> activatedPom = new ArrayList<Profile>();
List<Profile> activatedExternal = new ArrayList<Profile>();
List<Profile> activeByDefault = new ArrayList<Profile>();
List<Profile> rawProfiles = nativeModel.getProfiles();
List<Profile> expandedProfilesCache = null;
for (int i = 0; i < rawProfiles.size(); i++) {
Profile eachRawProfile = rawProfiles.get(i);
boolean shouldAdd = explicitProfiles.contains(eachRawProfile.getId()) || alwaysOnProfiles.contains(eachRawProfile.getId());
Activation activation = eachRawProfile.getActivation();
if (activation != null) {
if (activation.isActiveByDefault()) {
activeByDefault.add(eachRawProfile);
}
// expand only if necessary
if (expandedProfilesCache == null) expandedProfilesCache = doInterpolate(nativeModel, basedir).getProfiles();
Profile eachExpandedProfile = expandedProfilesCache.get(i);
for (ProfileActivator eachActivator : getProfileActivators(basedir)) {
try {
if (eachActivator.canDetermineActivation(eachExpandedProfile) && eachActivator.isActive(eachExpandedProfile)) {
shouldAdd = true;
break;
}
}
catch (ProfileActivationException e) {
Maven3ServerGlobals.getLogger().warn(e);
}
}
}
if (shouldAdd) {
if (MavenConstants.PROFILE_FROM_POM.equals(eachRawProfile.getSource())) {
activatedPom.add(eachRawProfile);
}
else {
activatedExternal.add(eachRawProfile);
}
}
}
List<Profile> activatedProfiles = new ArrayList<Profile>(activatedPom.isEmpty() ? activeByDefault : activatedPom);
activatedProfiles.addAll(activatedExternal);
for (Profile each : activatedProfiles) {
new DefaultProfileInjector().injectProfile(nativeModel, each, null, null);
}
return new ProfileApplicationResult(MavenModelConverter.convertModel(nativeModel, null),
collectProfilesIds(activatedProfiles));
}
private static Model doInterpolate(Model result, File basedir) throws RemoteException {
try {
AbstractStringBasedModelInterpolator interpolator = new CustomMaven3ModelInterpolator(new DefaultPathTranslator());
interpolator.initialize();
Properties props = MavenServerUtil.collectSystemProperties();
ProjectBuilderConfiguration config = new DefaultProjectBuilderConfiguration().setExecutionProperties(props);
result = interpolator.interpolate(result, basedir, config, false);
}
catch (ModelInterpolationException e) {
Maven3ServerGlobals.getLogger().warn(e);
}
catch (InitializationException e) {
Maven3ServerGlobals.getLogger().error(e);
}
return result;
}
private static Collection<String> collectProfilesIds(List<Profile> profiles) {
Collection<String> result = new THashSet<String>();
for (Profile each : profiles) {
if (each.getId() != null) {
result.add(each.getId());
}
}
return result;
}
private static ProfileActivator[] getProfileActivators(File basedir) throws RemoteException {
SystemPropertyProfileActivator sysPropertyActivator = new SystemPropertyProfileActivator();
DefaultContext context = new DefaultContext();
context.put("SystemProperties", MavenServerUtil.collectSystemProperties());
try {
sysPropertyActivator.contextualize(context);
}
catch (ContextException e) {
Maven3ServerGlobals.getLogger().error(e);
return new ProfileActivator[0];
}
return new ProfileActivator[]{new MyFileProfileActivator(basedir),
sysPropertyActivator,
new JdkPrefixProfileActivator(),
new OperatingSystemProfileActivator()};
}
}
@@ -0,0 +1,118 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.idea.maven.server;
import org.apache.maven.model.Activation;
import org.apache.maven.model.ActivationFile;
import org.apache.maven.model.Profile;
import org.apache.maven.profiles.activation.DetectedProfileActivator;
import org.codehaus.plexus.interpolation.EnvarBasedValueSource;
import org.codehaus.plexus.interpolation.InterpolationException;
import org.codehaus.plexus.interpolation.MapBasedValueSource;
import org.codehaus.plexus.interpolation.RegexBasedInterpolator;
import org.codehaus.plexus.logging.LogEnabled;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.util.StringUtils;
import java.io.File;
import java.io.IOException;
/**
* Copied from org.apache.maven.profiles.activation.FileProfileActivator
* added parameter baseDit to test file existing
*
* @author Sergey Evdokimov
*/
public class MyFileProfileActivator extends DetectedProfileActivator
implements LogEnabled
{
private Logger logger;
private final File baseDir;
public MyFileProfileActivator(File baseDir) {
this.baseDir = baseDir;
}
protected boolean canDetectActivation( Profile profile )
{
return profile.getActivation() != null && profile.getActivation().getFile() != null;
}
public boolean isActive( Profile profile )
{
Activation activation = profile.getActivation();
ActivationFile actFile = activation.getFile();
if ( actFile != null )
{
// check if the file exists, if it does then the profile will be active
String fileString = actFile.getExists();
RegexBasedInterpolator interpolator = new RegexBasedInterpolator();
try
{
interpolator.addValueSource( new EnvarBasedValueSource() );
}
catch ( IOException e )
{
// ignored
}
interpolator.addValueSource( new MapBasedValueSource( System.getProperties() ) );
try
{
if ( StringUtils.isNotEmpty(fileString) )
{
fileString = StringUtils.replace( interpolator.interpolate( fileString, "" ), "\\", "/" );
return fileExists(fileString);
}
// check if the file is missing, if it is then the profile will be active
fileString = actFile.getMissing();
if ( StringUtils.isNotEmpty( fileString ) )
{
fileString = StringUtils.replace( interpolator.interpolate( fileString, "" ), "\\", "/" );
return !fileExists(fileString);
}
}
catch ( InterpolationException e )
{
if ( logger.isDebugEnabled() )
{
logger.debug( "Failed to interpolate missing file location for profile activator: " + fileString, e );
}
else
{
logger.warn( "Failed to interpolate missing file location for profile activator: " + fileString + ". Run in debug mode (-X) for more information." );
}
}
}
return false;
}
private boolean fileExists(String path) {
return new File(path).exists() || new File(baseDir, path).exists();
}
public void enableLogging( Logger logger )
{
this.logger = logger;
}
}
@@ -37,7 +37,7 @@ public class FieldAccessor<FIELD_TYPE> {
return myValueCache;
}
private Object getFieldValue(Class c, String fieldName, Object o) {
private static Object getFieldValue(Class c, String fieldName, Object o) {
try {
Field f = c.getDeclaredField(fieldName);
f.setAccessible(true);
@@ -52,6 +52,6 @@ public class FieldAccessor<FIELD_TYPE> {
}
public static <FIELD_TYPE> FIELD_TYPE get(Class hostClass, Object host, String fieldName) {
return new FieldAccessor<FIELD_TYPE>(hostClass, host, fieldName).get();
return (FIELD_TYPE)getFieldValue(hostClass, fieldName, host);
}
}
@@ -259,9 +259,22 @@ public class MavenServerManager extends RemoteObjectWrapper<MavenServer> {
if (pluginFileOrDir.isDirectory()) {
classpath.add(new File(pluginFileOrDir.getParent(), "maven-server-api"));
classpath.add(new File(pluginFileOrDir.getParent(), "maven2-server-impl"));
File luceneLib = new File(PathUtil.getJarPathForClass(Query.class));
libDir = new File(luceneLib.getParentFile().getParentFile().getParentFile(), "maven2-server-impl/lib");
if (Boolean.getBoolean("idea.use.maven3")) {
classpath.add(new File(pluginFileOrDir.getParent(), "maven3-server-impl"));
File luceneLib = new File(PathUtil.getJarPathForClass(Query.class));
File maven3ServerRoot = new File(luceneLib.getParentFile().getParentFile().getParentFile(), "maven3-server-impl/lib/maven3");
libDir = new File(maven3ServerRoot, "lib");
classpath.add(new File(maven3ServerRoot, "boot/plexus-classworlds-2.4.jar"));
}
else {
classpath.add(new File(pluginFileOrDir.getParent(), "maven2-server-impl"));
File luceneLib = new File(PathUtil.getJarPathForClass(Query.class));
libDir = new File(luceneLib.getParentFile().getParentFile().getParentFile(), "maven2-server-impl/lib");
}
}
else {
libDir = pluginFileOrDir.getParentFile();