blob: a39b42b91c89d2577d0d9426659c5e0bd73a7d89 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.netbeans.modules.maven.apisupport;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.maven.artifact.Artifact;
import org.netbeans.api.project.Project;
import org.netbeans.api.project.ui.OpenProjects;
import org.netbeans.modules.apisupport.project.spi.NbModuleProvider;
import org.netbeans.modules.maven.api.FileUtilities;
import org.netbeans.modules.maven.api.NbMavenProject;
import org.netbeans.modules.maven.api.classpath.DependencyProjectsProvider;
import org.netbeans.modules.maven.api.execute.ExecutionContext;
import org.netbeans.modules.maven.api.execute.LateBoundPrerequisitesChecker;
import org.netbeans.modules.maven.api.execute.RunConfig;
import org.netbeans.modules.maven.api.execute.RunUtils;
import org.netbeans.spi.project.ActionProvider;
import org.netbeans.spi.project.ProjectServiceProvider;
import org.openide.filesystems.FileUtil;
import org.openide.util.Utilities;
/**
* adds -J-Dnetbeans.patches.%cnb%=%path% to netbeans.run.params.debug execution parameter, links up the module Compile on Save outputs.
* @author mkleint
*/
@ProjectServiceProvider(service=LateBoundPrerequisitesChecker.class, projectType="org-netbeans-modules-maven/" + NbMavenProject.TYPE_NBM_APPLICATION)
public class CoSApplicationLateBoundChecker implements LateBoundPrerequisitesChecker {
@Override
public boolean checkRunConfig(RunConfig config, ExecutionContext con) {
if (config.getProject() == null) {
return true;
}
if (!RunUtils.isCompileOnSaveEnabled(config)) { //#236324
return true;
}
if (ActionProvider.COMMAND_BUILD.equals(config.getActionName()) || ActionProvider.COMMAND_CLEAN.equals(config.getActionName()) ||
ActionProvider.COMMAND_REBUILD.equals(config.getActionName())) {
return true;
}
DependencyProjectsProvider dpp = config.getProject().getLookup().lookup(DependencyProjectsProvider.class);
//only one of these properties should ever be coming down from PrerequisitesCheckers
String params = config.getProperties().get(NetBeansRunParamsIDEChecker.PROPERTY);
String oldparams = config.getProperties().get(NetBeansRunParamsIDEChecker.OLD_PROPERTY);
StringBuilder sb = new StringBuilder(params != null ? params : oldparams != null ? oldparams : "");
final List<DependencyProjectsProvider.Pair> nonModules = new ArrayList<DependencyProjectsProvider.Pair>();
final Map<String, List<DependencyProjectsProvider.Pair>> extraCP = new HashMap<String, List<DependencyProjectsProvider.Pair>>();
final Map<String, DependencyProjectsProvider.Pair> modules = new HashMap<String, DependencyProjectsProvider.Pair>();
final Set<DependencyProjectsProvider.Pair> all = dpp.getDependencyProjects();
for (DependencyProjectsProvider.Pair pair : all) {
//only include OPEN modules with CoS on to limit scope. On windows the cmd line can easily overflow.
if (pair.isIncludedAtRuntime() && RunUtils.isCompileOnSaveEnabled(pair.getProject()) && OpenProjects.getDefault().isProjectOpen(pair.getProject())) {
NbModuleProvider nbm = pair.getProject().getLookup().lookup(NbModuleProvider.class);
if (nbm != null) {
Artifact a = pair.getArtifact();
modules.put(a.getGroupId() + ":" + a.getArtifactId() + ":" + a.getType() + ":" + a.getBaseVersion(), pair);
} else {
nonModules.add(pair);
}
}
}
if (!nonModules.isEmpty()) {
for (DependencyProjectsProvider.Pair pair : nonModules) {
//TODO what to do for OSGI (netbeans.patches. doesn't work here) and for non module jars (find where they belong?)
List<String> trail = new ArrayList<>(pair.getArtifact().getDependencyTrail());
Collections.reverse(trail); //we go from the artifact itself up, first module project artifact is our boy..
trail.remove(0); //first one is the actual artifact.
for (String s : trail) {
if (modules.containsKey(s)) {
//we have found a module match
List<DependencyProjectsProvider.Pair> cp = extraCP.get(s);
if (cp == null) {
cp = new ArrayList<DependencyProjectsProvider.Pair>();
extraCP.put(s, cp);
}
cp.add(pair);
}
}
}
}
String branding = PluginBackwardPropertyUtils.getPluginProperty(config.getProject(), "brandingToken", "cluster-app", "netbeans.branding.token");
//TODO care about figuring out build.outputdir?
//only relativize path on windows
assert config.getExecutionDirectory() != null : "RunConfig for " + config.getActionName() + " is missing executionDirectory"; //#243564 we need to learn which
File currentDir = Utilities.isWindows() && config.getExecutionDirectory() != null ? new File(new File(config.getExecutionDirectory(), "target"), branding) : null;
for (Map.Entry<String, DependencyProjectsProvider.Pair> pairEnt : modules.entrySet()) {
NbModuleProvider nbm = pairEnt.getValue().getProject().getLookup().lookup(NbModuleProvider.class);
if (nbm != null) {
String cnb = nbm.getCodeNameBase();
if (sb.length() > 0) {
sb.append(" ");
}
String v = projectToOutputDir(pairEnt.getValue().getProject(), currentDir);
boolean space = v.contains(" ");
sb.append("-J-Dnetbeans.patches.").append(cnb).append("=");
if (space) sb.append("\"");
sb.append(v);
if (space) sb.append("\"");
List<DependencyProjectsProvider.Pair> ex = extraCP.get(pairEnt.getKey());
boolean useOsgiDeps = MavenWhiteListQueryImpl.isUseOSGiDependencies(pairEnt.getValue().getProject());
if (ex != null && !ex.isEmpty()) {
for (DependencyProjectsProvider.Pair exPair : ex) {
NbMavenProject nbprj = exPair.getProject().getLookup().lookup(NbMavenProject.class);
if (nbprj != null && NbMavenProject.TYPE_OSGI.equals(nbprj.getPackagingType()) && useOsgiDeps) {
continue; //skip osgi if used as dependency, not classpath
}
//: or ; is there a constant for it?
sb.append(Utilities.isWindows() ? ";" : ":").append(projectToOutputDir(exPair.getProject(), currentDir));
}
}
}
}
//hard to decide what prop to set if none was set before, we need to recheck the version and act accordingly
String prop = NetBeansRunParamsIDEChecker.usingNbmPlugin311(config.getMavenProject()) ? NetBeansRunParamsIDEChecker.PROPERTY : NetBeansRunParamsIDEChecker.OLD_PROPERTY;
if (sb.length() > 0) {
config.setProperty(prop, sb.toString());
}
return true;
}
private String projectToOutputDir(Project p, File basedir) {
//attempt to resolve a relative path to save space on the cmd line..
File f = new File(new File(FileUtil.toFile(p.getProjectDirectory()), "target"), "classes");
String toRet = basedir != null ? FileUtilities.relativizeFile(basedir, f) : null;
if (toRet == null) {
toRet = f.getAbsolutePath();
}
return toRet;
}
}