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.net.URLClassLoader;
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.IMessageCodeVerifier;
42  
43  /**
44   * Verifies resources bundles in various locales against an enumType
45   * 
46   * @goal verify
47   * @phase verify
48   * @requiresProject true
49   */
50  public class VerifyMojo extends AbstractMojo {
51  
52    final static String MISSING_LOCALE = Cal10nConstants.CODE_URL_PREFIX
53        + "#missingLocale";
54    final static String MISSING_ENUM_TYPES = Cal10nConstants.CODE_URL_PREFIX
55        + "#missingEnumType";
56  
57    /**
58     * @parameter
59     * @required
60     */
61    private String[] enumTypes;
62  
63    /**
64     * The directory for compiled classes.
65     * 
66     * @parameter expression="${project.build.outputDirectory}"
67     * @required
68     * @readonly
69     */
70    private File outputDirectory;
71  
72    // direct dependencies of this project
73    /**
74     * 
75     * @parameter expression="${project.artifacts}"
76     * @required
77     * @readonly
78     */
79    private Set<Artifact> projectArtifacts;
80  
81    /**
82     * @parameter expression="${localRepository}"
83     * @required
84     * @readonly
85     * @since 1.0
86     */
87    private ArtifactRepository localRepository;
88  
89  
90    public void execute() throws MojoExecutionException, MojoFailureException {
91  
92      if (enumTypes == null) {
93        throw new MojoFailureException(
94            "Missing <enumTypes> element. Please see " + MISSING_ENUM_TYPES);
95      }
96      for (String enumTypeAsStr : enumTypes) {
97        IMessageCodeVerifier imcv = getMessageCodeVerifierInstance(enumTypeAsStr);
98        getLog().info("Checking all resource bundles for enum type [" + enumTypeAsStr + "]");
99        checkAllLocales(imcv);
100     }
101   }
102 
103   public void checkAllLocales(IMessageCodeVerifier 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 = "Missing @LocaleNames annotation in enum type ["
112           + 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.getResourceBundleName();
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           + "] codes.");
139     }
140   }
141 
142   IMessageCodeVerifier getMessageCodeVerifierInstance(String enumClassAsStr)
143       throws MojoExecutionException {
144     String errMsg = "Failed to instantiate MessageCodeVerifier class";
145     try {
146 
147       URLClassLoader cl = (URLClassLoader) buildClassLoader();
148       Class<?> cla = Class.forName(Cal10nConstants.MessageCodeVerifier_FQCN, true, cl);
149 
150       
151       Constructor<?> cons = cla.getConstructor(String.class);
152       IMessageCodeVerifier imcv = (IMessageCodeVerifier) cons
153           .newInstance(enumClassAsStr);
154       return imcv;
155     } catch (ClassNotFoundException e) {
156       throw new MojoExecutionException(errMsg, e);
157     } catch (NoClassDefFoundError e) {
158       throw new MojoExecutionException(errMsg, e);
159     } catch (Exception e) {
160       throw new MojoExecutionException(errMsg, e);
161     }
162   }
163 
164   ClassLoader buildClassLoader() {
165     ArrayList<URL> classpathURLArray = new ArrayList<URL>();
166     classpathURLArray.add(toURL(outputDirectory));
167     classpathURLArray.addAll(getDirectDependencies());
168     ClassLoader parentCL = this.getClass().getClassLoader();
169     return new ThisFirstClassLoader(classpathURLArray.toArray(new URL[] {}), parentCL);
170   }
171 
172   List<URL> getDirectDependencies() {
173     ArrayList<URL> urlList = new ArrayList<URL>();
174     for (Artifact a : projectArtifacts) {
175       // localRepository.getUrl() returns a bogus URL
176       String pathOfArtifact = localRepository.getBasedir() + "/"
177           + localRepository.pathOf(a);
178       try {
179         URL url = new URL("file:/" + pathOfArtifact);
180         urlList.add(url);
181       } catch (MalformedURLException e) {
182         e.printStackTrace();
183       }
184     }
185     return urlList;
186   }
187 
188   URL toURL(File file) {
189     try {
190       return file.toURI().toURL();
191     } catch (MalformedURLException e) {
192       // this should never happen
193       getLog().error("Failed to convert file [" + file + "] to a URL", e);
194       return null;
195     }
196   }
197 
198 }