001package org.andromda.core.translation;
002
003import org.andromda.core.common.ExceptionUtils;
004import org.andromda.core.common.Introspector;
005import org.apache.commons.lang.ObjectUtils;
006import org.apache.commons.lang.StringUtils;
007
008/**
009 * Contains translation utilities.
010 *
011 * @author Chad Brandon
012 */
013public class TranslationUtils
014{
015    /**
016     * <p>
017     * <code>TranslationUtils</code> instances should NOT be constructed in standard programming. Instead, the class
018     * should be used as <code>TranslationUtils.replacePattern(" some pattern ");</code>. </p>
019     * <p>
020     * This constructor is public to permit tools that require a JavaBean instance to operate. </p>
021     */
022    public TranslationUtils()
023    {
024        // Here for documentation purposes
025    }
026
027    /**
028     * Searches for and replaces the specified pattern with braces around it, like so: "{pattern}" every time it
029     * occurs in the string.
030     *
031     * @param string      the string to to perform replacement on.
032     * @param pattern     the pattern to find
033     * @param replaceWith the pattern to place the existing one with.
034     * @return String the string will all replacements
035     */
036    public static String replacePattern(
037        String string,
038        final String pattern,
039        final String replaceWith)
040    {
041        if (string != null)
042        {
043            ExceptionUtils.checkNull("pattern", pattern);
044            ExceptionUtils.checkNull("replaceWith", replaceWith);
045            string = StringUtils.replace(string, '{' + pattern + '}', replaceWith);
046        }
047        return string;
048    }
049
050    /**
051     * Searches for and replaces the specified pattern with braces around it, like so: "{pattern}" the first time it
052     * occurs in the string
053     *
054     * @param string      the string to to perform replacement on.
055     * @param pattern     the pattern to find
056     * @param replaceWith the pattern to place the existing one with.
057     * @return String the string will all replacements
058     */
059    public static String replaceFirstPattern(
060        String string,
061        final String pattern,
062        final String replaceWith)
063    {
064        if (string != null)
065        {
066            ExceptionUtils.checkNull("pattern", pattern);
067            ExceptionUtils.checkNull("replaceWith", replaceWith);
068            string = StringUtils.replaceOnce(string, '{' + pattern + '}', replaceWith);
069        }
070        return string;
071    }
072
073    /**
074     * Returns true if the specified pattern with braces around it, like so: "{pattern}" exists in the string.
075     *
076     * @param string  the string to to perform replacement on.
077     * @param pattern the pattern to find
078     * @return boolean true if the string contains the pattern, false otherwise
079     */
080    public static boolean containsPattern(
081        final String string,
082        final String pattern)
083    {
084        boolean containsPattern = string != null && pattern != null;
085        if (containsPattern)
086        {
087            containsPattern = StringUtils.contains(string, '{' + pattern + '}');
088        }
089        return containsPattern;
090    }
091
092    /**
093     * Calls the object's toString method and trims the value. Returns and empty string if null is given.
094     *
095     * @param object the object to use.
096     * @return String
097     */
098    public static String trimToEmpty(final Object object)
099    {
100        return StringUtils.trimToEmpty(ObjectUtils.toString(object));
101    }
102
103    /**
104     * Calls the object's toString method and deletes any whitespace from the value. Returns and empty string if null is
105     * given.
106     *
107     * @param object the object to deleteWhite space from.
108     * @return String
109     */
110    public static String deleteWhitespace(final Object object)
111    {
112        return StringUtils.deleteWhitespace(ObjectUtils.toString(object));
113    }
114
115    /**
116     * Retrieves the "starting" property name from one that is nested, for example, will return ' <name1>' from the
117     * string <name1>. <name2>. <name3>. If the property isn't nested, then just return the name that is passed in.
118     *
119     * @param property the property.
120     * @return String
121     */
122    public static String getStartingProperty(String property)
123    {
124        StringUtils.trimToEmpty(property);
125        int dotIndex = property.indexOf('.');
126        if (dotIndex != -1)
127        {
128            property = property.substring(0, dotIndex);
129        }
130        return property;
131    }
132
133    /**
134     * Removes any extra whitespace. Does not remove the spaces between the words. Only removes tabs and newline
135     * characters. This is to allow everything to be on one line while keeping the spaces between words.
136     *
137     * @param string the string
138     * @return String the string with the removed extra spaces.
139     */
140    public static String removeExtraWhitespace(final String string)
141    {
142        return string == null ? "" : string.replaceAll("[$\\s]+", " ").trim();
143    }
144
145    /**
146     * Just retrieves properties from a bean, but gives a more informational error when the property can't be
147     * retrieved, it also cleans the resulting property from any excess white space
148     *
149     * @param bean     the bean from which to retrieve the property
150     * @param property the property name
151     * @return Object the value of the property
152     */
153    public static Object getProperty(
154        final Object bean,
155        final String property)
156    {
157        final String methodName = "TranslationUtils.getProperty";
158        try
159        {
160            return Introspector.instance().getProperty(bean, property);
161        }
162        catch (final Exception exception)
163        {
164            throw new TranslatorException(
165                "Error performing " + methodName + " with bean '" + bean + "' and property '" + property + '\'',
166                exception);
167        }
168    }
169
170    /**
171     * Just retrieves properties from a bean, but gives a more informational error when the property can't be
172     * retrieved, it also cleans the resulting property from any excess white space
173     *
174     * @param bean     the bean from which to retrieve the property
175     * @param property the property name
176     * @return Object the value of the property
177     */
178    public static String getPropertyAsString(
179        final Object bean,
180        final String property)
181    {
182        return TranslationUtils.trimToEmpty(TranslationUtils.getProperty(bean, property));
183    }
184}