Beispiel #1
0
 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();
    //            }
    //        }
  }
Beispiel #3
0
 /** 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);
 }
Beispiel #4
0
 /**
  * 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);
        }
      }
    }
  }
Beispiel #7
0
  /**
   * 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();
  }
Beispiel #8
0
  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(), ","));
    }
  }