001package org.andromda.core.mapping;
002
003import java.io.FileNotFoundException;
004import java.io.FileReader;
005import java.util.ArrayList;
006import java.util.Collection;
007import java.util.Iterator;
008import java.util.LinkedHashSet;
009import java.util.List;
010import org.andromda.core.common.ExceptionUtils;
011import org.andromda.core.common.ResourceUtils;
012import org.apache.commons.lang.StringUtils;
013
014/**
015 * A single child mapping instance belonging to a Mappings instance. It doesn't make sense to instantiate this class by
016 * itself.
017 *
018 * @author Chad Brandon
019 * @author Wouter Zoons
020 * @see org.andromda.core.mapping.Mappings
021 */
022public class Mapping
023{
024    /**
025     * Stores the from elements.
026     */
027    private final Collection<String> froms = new LinkedHashSet<String>();
028
029    /**
030     * Adds the <code>from</code> type to the mapping.
031     *
032     * @param from the type that we are mapping from.
033     */
034    public void addFrom(final String from)
035    {
036        ExceptionUtils.checkNull("from", from);
037        froms.add(from);
038    }
039
040    /**
041     * Return the Collection of froms.
042     *
043     * @return Collection
044     */
045    public Collection<String> getFroms()
046    {
047        return froms;
048    }
049
050    /**
051     * Returns the to type for this mapping.
052     *
053     * @return String the to type
054     */
055    public String getTo()
056    {
057        final StringBuilder to = new StringBuilder();
058        if (StringUtils.isNotBlank(this.to))
059        {
060            to.append(this.to);
061        }
062        if (!this.paths.isEmpty())
063        {
064            try
065            {
066                for (final String path : paths)
067                {
068                    to.append(
069                        ResourceUtils.getContents(
070                            new FileReader(this.mappings.getCompletePath(path))));
071                }
072            }
073            catch (final FileNotFoundException exception)
074            {
075                throw new MappingsException(exception);
076            }
077        }
078        return to.toString();
079    }
080
081    /**
082     * Stores any paths used by this mapping.
083     */
084    private final List<String> paths = new ArrayList<String>();
085
086    /**
087     * Adds the path to the listof paths.
088     * @param path
089     */
090    public void addPath(final String path)
091    {
092        this.paths.add(path);
093    }
094
095    /**
096     * Stores the to mapping.
097     */
098    private String to;
099
100    /**
101     * Sets the type for this mapping.
102     *
103     * @param to the value to which the from
104     *        values are mapped.
105     */
106    public void setTo(final String to)
107    {
108        this.to = to;
109    }
110
111    /**
112     * The parent of this instance.
113     */
114    private Mappings mappings;
115
116    /**
117     * Sets the mappings to which this Mapping instance
118     * belongs.
119     *
120     * @param mappings the owning mappings.
121     */
122    final void setMappings(final Mappings mappings)
123    {
124        this.mappings = mappings;
125    }
126
127    /**
128     * Returns a String representation of this mapping in the form of <code>from1, from2, from3 --> to</code>.
129     *
130     * @return a String representing the mapping instance
131     */
132    public String toString()
133    {
134        final StringBuilder buffer = new StringBuilder(512); // 512 should be enough for resizing not to occur
135
136        for (Iterator<String> fromIterator = this.froms.iterator(); fromIterator.hasNext();)
137        {
138            final String from = fromIterator.next();
139            buffer.append(from);
140
141            if (fromIterator.hasNext())
142            {
143                buffer.append(", ");
144            }
145        }
146
147        buffer.append(" --> ").append(this.to);
148
149        return buffer.toString();
150    }
151}