package net.sf.invicta.process;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.collections.SequencedHashMap;
import net.sf.invicta.InvictaConstants;
import net.sf.invicta.InvictaException;
import net.sf.invicta.api.DefinedProperty;
import net.sf.invicta.api.InvictaComponent;
import net.sf.invicta.api.InvictaProject;
import net.sf.invicta.api.Product;
import net.sf.invicta.api.ProductContainer;
import net.sf.invicta.project.BasicProduct;
import net.sf.invicta.project.ComponentDefinition;
import net.sf.invicta.project.InvictaProjectException;
import net.sf.invicta.type.BasicDefinedProperty;
import net.sf.invicta.type.TypeDefinition;
import net.sf.invicta.type.TypeManager;
/**
* An implementation of the InvictaComponent interface of the API.
* Contains both a resolved definition of a component and a matching resolved
* type definition.
* This class acts as a delegator to ComponentDefinition and TypeDefinition
* classes.
*/
public class TypedComponent implements InvictaComponent {
protected ComponentDefinition component;
protected TypeDefinition type;
protected InvictaProjectImpl project;
protected Map definedProperties = new SequencedHashMap();
/**
* Creates a new TypedComponent by getting the type definition for the
* type of the given resolved component definition, validating that
* the component matches its type and formatting attributes of defined
* properties and products.
*
* @param typeManager
* @param component A resolved ComponentDefinition object.
* @param project The full project object.
* @throws InvictaException
*/
public TypedComponent(TypeManager typeManager, ComponentDefinition component,
InvictaProjectImpl project) throws InvictaException {
this.project = project;
this.component = component;
this.type = typeManager.getTypeDefinition(component.getType());
validateComponent();
createdTiedDefinedProperties();
formatProducts();
}
/**
* Returns a list of component names that this component depends on
* (directly).
*
* @return List of String objects.
*/
public List getDependComponentNames() {
return component.getDependComponentNames();
}
/**
* Returns a list of depend items of dependencies of this component.
*
* @return List of DependItem objects.
*/
public List getDependItems() {
return component.getDependItems();
}
/**
* Returns the relative directory of this component.
*
* @return String. Relative directory.
*/
public String getDir() {
return component.getDir();
}
/**
* Returns the products that this components depends on and are exported.
*
* @return ProductContainer
*/
public ProductContainer getExportedProducts() {
return component.getExportedProducts();
}
/**
* Returns the full name of this component.
*
* @return
*/
public String getName() {
return component.getName();
}
/**
* Returns the products that this components requires or defines
* (private, exported and self products).
*
* @return ProductContainer
*/
public ProductContainer getProducts() {
return component.getProducts();
}
/**
* Returns the products that this component requires
* (for compilation. private and exported without self products).
*
* @return ProductContainer
*/
public ProductContainer getProductsWithoutSelf() {
return component.getProductsWithoutSelf();
}
/**
* Returns the value of a property (component, project or general) with
* the given name.
* Returns null if the property is not defined.
*
* @param propertyName
* @return String
*/
public String getPropertyValue(String propertyName) {
DefinedProperty definedProperty = getDefinedProperty(propertyName);
if (definedProperty == null)
return null;
return definedProperty.getActualValue();
}
/**
* Returns a list of names of components that this component depends
* on directly or indirectly (recursively).
* @return A list of names (Strings).
*/
public List getRecursiveDependComponentNames() {
return component.getRecursiveDependComponentNames();
}
/**
* Returns a map of components (key=name, value=component) that this
* component depends on directly or indirectly (recursively).
* @return A map of components (key=name(String), value=InvictaComponent)
*/
public Map getRecursiveDependComponentsMap() {
return component.getRecursiveDependComponentNamesMap();
}
/**
* Returns the products that this components depends on recursively
* (directly and indirectly, exported and non-exported by dependent components,
* also includes self products).
*
* @return ProductContainer
*/
public ProductContainer getRecursiveProducts() {
return component.getRecursiveProducts();
}
/**
* Returns the products that this components depends on recursively
* (directly and indirectly, exported and non-exported by dependent components,
* doesn't include self products).
*
* @return ProductContainer
*/
public ProductContainer getRecursiveProductsWithoutSelf() {
return component.getRecursiveProductsWithoutSelf();
}
/**
* Returns the products that the product with the given defined name
* depends on recursively (directly and indirectly, exported and non-exported).
*
* @return
* @throws InvictaProjectException
*/
public ProductContainer getRecursiveSelfProducts(List productNames)
throws InvictaProjectException {
return component.getRecursiveSelfProducts(productNames);
}
/**
* Returns the products with the given name that are defined in this component
*
* @param productName
* @return ProductContainer
*/
public ProductContainer getSelfProducts(String productName) {
return component.getSelfProducts(productName);
}
/**
* Returns the products that are defined in this component.
*
* @return ProductContainer
*/
public ProductContainer getSelfProducts() {
return component.getSelfProducts();
}
/**
* Returns the products that the product with the given defined name
* depends on recursively (directly and indirectly, exported and non-exported).
*
* @param productName
* @return
* @throws InvictaProjectException
*/
public ProductContainer getRecursiveSelfProducts(String productName)
throws InvictaProjectException {
return component.getRecursiveSelfProducts(productName);
}
/**
* Returns the full ANT template code of this component.
*
* @return String. ANT template code.
*/
public String getTemplate() {
return type.getAntTemplateString();
}
/**
* Returns the name of the type of this component ('JAR' for example).
*
* @return String. The type name.
*/
public String getTypeName() {
return type.getName();
}
/**
* Returns a list of components that this component depends on (directly).
*
* @return List of InvictaComponent objects.
*/
public List getDependComponents() {
return getComponentsForNames(component.getDependComponentNames());
}
/**
* Returns a product with the given type and name.
* Returns null if a matching product doesn't exist.
*
* @param type Optional. Ignored if null.
* @param name Optional. Ignored if null.
* @return Product
*/
public Product getSelfProduct(String type, String name) {
return component.getSelfProduct(type, name);
}
/**
* Returns a list of components that this componen depends on recursively
* (directly of indirectly).
*
* @return List of InvictaComponent objects.
*/
public List getRecursiveDependComponents() {
return component.getRecursiveDependComponents();
}
/**
*
* @see java.lang.Comparable#compareTo(Object)
*/
public int compareTo(Object object) {
return this.component.getName().compareTo(((TypedComponent)object).getName());
}
/**
* Returns the projec that this component is part of.
* @return InvictaProject
*/
public InvictaProject getProject() {
return this.project;
}
/**
* Returns a map of the properties defined for this component (according
* to the type definition of this component).
* @return Map: Key=String (property name), Value=DefinedProperty
*/
public Map getDefinedPropertiesMap() {
return this.definedProperties;
}
/**
* Returns a list of the properties defined for this component (according
* to the type definition of this component).
* @return List of DefinedProperty objects.
*/
public List getDefinedProperties() {
return new ArrayList(this.definedProperties.values());
}
/**
* Returns a property with the given name that is defined for this
* component.
* @param propertyName
* @return DefinedProperty. null if no property with the given name is defined.
*/
public DefinedProperty getDefinedProperty(String propertyName) {
return (DefinedProperty)this.definedProperties.get(propertyName);
}
/**
* Returns the a reference (ANT property reference) to the value of a
* property (component, project or general) with the given name.
* Returns null if the property is not defined.
*
* @param propertyName
* @return String. For example: ${sample.utils.src.dir}
*/
public String getPropertyReferenceValue(String propertyName) {
DefinedProperty property = getDefinedProperty(propertyName);
if (property == null)
return null;
return property.getReferenceValue();
}
/**
* Returns the name of this component.
*
* @return String. Component name.
*/
public boolean containsTarget(String targetName) {
return type.containsTarget(targetName);
}
/**
* Returns the name of the building target (target template) of
* this component. For example: 'build'.
* @return String. Building target.
*/
public String getBuildTarget() {
return type.getBuildTarget();
}
/**
* Returns the name of the cleaning target (target template) of
* this component. For example: 'clean'.
* @return String. Initialization target.
*/
public String getCleanTarget() {
return type.getCleanTarget();
}
/**
* Returns the name of the distribution target (target template) of
* this component. For example: 'dist'
* @return String. Distribution target.
*/
public String getDistTarget() {
return type.getDistTarget();
}
public Map getTargetMap() {
return this.type.getTargetMap();
}
/**
*
*/
public List getTargetList() {
return this.type.getTargetList();
}
/**
* Returns a value of a property specifically defined in this component's definition.
* @param string
* @return Sting
*/
public String getComponentPropertyValue(String name) {
return this.component.getPropertyValue(name);
}
/**
*
*/
protected void createdTiedDefinedProperties() throws InvictaException {
// Go over all basic defined properties.
for (Iterator iter = this.type.getDefinedProperties().values().iterator(); iter.hasNext();) {
BasicDefinedProperty property = (BasicDefinedProperty) iter.next();
TiedDefinedProperty tiedProperty = new TiedDefinedProperty(property, this, this.project);
this.definedProperties.put(tiedProperty.getName(), tiedProperty);
}
}
protected void validateComponent() throws InvictaException{
// Make sure that all required properties are defined.
for (Iterator iter = this.type.getDefinedProperties().values().iterator(); iter.hasNext();) {
BasicDefinedProperty definedProperty = (BasicDefinedProperty) iter.next();
// Make sure that a component property was defined.
if (definedProperty.isComponentType()) {
if (definedProperty.getDefaultValue() != null) {
this.component.setPropertyValue(definedProperty.getName(), definedProperty.getDefaultValue());
} else if (this.component.getPropertyValue(definedProperty.getName()) == null) {
throw InvictaProcessException.propertyUndefined(
this.type.getName(), this.component.getName(), definedProperty.getName());
}
// Make sure that a project property was defined.
} else if (definedProperty.isProjectType()) {
if (definedProperty.getDefaultValue() != null) {
this.project.setProjectProperty(definedProperty.getName(), definedProperty.getDefaultValue(), definedProperty.getDescription());
} else if (this.project.getProjectPropertyValue(definedProperty.getName()) == null) {
throw InvictaProcessException.projectPropertyUndefined(
this.type.getName(), definedProperty.getName());
}
}
}
}
protected void formatProducts() {
for (Iterator iter = this.component.getSelfProducts().iterator(); iter.hasNext();) {
BasicProduct product = (BasicProduct) iter.next();
DefinedProperty property =
getDefinedProperty(InvictaConstants.PRODUCT_DIR_PROPERTY);
if (property != null) {
product.setProductDir(property.getActualValue());
}
}
}
/**
*
* @param names
* @return List
*/
protected List getComponentsForNames(List names) {
List components = new ArrayList();
for (Iterator iter = names.iterator(); iter.hasNext();) {
String componentName = (String) iter.next();
components.add(this.project.getComponent(componentName));
}
return components;
}
/**
* Returns the name of the initialization target (target template) of
* this component. For example: 'init'.
* @return String. Initialization target.
*/
public String getInitTarget() {
return this.type.getInitTarget();
}
}
|