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  
23  package ch.qos.cal10n.verifier;
24  
25  import java.text.MessageFormat;
26  import java.util.ArrayList;
27  import java.util.Enumeration;
28  import java.util.HashSet;
29  import java.util.List;
30  import java.util.Locale;
31  import java.util.ResourceBundle;
32  import java.util.Set;
33  
34  import ch.qos.cal10n.Cal10nConstants;
35  import ch.qos.cal10n.util.AnnotationExtractor;
36  import ch.qos.cal10n.util.CAL10NResourceBundleFinder;
37  import ch.qos.cal10n.util.MiscUtil;
38  import ch.qos.cal10n.verifier.Cal10nError.ErrorType;
39  
40  /**
41   * Given an enum class, verify that the resource bundles corresponding to a
42   * given locale contains the correct keys.
43   * 
44   * @author Ceki Gulcu
45   */
46  public class MessageKeyVerifier implements IMessageKeyVerifier {
47  
48    Class<? extends Enum<?>> enumType;
49    String enumTypeAsStr;
50  
51    public MessageKeyVerifier(Class<? extends Enum<?>> enumClass) {
52      this.enumType = enumClass;
53      this.enumTypeAsStr = enumClass.getName();
54    }
55  
56    @SuppressWarnings("unchecked")
57    public MessageKeyVerifier(String enumTypeAsStr) {
58      this.enumTypeAsStr = enumTypeAsStr;
59      String errMsg = "Failed to find enum class [" + enumTypeAsStr + "]";
60      try {
61        this.enumType = (Class<? extends Enum<?>>) Class.forName(enumTypeAsStr);
62      } catch (ClassNotFoundException e) {
63        throw new IllegalStateException(errMsg, e);
64      } catch (NoClassDefFoundError e) {
65        throw new IllegalStateException(errMsg, e);
66      }
67    }
68  
69    public Class<? extends Enum<?>> getEnumType() {
70      return enumType;
71    }
72  
73    public String getEnumTypeAsStr() {
74      return enumTypeAsStr;
75    }
76  
77    public List<Cal10nError> verify(Locale locale) {
78      List<Cal10nError> errorList = new ArrayList<Cal10nError>();
79  
80      String baseName = AnnotationExtractor.getBaseName(enumType);
81  
82      if (baseName == null) {
83        errorList.add(new Cal10nError(ErrorType.MISSING_BN_ANNOTATION, "",
84            enumType, locale, ""));
85        // no point in continuing
86        return errorList;
87      }
88  
89      String charset = AnnotationExtractor.getCharset(enumType, Locale.FRENCH);
90      ResourceBundle rb = CAL10NResourceBundleFinder.getBundle(this.getClass()
91          .getClassLoader(), baseName, locale, charset);
92  
93      ErrorFactory errorFactory = new ErrorFactory(enumType, locale, baseName);
94  
95      if (rb == null) {
96        errorList.add(errorFactory.buildError(ErrorType.FAILED_TO_FIND_RB, ""));
97     // no point in continuing
98        return errorList;
99      }
100     
101     Set<String> rbKeySet = buildKeySetFromEnumeration(rb.getKeys());
102 
103     if (rbKeySet.size() == 0) {
104       errorList.add(errorFactory.buildError(ErrorType.EMPTY_RB, ""));
105     }
106 
107     Enum<?>[] enumArray = enumType.getEnumConstants();
108     if (enumArray == null || enumArray.length == 0) {
109       errorList.add(errorFactory.buildError(ErrorType.EMPTY_ENUM, ""));
110     }
111 
112     if (errorList.size() != 0) {
113       return errorList;
114     }
115 
116     for (Enum<?> e : enumArray) {
117       String enumKey = e.toString();
118       if (rbKeySet.contains(enumKey)) {
119         rbKeySet.remove(enumKey);
120       } else {
121         errorList.add(errorFactory.buildError(ErrorType.ABSENT_IN_RB, enumKey));
122       }
123     }
124 
125     for (String rbKey : rbKeySet) {
126       errorList.add(errorFactory.buildError(ErrorType.ABSENT_IN_ENUM, rbKey));
127     }
128     return errorList;
129   }
130 
131   private Set<String> buildKeySetFromEnumeration(Enumeration<String> e) {
132     Set<String> set = new HashSet<String>();
133     while (e.hasMoreElements()) {
134       String s = e.nextElement();
135       set.add(s);
136     }
137     return set;
138   }
139 
140   public List<String> typeIsolatedVerify(Locale locale) {
141     List<Cal10nError> errorList = verify(locale);
142     List<String> strList = new ArrayList<String>();
143     for (Cal10nError error : errorList) {
144       strList.add(error.toString());
145     }
146     return strList;
147   }
148 
149   /***
150    * Verify all declared locales in one step.
151    */
152   public List<Cal10nError> verifyAllLocales() {
153     List<Cal10nError> errorList = new ArrayList<Cal10nError>();
154 
155     String[] localeNameArray = getLocaleNames();
156 
157     if (localeNameArray == null || localeNameArray.length == 0) {
158       String errMsg = MessageFormat.format(Cal10nConstants.MISSING_LD_ANNOTATION_MESSAGE, enumTypeAsStr);
159       throw new IllegalStateException(errMsg);
160     }
161     for (String localeName : localeNameArray) {
162       Locale locale = MiscUtil.toLocale(localeName);
163       System.out.println(locale);
164       List<Cal10nError> tmpList = verify(locale);
165       errorList.addAll(tmpList);
166     }
167 
168     return errorList;
169   }
170 
171   public String[] getLocaleNames() {
172     String[] localeNameArray = AnnotationExtractor.getLocaleNames(enumType);
173     return localeNameArray;
174   }
175 
176   public String getBaseName() {
177     String rbName = AnnotationExtractor.getBaseName(enumType);
178     return rbName;
179   }
180 
181 }