blob: ac10efbf7a8ccf1b69167217be2b43053ac21eb2 [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.apache.easyant.core.services;
import org.apache.easyant.core.EasyAntConstants;
import org.apache.easyant.core.EasyAntMagicNames;
import org.apache.easyant.core.ant.ProjectUtils;
import org.apache.easyant.core.ant.listerners.TaskCollectorFromImplicitTargetListener;
import org.apache.easyant.core.descriptor.EasyAntModuleDescriptor;
import org.apache.easyant.core.descriptor.PluginType;
import org.apache.easyant.core.descriptor.PropertyDescriptor;
import org.apache.easyant.core.parser.DefaultEasyAntXmlModuleDescriptorParser;
import org.apache.easyant.core.parser.EasyAntModuleDescriptorParser;
import org.apache.easyant.core.report.*;
import org.apache.easyant.tasks.*;
import org.apache.ivy.Ivy;
import org.apache.ivy.ant.IvyAntSettings;
import org.apache.ivy.core.IvyContext;
import org.apache.ivy.core.module.id.ModuleId;
import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.core.report.ArtifactDownloadReport;
import org.apache.ivy.core.report.ResolveReport;
import org.apache.ivy.core.resolve.IvyNode;
import org.apache.ivy.core.resolve.ResolveOptions;
import org.apache.ivy.core.resolve.ResolvedModuleRevision;
import org.apache.ivy.core.settings.IvySettings;
import org.apache.ivy.plugins.matcher.PatternMatcher;
import org.apache.ivy.plugins.parser.ModuleDescriptorParserRegistry;
import org.apache.ivy.plugins.repository.url.URLResource;
import org.apache.ivy.plugins.resolver.DependencyResolver;
import org.apache.ivy.util.Message;
import org.apache.tools.ant.*;
import org.apache.tools.ant.property.ParseNextProperty;
import org.apache.tools.ant.property.PropertyExpander;
import org.apache.tools.ant.taskdefs.Property;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.Path;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.ParsePosition;
import java.util.Enumeration;
import java.util.Map;
import java.util.Properties;
public class DefaultPluginService implements PluginService {
private final EasyAntModuleDescriptorParser parser;
private final Ivy ivyInstance;
private final IvyAntSettings easyantIvySettings;
private boolean offlineMode;
/**
* This is the default constructor, the IvyContext should be the IvyContext configured to the easyant ivy instance
*
* @param easyantIvySettings the easyant ivy instance
*/
public DefaultPluginService(final IvyAntSettings easyantIvySettings) {
this(easyantIvySettings, new DefaultEasyAntXmlModuleDescriptorParser());
}
/**
* A custom constructor if you want to specify your own parser / configuration service, you should use this
* constructor the IvyContext should be the IvyContext configured to the easyant ivy instance
*
* @param easyantIvySetings the easyant ivy instance
* @param parser a valid easyantModuleDescriptor
*/
public DefaultPluginService(final IvyAntSettings easyantIvySetings, EasyAntModuleDescriptorParser parser) {
this.easyantIvySettings = easyantIvySetings;
this.ivyInstance = easyantIvySetings.getConfiguredIvyInstance(easyantIvySetings);
if (parser == null) {
throw new IllegalArgumentException("You must set a valid easyant module descriptor parser");
}
this.parser = parser;
ModuleDescriptorParserRegistry.getInstance().addParser(parser);
}
public EasyAntReport getPluginInfo(File pluginIvyFile, File sourceDirectory, String conf) throws Exception {
IvyContext.pushNewContext().setIvy(ivyInstance);
EasyAntReport eaReport = null;
try {
ResolveOptions resolveOptions = buildResolveOptions(conf);
ResolveReport report = IvyContext.getContext().getIvy().getResolveEngine()
.resolve(pluginIvyFile.toURI().toURL(), resolveOptions);
eaReport = new EasyAntReport();
eaReport.setResolveReport(report);
eaReport.setModuleDescriptor(report.getModuleDescriptor());
Project project = buildProject();
// expose resolve report for import deferred
project.addReference(EasyAntMagicNames.IMPORTED_MODULES_RESOLVE_REPORT_REF, report);
// emulate top level project
ImportTestModule importTestModule = new ImportTestModule();
importTestModule.setModuleIvy(pluginIvyFile);
importTestModule.setSourceDirectory(sourceDirectory);
importTestModule.setOwningTarget(ProjectUtils.createTopLevelTarget());
importTestModule.setLocation(new Location(ProjectUtils.emulateMainScript(project).getAbsolutePath()));
importTestModule.setProject(project);
importTestModule.execute();
analyseProject(project, eaReport, conf);
} catch (Exception e) {
throw new Exception("An error occured while fetching plugin informations : " + e.getMessage(), e);
} finally {
IvyContext.popContext();
}
return eaReport;
}
private ResolveOptions buildResolveOptions(String conf) {
ResolveOptions resolveOptions = new ResolveOptions();
resolveOptions.setLog(ResolveOptions.LOG_QUIET);
resolveOptions.setConfs(conf.split(","));
resolveOptions.setUseCacheOnly(offlineMode);
return resolveOptions;
}
public EasyAntReport getPluginInfo(final ModuleRevisionId moduleRevisionId, String conf) throws Exception {
IvyContext.pushNewContext().setIvy(ivyInstance);
EasyAntReport eaReport = null;
try {
ResolveOptions resolveOptions = buildResolveOptions(conf);
final ResolveReport report = IvyContext.getContext().getIvy().getResolveEngine()
.resolve(moduleRevisionId, resolveOptions, false);
eaReport = new EasyAntReport();
eaReport.setResolveReport(report);
eaReport.setModuleDescriptor(report.getModuleDescriptor());
Project project = buildProject();
// expose resolve report for import deferred
project.addReference(EasyAntMagicNames.IMPORTED_MODULES_RESOLVE_REPORT_REF, report);
AbstractImport abstractImport = new AbstractImport() {
@Override
public void execute() throws BuildException {
Path path = createModulePath(moduleRevisionId.getModuleId());
File antFile = null;
for (ArtifactDownloadReport artifact : report.getConfigurationReport(getMainConf()).getAllArtifactsReports()) {
if ("ant".equals(artifact.getType())) {
antFile = artifact.getLocalFile();
} else if (shouldBeAddedToClasspath(artifact)) {
path.createPathElement().setLocation(artifact.getLocalFile());
} else {
handleOtherResourceFile(moduleRevisionId, artifact.getName(), artifact.getExt(),
artifact.getLocalFile());
}
}
if (antFile != null && antFile.exists()) {
ProjectHelper.configureProject(getProject(), antFile);
}
}
};
abstractImport.setProject(project);
// location ?
abstractImport.execute();
analyseProject(project, eaReport, conf);
} catch (Exception e) {
throw new Exception("An error occured while fetching plugin informations : " + e.getMessage(), e);
} finally {
IvyContext.popContext();
}
return eaReport;
}
private Project buildProject() {
Project project = new Project();
project.setNewProperty(EasyAntMagicNames.AUDIT_MODE, "true");
project.setNewProperty(EasyAntMagicNames.SKIP_CORE_REVISION_CHECKER, "true");
project.addReference(EasyAntMagicNames.EASYANT_IVY_INSTANCE, easyantIvySettings);
TaskCollectorFromImplicitTargetListener listener = new TaskCollectorFromImplicitTargetListener();
listener.addClassToCollect(ParameterTask.class);
listener.addClassToCollect(Property.class);
listener.addClassToCollect(Import.class);
listener.addClassToCollect(ImportDeferred.class);
listener.addClassToCollect(Path.class);
listener.addClassToCollect(PathTask.class);
listener.addClassToCollect(FileSet.class);
project.addBuildListener(listener);
// add a property helper to ignore basedir property on reports
PropertyHelper propertyHelper = PropertyHelper.getPropertyHelper(project);
propertyHelper.add(new BypassDefaultPropertyExpander());
project.init();
ProjectUtils.configureProjectHelper(project);
return project;
}
private void analyseProject(Project project, EasyAntReport eaReport, String conf) throws Exception {
// handle tasks from implicit target
// When using import/include, ant create a "implicit target" to process root tasks. When tasks are declared
// outside of a target in root project we are able to parse them "normally" as this implicit target is added to
// the project. However this is not the case for tasks declared outside any target in imported build script.
// So we use a listener to collect required informations
for (BuildListener buildListener : project.getBuildListeners()) {
if (buildListener instanceof TaskCollectorFromImplicitTargetListener) {
TaskCollectorFromImplicitTargetListener taskCollectorFromImplicitTargetListener = (TaskCollectorFromImplicitTargetListener) buildListener;
for (Task task : taskCollectorFromImplicitTargetListener.getTasksCollected()) {
handleTask(project, eaReport, conf, task);
}
}
}
// handle tasks declared in targets
Map<String, Target> targets = ProjectUtils.removeDuplicateTargets(project.getTargets());
for (Target target : targets.values()) {
if (!"".equals(target.getName())) {
// gather root module location from target if no task at root level was defined
TaskCollectorFromImplicitTargetListener.gatherRootModuleLocation(target.getProject(),
target.getLocation());
handleTarget(target, eaReport);
for (int i = 0; i < target.getTasks().length; i++) {
Task task = target.getTasks()[i];
handleTask(project, eaReport, conf, task);
}
}
}
}
private Object maybeConfigureTask(Task task) {
if (task.getRuntimeConfigurableWrapper().getProxy() instanceof UnknownElement) {
UnknownElement ue = (UnknownElement) task.getRuntimeConfigurableWrapper().getProxy();
ue.maybeConfigure();
return ue.getRealThing();
} else if (task instanceof UnknownElement) {
UnknownElement ue = (UnknownElement) task;
ue.maybeConfigure();
return ue.getRealThing();
} else {
return task;
}
}
private void handleTask(Project project, EasyAntReport eaReport, String conf, Task task) throws Exception {
Class<?> taskClass = ComponentHelper.getComponentHelper(project).getComponentClass(task.getTaskType());
if (taskClass != null) {
if (ParameterTask.class.isAssignableFrom(taskClass)) {
ParameterTask parameterTask = (ParameterTask) maybeConfigureTask(task);
handleParameterTask(parameterTask, eaReport);
}
if (Property.class.isAssignableFrom(taskClass)) {
Property propertyTask = (Property) maybeConfigureTask(task);
handleProperty(propertyTask, eaReport);
}
if (Import.class.isAssignableFrom(taskClass)) {
Import importTask = (Import) maybeConfigureTask(task);
handleImport(importTask, eaReport, conf);
}
if (ImportDeferred.class.isAssignableFrom(taskClass)) {
ImportDeferred importTask = (ImportDeferred) maybeConfigureTask(task);
handleImportDeferred(importTask, eaReport, conf);
}
if (Path.class.isAssignableFrom(taskClass)) {
Path path = (Path) maybeConfigureTask(task);
handlePathParameter(task.getRuntimeConfigurableWrapper().getId(), path, task.getOwningTarget(),
eaReport);
}
if (PathTask.class.isAssignableFrom(taskClass)) {
PathTask pathTask = (PathTask) maybeConfigureTask(task);
handlePathParameter(pathTask, eaReport);
}
if (FileSet.class.isAssignableFrom(taskClass)) {
FileSet fileSet = (FileSet) maybeConfigureTask(task);
handleFilesetParameter(task.getRuntimeConfigurableWrapper().getId(), fileSet, task.getOwningTarget(),
eaReport);
}
}
}
private boolean isCurrentModule(Project project, Location location) {
String rootModuleLocation = project.getProperty(TaskCollectorFromImplicitTargetListener.ROOT_MODULE_LOCATION);
if (rootModuleLocation == null) {
throw new IllegalStateException(
"rootModuleLocation not found, looks like TaskCollectorFromImplicitTargetListener is not properly configured");
}
return location != null && location.getFileName().equals(rootModuleLocation);
}
private void handleImport(Import importTask, EasyAntReport eaReport, String conf) throws Exception {
ImportedModuleReport importedModuleReport = new ImportedModuleReport();
importedModuleReport.setModuleMrid(importTask.getMrid());
importedModuleReport.setOrganisation(importTask.getOrganisation());
importedModuleReport.setModule(importTask.getModule());
importedModuleReport.setRevision(importTask.getRevision());
importedModuleReport.setMandatory(importTask.isMandatory());
importedModuleReport.setMode(importTask.getMode());
importedModuleReport.setAs(importTask.getAs());
EasyAntReport pluginInfo = getPluginInfo(ModuleRevisionId.parse(importedModuleReport.getModuleMrid()), conf);
importedModuleReport.setEasyantReport(pluginInfo);
eaReport.addImportedModuleReport(importedModuleReport,
isCurrentModule(importTask.getProject(), importTask.getLocation()));
Message.debug("Ant file import another module called : " + importedModuleReport.getModuleMrid() + " with mode "
+ importedModuleReport.getMode());
}
private void handleImportDeferred(ImportDeferred importTask, EasyAntReport eaReport, String conf) throws Exception {
ImportedModuleReport importedModuleReport = new ImportedModuleReport();
importedModuleReport.setOrganisation(importTask.getOrganisation());
importedModuleReport.setModule(importTask.getModule());
ResolveReport resolveReport = importTask.getProject().getReference(
EasyAntMagicNames.IMPORTED_MODULES_RESOLVE_REPORT_REF);
if (resolveReport != null) {
for (Object o : resolveReport.getDependencies()) {
IvyNode dependency = (IvyNode) o;
if (dependency.getResolvedId().getOrganisation().equals(importTask.getOrganisation()) //
&& dependency.getResolvedId().getName().equals(importTask.getModule())) {
importedModuleReport.setRevision(dependency.getResolvedId().getRevision());
}
}
}
importedModuleReport.setMandatory(importTask.isMandatory());
importedModuleReport.setMode(importTask.getMode());
importedModuleReport.setAs(importTask.getAs());
EasyAntReport pluginInfo = getPluginInfo(ModuleRevisionId.parse(importedModuleReport.getModuleMrid()), conf);
importedModuleReport.setEasyantReport(pluginInfo);
eaReport.addImportedModuleReport(importedModuleReport,
isCurrentModule(importTask.getProject(), importTask.getLocation()));
Message.debug("Ant file import another module called : " + importedModuleReport.getModuleMrid() + " with mode "
+ importedModuleReport.getMode());
}
private void handleProperty(Property property, EasyAntReport eaReport) throws IOException {
boolean isCurrentModule = isCurrentModule(property.getProject(), property.getLocation());
if (property.getFile() != null) {
Properties propToLoad = new Properties();
File f = property.getFile();
if (f.exists()) {
FileInputStream fis = null;
try {
fis = new FileInputStream(f);
propToLoad.load(fis);
for (Object o : propToLoad.keySet()) {
String key = (String) o;
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(key);
propertyDescriptor.setValue(propToLoad.getProperty(key));
if (property.getOwningTarget() != null) {
propertyDescriptor.setOwningTarget(property.getOwningTarget().getName());
}
eaReport.addPropertyDescriptor(propertyDescriptor.getName(), propertyDescriptor,
isCurrentModule);
}
} catch (IOException e) {
IOException ioe = new IOException("Unable to parse the property file :" + property.getFile());
ioe.initCause(e);
throw ioe;
} finally {
if (fis != null) {
fis.close();
}
}
}
}
if (property.getName() != null) {
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(property.getName());
propertyDescriptor.setValue(property.getValue());
if (property.getOwningTarget() != null) {
propertyDescriptor.setOwningTarget(property.getOwningTarget().getName());
}
eaReport.addPropertyDescriptor(property.getName(), propertyDescriptor, isCurrentModule);
}
}
private void handleParameterTask(ParameterTask parameterTask, EasyAntReport eaReport) {
boolean isCurrentModule = isCurrentModule(parameterTask.getProject(), parameterTask.getLocation());
if (parameterTask.getProperty() != null) {
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(parameterTask.getProperty());
propertyDescriptor.setDefaultValue(parameterTask.getDefault());
// Use unsafe version since we are in audit mode and we want the real value of the required field
// (#isRequired method will always return false in audit mode)
propertyDescriptor.setRequired(parameterTask.isRequiredUnsafe());
propertyDescriptor.setDescription(parameterTask.getDescription());
if (parameterTask.getOwningTarget() != null) {
propertyDescriptor.setOwningTarget(parameterTask.getOwningTarget().getName());
}
Message.debug("Ant file has a property called : " + propertyDescriptor.getName());
eaReport.addPropertyDescriptor(propertyDescriptor.getName(), propertyDescriptor, isCurrentModule);
} else if (parameterTask.getPath() != null) {
ParameterReport parameterReport = new ParameterReport(ParameterType.PATH);
parameterReport.setName(parameterTask.getPath());
// Use unsafe version since we are in audit mode and we want the real value of the required field
// (#isRequired method will always return false in audit mode)
parameterReport.setRequired(parameterTask.isRequiredUnsafe());
parameterReport.setDescription(parameterTask.getDescription());
if (parameterTask.getOwningTarget() != null) {
parameterReport.setOwningTarget(parameterTask.getOwningTarget().getName());
}
eaReport.addParameterReport(parameterReport, isCurrentModule);
Message.debug("Ant file has a path called : " + parameterReport.getName());
}
}
private void handleFilesetParameter(String id, FileSet fileSet, Target target, EasyAntReport eaReport) {
ParameterReport parameterReport = new ParameterReport(ParameterType.FILESET);
if (id != null) {
parameterReport.setName(id);
parameterReport.setRequired(false);
parameterReport.setDescription(fileSet.getDescription());
if (target != null) {
parameterReport.setOwningTarget(target.getName());
}
eaReport.addParameterReport(parameterReport, isCurrentModule(fileSet.getProject(), fileSet.getLocation()));
Message.debug("Ant file has a fileset called : " + parameterReport.getName());
}
}
private void handlePathParameter(String pathid, Path path, Target target, EasyAntReport eaReport) {
ParameterReport parameterReport = new ParameterReport(ParameterType.PATH);
if (pathid != null) {
parameterReport.setName(pathid);
parameterReport.setRequired(false);
parameterReport.setDescription(path.getDescription());
if (target != null) {
parameterReport.setOwningTarget(target.getName());
}
eaReport.addParameterReport(parameterReport, isCurrentModule(path.getProject(), path.getLocation()));
Message.debug("Ant file has a path called : " + parameterReport.getName());
}
}
private void handlePathParameter(PathTask pathTask, EasyAntReport eaReport) {
ParameterReport parameterReport = new ParameterReport(ParameterType.PATH);
if (pathTask.getPathid() != null) {
parameterReport.setName(pathTask.getPathid());
parameterReport.setRequired(false);
parameterReport.setDescription(pathTask.getDescription());
if (pathTask.getOwningTarget() != null) {
parameterReport.setOwningTarget(pathTask.getOwningTarget().getName());
}
eaReport.addParameterReport(parameterReport, isCurrentModule(pathTask.getProject(), pathTask.getLocation()));
Message.debug("Ant file has a path called : " + parameterReport.getName());
}
}
private void handleTarget(Target target, EasyAntReport eaReport) {
boolean isCurrentModule = isCurrentModule(target.getProject(), target.getLocation());
boolean isExtensionPoint = target instanceof ExtensionPoint;
if (!isExtensionPoint) {
TargetReport targetReport = new TargetReport();
targetReport.setName(target.getName());
StringBuilder sb = new StringBuilder();
Enumeration<?> targetDeps = target.getDependencies();
while (targetDeps.hasMoreElements()) {
String t = (String) targetDeps.nextElement();
sb.append(t);
if (targetDeps.hasMoreElements()) {
sb.append(",");
}
}
targetReport.setDepends(sb.toString());
targetReport.setDescription(target.getDescription());
targetReport.setIfCase(target.getIf());
targetReport.setUnlessCase(target.getUnless());
for (Target currentTarget : target.getProject().getTargets().values()) {
if (currentTarget instanceof ExtensionPoint) {
Enumeration<?> dependencies = currentTarget.getDependencies();
while (dependencies.hasMoreElements()) {
String dep = (String) dependencies.nextElement();
if (dep.equals(target.getName())) {
targetReport.setExtensionPoint(currentTarget.getName());
}
}
}
}
eaReport.addTargetReport(targetReport, isCurrentModule);
Message.debug("Ant file has a target called : " + targetReport.getName());
} else {
ExtensionPointReport extensionPoint = new ExtensionPointReport(target.getName());
StringBuilder sb = new StringBuilder();
Enumeration<?> targetDeps = target.getDependencies();
while (targetDeps.hasMoreElements()) {
String t = (String) targetDeps.nextElement();
sb.append(t);
if (targetDeps.hasMoreElements()) {
sb.append(",");
}
}
extensionPoint.setDepends(sb.toString());
extensionPoint.setDescription(target.getDescription());
eaReport.addExtensionPointReport(extensionPoint, isCurrentModule);
Message.debug("Ant file has an extensionPoint called : " + extensionPoint.getName());
}
}
public EasyAntReport getPluginInfo(ModuleRevisionId moduleRevisionId) throws Exception {
return getPluginInfo(moduleRevisionId, "default");
}
public EasyAntReport getPluginInfo(String moduleRevisionId) throws Exception {
ModuleRevisionId module = buildModuleRevisionId(moduleRevisionId, PluginType.PLUGIN);
return getPluginInfo(module);
}
public EasyAntReport getBuildTypeInfo(String moduleRevisionId) throws Exception {
ModuleRevisionId module = buildModuleRevisionId(moduleRevisionId, PluginType.BUILDTYPE);
return getPluginInfo(module);
}
public EasyAntModuleDescriptor getEasyAntModuleDescriptor(File moduleDescriptor) throws Exception {
if (moduleDescriptor == null) {
throw new Exception("moduleDescriptor cannot be null");
}
if (!moduleDescriptor.exists()) {
throw new Exception("imposible to find the specified module descriptor"
+ moduleDescriptor.getAbsolutePath());
}
IvyContext.pushNewContext().setIvy(ivyInstance);
// First we need to parse the specified file to retrieve all the easyant
// stuff
parser.parseDescriptor(ivyInstance.getSettings(), moduleDescriptor.toURI().toURL(), new URLResource(
moduleDescriptor.toURI().toURL()), true);
EasyAntModuleDescriptor md = parser.getEasyAntModuleDescriptor();
IvyContext.popContext();
return md;
}
public EasyAntReport generateEasyAntReport(File moduleDescriptor, File optionalAntModule, File overrideAntModule)
throws Exception {
EasyAntReport eaReport = new EasyAntReport();
EasyAntModuleDescriptor md = getEasyAntModuleDescriptor(moduleDescriptor);
eaReport.setModuleDescriptor(md.getIvyModuleDescriptor());
Project p = buildProject();
Target implicitTarget = ProjectUtils.createTopLevelTarget();
p.addTarget(implicitTarget);
// calculate basedir
if (moduleDescriptor != null) {
p.setBaseDir(moduleDescriptor.getParentFile());
} else if (optionalAntModule != null) {
p.setBaseDir(optionalAntModule.getParentFile());
} else if (overrideAntModule != null) {
p.setBaseDir(overrideAntModule.getParentFile());
}
LoadModule loadModule = new LoadModule();
loadModule.setBuildModule(moduleDescriptor);
loadModule.setBuildFile(optionalAntModule);
loadModule.setOwningTarget(implicitTarget);
loadModule.setLocation(new Location(ProjectUtils.emulateMainScript(p).getAbsolutePath()));
loadModule.setProject(p);
loadModule.setTaskName("load-module");
loadModule.execute();
ProjectHelper projectHelper = ProjectUtils.getConfiguredProjectHelper(p);
projectHelper.resolveExtensionOfAttributes(p);
analyseProject(p, eaReport, "default");
return eaReport;
}
public ModuleRevisionId[] search(String organisation, String moduleName, String revision, String branch,
String matcher, String resolver) throws Exception {
IvySettings settings = ivyInstance.getSettings();
if (moduleName == null && PatternMatcher.EXACT.equals(matcher)) {
throw new Exception("no module name provided for ivy repository graph task: "
+ "It can either be set explicitely via the attribute 'module' or "
+ "via 'ivy.module' property or a prior call to <resolve/>");
} else if (moduleName == null && !PatternMatcher.EXACT.equals(matcher)) {
moduleName = PatternMatcher.ANY_EXPRESSION;
}
ModuleRevisionId mrid = ModuleRevisionId.newInstance(organisation, moduleName, revision);
ModuleRevisionId criteria;
if ((revision == null) || settings.getVersionMatcher().isDynamic(mrid)) {
criteria = new ModuleRevisionId(new ModuleId(organisation, moduleName), branch, "*");
} else {
criteria = new ModuleRevisionId(new ModuleId(organisation, moduleName), branch, revision);
}
PatternMatcher patternMatcher = settings.getMatcher(matcher);
if (PatternMatcher.ANY_EXPRESSION.equals(resolver)) {
// search in all resolvers. this can be quite slow for complex
// repository configurations
// with ChainResolvers, since resolvers in chains will be searched
// multiple times.
return ivyInstance.listModules(criteria, patternMatcher);
} else {
// limit search to the specified resolver.
DependencyResolver dependencyResolver = resolver == null ? settings.getDefaultResolver() : settings
.getResolver(resolver);
if (dependencyResolver == null) {
throw new IllegalArgumentException("Unknown dependency resolver for search: " + resolver);
}
ivyInstance.pushContext();
try {
return ivyInstance.getSearchEngine().listModules(dependencyResolver, criteria, patternMatcher);
} finally {
ivyInstance.popContext();
}
}
}
public ModuleRevisionId[] search(String organisation, String moduleName) throws Exception {
return search(organisation, moduleName, null, null, PatternMatcher.EXACT_OR_REGEXP, null);
}
public String[] searchModule(String organisation, String moduleName) throws Exception {
ModuleRevisionId[] mrids = search(organisation, moduleName);
String[] result = new String[mrids.length];
for (int i = 0; i < mrids.length; i++) {
result[i] = mrids[i].toString();
}
return result;
}
public String getDescription(ModuleRevisionId mrid) {
ResolvedModuleRevision rmr = ivyInstance.findModule(mrid);
return rmr.getDescriptor().getDescription();
}
public String getPluginDescription(String moduleRevisionId) {
ModuleRevisionId module = buildModuleRevisionId(moduleRevisionId, PluginType.PLUGIN);
return getDescription(module);
}
public String getBuildTypeDescription(String moduleRevisionId) {
ModuleRevisionId module = buildModuleRevisionId(moduleRevisionId, PluginType.BUILDTYPE);
return getDescription(module);
}
private ModuleRevisionId buildModuleRevisionId(String moduleRevisionId, PluginType pluginType) {
String mrid = moduleRevisionId;
if (!mrid.matches(".*#.*")) {
if (pluginType.equals(PluginType.BUILDTYPE)) {
Message.debug("No organisation specified for buildtype " + mrid + " using the default one");
mrid = EasyAntConstants.EASYANT_BUILDTYPES_ORGANISATION + "#" + mrid;
} else {
Message.debug("No organisation specified for plugin " + mrid + " using the default one");
mrid = EasyAntConstants.EASYANT_PLUGIN_ORGANISATION + "#" + mrid;
}
}
return ModuleRevisionId.parse(mrid);
}
public EasyAntReport generateEasyAntReport(File moduleDescriptor) throws Exception {
return generateEasyAntReport(moduleDescriptor, null, null);
}
/**
* Don't try to expand property on reports. Bypassing default property expander allow us to show real static value
* of properties on reports.
*/
private class BypassDefaultPropertyExpander implements PropertyExpander {
public String parsePropertyName(String s, ParsePosition pos, ParseNextProperty notUsed) {
int index = pos.getIndex();
// directly check near, triggering characters:
if (s.length() - index >= 3 && '$' == s.charAt(index) && '{' == s.charAt(index + 1)) {
int start = index;
// defer to String.indexOf() for protracted check:
int end = s.indexOf('}', start);
if (end < 0) {
throw new BuildException("Syntax error in property: " + s.substring(index));
}
// set marker after "}"
pos.setIndex(end + 1);
// allow to resolve path to property files
// this is mandatory if we want report to contains properties loaded by
// property file like done on buildtypes
// in that case property needs to be really expanded so we need to strips "${" and "}" characters
String strippedPropertyName = s.substring(start + 2, end);
if (strippedPropertyName.endsWith("properties.file")) {
return strippedPropertyName;
}
// in other cases return the whole property with "${" and "}"
return start == end ? "" : s.substring(start, end + 1);
}
return null;
}
}
public void setOfflineMode(boolean offlineMode) {
this.offlineMode = offlineMode;
}
}