View Javadoc
1   package org.andromda.core.translation.library;
2   
3   import java.util.ArrayList;
4   import java.util.Collection;
5   import java.util.LinkedHashMap;
6   import java.util.Map;
7   import org.andromda.core.common.ExceptionUtils;
8   import org.andromda.core.translation.TranslationUtils;
9   import org.apache.commons.lang.StringUtils;
10  import org.apache.commons.lang.builder.ToStringBuilder;
11  
12  /**
13   * Represents a translation XML template found within a translation library.
14   *
15   * @author Chad Brandon
16   */
17  public class Translation
18  {
19      private String name;
20      private final Map<String, Fragment> fragments = new LinkedHashMap<String, Fragment>();
21      private final Collection<String> ignorePatterns = new ArrayList<String>();
22  
23      /**
24       * The library translation to which this translation belongs.
25       */
26      private LibraryTranslation libraryTranslation;
27  
28      /**
29       * Gets the LibraryTranslation to which this Translation belongs.
30       *
31       * @return LibraryTranslation
32       */
33      protected LibraryTranslation getLibraryTranslation()
34      {
35          // should never happen, but it doesn't hurt to be safe
36          if (this.libraryTranslation == null)
37          {
38              throw new LibraryException("Translation.getLibraryTranslation - libraryTranslation can not be null");
39          }
40          return libraryTranslation;
41      }
42  
43      /**
44       * Sets the LibraryTranslation to which this Translation belongs.
45       *
46       * @param translation the LibraryTranslation to which this Translation belongs.
47       */
48      protected void setLibraryTranslation(final LibraryTranslation translation)
49      {
50          libraryTranslation = translation;
51      }
52  
53      /**
54       * Gets the fragment matching (using regular expressions) the specified name.
55       *
56       * @param name the name of the fragment to retrieve.
57       * @return Fragment
58       */
59      protected Fragment getFragment(final String name)
60      {
61          Fragment fragment = null;
62          // search through the names and the first name that matches
63          // one of the names return the value of that name.
64          for (String nextName : fragments.keySet())
65          {
66              if (name.matches(nextName))
67              {
68                  fragment = fragments.get(nextName);
69              }
70          }
71  
72          // if the fragment is null, and the name isn't in an ignorePattern
73          // element, then give an error
74          if (fragment == null && !this.isIgnorePattern(name))
75          {
76              // TODO: make this work correctly with unsupported functions.
77  
78              /*
79               * logger.error("ERROR! expression fragment '" + name + "' is not
80               * currently supported --> add a <fragment/> with " + " a name that
81               * matches this expression to your translation file " + "'" +
82               * this.getLibraryTranslation().getFile() + "' to enable support");
83               */
84          }
85          return fragment;
86      }
87  
88      /**
89       * Adds a new Translation fragment to the Translation.
90       *
91       * @param fragment new Translation fragment
92       */
93      public void addFragment(final Fragment fragment)
94      {
95          ExceptionUtils.checkNull(
96              "fragment",
97              fragment);
98          fragment.setTranslation(this);
99          this.fragments.put(
100             fragment.getName(),
101             fragment);
102     }
103 
104     /**
105      * Gets the name of this Translation.
106      *
107      * @return String
108      */
109     protected String getName()
110     {
111         return name;
112     }
113 
114     /**
115      * @param name
116      */
117     protected void setName(final String name)
118     {
119         this.name = name;
120     }
121 
122     /**
123      * Adds an <code>ignorePattern</code> to the Collection of ignorePatterns.
124      *
125      * @param ignorePattern the pattern to ignore.
126      */
127     public void addIgnorePattern(final String ignorePattern)
128     {
129         this.ignorePatterns.add(StringUtils.trimToEmpty(ignorePattern));
130     }
131 
132     /**
133      * Checks to see if the pattern is an ignore pattern. What this means is that if if this pattern matches on a
134      * regular expression found in the collection of ignore patterns then the TranslationLibrary won't complain if it
135      * doesn't match a fragment name.
136      *
137      * @param pattern
138      * @return boolean <code>true</code> if its an ignore pattern, <code>false</code> otherwise.
139      */
140     public boolean isIgnorePattern(String pattern)
141     {
142         boolean isIgnorePattern = false;
143         pattern = StringUtils.trimToEmpty(pattern);
144         // search through the ignorePatterns and see if one
145         // of them matches the passed in pattern.
146         for (String nextIgnorePattern : this.ignorePatterns)
147         {
148             isIgnorePattern = pattern.matches(StringUtils.trimToEmpty(nextIgnorePattern));
149             if (isIgnorePattern)
150             {
151                 break;
152             }
153         }
154         return isIgnorePattern;
155     }
156 
157     /**
158      * Gets the "translated" value of this Fragment if it exists. That is, it retrieves the fragment body for the name
159      * of this fragment and replaces any fragment references with other fragment bodies (if they exist)
160      *
161      * @param name the name of the fragment.
162      * @param kind the kind of the fragment.
163      * @return String the translated body of the fragment kind.
164      */
165     protected String getTranslated(
166         String name,
167         String kind)
168     {
169         // clean the strings first
170         name = StringUtils.trimToEmpty(name);
171         kind = StringUtils.trimToEmpty(kind);
172 
173         ExceptionUtils.checkEmpty(
174             "name",
175             name);
176 
177         Fragment fragment = this.getFragment(name);
178         String translated = "";
179         if (fragment != null)
180         {
181             translated = fragment.getKind(kind);
182             String begin = "fragment{";
183             int beginLength = begin.length();
184             String end = "}";
185             for (int beginIndex = translated.indexOf(begin); beginIndex != -1;
186                 beginIndex = translated.indexOf(begin))
187             {
188                 String fragmentName = translated.substring(
189                         beginIndex + beginLength,
190                         translated.length());
191                 int endIndex = fragmentName.indexOf(end);
192                 if (endIndex != -1)
193                 {
194                     fragmentName = fragmentName.substring(
195                             0,
196                             endIndex);
197                 }
198                 StringBuilder toReplace = new StringBuilder(begin);
199                 toReplace.append(fragmentName);
200                 toReplace.append(end);
201                 translated =
202                     StringUtils.replace(
203                         translated,
204                         toReplace.toString(),
205                         this.getTranslated(
206                             fragmentName,
207                             kind));
208             }
209         }
210         return TranslationUtils.removeExtraWhitespace(translated);
211     }
212 
213     /**
214      * @see Object#toString()
215      */
216     public String toString()
217     {
218         return ToStringBuilder.reflectionToString(this);
219     }
220 }