001/* 002 * ModeShape (http://www.modeshape.org) 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.modeshape.common; 017 018import static org.hamcrest.core.Is.is; 019import static org.hamcrest.core.IsNull.notNullValue; 020import static org.junit.Assert.assertThat; 021import static org.junit.Assert.fail; 022import java.lang.annotation.Annotation; 023import java.lang.reflect.Field; 024import java.lang.reflect.Method; 025import java.lang.reflect.Modifier; 026import java.util.Locale; 027import java.util.Set; 028import org.junit.Test; 029import org.modeshape.common.annotation.Category; 030import org.modeshape.common.annotation.Description; 031import org.modeshape.common.annotation.Label; 032import org.modeshape.common.i18n.I18n; 033 034/** 035 * @author John Verhaeg 036 */ 037public abstract class AbstractI18nTest { 038 039 private Class<?> i18nClass; 040 041 protected AbstractI18nTest( Class<?> i18nClass ) { 042 this.i18nClass = i18nClass; 043 } 044 045 @Test 046 public void shouldNotHaveProblems() throws Exception { 047 for (Field fld : i18nClass.getDeclaredFields()) { 048 if (fld.getType() == I18n.class && (fld.getModifiers() & Modifier.PUBLIC) == Modifier.PUBLIC 049 && (fld.getModifiers() & Modifier.STATIC) == Modifier.STATIC 050 && (fld.getModifiers() & Modifier.FINAL) != Modifier.FINAL) { 051 I18n i18n = (I18n)fld.get(null); 052 if (i18n.hasProblem()) { 053 fail(i18n.problem()); 054 } 055 } 056 } 057 // Check for global problems after checking field problems since global problems are detected lazily upon field usage 058 Set<Locale> locales = I18n.getLocalizationProblemLocales(i18nClass); 059 if (!locales.isEmpty()) { 060 for (Locale locale : locales) { 061 Set<String> problems = I18n.getLocalizationProblems(i18nClass, locale); 062 try { 063 assertThat(problems.isEmpty(), is(true)); 064 } catch (AssertionError error) { 065 fail(problems.iterator().next()); 066 } 067 } 068 } 069 } 070 071 protected static final String[] ANNOTATION_NAMES = {"Description", "Category", "Label"}; 072 073 /** 074 * Utility method that can be used to verify that an I18n field exists for all of the I18n-related annotations on the supplied 075 * object. I18n-related annotations include {@link Description}, {@link Label}, and {@link Category}. 076 * 077 * @param annotated the object that has field or method annotations 078 * @throws Exception if there is a problem 079 */ 080 protected void verifyI18nForAnnotationsOnObject( Object annotated ) throws Exception { 081 // Check the known annotations that work with I18ns ... 082 Class<?> clazz = annotated.getClass(); 083 for (Field field : clazz.getDeclaredFields()) { 084 for (Annotation annotation : field.getAnnotations()) { 085 verifyI18nForAnnotation(annotation, field); 086 } 087 } 088 for (Method method : clazz.getDeclaredMethods()) { 089 for (Annotation annotation : method.getAnnotations()) { 090 verifyI18nForAnnotation(annotation, method); 091 } 092 } 093 } 094 095 protected void verifyI18nForAnnotation( Annotation annotation, 096 Object annotatedObject ) throws Exception { 097 String i18nIdentifier; 098 Class<?> i18nClass; 099 if (annotation instanceof Category) { 100 Category cat = (Category)annotation; 101 i18nClass = cat.i18n(); 102 i18nIdentifier = cat.value(); 103 } else if (annotation instanceof Description) { 104 Description desc = (Description)annotation; 105 i18nClass = desc.i18n(); 106 i18nIdentifier = desc.value(); 107 } else if (annotation instanceof Label) { 108 Label label = (Label)annotation; 109 i18nClass = label.i18n(); 110 i18nIdentifier = label.value(); 111 } else { 112 return; 113 } 114 assertThat(i18nClass, is(notNullValue())); 115 assertThat(i18nIdentifier, is(notNullValue())); 116 try { 117 Field fld = i18nClass.getField(i18nIdentifier); 118 assertThat(fld, is(notNullValue())); 119 // Now check the I18n field ... 120 if (fld.getType() == I18n.class && (fld.getModifiers() & Modifier.PUBLIC) == Modifier.PUBLIC 121 && (fld.getModifiers() & Modifier.STATIC) == Modifier.STATIC 122 && (fld.getModifiers() & Modifier.FINAL) != Modifier.FINAL) { 123 I18n i18n = (I18n)fld.get(null); 124 if (i18n.hasProblem()) { 125 fail(i18n.problem()); 126 } 127 } 128 } catch (NoSuchFieldException e) { 129 fail("Missing I18n field on " + i18nClass.getName() + " for " + annotation + " on " + annotatedObject); 130 } 131 } 132}