001package org.andromda.core.cartridge.template;
002
003import java.io.File;
004import org.andromda.core.cartridge.Resource;
005import org.andromda.core.common.XmlObjectFactory;
006import org.andromda.core.metafacade.MetafacadeConstants;
007import org.apache.commons.lang.StringUtils;
008
009/**
010 * This class implements the <code>&lt;template&gt;</code> tag in a cartridge
011 * descriptor file.
012 *
013 * @author <a href="http://www.mbohlen.de">Matthias Bohlen </a>
014 * @author Anthony Mowers
015 * @author Chad Brandon
016 * @author Bob Fields
017 */
018public class Template
019    extends Resource
020{
021    /**
022     * The default constructor used by the {@link XmlObjectFactory} to instantiate the template configuration.
023     */
024    public Template()
025    {
026        this.supportedModelElements = new ModelElements();
027    }
028
029    /**
030     * A flag indicating whether or not empty files should
031     * be generated.
032     */
033    private boolean generateEmptyFiles = false;
034
035    /**
036     * Tells us whether output files should be generated if this template does not produce any output.
037     *
038     * @param generateEmptyFiles generate files for empty output yes/no
039     */
040    public void setGenerateEmptyFiles(final boolean generateEmptyFiles)
041    {
042        this.generateEmptyFiles = generateEmptyFiles;
043    }
044
045    /**
046     * Tells us whether output files are generated by this template if the template produces empty output.
047     *
048     * @return boolean
049     */
050    public boolean isGenerateEmptyFiles()
051    {
052        return generateEmptyFiles;
053    }
054
055    /**
056     * Returns the fully qualified output file, this means:
057     * <ul>
058     * <li>the output pattern has been translated</li>
059     * <li>the output dir name has been prepended</li>
060     * </ul>
061     *
062     * @param metafacadeName name of the metafacade.
063     * @param packageName name of the package from the model in which the class
064     *        is contained
065     * @param directory the directory as a File.
066     * @param outputPattern if defined, this overrides the value of {@link Resource#getOutputPattern()}.
067     * @return File absolute directory.
068     */
069    public File getOutputLocation(
070        final String metafacadeName,
071        final String packageName,
072        final File directory,
073        String outputPattern)
074    {
075        File file;
076
077        if (StringUtils.isBlank(outputPattern))
078        {
079            outputPattern = this.getOutputPattern();
080        }
081        // - if singleFileOutput is set to true, then
082        //   just use the output pattern as the file to
083        //   output to, otherwise we replace using message format.
084        if (this.isOutputToSingleFile())
085        {
086            file = super.getOutputLocation(
087                    new String[] {outputPattern},
088                    directory,
089                    outputPattern);
090        }
091        else
092        {
093            file =
094                super.getOutputLocation(
095                    new String[]
096                    {
097                        StringUtils.replace(
098                            StringUtils.trimToEmpty(packageName),
099                            MetafacadeConstants.NAMESPACE_SCOPE_OPERATOR,
100                            File.separator), metafacadeName
101                    },
102                    directory,
103                    outputPattern);
104        }
105        return file;
106    }
107
108    /**
109     * Tells us the model elements that are supported by this template (i.e. will be processed by this template)
110     *
111     * @return ModelElements all the model elements that should be processed by thsi template
112     * @see org.andromda.core.cartridge.template.ModelElements
113     */
114    public ModelElements getSupportedModeElements()
115    {
116        final String methodName = "Template.getModelElements";
117        if (this.supportedModelElements == null)
118        {
119            throw new TemplateException(methodName + " - supportedModelElements is null!");
120        }
121        return this.supportedModelElements;
122    }
123
124    /**
125     * Sets the model elements that are supported by this template.
126     *
127     * @param supportedModelElements the ModelElements instance.
128     * @see org.andromda.core.cartridge.template.ModelElements
129     */
130    public void setSupportedModelElements(final ModelElements supportedModelElements)
131    {
132        this.supportedModelElements = supportedModelElements;
133    }
134
135    private boolean outputToSingleFile = false;
136
137    /**
138     * If output to single file is <code>true</code> then all model elements found by the processor (i.e. all those
139     * having matching modelElements) will aggregated and output to one single file.
140     *
141     * @return Returns the outputToSingleFile.
142     */
143    public boolean isOutputToSingleFile()
144    {
145        return outputToSingleFile;
146    }
147
148    /**
149     * Sets whether or not we should aggregate elements and output to a single file.
150     *
151     * @param outputToSingleFile The outputToSingleFile to set.
152     */
153    public void setOutputToSingleFile(final boolean outputToSingleFile)
154    {
155        this.outputToSingleFile = outputToSingleFile;
156    }
157
158    /**
159     * Indicates whether or not files should be output when there are no elements when aggregating.
160     */
161    private boolean outputOnEmptyElements = true;
162
163    /**
164     * Indicates that when there are no elements in the collection of elements (when {@link #isOutputToSingleFile()} is
165     * <code>true</code>, whether or not the file should be output.  Default is <code>true</code>
166     *
167     * @return true/false
168     * @see #isOutputToSingleFile()
169     */
170    public boolean isOutputOnEmptyElements()
171    {
172        return this.outputOnEmptyElements;
173    }
174
175    /**
176     * Sets whether or not we should output a file when no elements exist in the collection of elements when {@link
177     * #isOutputToSingleFile()} returns <code>true</code>.
178     *
179     * @param outputOnEmptyElements the boolean flag.
180     * @see #isOutputOnEmptyElements()
181     * @see #isOutputToSingleFile()
182     */
183    public void setOutputOnEmptyElements(final boolean outputOnEmptyElements)
184    {
185        this.outputOnEmptyElements = outputOnEmptyElements;
186    }
187
188    /**
189     * @see Object#toString()
190     */
191    @Override
192    public String toString()
193    {
194        StringBuilder builder = new StringBuilder();
195        builder.append(super.toString());
196        builder.append(" [generateEmptyFiles=").append(this.generateEmptyFiles);
197        builder.append(", outputToSingleFile=").append(this.outputToSingleFile);
198        builder.append(", outputOnEmptyElements=").append(this.outputOnEmptyElements);
199        builder.append(", supportedModelElements=").append(this.supportedModelElements);
200        builder.append("]");
201        return builder.toString();
202    }
203
204    /**
205     * The model elements (i.e. metafacades) supported by this template.
206     */
207    private ModelElements supportedModelElements = null;
208}