Package org.andromda.andromdapp

Source Code of org.andromda.andromdapp.AndroMDAppType

package org.andromda.andromdapp;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringWriter;

import java.net.URL;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;

import org.andromda.core.common.ClassUtils;
import org.andromda.core.common.ComponentContainer;
import org.andromda.core.common.Constants;
import org.andromda.core.common.ResourceFinder;
import org.andromda.core.common.ResourceUtils;
import org.andromda.core.common.ResourceWriter;
import org.andromda.core.templateengine.TemplateEngine;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;


/**
* Represents an AndroMDApp type (j2ee, .net, etc).
*
* @author Chad Brandon
*/
public class AndroMDAppType
{
    /**
     * The velocity template context.
     */
    private final Map templateContext = new LinkedHashMap();

    /**
     * The namespace used to initialize the template engine.
     */
    private static final String NAMESPACE = "andromdapp";

    /**
     * The location to which temporary merge location files are written.
     */
    private static final String TEMPORARY_MERGE_LOCATION = Constants.TEMPORARY_DIRECTORY + '/' + NAMESPACE;

    /**
     * Performs any required initialization for the type.
     *
     * @throws Exception
     */
    protected void initialize()
        throws Exception
    {
        if (this.configurations != null)
        {
            for (final Iterator iterator = this.configurations.iterator(); iterator.hasNext();)
            {
                this.templateContext.putAll(((Configuration)iterator.next()).getAllProperties());
            }
        }
    }

    /**
     * Prompts the user for the input required to generate an application with
     * the correct information and returns the descriptor contents after being interpolated by all
     * properties in the template context.
     *
     * @return the results of the interpolated descriptor.
     * @throws Exception
     */
    protected String promptUser()
        throws Exception
    {
        for (final Iterator iterator = this.getPrompts().iterator(); iterator.hasNext();)
        {
            final Prompt prompt = (Prompt)iterator.next();
            final String id = prompt.getId();

            boolean validPreconditions = true;
            for (final Iterator preconditionsIterator = prompt.getPreconditions().iterator();
                preconditionsIterator.hasNext();)
            {
                final Conditions preconditions = (Conditions)preconditionsIterator.next();
                final String conditionsType = preconditions.getType();
                for (final Iterator conditionIterator = preconditions.getConditions().iterator();
                    conditionIterator.hasNext();)
                {
                    final Condition precondition = (Condition)conditionIterator.next();
                    validPreconditions = precondition.evaluate(this.templateContext.get(precondition.getId()));

                    // - if we're 'anding' the conditions, we break at the first false
                    if (Conditions.TYPE_AND.equals(conditionsType))
                    {
                        if (!validPreconditions)
                        {
                            break;
                        }
                    }
                    else
                    {
                        // otherwise we break at the first true condition
                        if (validPreconditions)
                        {
                            break;
                        }
                    }
                }
            }

            if (validPreconditions)
            {
                Object response = this.templateContext.get(id);

                // - only prompt when the id isn't already in the context
                if (response == null)
                {
                    do
                    {
                        response = this.promptForInput(prompt);
                    }
                    while (!prompt.isValidResponse(ObjectUtils.toString(response)));
                }
                this.setConditionalProperties(
                    prompt.getConditions(),
                    response);
                if (prompt.isSetResponseAsTrue())
                {
                    this.templateContext.put(
                        response,
                        Boolean.TRUE);
                }
                this.templateContext.put(
                    id,
                    prompt.getResponse(response));
            }
        }
        return this.getTemplateEngine().getEvaluatedExpression(
            ResourceUtils.getContents(this.resource),
            this.templateContext);
    }

    /**
     * Prompts the user for the information contained in the given
     * <code>prompt</code>.
     *
     * @param prompt the prompt from which to format the prompt text.
     * @return the response of the prompt.
     */
    private String promptForInput(final Prompt prompt)
    {
        this.printPromptText(prompt.getText());
        final String input = this.readLine();
        return input;
    }

    /**
     * Prompts the user for the information contained in the given
     * <code>prompt</code>.
     *
     * @param prompt the prompt from which to format the prompt text.
     * @return the response of the prompt.
     */
    private void setConditionalProperties(
        final List conditions,
        final Object value)
    {
        for (final Iterator iterator = conditions.iterator(); iterator.hasNext();)
        {
            final Condition condition = (Condition)iterator.next();
            final String equalCondition = condition.getEqual();
            if (equalCondition != null && equalCondition.equals(value))
            {
                this.setProperties(condition);
            }
            final String notEqualCondition = condition.getNotEqual();
            if (notEqualCondition != null && !notEqualCondition.equals(value))
            {
                this.setProperties(condition);
            }
        }
    }

    /**
     * Sets the prompt values from the given <code>condition</code>.
     *
     * @param condition the condition from which to populate the values.
     */
    private void setProperties(final Condition condition)
    {
        if (condition != null)
        {
            final Map values = condition.getProperties();
            for (final Iterator valueIterator = values.keySet().iterator(); valueIterator.hasNext();)
            {
                final String id = (String)valueIterator.next();
                this.templateContext.put(
                    id,
                    values.get(id));
            }
        }
    }

    /**
     * The template engine class.
     */
    private String templateEngineClass;

    /**
     * Sets the class of the template engine to use.
     *
     * @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;

    /**
     * Gets the template that that will process the templates.
     *
     * @return the template engine instance.
     * @throws Exception
     */
    private TemplateEngine getTemplateEngine()
        throws Exception
    {
        if (this.templateEngine == null)
        {
            this.templateEngine =
                (TemplateEngine)ComponentContainer.instance().newComponent(
                    this.templateEngineClass,
                    TemplateEngine.class);
            this.getTemplateEngine().setMergeLocation(TEMPORARY_MERGE_LOCATION);
            this.getTemplateEngine().initialize(NAMESPACE);
        }
        return this.templateEngine;
    }

    /**
     * Stores the template engine exclusions.
     */
    private Map templateEngineExclusions = new LinkedHashMap();

    /**
     * Adds a template engine exclusion (these are the things that the template engine
     * will exclude when processing templates)
     *
     * @param path the path to the resulting output
     * @param patterns any patterns to which the conditions should apply
     */
    public void addTemplateEngineExclusion(
        final String path,
        final String patterns)
    {
        this.templateEngineExclusions.put(
            path,
            AndroMDAppUtils.stringToArray(patterns));
    }

    /**
     * Gets the template engine exclusions.
     *
     * @return the map of template engine exclusion paths and its patterns (if it has any defined).
     */
    final Map getTemplateEngineExclusions()
    {
        return this.templateEngineExclusions;
    }

    /**
     * The 'yes' response.
     */
    private static final String RESPONSE_YES = "yes";

    /**
     * The 'no' response.
     */
    private static final String RESPONSE_NO = "no";

    /**
     * A margin consisting of some whitespace.
     */
    private static final String MARGIN = "    ";

    /**
     * Stores the forward slash character.
     */
    private static final String FORWARD_SLASH = "/";

    /**
     * Processes the files for the project.
     *
     * @param write whether or not the resources should be written when collected.
     * @throws Exception
     */
    protected List processResources(boolean write)
        throws Exception
    {
        // - all resources that have been processed.
        final List processedResources = new ArrayList();
        final File rootDirectory = this.verifyRootDirectory(new File(this.getRoot()));
        final String bannerStart = write ? "G e n e r a t i n g" : "R e m o v i n g";
        this.printLine();
        this.printText(MARGIN + bannerStart + "   A n d r o M D A   P o w e r e d   A p p l i c a t i o n");
        this.printLine();
        rootDirectory.mkdirs();

        final Map locations = new LinkedHashMap();

        // - first write any mapped resources
        for (final Iterator iterator = this.resourceLocations.iterator(); iterator.hasNext();)
        {
            final String location = (String)iterator.next();
            final URL[] resourceDirectories = ResourceFinder.findResources(location);
            if (resourceDirectories != null)
            {
                final int numberOfResourceDirectories = resourceDirectories.length;
                for (int ctr = 0; ctr < numberOfResourceDirectories; ctr++)
                {
                    final URL resourceDirectory = resourceDirectories[ctr];
                    final List contents = ResourceUtils.getDirectoryContents(
                            resourceDirectory,
                            false,
                            null);
                    final Set newContents = new LinkedHashSet();
                    locations.put(
                        location,
                        newContents);
                    for (final ListIterator contentsIterator = contents.listIterator(); contentsIterator.hasNext();)
                    {
                        final String path = (String)contentsIterator.next();
                        if (!path.endsWith(FORWARD_SLASH))
                        {
                            boolean hasNewPath = false;
                            for (final Iterator mappingIterator = this.mappings.iterator(); mappingIterator.hasNext();)
                            {
                                final Mapping mapping = (Mapping)mappingIterator.next();
                                String newPath = mapping.getMatch(path);
                                if (newPath != null && newPath.length() > 0)
                                {
                                    final URL absolutePath = ResourceUtils.getResource(path);
                                    if (absolutePath != null)
                                    {
                                        newPath =
                                            this.getTemplateEngine().getEvaluatedExpression(
                                                newPath,
                                                this.templateContext);
                                        ResourceWriter.instance().writeUrlToFile(
                                            absolutePath,
                                            ResourceUtils.normalizePath(TEMPORARY_MERGE_LOCATION + '/' + newPath));
                                        newContents.add(newPath);
                                        hasNewPath = true;
                                    }
                                }
                            }
                            if (!hasNewPath)
                            {
                                newContents.add(path);
                            }
                        }
                    }
                }
            }
        }

        // - second process and write any output from the defined resource locations.
        for (final Iterator iterator = locations.keySet().iterator(); iterator.hasNext();)
        {
            final String location = (String)iterator.next();
            final Collection contents = (Collection)locations.get(location);
            if (contents != null)
            {
                for (final Iterator contentsIterator = contents.iterator(); contentsIterator.hasNext();)
                {
                    final String path = (String)contentsIterator.next();
                    final String projectRelativePath = StringUtils.replace(
                            path,
                            location,
                            "");
                    if (this.isWriteable(projectRelativePath))
                    {
                        if (this.isValidTemplate(path))
                        {
                            final File outputFile =
                                new File(
                                    rootDirectory.getAbsolutePath(),
                                    this.trimTemplateExtension(projectRelativePath));
                            if (write)
                            {
                                final StringWriter writer = new StringWriter();
                                try
                                {
                                    this.getTemplateEngine().processTemplate(
                                        path,
                                        this.templateContext,
                                        writer);
                                }
                                catch (final Throwable throwable)
                                {
                                    throw new AndroMDAppException("An error occured while processing template --> '" +
                                        path + "' with template context '" + this.templateContext + "'", throwable);
                                }
                                writer.flush();
                                this.printText(MARGIN + "Output: '" + outputFile.toURI().toURL() + "'");
                                ResourceWriter.instance().writeStringToFile(
                                    writer.toString(),
                                    outputFile);
                            }
                            processedResources.add(outputFile);
                        }
                        else if (!path.endsWith(FORWARD_SLASH))
                        {
                            final File outputFile = new File(
                                    rootDirectory.getAbsolutePath(),
                                    projectRelativePath);

                            // - try the template engine merge location first
                            URL resource =
                                ResourceUtils.toURL(ResourceUtils.normalizePath(TEMPORARY_MERGE_LOCATION + '/' + path));
                            if (resource == null)
                            {
                                // - if we didn't find the file in the merge location, try the classpath
                                resource = ClassUtils.getClassLoader().getResource(path);
                            }
                            if (resource != null)
                            {
                                if (write)
                                {
                                    ResourceWriter.instance().writeUrlToFile(
                                        resource,
                                        outputFile.toString());
                                    this.printText(MARGIN + "Output: '" + outputFile.toURI().toURL() + "'");
                                }
                                processedResources.add(outputFile);
                            }
                        }
                    }
                }
            }
        }

        // - write any directories that are defined.
        for (final Iterator directoryIterator = this.directories.iterator(); directoryIterator.hasNext();)
        {
            final String directoryPath = ((String)directoryIterator.next()).trim();
            final File directory = new File(rootDirectory, directoryPath);
            if (this.isWriteable(directoryPath))
            {
                directory.mkdirs();
                this.printText(MARGIN + "Output: '" + directory.toURI().toURL() + "'");
            }
        }

        if (write)
        {
            // - write the "instructions can be found" information
            this.printLine();
            this.printText(MARGIN + "New application generated to --> '" + rootDirectory.toURI().toURL() + "'");
            if (this.instructions != null && this.instructions.trim().length() > 0)
            {
                File instructions = new File(
                        rootDirectory.getAbsolutePath(),
                        this.instructions);
                if (!instructions.exists())
                {
                    throw new AndroMDAppException("No instructions are available at --> '" + instructions +
                        "', please make sure you have the correct instructions defined in your descriptor --> '" +
                        this.resource + "'");
                }
                this.printText(MARGIN + "Instructions for your new application --> '" + instructions.toURI().toURL() + "'");
            }
            this.printLine();
        }
        return processedResources;
    }

    /**
     * Indicates whether or not this path is <em>writable</em>
     * based on the path and any output conditions that may be specified.
     *
     * @param path the path to check.
     * @return true/false
     */
    private boolean isWriteable(String path)
    {
        path = path.replaceAll(
                "\\\\+",
                FORWARD_SLASH);
        if (path.startsWith(FORWARD_SLASH))
        {
            path = path.substring(
                    1,
                    path.length());
        }

        Boolean writable = null;

        final Map evaluatedPaths = new LinkedHashMap();
        for (final Iterator iterator = this.outputConditions.iterator(); iterator.hasNext();)
        {
            final Conditions conditions = (Conditions)iterator.next();
            final Map outputPaths = conditions.getOutputPaths();
            final String conditionsType = conditions.getType();
            int ctr = 0;
            for (final Iterator pathIterator = outputPaths.keySet().iterator(); pathIterator.hasNext(); ctr++)
            {
                final String outputPath = (String)pathIterator.next();

                // - only evaluate if we haven't yet evaluated
                writable = (Boolean)evaluatedPaths.get(path);
                if (writable == null)
                {
                    if (path.startsWith(outputPath))
                    {
                        final String[] patterns = (String[])outputPaths.get(outputPath);
                        if (ResourceUtils.matchesAtLeastOnePattern(
                                path,
                                patterns))
                        {
                            // - assume writable is false, since the path matches at least one conditions path.
                            for (final Iterator conditionIterator = conditions.getConditions().iterator();
                                conditionIterator.hasNext();)
                            {
                                final Condition condition = (Condition)conditionIterator.next();
                                final String id = condition.getId();
                                if (id != null && id.trim().length() > 0)
                                {
                                    final boolean result = condition.evaluate(this.templateContext.get(id));
                                    writable = Boolean.valueOf(result);
                                    if (Conditions.TYPE_AND.equals(conditionsType) && !result)
                                    {
                                        // - if we 'and' the conditions, we break at the first false
                                        break;
                                    }
                                    else if (Conditions.TYPE_OR.equals(conditionsType) && result)
                                    {
                                        // - otherwise we break at the first true condition
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    if (writable != null)
                    {
                        evaluatedPaths.put(
                            path,
                            writable);
                    }
                }
            }
        }

        // - if writable is still null, set to true
        if (writable == null)
        {
            writable = Boolean.TRUE;
        }
        return writable.booleanValue();
    }

    /**
     * Indicates whether or not the given <code>path</code> matches at least
     * one of the file extensions stored in the {@link #templateExtensions}
     * and isn't in the template engine exclusions.
     *
     * @param path the path to check.
     * @return true/false
     */
    private boolean isValidTemplate(final String path)
    {
        boolean exclude = false;
        final Map exclusions = this.getTemplateEngineExclusions();
        for (final Iterator pathIterator = exclusions.keySet().iterator(); pathIterator.hasNext();)
        {
            final String exclusionPath = (String)pathIterator.next();
            if (path.startsWith(exclusionPath))
            {
                final String[] patterns = (String[])exclusions.get(exclusionPath);
                exclude = ResourceUtils.matchesAtLeastOnePattern(
                    exclusionPath,
                    patterns);
                if (exclude)
                {
                    break;
                }
            }
        }
        boolean validTemplate = false;
        if (!exclude)
        {
            if (this.templateExtensions != null)
            {
                final int numberOfExtensions = this.templateExtensions.length;
                for (int ctr = 0; ctr < numberOfExtensions; ctr++)
                {
                    final String extension = '.' + this.templateExtensions[ctr];
                    validTemplate = extension != null && path.endsWith(extension);
                    if (validTemplate)
                    {
                        break;
                    }
                }
            }
        }
        return validTemplate;
    }

    /**
     * Trims the first template extension it encounters and returns.
     *
     * @param path the path of which to trim the extension.
     * @return the trimmed path.
     */
    private String trimTemplateExtension(String path)
    {
        if (this.templateExtensions != null)
        {
            final int numberOfExtensions = this.templateExtensions.length;
            for (int ctr = 0; ctr < numberOfExtensions; ctr++)
            {
                final String extension = '.' + this.templateExtensions[ctr];
                if (extension != null && path.endsWith(extension))
                {
                    path = path.substring(
                            0,
                            path.length() - extension.length());
                    break;
                }
            }
        }
        return path;
    }

    /**
     * Prints a line separator.
     */
    private void printLine()
    {
        this.printText("-------------------------------------------------------------------------------------");
    }

    /**
     * Verifies that if the root directory already exists, the user is prompted
     * to make sure its ok if we generate over it, otherwise the user can change
     * his/her application directory.
     *
     * @param rootDirectory the root directory that will be verified.
     * @return the appropriate root directory.
     */
    private File verifyRootDirectory(final File rootDirectory)
    {
        File applicationRoot = rootDirectory;
        if (rootDirectory.exists() && !this.isOvewrite())
        {
            this.printPromptText(
                "'" + rootDirectory.getAbsolutePath() +
                "' already exists, would you like to try a new name? [yes, no]: ");
            String response = this.readLine();
            while (!RESPONSE_YES.equals(response) && !RESPONSE_NO.equals(response))
            {
                response = this.readLine();
            }
            if (RESPONSE_YES.equals(response))
            {
                this.printPromptText("Please enter the name for your application root directory: ");
                String rootName;
                do
                {
                    rootName = this.readLine();
                }
                while (rootName == null || rootName.trim().length() == 0);
                applicationRoot = this.verifyRootDirectory(new File(rootName));
            }
        }
        return applicationRoot;
    }

    /**
     * Indicates whether or not this andromdapp type should overwrite any
     * previous applications with the same name.  This returns true on the first
     * configuration that has that flag set to true.
     *
     * @return true/false
     */
    private boolean isOvewrite()
    {
        boolean overwrite = false;
        if (this.configurations != null)
        {
            for (final Iterator iterator = this.configurations.iterator(); iterator.hasNext();)
            {
                final Configuration configuration = (Configuration)iterator.next();
                overwrite = configuration.isOverwrite();
                if (overwrite)
                {
                    break;
                }
            }
        }
        return overwrite;
    }

    /**
     * Prints text to the console.
     *
     * @param text the text to print to the console;
     */
    private void printPromptText(final String text)
    {
        System.out.println();
        this.printText(text);
    }

    /**
     * Prints text to the console.
     *
     * @param text the text to print to the console;
     */
    private void printText(final String text)
    {
        System.out.println(text);
        System.out.flush();
    }

    /**
     * Reads a line from standard input and returns the value.
     *
     * @return the value read from standard input.
     */
    private String readLine()
    {
        final BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
        String inputString = null;
        try
        {
            inputString = input.readLine();
        }
        catch (final IOException exception)
        {
            inputString = null;
        }
        return inputString == null || inputString.trim().length() == 0 ? null : inputString;
    }

    /**
     * The type of this AndroMDAppType (i.e. 'j2ee', '.net', etc).
     */
    private String type;

    /**
     * Gets the type of this AndroMDAppType.
     *
     * @return Returns the type.
     */
    public String getType()
    {
        return this.type;
    }

    /**
     * Sets the type of this AndroMDAppType.
     *
     * @param type The type to set.
     */
    public void setType(String type)
    {
        this.type = type;
    }

    /**
     * The root directory in which the application will be created.
     */
    private String root;

    /**
     * Gets the application root directory name.
     *
     * @return Returns the root.
     */
    public String getRoot()
    {
        return this.root;
    }

    /**
     * Sets the application root directory name.
     *
     * @param root The root to set.
     */
    public void setRoot(String root)
    {
        this.root = root;
    }

    /**
     * Stores any configuration information used when running this type.
     */
    private List configurations;

    /**
     * Sets the configuration instance for this type.
     *
     * @param configuration the optional configuration instance.
     */
    final void setConfigurations(final List configurations)
    {
        this.configurations = configurations;
    }

    /**
     * Stores the available prompts for this andromdapp.
     */
    private final List prompts = new ArrayList();

    /**
     * Adds a prompt to the collection of prompts contained within this
     * instance.
     *
     * @param prompt the prompt to add.
     */
    public void addPrompt(final Prompt prompt)
    {
        this.prompts.add(prompt);
    }

    /**
     * Gets all available prompts.
     *
     * @return the list of prompts.
     */
    public List getPrompts()
    {
        return this.prompts;
    }

    /**
     * The locations where templates are stored.
     */
    private List resourceLocations = new ArrayList();

    /**
     * Adds a location where templates and or project files are located.
     *
     * @param resourceLocation the path to location.
     */
    public void addResourceLocation(final String resourceLocation)
    {
        this.resourceLocations.add(resourceLocation);
    }

    /**
     * The any empty directories that should be created when generating the
     * application.
     */
    private List directories = new ArrayList();

    /**
     * The relative path to the directory to be created.
     *
     * @param directory the path to the directory.
     */
    public void addDirectory(final String directory)
    {
        this.directories.add(directory);
    }

    /**
     * Stores the output conditions (that is the conditions
     * that must apply for the defined output to be written).
     */
    private List outputConditions = new ArrayList();

    /**
     * Adds an conditions element to the output conditions..
     *
     * @param outputCondition the output conditions to add.
     */
    public void addOutputConditions(final Conditions outputConditions)
    {
        this.outputConditions.add(outputConditions);
    }

    /**
     * Stores the patterns of the templates that the template engine should
     * process.
     */
    private String[] templateExtensions;

    /**
     * @param templateExtensions The templateExtensions to set.
     */
    public void setTemplateExtensions(final String templateExtensions)
    {
        this.templateExtensions = AndroMDAppUtils.stringToArray(templateExtensions);
    }

    /**
     * The path to the instructions on how to operation the build of the new
     * application.
     */
    private String instructions;

    /**
     * Sets the path to the instructions (i.e.could be a path to a readme file).
     *
     * @param instructions the path to the instructions.
     */
    public void setInstructions(final String instructions)
    {
        this.instructions = instructions;
    }

    /**
     * @see java.lang.Object#toString()
     */
    public String toString()
    {
        return super.toString() + "[" + this.getType() + "]";
    }

    /**
     * The resource that configured this AndroMDAppType instance.
     */
    URL resource;

    /**
     * Sets the resource that configured this AndroMDAppType instance.
     *
     * @param resource the resource.
     */
    final void setResource(final URL resource)
    {
        this.resource = resource;
    }

    /**
     * Gets the resource that configured this instance.
     *
     * @return the resource.
     */
    final URL getResource()
    {
        return this.resource;
    }

    /**
     * Stores any of the mappings available to this type.
     */
    private List mappings = new ArrayList();

    /**
     * Adds a new mapping to this type.
     *
     * @param mapping the mapping which maps the new output paths.
     */
    public void addMapping(final Mapping mapping)
    {
        this.mappings.add(mapping);
    }

    /**
     * Adds the given map of properties to the current template context.
     *
     * @param map the map of properties.
     */
    final void addToTemplateContext(final Map map)
    {
        this.templateContext.putAll(map);
    }

    /**
     * Gets the current template context for this instance.
     *
     * @return the template context.
     */
    final Map getTemplateContext()
    {
        return this.templateContext;
    }

    /**
     * Instantiates the template object with the given <code>className</code> and adds
     * it to the current template context.
     *
     * @param name the name of the template variable.
     * @param className the name of the class to instantiate.
     */
    public void addTemplateObject(
        final String name,
        final String className)
    {
        this.templateContext.put(
            name,
            ClassUtils.newInstance(className));
    }
}
TOP

Related Classes of org.andromda.andromdapp.AndroMDAppType

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.