/* * 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.napile.idea.thermit.config.execution; import java.io.File; import java.util.ArrayList; import java.util.List; import org.jetbrains.annotations.NonNls; import org.napile.idea.thermit.ThermitBundle; import org.napile.idea.thermit.ThermitClasses; import org.napile.idea.thermit.config.impl.AntBuildFileImpl; import org.napile.idea.thermit.config.impl.AntInstallation; import org.napile.idea.thermit.config.impl.BuildFileProperty; import org.napile.idea.thermit.config.impl.GlobalThermitConfiguration; import org.napile.idea.thermit.config.impl.ThermitConfigurationImpl; import com.intellij.execution.CantRunException; import com.intellij.execution.configurations.JavaParameters; import com.intellij.execution.configurations.ParametersList; import com.intellij.ide.macro.Macro; import com.intellij.ide.macro.MacroManager; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.projectRoots.JavaSdkType; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.SdkTypeId; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.ArrayUtil; import com.intellij.util.PathUtil; import com.intellij.util.config.AbstractProperty; import com.intellij.util.containers.ContainerUtil; public class AntCommandLineBuilder { private final List<String> myTargets = new ArrayList<String>(); private final JavaParameters myCommandLine = new JavaParameters(); private String myBuildFilePath; private List<BuildFileProperty> myProperties; private boolean myDone = false; @NonNls private final List<String> myExpandedProperties = new ArrayList<String>(); @NonNls private static final String INPUT_HANDLER_PARAMETER = "-inputhandler"; @NonNls private static final String LOGFILE_PARAMETER = "-logfile"; @NonNls private static final String LOGFILE_SHORT_PARAMETER = "-l"; public void calculateProperties(final DataContext dataContext, List<BuildFileProperty> additionalProperties) throws Macro.ExecutionCancelledException { for(BuildFileProperty property : myProperties) { expandProperty(dataContext, property); } for(BuildFileProperty property : additionalProperties) { expandProperty(dataContext, property); } } private void expandProperty(DataContext dataContext, BuildFileProperty property) throws Macro.ExecutionCancelledException { String value = property.getPropertyValue(); final MacroManager macroManager = GlobalThermitConfiguration.getMacroManager(); value = macroManager.expandMacrosInString(value, true, dataContext); value = macroManager.expandMacrosInString(value, false, dataContext); myExpandedProperties.add("-D" + property.getPropertyName() + "=" + value); } public void addTarget(String targetName) { myTargets.add(targetName); } public void setBuildFile(AbstractProperty.AbstractPropertyContainer container, File buildFile) throws CantRunException { String jdkName = AntBuildFileImpl.CUSTOM_JDK_NAME.get(container); Sdk jdk; if(jdkName != null && jdkName.length() > 0) { jdk = GlobalThermitConfiguration.findJdk(jdkName); } else { jdkName = ThermitConfigurationImpl.DEFAULT_JDK_NAME.get(container); if(jdkName == null || jdkName.length() == 0) { throw new CantRunException(ThermitBundle.message("project.jdk.not.specified.error.message")); } jdk = GlobalThermitConfiguration.findJdk(jdkName); } if(jdk == null) { throw new CantRunException(ThermitBundle.message("jdk.with.name.not.configured.error.message", jdkName)); } VirtualFile homeDirectory = jdk.getHomeDirectory(); if(homeDirectory == null) { throw new CantRunException(ThermitBundle.message("jdk.with.name.bad.configured.error.message", jdkName)); } myCommandLine.setJdk(jdk); final ParametersList vmParametersList = myCommandLine.getVMParametersList(); vmParametersList.add("-Xmx" + AntBuildFileImpl.MAX_HEAP_SIZE.get(container) + "m"); vmParametersList.add("-Xss" + AntBuildFileImpl.MAX_STACK_SIZE.get(container) + "m"); final AntInstallation antInstallation = AntBuildFileImpl.ANT_INSTALLATION.get(container); if(antInstallation == null) { throw new CantRunException(ThermitBundle.message("ant.installation.not.configured.error.message")); } final String antHome = AntInstallation.HOME_DIR.get(antInstallation.getProperties()); vmParametersList.add("-Dthermit.home=" + antHome); String[] urls = jdk.getRootProvider().getUrls(OrderRootType.CLASSES); final String jdkHome = homeDirectory.getPath().replace('/', File.separatorChar); @NonNls final String pathToJre = jdkHome + File.separator + "jre" + File.separator; for(String url : urls) { final String path = PathUtil.toPresentableUrl(url); if(!path.startsWith(pathToJre)) { myCommandLine.getClassPath().add(path); } } myCommandLine.getClassPath().addAllFiles(AntBuildFileImpl.ALL_CLASS_PATH.get(container)); myCommandLine.getClassPath().addAllFiles(AntBuildFileImpl.getUserHomeLibraries()); final SdkTypeId sdkType = jdk.getSdkType(); if(sdkType instanceof JavaSdkType) { final String toolsJar = ((JavaSdkType) sdkType).getToolsPath(jdk); if(toolsJar != null) { myCommandLine.getClassPath().add(toolsJar); } } PathUtilEx.addRtJar(myCommandLine.getClassPath()); myCommandLine.getClassPath().add(findIdeaRunnerLib()); myCommandLine.setMainClass(ThermitClasses.RUNNER_MAIN); final ParametersList programParameters = myCommandLine.getProgramParametersList(); final String additionalParams = AntBuildFileImpl.ANT_COMMAND_LINE_PARAMETERS.get(container); if(additionalParams != null) { for(String param : ParametersList.parse(additionalParams)) { if(param.startsWith("-J")) { final String cutParam = param.substring("-J".length()); if(cutParam.length() > 0) { vmParametersList.add(cutParam); } } else { programParameters.add(param); } } } if(!(programParameters.getList().contains(LOGFILE_SHORT_PARAMETER) || programParameters.getList().contains(LOGFILE_PARAMETER))) programParameters.add("-logger", ThermitClasses.RUNNER_LOGGER); if(!programParameters.getList().contains(INPUT_HANDLER_PARAMETER)) programParameters.add(INPUT_HANDLER_PARAMETER, ThermitClasses.RUNNER_INPUT_HANDLER); myProperties = AntBuildFileImpl.ANT_PROPERTIES.get(container); myBuildFilePath = buildFile.getAbsolutePath(); myCommandLine.setWorkingDirectory(buildFile.getParent()); } private File findIdeaRunnerLib() { File temp = null; File antHome = new File(PathManager.getPluginsPath() + "/idea.thermit/lib"); if(antHome.exists() && (temp = new File(antHome, "idea.thermit.runner.jar")).exists()) return temp; // search in bundled plugins antHome = new File(PathManager.getHomePath()); if(antHome.exists()) { antHome = new File(antHome, "plugins/idea.thermit/lib"); if(antHome.exists() && (temp = new File(antHome, "idea.thermit.runner.jar")).exists()) return temp; } throw new UnsupportedOperationException(); } public JavaParameters getCommandLine() { if(myDone) return myCommandLine; ParametersList programParameters = myCommandLine.getProgramParametersList(); for(final String property : myExpandedProperties) { if(property != null) { programParameters.add(property); } } programParameters.add("-buildfile", myBuildFilePath); for(final String target : myTargets) { if(target != null) { programParameters.add(target); } } myDone = true; return myCommandLine; } public void addTargets(String[] targets) { ContainerUtil.addAll(myTargets, targets); } public String[] getTargets() { return ArrayUtil.toStringArray(myTargets); } }