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.text.MessageFormat;
29  import java.util.ArrayList;
30  import java.util.List;
31  import java.util.Locale;
32  import java.util.Set;
33  
34  import org.apache.maven.artifact.Artifact;
35  import org.apache.maven.artifact.repository.ArtifactRepository;
36  import org.apache.maven.plugin.AbstractMojo;
37  import org.apache.maven.plugin.MojoExecutionException;
38  import org.apache.maven.plugin.MojoFailureException;
39  
40  import ch.qos.cal10n.Cal10nConstants;
41  import ch.qos.cal10n.verifier.IMessageKeyVerifier;
42  
43  
44  // Adding @requiresDependencyResolution  fixes  http://jira.qos.ch/browse/CAL-18
45  
46  /**
47   * Verifies resources bundles in various locales against an enumType
48   *
49   * @goal verify
50   * @phase verify
51   * @requiresProject true
52   * @requiresDependencyResolution
53   */
54  public class VerifyMojo extends AbstractMojo {
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(Cal10nConstants.MISSING_ENUM_TYPES_MSG);
92      }
93      for (String enumTypeAsStr : enumTypes) {
94        IMessageKeyVerifier imcv = getMessageKeyVerifierInstance(enumTypeAsStr);
95        getLog()
96            .info(
97                "Checking all resource bundles for enum type [" + enumTypeAsStr
98                    + "]");
99        checkAllLocales(imcv);
100     }
101   }
102 
103   public void checkAllLocales(IMessageKeyVerifier mcv)
104       throws MojoFailureException, MojoExecutionException {
105 
106     String enumClassAsStr = mcv.getEnumTypeAsStr();
107 
108     String[] localeNameArray = mcv.getLocaleNames();
109 
110     if (localeNameArray == null || localeNameArray.length == 0) {
111       String errMsg = MessageFormat.format(
112           Cal10nConstants.MISSING_LD_ANNOTATION_MESSAGE, enumClassAsStr);
113       getLog().error(errMsg);
114       throw new MojoFailureException(errMsg);
115     }
116 
117     boolean failure = false;
118     for (String localeName : localeNameArray) {
119       Locale locale = new Locale(localeName);
120       List<String> errorList = mcv.typeIsolatedVerify(locale);
121       if (errorList.size() == 0) {
122         String resouceBundleName = mcv.getBaseName();
123         getLog().info(
124             "SUCCESSFUL verification for resource bundle [" + resouceBundleName
125                 + "] for locale [" + locale + "]");
126       } else {
127         failure = true;
128         getLog().error(
129             "FAILURE during verification of resource bundle for locale ["
130                 + locale + "] enum class [" + enumClassAsStr + "]");
131         for (String s : errorList) {
132           getLog().error(s);
133         }
134       }
135     }
136     if (failure) {
137       throw new MojoFailureException("FAIL Verification of [" + enumClassAsStr
138           + "] keys.");
139     }
140   }
141 
142   IMessageKeyVerifier getMessageKeyVerifierInstance(String enumClassAsStr)
143       throws MojoExecutionException {
144     String errMsg = "Failed to instantiate MessageKeyVerifier class";
145     try {
146       ThisFirstClassLoader thisFirstClassLoader = (ThisFirstClassLoader) buildClassLoader();
147       Class<?> mkvClass = Class.forName(
148           Cal10nConstants.MessageKeyVerifier_FQCN, true, thisFirstClassLoader);
149       Constructor<?> mkvCons = mkvClass.getConstructor(String.class);
150       IMessageKeyVerifier imcv = (IMessageKeyVerifier) mkvCons
151           .newInstance(enumClassAsStr);
152       return imcv;
153     } catch (ClassNotFoundException e) {
154       throw new MojoExecutionException(errMsg, e);
155     } catch (NoClassDefFoundError e) {
156       throw new MojoExecutionException(errMsg, e);
157     } catch (Exception e) {
158       throw new MojoExecutionException(errMsg, e);
159     }
160   }
161 
162   ClassLoader buildClassLoader() {
163     ArrayList<URL> classpathURLList = new ArrayList<URL>();
164     classpathURLList.add(toURL(outputDirectory));
165     classpathURLList.addAll(getDirectDependencies());
166     ClassLoader parentCL = this.getClass().getClassLoader();
167     URL[] classpathURLArray = classpathURLList.toArray(new URL[] {});
168     return new ThisFirstClassLoader(classpathURLArray, parentCL);
169   }
170 
171   List<URL> getDirectDependencies() {
172     ArrayList<URL> urlList = new ArrayList<URL>();
173     for (Artifact a : projectArtifacts) {
174       String pathOfArtifact = localRepository.getBasedir() + "/"
175           + localRepository.pathOf(a);
176       File artifactAsFile = new File(pathOfArtifact);
177       if (!artifactAsFile.exists()) {
178         getLog()
179             .error("Artifact [" + artifactAsFile + "] could not be located");
180       }
181       try {
182         URL url = artifactAsFile.toURI().toURL();
183         urlList.add(url);
184       } catch (MalformedURLException e) {
185         getLog().info("Failed to build URL", e);
186       }
187     }
188     return urlList;
189   }
190 
191   URL toURL(File file) {
192     try {
193       return file.toURI().toURL();
194     } catch (MalformedURLException e) {
195       // this should never happen
196       getLog().error("Failed to convert file [" + file + "] to a URL", e);
197       return null;
198     }
199   }
200 
201 }