private void assertPathSpec(boolean condition, String pathSpec) { Assert.isTrue( condition, "Path spec '" + pathSpec + "' is invalid. Valid syntax is: <toPathId>[?|!] [<|+|=] [fromPathId] [(<option1>, ...)]"); }
/** * This method attempts to find a matching dependency quickly, by bypassing full resolution of the * classpath path group for a plugin. It assumes the following: 1. The dependendency is directly * defined by the plugin artifact (this should always be true when a plugin implements an abstract * method of another) 2. The plugin artifact defines no overrides that effect the dependency (this * should be true as the plugin should just define the version it wants directly). If the * performance of resolvePathGroup is improved this method could be replaced by the version below. */ private RepoArtifactId fastFindMatchingDependency(Target target, RepoArtifactId id) { // Find the matching id that belongs to the classpath PathGroup pathGroup = target.getPathGroup("classpath"); RepoArtifactId match = null; String matchingPath = null; for (Iterator i = target.getPlugin().getArtifact().getDependencies().iterator(); i.hasNext(); ) { RepoDependency dependency = (RepoDependency) i.next(); if (dependency.getId().matches(id)) { for (Iterator j = dependency.getPathSpecs().iterator(); j.hasNext(); ) { RepoPathSpec pathSpec = (RepoPathSpec) j.next(); if (pathGroup.getPaths().contains("plugin." + pathSpec.getTo())) { match = dependency.getId(); matchingPath = pathSpec.getTo(); break; } } } } Assert.isTrue( match != null, target.getPlugin().getArtifact().getId().toShortString() + " does not declare a dependency that matches " + id); // Apply any project overrides for (Iterator i = overrides.iterator(); i.hasNext(); ) { ws.quokka.core.model.Override override = (ws.quokka.core.model.Override) i.next(); if (override.getWithVersion() != null && override.matches(match)) { Set paths = override.matchingPluginPaths(target.getPlugin().getArtifact().getId()); if (paths.contains(matchingPath) || ((paths.size() == 1) && paths.contains("*"))) { log.verbose("Overriding " + match.toShortString() + " to " + override.getWithVersion()); if (log.isDebugEnabled()) { log.debug( "Applied " + override + (override.getLocator() == null ? "" : " from " + override.getLocator())); } return new RepoArtifactId( id.getGroup(), id.getName(), id.getType(), override.getWithVersion()); } } } return match; // Slow code // List artifacts = resolvePathGroup(target, "classpath"); // for (Iterator i = artifacts.iterator(); i.hasNext();) { // RepoArtifact artifact = (RepoArtifact) i.next(); // if (artifact.getId().matches(id)) { // return artifact.getId(); // } // } }
/** Ensures the object is valid. e.g. checks the kind is defined */ public void validate() { Assert.isTrue( (kind != null) && (kind.equals(RENAMED) || kind.equals(RENAMED_RESET) || kind.equals(EQUIVALENT) || kind.equals(ALIAS) || kind.equals(BUNDLED)), "Invalid kind for conflict: " + kind); }
/** * Returns a path specification from its shorthand form * * @param toRequired if true, the to path id is mandatory, otherwise it can be omitted */ public void parseShorthand(String shorthand, boolean toRequired) { if (toRequired) { parseShorthand(shorthand); } else { parseShorthand( "*" + (isDelimeter(shorthand.substring(0, 1), "?!<+=") ? "" : "=") + shorthand); Assert.isTrue( to.equals("*"), "The to path cannot be specified for this path specification: " + shorthand); to = null; from = (from == null) ? RUNTIME : from; } }
private void resolvePath( List ids, List paths, boolean mergeWithCore, boolean overrideCore, Target target, boolean flatten) { String projectPrefix = "project."; String pluginPrefix = "plugin."; String propertyPrefix = "property."; for (Iterator i = ids.iterator(); i.hasNext(); ) { String id = (String) i.next(); if (id.startsWith(projectPrefix)) { String projectPathId = id.substring(projectPrefix.length()); Assert.isTrue( resolvedPaths.get(projectPathId) != null, "Project path '" + projectPathId + "' is not defined"); paths.add(getReslovedProjectPath(projectPathId, mergeWithCore, overrideCore, flatten)); } else if (id.startsWith(pluginPrefix)) { String pluginPathId = id.substring(pluginPrefix.length()); paths.add( getResolvedPluginPath( target.getPlugin(), pluginPathId, mergeWithCore, overrideCore, flatten)); } else if (id.startsWith(propertyPrefix)) { String property = id.substring(propertyPrefix.length()); property = Strings.replace(property, "prefix", target.getPrefix()); String value = project.getProperties().getProperty(property); if (value != null) { resolvePath( Strings.commaSepList(value), paths, mergeWithCore, overrideCore, target, flatten); } } else if (id.equals("plugin")) { ResolvedPath path = new ResolvedPath(); path.setId("Plugin:"); path.add(target.getPlugin().getArtifact()); paths.add(path); } else { throw new BuildException( "A path group must contain a comma separated list of: plugin | plugin.<pluginpath> | project.<projectpath> | property.<reference to a property containing additional paths>: id=" + id); } } }
private void addPathSpecDefaults(DependencySet dependencySet) { for (Iterator i = dependencySet.getDependencies().iterator(); i.hasNext(); ) { RepoDependency dependency = (RepoDependency) i.next(); for (Iterator j = dependency.getPathSpecs().iterator(); j.hasNext(); ) { RepoPathSpec pathSpec = (RepoPathSpec) j.next(); if (dependency instanceof PluginDependency) { // TODO: use defaults for plugin dependencies (from path defined in the repository?) } else { RepoPath path = (RepoPath) resolvedPaths.get(pathSpec.getTo()); Assert.isTrue( path != null, pathSpec.getLocator(), "The 'to' path '" + pathSpec.getTo() + "' is not defined in the project"); pathSpec.mergeDefaults(path); } } } }
/** * Converts the path spec to its short hand form. It minimises the output by matching elminating * settings that match either the path or in-built defaults. */ public String toShortHand(RepoPath path) { Assert.isTrue( path.getId().equals(to), "Attempt to create shorthand with the wrong path: to=" + to + ", path=" + path.getId()); StringBuffer sb = new StringBuffer(to); if (mandatory.booleanValue() != path.isMandatoryDefault()) { sb.append(mandatory.booleanValue() ? "!" : "?"); } if (descend.booleanValue() != path.isDescendDefault()) { sb.append(descend.booleanValue() ? "<" : "+"); } if (!from.equals(RUNTIME)) { sb.append((descend.booleanValue() == path.isDescendDefault()) ? "=" : ""); sb.append(from); } sb.append((options == null) ? "" : ("(" + options + ")")); return sb.toString(); }
public void execute() throws BuildException { if (id == null) { throw new BuildException("id attribute is mandatory for buildpath", getLocation()); } if (cache == null) { cache = utils.normalise( getProject().getProperty("q.project.targetDir") + "/build-sequence/" + id + ".txt"); } // Collect all of the project files List projects = new ArrayList(); for (Iterator i = projectCollections.iterator(); i.hasNext(); ) { ResourceCollection rc = (ResourceCollection) i.next(); for (Iterator j = rc.iterator(); j.hasNext(); ) { Resource resource = (Resource) j.next(); Assert.isTrue( resource instanceof FileResource, getLocation(), "Collections of files are expected"); projects.add(((FileResource) resource).getFile()); } } List seq = null; if (sequence) { // See if the build sequence is already generated and is up to date UpToDate upToDate = new UpToDate(); upToDate.setTargetFile(cache); upToDate.setProject(getProject()); for (Iterator i = projects.iterator(); i.hasNext(); ) { File file = (File) i.next(); upToDate.addSrcfiles(utils.toFileSet(file)); } // Load or generate the sequence if (upToDate.eval()) { log("Loading existing build configuration as it is up to date", Project.MSG_VERBOSE); seq = loadSequence(cache); if (!matches(projects, seq)) { log( "Invalidating loaded sequence as project list no longer matches", Project.MSG_VERBOSE); seq = null; } } if (seq == null) { log("Generating build sequence", Project.MSG_VERBOSE); seq = generateSequence(projects); saveSequence(seq, cache); } } else { seq = projects; } // Convert the sequence into a path and set it as a reference Path path = new Path(getProject()); for (Iterator i = seq.iterator(); i.hasNext(); ) { File file = (File) i.next(); Path element = new Path(getProject(), file.getParentFile().getAbsolutePath()); path.add(element); } getProject().addReference(id, path); }
public List _resolvePathGroup(Target target, String pathGroupId) { Plugin plugin = target.getPlugin(); PathGroup pathGroup = target.getPathGroup(pathGroupId); if (pathGroup == null) { if (plugin.getDeclaringPlugin() != null) { String declaringTargetName = plugin.getDeclaringPlugin().getNameSpace() + ":" + parseImplements(target)[2]; pathGroup = plugin.getDeclaringPlugin().getTarget(declaringTargetName).getPathGroup(pathGroupId); // TODO: Check the path group only refers to project paths? } Assert.isTrue( pathGroup != null, "Target '" + target.getName() + "' has requested path group '" + pathGroupId + "' that does not exist"); } if (log.isDebugEnabled()) { log.debug( "Resolving path: target=" + target.getName() + ", pathGroup=" + pathGroupId + ", pathGroupElements=" + pathGroup.getPaths()); } List paths = new ArrayList(); // Note: merging with core is turned off here so that the proper path tree is maintained // However, core overrides are still applied by separating that into a different flag resolvePath( pathGroup.getPaths(), paths, false, pathGroup.getMergeWithCore().booleanValue(), target, false); if (log.isDebugEnabled()) { log.debug("Resolved the following paths for path group '" + pathGroup + "'"); for (Iterator i = paths.iterator(); i.hasNext(); ) { ResolvedPath path = (ResolvedPath) i.next(); log.debug(pathResolver.formatPath(path, false)); } } ResolvedPath path = pathResolver.merge(paths); if (pathGroup.getMergeWithCore().booleanValue()) { path = mergeWithCore(path); } // System.out.println(pathResolver.formatPath(path, false)); StringBuffer sb = new StringBuffer(); for (Iterator i = path.getArtifacts().iterator(); i.hasNext(); ) { RepoArtifact artifact = (RepoArtifact) i.next(); sb.append(artifact.getId().toShortString()).append(";"); } if (log.isDebugEnabled()) { log.debug( "Resolved path: target=" + target.getName() + ", pathGroup=" + pathGroupId + ", path=" + sb.toString()); } return path.getArtifacts(); }
public void initialise() { pathResolver = new Resolver(repository, log); // Add ant-types path project .getDependencySet() .addPath( new Path( "ant-types", "Dependencies added to this path are available to ant optional tasks.")); // Get dependency sets, applying profiles and overrides List sets = depthFirst(project.getDependencySet()); // O pass: aggregate overrides for (Iterator i = sets.iterator(); i.hasNext(); ) { DependencySet set = (DependencySet) i.next(); overrides.addAll(set.getOverrides()); } // 1st pass: Define targets, paths, imported URLs Map targets = new HashMap(); for (Iterator i = sets.iterator(); i.hasNext(); ) { DependencySet set = (DependencySet) i.next(); // Get targets for (Iterator j = set.getDependencies().iterator(); j.hasNext(); ) { Dependency dependency = (Dependency) j.next(); if (dependency instanceof PluginDependency) { resolveTargets(targets, (PluginDependency) dependency); } } // Get paths for (Iterator j = set.getPaths().values().iterator(); j.hasNext(); ) { addPath((Path) j.next()); } if (set.getImportURL() != null) { resolvedImports.add(set.getImportURL()); } // Find the unique names for all declared artifacts Set uniqueNames = new HashSet(); for (Iterator j = project.getArtifacts().iterator(); j.hasNext(); ) { Artifact artifact = (Artifact) j.next(); uniqueNames.add(artifact.getId().getName()); } // Create artifacts for any licenses referenced by files for (Iterator j = set.getLicenses().iterator(); j.hasNext(); ) { License license = (License) j.next(); if (license.getFile() != null) { Assert.isTrue( project.getArtifacts().size() != 0, license.getLocator(), "There are no artifacts defined for a license to be applied to."); Artifact artifact = (Artifact) project.getArtifacts().iterator().next(); RepoArtifactId id = artifact.getId(); // If no name is specified, default it to name of the artifact if it is unique, // otherwise use the default from the group String name = license.getId().getName(); String defaultName = RepoArtifactId.defaultName(id.getGroup()); if (name == null) { if (uniqueNames.size() == 1) { name = (String) uniqueNames.iterator().next(); } else { name = defaultName; } } Artifact licenseArtifact = new Artifact(id.getGroup(), name, "license", id.getVersion()); licenseArtifact.setDescription( "License for " + id.getGroup() + (name.equals(defaultName) ? "" : (":" + name))); project.addArtifact(licenseArtifact); license.setId(licenseArtifact.getId()); } } } // 2nd pass: Define default paths specs, add imported targets for (Iterator i = sets.iterator(); i.hasNext(); ) { DependencySet set = (DependencySet) i.next(); // Fill in path spec defaults now that the project paths have been defined addPathSpecDefaults(set); } // 3rd pass: Reverse order for build resources List reverse = new ArrayList(sets); Collections.reverse(reverse); for (Iterator i = reverse.iterator(); i.hasNext(); ) { DependencySet set = (DependencySet) i.next(); buildResources.putAll(set.getBuildResources()); // Parent overrides children } resolvedTargets = targets; corePath = resolveCorePath(); if ("true".equals(antProject.getProperty("quokka.project.overrideCore"))) { coreOverrides = getCoreOverrides(); } }
private void addTarget(Map resolved, Target target) { // System.out.println("Adding " + target.getName() + " from " + parents); if (target.getPrefix() != null) { target.setDefaultProperties(expandPrefix(target.getPrefix(), target.getDefaultProperties())); } Target existing = (Target) resolved.get(target.getName()); if (existing != null) { RepoArtifactId targetId = target.getPlugin().getArtifact().getId(); RepoArtifactId existingId = existing.getPlugin().getArtifact().getId(); Assert.isTrue( targetId.equals(existingId), target.getLocator(), "Multiple targets are defined with the name '" + target.getName() + "'. Declared in " + targetId + " and " + existingId); return; } resolved.put(target.getName(), target); registerTypes(target); registerProjectPaths(target); buildResources.putAll(target.getPlugin().getBuildResources()); // PluginDependency declares the target addDependentTargets(resolved, target); if (target.getImplementsPlugin() != null) { // PluginDependency implements the target declared in another plugin String[] implementsPlugin = parseImplements(target); RepoArtifactId declaringPluginId = fastFindMatchingDependency( target, new RepoArtifactId( implementsPlugin[0], implementsPlugin[1], "plugin", (Version) null)); Plugin declaringPlugin = getPluginInstance(declaringPluginId); String declaringTargetName = declaringPlugin.getNameSpace() + ":" + implementsPlugin[2]; // Get the declaring plugin and find the matching target Target declaringTarget = (Target) resolved.get(declaringTargetName); if (declaringTarget == null) { declaringTarget = declaringPlugin.getTarget(declaringTargetName); Assert.isTrue( declaringTarget != null, target.getLocator(), "'" + declaringTargetName + "' is not defined in '" + declaringPluginId.toShortString() + "'"); addTarget(resolved, declaringTarget); } Assert.isTrue( declaringTarget.isAbstract(), target.getLocator(), "Target is attempting to implement a non-abstract target: target=" + target.getName() + ", implements=" + declaringTarget.getName()); target.getPlugin().setDeclaringPlugin(declaringTarget.getPlugin()); if (!declaringTarget.isImplemented()) { declaringTarget.setImplemented(true); declaringTarget.clearDependencies(); } declaringTarget.addDependency(target.getName()); // Add the declaring targets dependencies to ensure the implementation is executed before them for (Iterator i = declaringTarget.getOriginalDependencies().iterator(); i.hasNext(); ) { String dependency = (String) i.next(); target.addDependency(dependency); } } }
private void resolveTargets(Map resolved, PluginDependency pluginDependency) { List dependencyTargets = new ArrayList(pluginDependency.getTargets()); Plugin plugin = getPluginInstance(pluginDependency.getId()); plugin.setDependency(pluginDependency); for (Iterator i = plugin.getTargets().iterator(); i.hasNext(); ) { Target target = (Target) i.next(); // If the target is based on a template internally, merge with the template if (target.getTemplateName() != null) { String template = target.getTemplateName(); template = (template.indexOf(":") != -1) ? template : (target.getPlugin().getNameSpace() + ":" + template); target.merge(plugin.getTarget(template)); } // Process explicit target definitions boolean added = false; for (Iterator j = dependencyTargets.iterator(); j.hasNext(); ) { PluginDependencyTarget dependencyTarget = (PluginDependencyTarget) j.next(); Target targetInstance = null; if (dependencyTarget.getTemplate() == null) { // Enabling a target String name = dependencyTarget.getName(); name = (name.indexOf(":") != -1) ? name : (target.getPlugin().getNameSpace() + ":" + name); if (target.getName().equals(name)) { Assert.isTrue( !target.isTemplate(), dependencyTarget.getLocator(), "The named target '" + name + "' is a template"); String prefix = dependencyTarget.getPrefix(); Assert.isTrue( (prefix == null) || prefix.equals(target.getPrefix()), dependencyTarget.getLocator(), "The prefix '" + prefix + "' should match the target prefix '" + target.getPrefix() + "' if specified"); if (dependencyTarget.getAlias() != null) { target.setAlias(dependencyTarget.getAlias()); } targetInstance = target; } } else { // Instantiation of a template String template = dependencyTarget.getTemplate(); template = (template.indexOf(":") != -1) ? template : (target.getPlugin().getNameSpace() + ":" + template); if (target.getName().equals(template)) { Assert.isTrue( target.isTemplate(), dependencyTarget.getLocator(), "The named target '" + template + "' is not a template"); targetInstance = (Target) target.clone(); targetInstance.setPrefix(dependencyTarget.getPrefix()); targetInstance.setTemplateName(target.getName()); targetInstance.setName(dependencyTarget.getName()); } } if (targetInstance != null) { added = true; for (Iterator k = dependencyTarget.getDependencies().iterator(); k.hasNext(); ) { String dependency = (String) k.next(); targetInstance.addDependency(dependency); } // Record the plugin dependency target that introduced the target // This will be used later for dependency-of processing targetInstance.setPluginDependencyTarget(dependencyTarget); addTarget(resolved, targetInstance); j.remove(); } } // Use defaults if (!added && pluginDependency.isUseDefaults() && target.isEnabledByDefault()) { addTarget(resolved, target); } } if (dependencyTargets.size() != 0) { List names = new ArrayList(); for (Iterator i = dependencyTargets.iterator(); i.hasNext(); ) { PluginDependencyTarget target = (PluginDependencyTarget) i.next(); names.add(target.getName()); } Assert.isTrue( false, pluginDependency.getLocator(), "The following targets are not defined in plugin '" + plugin.getArtifact().getId().toShortString() + "': " + Strings.join(names.iterator(), ",")); } }