View Javadoc

1   /*
2    * Copyright (c) 2009 QOS.ch All rights reserved.
3    * 
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   * 
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   * 
14   * THE SOFTWARE IS PROVIDED "AS  IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  package ch.qos.cal10n.plugins;
23  
24  import java.io.File;
25  import java.lang.reflect.Constructor;
26  import java.net.MalformedURLException;
27  import java.net.URL;
28  import java.util.ArrayList;
29  import java.util.List;
30  import java.util.Locale;
31  import java.util.Set;
32  
33  import org.apache.maven.artifact.Artifact;
34  import org.apache.maven.artifact.repository.ArtifactRepository;
35  import org.apache.maven.plugin.AbstractMojo;
36  import org.apache.maven.plugin.MojoExecutionException;
37  import org.apache.maven.plugin.MojoFailureException;
38  
39  import ch.qos.cal10n.Cal10nConstants;
40  import ch.qos.cal10n.verifier.IMessageKeyVerifier;
41  
42  /**
43   * Verifies resources bundles in various locales against an enumType
44   * 
45   * @goal verify
46   * @phase verify
47   * @requiresProject true
48   */
49  public class VerifyMojo extends AbstractMojo {
50  
51    final static String MISSING_LOCALE = Cal10nConstants.CODE_URL_PREFIX
52        + "#missingLocale";
53    final static String MISSING_ENUM_TYPES = Cal10nConstants.CODE_URL_PREFIX
54        + "#missingEnumType";
55  
56    /**
57     * @parameter
58     * @required
59     */
60    private String[] enumTypes;
61  
62    /**
63     * The directory for compiled classes.
64     * 
65     * @parameter expression="${project.build.outputDirectory}"
66     * @required
67     * @readonly
68     */
69    private File outputDirectory;
70  
71    // direct dependencies of this project
72    /**
73     * 
74     * @parameter expression="${project.artifacts}"
75     * @required
76     * @readonly
77     */
78    private Set<Artifact> projectArtifacts;
79  
80    /**
81     * @parameter expression="${localRepository}"
82     * @required
83     * @readonly
84     * @since 1.0
85     */
86    private ArtifactRepository localRepository;
87  
88    public void execute() throws MojoExecutionException, MojoFailureException {
89  
90      if (enumTypes == null) {
91        throw new MojoFailureException("Missing <enumTypes> element. Please see "
92            + MISSING_ENUM_TYPES);
93      }
94      for (String enumTypeAsStr : enumTypes) {
95        IMessageKeyVerifier imcv = getMessageKeyVerifierInstance(enumTypeAsStr);
96        getLog()
97            .info(
98                "Checking all resource bundles for enum type [" + enumTypeAsStr
99                    + "]");
100       checkAllLocales(imcv);
101     }
102   }
103 
104   public void checkAllLocales(IMessageKeyVerifier mcv)
105       throws MojoFailureException, MojoExecutionException {
106 
107     String enumClassAsStr = mcv.getEnumTypeAsStr();
108 
109     String[] localeNameArray = mcv.getLocaleNames();
110 
111     if (localeNameArray == null || localeNameArray.length == 0) {
112       String errMsg = "Missing @LocaleNames annotation in enum type ["
113           + enumClassAsStr + "]. Please see "+MISSING_LOCALE;
114       getLog().error(errMsg);
115       throw new MojoFailureException(errMsg);
116     }
117 
118     boolean failure = false;
119     for (String localeName : localeNameArray) {
120       Locale locale = new Locale(localeName);
121       List<String> errorList = mcv.typeIsolatedVerify(locale);
122       if (errorList.size() == 0) {
123         String resouceBundleName = mcv.getResourceBundleName();
124         getLog().info(
125             "SUCCESSFUL verification for resource bundle [" + resouceBundleName
126                 + "] for locale [" + locale + "]");
127       } else {
128         failure = true;
129         getLog().error(
130             "FAILURE during verification of resource bundle for locale ["
131                 + locale + "] enum class [" + enumClassAsStr + "]");
132         for (String s : errorList) {
133           getLog().error(s);
134         }
135       }
136     }
137     if (failure) {
138       throw new MojoFailureException("FAIL Verification of [" + enumClassAsStr
139           + "] keys.");
140     }
141   }
142 
143   IMessageKeyVerifier getMessageKeyVerifierInstance(String enumClassAsStr)
144       throws MojoExecutionException {
145     String errMsg = "Failed to instantiate MessageKeyVerifier class";
146     try {
147       ThisFirstClassLoader thisFirstClassLoader = (ThisFirstClassLoader) buildClassLoader();
148       Class<?> mkvClass = Class.forName(Cal10nConstants.MessageKeyVerifier_FQCN,
149           true, thisFirstClassLoader);
150       Constructor<?> mkvCons = mkvClass.getConstructor(String.class);
151       IMessageKeyVerifier imcv = (IMessageKeyVerifier) mkvCons
152           .newInstance(enumClassAsStr);
153       return imcv;
154     } catch (ClassNotFoundException e) {
155       throw new MojoExecutionException(errMsg, e);
156     } catch (NoClassDefFoundError e) {
157       throw new MojoExecutionException(errMsg, e);
158     } catch (Exception e) {
159       throw new MojoExecutionException(errMsg, e);
160     }
161   }
162 
163   ClassLoader buildClassLoader() {
164     ArrayList<URL> classpathURLList = new ArrayList<URL>();
165     classpathURLList.add(toURL(outputDirectory));
166     classpathURLList.addAll(getDirectDependencies());
167     ClassLoader parentCL = this.getClass().getClassLoader();
168     URL[] classpathURLArray = classpathURLList.toArray(new URL[] {});
169     return new ThisFirstClassLoader(classpathURLArray, parentCL);
170   }
171 
172   List<URL> getDirectDependencies() {
173     ArrayList<URL> urlList = new ArrayList<URL>();
174     for (Artifact a : projectArtifacts) {
175       String pathOfArtifact = localRepository.getBasedir() + "/"
176           + localRepository.pathOf(a);
177       File artifactAsFile = new File(pathOfArtifact);
178       if (!artifactAsFile.exists()) {
179         getLog()
180             .error("Artifact [" + artifactAsFile + "] could not be located");
181       }
182       try {
183         URL url = artifactAsFile.toURI().toURL();
184         urlList.add(url);
185       } catch (MalformedURLException e) {
186         getLog().info("Failed to build URL", e);
187       }
188     }
189     return urlList;
190   }
191 
192   URL toURL(File file) {
193     try {
194       return file.toURI().toURL();
195     } catch (MalformedURLException e) {
196       // this should never happen
197       getLog().error("Failed to convert file [" + file + "] to a URL", e);
198       return null;
199     }
200   }
201 
202 }