BasePlugin.java
package org.andromda.core.common;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.andromda.core.configuration.NamespaceProperties;
import org.andromda.core.configuration.Namespaces;
import org.andromda.core.configuration.Property;
import org.andromda.core.namespace.BaseNamespaceComponent;
import org.andromda.core.templateengine.TemplateEngine;
import org.apache.log4j.Logger;
/**
* Represents the base plugin of AndroMDA. All Plugin instances inherit from this class.
*
* @author Chad Brandon
*/
public abstract class BasePlugin
extends BaseNamespaceComponent
implements Plugin
{
/**
* Property references made available to the plugin
*/
private final Collection<String> propertyReferences = new ArrayList<String>();
/**
* The template objects made available to templates of this BasePlugin.
*/
private final Collection<TemplateObject> templateObjects = new ArrayList<TemplateObject>();
/**
* @see org.andromda.core.common.Plugin#initialize()
*/
public void initialize()
throws Exception
{
// set the template engine merge location (this needs to be
// set before the template engine is initialized) so that the
// merge property can be set once on the template engine.
final Property mergeProperty =
Namespaces.instance().getProperty(
this.getNamespace(),
NamespaceProperties.MERGE_LOCATION,
false);
this.mergeLocation = mergeProperty != null ? new File(mergeProperty.getValue()).toURI().toURL() : null;
if (this.mergeLocation != null)
{
this.getTemplateEngine().setMergeLocation(this.getMergeLocation().getFile());
}
this.getTemplateEngine().initialize(this.getNamespace());
for (final TemplateObject templateObject : this.templateObjects) {
templateObject.setResource(this.getResource());
templateObject.setNamespace(this.getNamespace());
}
}
/**
* The current cartridge merge location.
*/
private URL mergeLocation;
/**
* Gets the current merge location for this plugin.
*
* @return the merge location (a file path).
*/
protected URL getMergeLocation()
{
return this.mergeLocation;
}
/**
* @see org.andromda.core.common.Plugin#shutdown()
*/
public void shutdown()
{
this.getTemplateEngine().shutdown();
}
/**
* Adds the <code>templateObject</code> to the collection of template objects that will be made available to the
* plugin during processing.
*
* @param templateObject the TemplateObject to add.
*/
public void addTemplateObject(final TemplateObject templateObject)
{
if (templateObject != null)
{
this.templateObjects.add(templateObject);
}
}
/**
* Adds a macro library to the TemplateEngine used by this BasePlugin.
*
* @param macrolibrary
*/
public void addMacrolibrary(final String macrolibrary)
{
this.getTemplateEngine().addMacroLibrary(macrolibrary);
}
/**
* @see org.andromda.core.common.Plugin#getTemplateObjects()
*/
public Collection<TemplateObject> getTemplateObjects()
{
return this.templateObjects;
}
private String templateEngineClass;
/**
* Sets the template engine class for this cartridge.
*
* @param templateEngineClass the Class of the template engine implementation.
*/
public void setTemplateEngineClass(final String templateEngineClass)
{
this.templateEngineClass = templateEngineClass;
}
/**
* The template engine that this plugin will use.
*/
private TemplateEngine templateEngine = null;
/**
* @see org.andromda.core.common.Plugin#getTemplateEngine()
*/
public TemplateEngine getTemplateEngine()
{
if (this.templateEngine == null)
{
this.templateEngine =
(TemplateEngine)ComponentContainer.instance().newComponent(
this.templateEngineClass, TemplateEngine.class);
}
return this.templateEngine;
}
/**
* @see org.andromda.core.common.Plugin#getPropertyReferences()
*/
public String[] getPropertyReferences()
{
return this.propertyReferences.toArray(new String[this.propertyReferences.size()]);
}
/**
* Adds a property reference. Property references are those properties that are expected to be supplied by the
* calling client. These supplied properties are made available to the template during processing.
*
* @param reference the namespace of the reference.
*/
public void addPropertyReference(final String reference)
{
this.propertyReferences.add(reference);
}
/**
* Populates the <code>templateContext</code> with the properties and template objects defined in the
* <code>plugin</code>'s descriptor. If the <code>templateContext</code> is null, a new Map instance will be created
* before populating the context.
*
* @param templateContext the context of the template to populate.
*/
protected void populateTemplateContext(Map<String, Object> templateContext)
{
if (templateContext == null)
{
templateContext = new LinkedHashMap<String, Object>();
}
this.addTemplateObjectsToContext(templateContext);
this.addPropertyReferencesToContext(templateContext);
}
/**
* Takes all the template objects defined in the plugin's descriptor and places them in the
* <code>templateContext</code>.
*
* @param templateContext the template context
*/
private void addTemplateObjectsToContext(final Map<String, Object> templateContext)
{
// add all the TemplateObject objects to the template context
final Collection<TemplateObject> templateObjects = this.getTemplateObjects();
if (templateObjects != null && !templateObjects.isEmpty())
{
for (TemplateObject templateObject : templateObjects)
{
templateContext.put(
templateObject.getName(),
templateObject.getObject());
}
}
}
/**
* Takes all the property references defined in the plugin's descriptor and looks up the corresponding values
* supplied by the calling client and supplies them to the <code>templateContext</code>.
*
* @param templateContext the template context
*/
private void addPropertyReferencesToContext(final Map<String, Object> templateContext)
{
final String[] propertyReferences = this.getPropertyReferences();
if (propertyReferences != null && propertyReferences.length > 0)
{
final Namespaces namespaces = Namespaces.instance();
for (final String reference : propertyReferences) {
templateContext.put(
reference,
namespaces.getPropertyValue(
this.getNamespace(),
reference));
}
}
}
/**
* Stores the contents of the plugin.
*/
private List<String> contents = null;
/**
* @see org.andromda.core.common.Plugin#getContents()
*/
public List<String> getContents()
{
if (this.contents == null)
{
if (ResourceUtils.isArchive(this.getResource()))
{
this.contents = ResourceUtils.getClassPathArchiveContents(this.getResource());
if (this.getMergeLocation() != null)
{
final Collection<String> mergeContents = ResourceUtils.getDirectoryContents(
this.getMergeLocation(),
0);
if (mergeContents != null && !mergeContents.isEmpty())
{
this.contents.addAll(mergeContents);
}
}
}
else
{
// we step down 1 level if its a directory (instead of an
// archive since we get the contents relative to the plugin
// resource which is in the META-INF directory
this.contents = ResourceUtils.getDirectoryContents(
this.getResource(),
2);
}
}
return contents;
}
/**
* Retrieves the logger instance that should be used for logging output for the plugin sub classes.
*
* @return the logger.
*/
protected Logger getLogger()
{
return AndroMDALogger.getNamespaceLogger(this.getNamespace());
}
/**
* @see Object#toString()
*/
public String toString()
{
return super.toString() + '[' + this.getNamespace() + ']';
}
}