/** * Get the list of all Ant files we want to process. These can be project and antlib files. * * @return antFiles a list of ant files to be processed */ public ArrayList getAntFiles(Project project, boolean homeOnly) { ArrayList antFiles = new ArrayList(); Map targets = project.getTargets(); Iterator targetsIter = targets.values().iterator(); String projectHome = null; try { projectHome = new File(project.getProperty("helium.dir")).getCanonicalPath(); while (targetsIter.hasNext()) { Target target = (Target) targetsIter.next(); String projectPath = new File(target.getLocation().getFileName()).getCanonicalPath(); if (!antFiles.contains(projectPath)) { if (homeOnly) { if (!projectPath.contains(projectHome)) { antFiles.add(projectPath); } } else antFiles.add(projectPath); } } if (rc != null) { Iterator extraFilesIter = rc.iterator(); while (extraFilesIter.hasNext()) { FileResource f = (FileResource) extraFilesIter.next(); String extrafile = f.getFile().getCanonicalPath(); if (!antFiles.contains(f.toString()) && !f.getFile().getName().startsWith("test_")) { if (homeOnly) { if (!extrafile.contains(projectHome)) { antFiles.add(extrafile); } } else antFiles.add(extrafile); } } } } catch (Exception e) { log(e.getMessage(), Project.MSG_ERR); e.printStackTrace(); } return antFiles; }
private void processTarget(Element targetNode, Element outProjectNode) throws IOException, DocumentException { String targetName = targetNode.attributeValue("name"); log("Processing target: " + targetName, Project.MSG_DEBUG); // Add documentation // Get comment element before the target element to extract target doc String commentText = ""; List children = targetNode.selectNodes("preceding-sibling::node()"); if (children.size() > 0) { // Scan past the text nodes, which are most likely whitespace int index = children.size() - 1; Node child = (Node) children.get(index); while (index > 0 && child.getNodeType() == Node.TEXT_NODE) { index--; child = (Node) children.get(index); } // Check if there is a comment node if (child.getNodeType() == Node.COMMENT_NODE) { Comment targetComment = (Comment) child; commentText = targetComment.getStringValue().trim(); log(targetName + " comment: " + commentText, Project.MSG_DEBUG); } else { log("Target has no comment: " + targetName, Project.MSG_WARN); } Node previousNode = (Node) children.get(children.size() - 1); } if (!commentText.contains("Private:")) { Element outTargetNode = outProjectNode.addElement("target"); addTextElement(outTargetNode, "name", targetNode.attributeValue("name")); addTextElement(outTargetNode, "ifDependency", targetNode.attributeValue("if")); addTextElement(outTargetNode, "unlessDependency", targetNode.attributeValue("unless")); addTextElement(outTargetNode, "description", targetNode.attributeValue("description")); addTextElement(outTargetNode, "tasks", String.valueOf(targetNode.elements().size())); // Add location Project project = getProject(); Target antTarget = (Target) project.getTargets().get(targetName); if (antTarget == null) return; addTextElement(outTargetNode, "location", antTarget.getLocation().toString()); // Add dependencies Enumeration dependencies = antTarget.getDependencies(); while (dependencies.hasMoreElements()) { String dependency = (String) dependencies.nextElement(); Element dependencyElement = addTextElement(outTargetNode, "dependency", dependency); dependencyElement.addAttribute("type", "direct"); } callAntTargetVisitor(targetNode, outTargetNode, outProjectNode); // Process the comment text as MediaWiki syntax and convert to HTML insertDocumentation(outTargetNode, commentText); // Get names of all properties used in this target ArrayList properties = new ArrayList(); Visitor visitor = new AntPropertyVisitor(properties); targetNode.accept(visitor); for (Iterator iterator = properties.iterator(); iterator.hasNext(); ) { String property = (String) iterator.next(); addTextElement(outTargetNode, "propertyDependency", property); } // Add the raw XML content of the element String targetXml = targetNode.asXML(); // Replace the CDATA end notation to avoid nested CDATA sections targetXml = targetXml.replace("]]>", "] ]>"); addTextElement(outTargetNode, "source", targetXml, true); } }
/** * Initialisation routine called after handler creation with the element name and attributes. * The attributes which this handler can deal with are: <code>"name"</code>, <code>"depends" * </code>, <code>"if"</code>, <code>"unless"</code>, <code>"id"</code> and <code>"description" * </code>. * * @param uri The namespace URI for this element. * @param tag Name of the element which caused this handler to be created. Should not be <code> * null</code>. Ignored in this implementation. * @param qname The qualified name for this element. * @param attrs Attributes of the element which caused this handler to be created. Must not be * <code>null</code>. * @param context The current context. * @exception SAXParseException if an unexpected attribute is encountered or if the <code>"name" * </code> attribute is missing. */ public void onStartElement( String uri, String tag, String qname, Attributes attrs, AntXMLContext context) throws SAXParseException { String name = null; String depends = ""; String extensionPoint = null; OnMissingExtensionPoint extensionPointMissing = null; Project project = context.getProject(); Target target = "target".equals(tag) ? new Target() : new ExtensionPoint(); target.setProject(project); target.setLocation(new Location(context.getLocator())); context.addTarget(target); for (int i = 0; i < attrs.getLength(); i++) { String attrUri = attrs.getURI(i); if (attrUri != null && !attrUri.equals("") && !attrUri.equals(uri)) { continue; // Ignore attributes from unknown uris } String key = attrs.getLocalName(i); String value = attrs.getValue(i); if (key.equals("name")) { name = value; if ("".equals(name)) { throw new BuildException("name attribute must " + "not be empty"); } } else if (key.equals("depends")) { depends = value; } else if (key.equals("if")) { target.setIf(value); } else if (key.equals("unless")) { target.setUnless(value); } else if (key.equals("id")) { if (value != null && !value.equals("")) { context.getProject().addReference(value, target); } } else if (key.equals("description")) { target.setDescription(value); } else if (key.equals("extensionOf")) { extensionPoint = value; } else if (key.equals("onMissingExtensionPoint")) { try { extensionPointMissing = OnMissingExtensionPoint.valueOf(value); } catch (IllegalArgumentException e) { throw new BuildException("Invalid onMissingExtensionPoint " + value); } } else { throw new SAXParseException("Unexpected attribute \"" + key + "\"", context.getLocator()); } } if (name == null) { throw new SAXParseException( "target element appears without a name attribute", context.getLocator()); } String prefix = null; boolean isInIncludeMode = context.isIgnoringProjectTag() && isInIncludeMode(); String sep = getCurrentPrefixSeparator(); if (isInIncludeMode) { prefix = getTargetPrefix(context); if (prefix == null) { throw new BuildException( "can't include build file " + context.getBuildFileURL() + ", no as attribute has been given" + " and the project tag doesn't" + " specify a name attribute"); } name = prefix + sep + name; } // Check if this target is in the current build file if (context.getCurrentTargets().get(name) != null) { throw new BuildException("Duplicate target '" + name + "'", target.getLocation()); } Hashtable projectTargets = project.getTargets(); boolean usedTarget = false; // If the name has not already been defined define it if (projectTargets.containsKey(name)) { project.log( "Already defined in main or a previous import, ignore " + name, Project.MSG_VERBOSE); } else { target.setName(name); context.getCurrentTargets().put(name, target); project.addOrReplaceTarget(name, target); usedTarget = true; } if (depends.length() > 0) { if (!isInIncludeMode) { target.setDepends(depends); } else { for (Iterator iter = Target.parseDepends(depends, name, "depends").iterator(); iter.hasNext(); ) { target.addDependency(prefix + sep + iter.next()); } } } if (!isInIncludeMode && context.isIgnoringProjectTag() && (prefix = getTargetPrefix(context)) != null) { // In an imported file (and not completely // ignoring the project tag or having a preconfigured prefix) String newName = prefix + sep + name; Target newTarget = usedTarget ? new Target(target) : target; newTarget.setName(newName); context.getCurrentTargets().put(newName, newTarget); project.addOrReplaceTarget(newName, newTarget); } if (extensionPointMissing != null && extensionPoint == null) { throw new BuildException( "onMissingExtensionPoint attribute cannot " + "be specified unless extensionOf is specified", target.getLocation()); } if (extensionPoint != null) { ProjectHelper helper = (ProjectHelper) context.getProject().getReference(ProjectHelper.PROJECTHELPER_REFERENCE); for (Iterator iter = Target.parseDepends(extensionPoint, name, "extensionOf").iterator(); iter.hasNext(); ) { String tgName = (String) iter.next(); if (isInIncludeMode()) { tgName = prefix + sep + tgName; } if (extensionPointMissing == null) { extensionPointMissing = OnMissingExtensionPoint.FAIL; } // defer extensionpoint resolution until the full // import stack has been processed helper.getExtensionStack().add(new String[] {tgName, name, extensionPointMissing.name()}); } } }
private List generateSequence(List projects) { DefaultModelFactory factory = new DefaultModelFactory(); Repository repository = (Repository) getProject().getReference("q.project.repository"); factory.setRepository(repository); // 1st pass: map artifacts generated from each project to a target representing their project // files Project tempProject = new Project(); Map targetsByArtifact = new HashMap(); Map targetsByProject = new HashMap(); List models = new ArrayList(); for (Iterator i = projects.iterator(); i.hasNext(); ) { File projectFile = (File) i.next(); // For now, we assume the default profile will contain all dependencies ProjectModel model = factory.getProjectModel( projectFile, Collections.EMPTY_LIST, true, null, new TaskLogger(this), getProject()); models.add(model); // Create a target for each project file Target target = new Target(); target.setName(projectFile.getAbsolutePath()); tempProject.addTarget(target); targetsByProject.put(model.getProject().getProjectFile(), target); // Map the artifacts to the target for (Iterator j = model.getProject().getArtifacts().iterator(); j.hasNext(); ) { Artifact artifact = (Artifact) j.next(); targetsByArtifact.put(artifact.getId(), target); } } // 2nd pass: Process project dependencies. Where a dependency uses an artifactId found in the // 1st pass, // set up a dependency between the projects. for (Iterator i = models.iterator(); i.hasNext(); ) { ProjectModel model = (ProjectModel) i.next(); Target projectTarget = (Target) targetsByProject.get(model.getProject().getProjectFile()); Set dependencies = getDependencies(model); // Where there is a dependency between projects, mirror it in the targets for (Iterator j = dependencies.iterator(); j.hasNext(); ) { RepoArtifactId id = (RepoArtifactId) j.next(); Target dependencyTarget = (Target) targetsByArtifact.get(id); if (dependencyTarget != null) { projectTarget.addDependency(dependencyTarget.getName()); } } } // Use ANT's target dependency mechanism to produce a build sequence String anyTarget = ((Target) targetsByArtifact.values().iterator().next()).getName(); Collection sequencedTargets = tempProject.topoSort(anyTarget, tempProject.getTargets()); // Transform targets into a list of files List sequence = new ArrayList(); for (Iterator i = sequencedTargets.iterator(); i.hasNext(); ) { Target seqTarget = (Target) i.next(); sequence.add(new File(seqTarget.getName())); } return sequence; }
/** * Parse a source xml input. * * @param project the current project * @param source the xml source * @exception BuildException if an error occurs */ public void parse(Project project, Object source) throws BuildException { getImportStack().addElement(source); AntXMLContext context = null; context = (AntXMLContext) project.getReference(REFID_CONTEXT); if (context == null) { context = new AntXMLContext(project); project.addReference(REFID_CONTEXT, context); project.addReference(REFID_TARGETS, context.getTargets()); } if (getImportStack().size() > 1) { // we are in an imported file. context.setIgnoreProjectTag(true); Target currentTarget = context.getCurrentTarget(); Target currentImplicit = context.getImplicitTarget(); Map currentTargets = context.getCurrentTargets(); try { Target newCurrent = new Target(); newCurrent.setProject(project); newCurrent.setName(""); context.setCurrentTarget(newCurrent); context.setCurrentTargets(new HashMap()); context.setImplicitTarget(newCurrent); parse(project, source, new RootHandler(context, mainHandler)); newCurrent.execute(); } finally { context.setCurrentTarget(currentTarget); context.setImplicitTarget(currentImplicit); context.setCurrentTargets(currentTargets); } } else { // top level file context.setCurrentTargets(new HashMap()); parse(project, source, new RootHandler(context, mainHandler)); // Execute the top-level target context.getImplicitTarget().execute(); // resolve extensionOf attributes for (Iterator i = getExtensionStack().iterator(); i.hasNext(); ) { String[] extensionInfo = (String[]) i.next(); String tgName = extensionInfo[0]; String name = extensionInfo[1]; OnMissingExtensionPoint missingBehaviour = OnMissingExtensionPoint.valueOf(extensionInfo[2]); Hashtable projectTargets = project.getTargets(); if (!projectTargets.containsKey(tgName)) { String message = "can't add target " + name + " to extension-point " + tgName + " because the extension-point is unknown."; if (missingBehaviour == OnMissingExtensionPoint.FAIL) { throw new BuildException(message); } else if (missingBehaviour == OnMissingExtensionPoint.WARN) { Target target = (Target) projectTargets.get(name); context.getProject().log(target, "Warning: " + message, Project.MSG_WARN); } } else { Target t = (Target) projectTargets.get(tgName); if (!(t instanceof ExtensionPoint)) { throw new BuildException("referenced target " + tgName + " is not an extension-point"); } t.addDependency(name); } } } }