001 package org.andromda.translation.ocl.testsuite;
002
003 import java.io.File;
004 import java.net.URL;
005 import java.util.Arrays;
006 import java.util.LinkedHashMap;
007 import java.util.List;
008 import java.util.Map;
009 import org.andromda.core.common.XmlObjectFactory;
010 import org.apache.commons.lang.StringUtils;
011 import org.apache.log4j.Logger;
012
013
014 /**
015 * Finds all translation tests from the current base directory up.
016 *
017 * @author Chad Brandon
018 */
019 public class TranslationTestDiscoverer
020 {
021 private static final Logger logger = Logger.getLogger(TranslationTestDiscoverer.class);
022
023 /**
024 * This is the prefix of translation tests, each translation test must start with this in order to be found.
025 */
026 private static final String TEST_PREFIX = "TranslationTest-";
027
028 /**
029 * Names of ignored files when file.isDirectory()
030 */
031 private static final List<String> IGNORED_DIRECTORIES = Arrays.asList("CVS", ".svn");
032
033 /**
034 * Stores the discovered translation tests.
035 */
036 private Map<String, TranslationTest> translationTests = new LinkedHashMap<String, TranslationTest>();
037
038 /**
039 * The shared instance
040 */
041 private static TranslationTestDiscoverer instance;
042
043 /**
044 * Gets the shared instance of this TranslationTestDiscoverer.
045 *
046 * @return the shared TranslationTestDiscoverer.
047 */
048 public static TranslationTestDiscoverer instance()
049 {
050 if (instance == null)
051 {
052 instance = new TranslationTestDiscoverer();
053 }
054 return instance;
055 }
056
057 /**
058 * This method discovers all translation tests within the given <code>directory</code>.
059 * @param directory
060 */
061 public void discoverTests(final String directory)
062 {
063 if (StringUtils.isBlank(directory))
064 {
065 throw new TranslationTestDiscovererException("The 'directory' " +
066 " was not specified, please specify this value with the location from which to" +
067 " begin the discovery of translation test files");
068 }
069 if (this.translationTests.isEmpty())
070 {
071 this.discoverTests(new File(directory));
072 }
073 }
074
075 /**
076 * This method discovers all translation tests within the <code>currentDirectory</code>, it travels down the
077 * directory structure looking for files that have a prefix of 'TranslationTest-'.
078 */
079 private void discoverTests(final File currentDirectory)
080 {
081 try
082 {
083 final String[] files = currentDirectory.list();
084 if (files == null || files.length == 0)
085 {
086 if (logger.isDebugEnabled())
087 {
088 logger.debug("no files or directories found in directory '" + currentDirectory + '\'');
089 }
090 } else
091 {
092 for (String filename : files)
093 {
094 File file = new File(currentDirectory, filename);
095 if (StringUtils.trimToEmpty(file.getName()).startsWith(TEST_PREFIX))
096 {
097 final URL testUrl = file.toURI().toURL();
098 if (logger.isInfoEnabled())
099 {
100 logger.info("found translation test --> '" + testUrl + '\'');
101 }
102
103 TranslationTest test =
104 (TranslationTest) XmlObjectFactory.getInstance(TranslationTest.class).getObject(testUrl);
105 test.setUri(testUrl);
106 this.translationTests.put(
107 test.getTranslation(),
108 test);
109 } else if (file.isDirectory() && !IGNORED_DIRECTORIES.contains(file.getName()))
110 {
111 this.discoverTests(file);
112 }
113 }
114 }
115 }
116 catch (final Throwable throwable)
117 {
118 logger.error(throwable);
119 throw new TranslationTestDiscovererException(throwable);
120 }
121 }
122
123 /**
124 * Returns the TranslationTest for the given <code>translation</code> (if one can be found), otherwise returns
125 * null.
126 *
127 * @param translation the name of the translation
128 * @return TranslationTest
129 */
130 public TranslationTest getTest(String translation)
131 {
132 return this.translationTests.get(StringUtils.trimToEmpty(translation));
133 }
134
135 /**
136 * Returns the discovered translation tests keyed by <code>translation<code>.
137 * @return translationTests
138 */
139 public Map<String, TranslationTest> getTests()
140 {
141 return this.translationTests;
142 }
143
144 /**
145 * Shuts down this instance and releases any resources.
146 */
147 public void shutdown()
148 {
149 this.translationTests.clear();
150 TranslationTestDiscoverer.instance = null;
151 }
152 }