package org.springframework.roo.project;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.springframework.roo.support.util.DomUtils;
import org.springframework.roo.support.util.XmlUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
/**
* Immutable representation of an execution specification for a (Maven) build
* plugin
*
* @author Adrian Colyer
* @author Alan Stewart
* @author Andrew Swan
* @since 1.0
*/
public class Execution implements Comparable<Execution> {
private final Configuration configuration;
private final List<String> goals;
private final String id;
private final String phase;
/**
* Constructor
*
* @param id the unique ID of this execution (required)
* @param phase the Maven life-cycle phase to which this execution is bound
* (required)
* @param configuration the execution-level configuration; can be
* <code>null</code>
* @param goals the goals to execute (must be at least one)
* @since 1.2.0
*/
public Execution(final String id, final String phase, final Configuration configuration,
final String... goals) {
Validate.notNull(id, "execution id must be specified");
Validate.notNull(phase, "execution phase must be specified");
this.configuration = configuration;
this.goals =
goals == null ? Collections.<String>emptyList() : Collections.unmodifiableList(Arrays
.asList(goals));
this.id = id.trim();
this.phase = phase.trim();
}
/**
* Constructor for no execution-level {@link Configuration}
*
* @param id the unique ID of this execution (required)
* @param phase the Maven life-cycle phase to which this execution is bound
* (required)
* @param goals the goals to execute (must be at least one)
*/
public Execution(final String id, final String phase, final String... goals) {
this(id, phase, null, goals);
}
public int compareTo(final Execution other) {
if (other == null) {
throw new NullPointerException();
}
int result = id.compareTo(other.id);
if (result == 0) {
result = phase.compareTo(other.phase);
}
if (result == 0) {
final String[] thisGoals = (String[]) goals.toArray();
final String[] oGoals = (String[]) other.goals.toArray();
Arrays.sort(thisGoals);
Arrays.sort(oGoals);
result = Arrays.toString(thisGoals).compareTo(Arrays.toString(oGoals));
}
if (result == 0) {
result = ObjectUtils.compare(configuration, other.configuration);
}
return result;
}
@Override
public boolean equals(final Object obj) {
return obj instanceof Execution && compareTo((Execution) obj) == 0;
}
/**
* Returns this execution's configuration, if any; this is separate from any
* configuration defined at the plugin level
*
* @return <code>null</code> if there is none
* @since 1.2.0
*/
public Configuration getConfiguration() {
return configuration;
}
/**
* Returns the XML element for this execution within the given Maven POM
*
* @param document the Maven POM to which to add the element (required)
* @return a non-<code>null</code> element
*/
public Element getElement(final Document document) {
final Element executionElement = document.createElement("execution");
// ID
if (StringUtils.isNotBlank(id)) {
executionElement.appendChild(XmlUtils.createTextElement(document, "id", id));
}
// Phase
if (StringUtils.isNotBlank(phase)) {
executionElement.appendChild(XmlUtils.createTextElement(document, "phase", phase));
}
// Goals
final Element goalsElement = DomUtils.createChildElement("goals", executionElement, document);
for (final String goal : goals) {
goalsElement.appendChild(XmlUtils.createTextElement(document, "goal", goal));
}
// Configuration
if (configuration != null) {
final Node configurationNode = document.importNode(configuration.getConfiguration(), true);
executionElement.appendChild(configurationNode);
}
return executionElement;
}
/**
* Returns the goals this execution will execute
*
* @return a non-empty list
*/
public List<String> getGoals() {
return goals;
}
/**
* Returns the unique ID of this execution
*
* @return a non-blank ID
*/
public String getId() {
return id;
}
/**
* Returns the Maven lifecycle phase to which this execution is bound
*
* @return a non-blank phase name
*/
public String getPhase() {
return phase;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ObjectUtils.hashCode(goals);
result = prime * result + ObjectUtils.hashCode(id);
result = prime * result + ObjectUtils.hashCode(phase);
result = prime * result + ObjectUtils.hashCode(configuration);
return result;
}
@Override
public String toString() {
final ToStringBuilder tsb = new ToStringBuilder(this);
tsb.append("id", id);
tsb.append("phase", phase);
tsb.append("goals", goals);
tsb.append("configuration", configuration);
return tsb.toString();
}
}