001/** 002 * Copyright (c) 2009, Regents of the University of Colorado 003 * All rights reserved. 004 * 005 * Redistribution and use in source and binary forms, with or without 006 * modification, are permitted provided that the following conditions are met: 007 * 008 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 009 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 010 * Neither the name of the University of Colorado at Boulder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 011 * 012 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 013 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 014 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 015 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 016 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 017 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 018 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 019 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 020 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 021 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 022 * POSSIBILITY OF SUCH DAMAGE. 023 */ 024package org.cleartk.test.util; 025 026import java.io.File; 027import java.lang.reflect.Field; 028import java.lang.reflect.Modifier; 029import java.util.ArrayList; 030import java.util.Iterator; 031import java.util.List; 032 033import org.apache.commons.io.filefilter.FileFilterUtils; 034import org.apache.commons.io.filefilter.IOFileFilter; 035import org.apache.commons.io.filefilter.SuffixFileFilter; 036import org.apache.commons.io.filefilter.TrueFileFilter; 037import org.junit.Assert; 038import org.apache.uima.fit.factory.ConfigurationParameterFactory; 039 040/** 041 * <br> 042 * Copyright (c) 2009, Regents of the University of Colorado <br> 043 * All rights reserved. 044 * 045 * @author Philip Ogren 046 */ 047public class ParametersTestUtil { 048 049 public static void testParameterDefinitions(String outputDirectory, String... excludeFiles) 050 throws ClassNotFoundException { 051 IOFileFilter includeFilter = new SuffixFileFilter(".java"); 052 053 if (excludeFiles != null) { 054 IOFileFilter excludeFilter = FileFilterUtils.notFileFilter(new SuffixFileFilter(excludeFiles)); 055 includeFilter = FileFilterUtils.and(excludeFilter, includeFilter); 056 } 057 058 Iterator<File> files = org.apache.commons.io.FileUtils.iterateFiles( 059 new File(outputDirectory), 060 includeFilter, 061 TrueFileFilter.INSTANCE); 062 testParameterDefinitions(files); 063 } 064 065 public static void testParameterDefinitions(Iterator<File> files) throws ClassNotFoundException { 066 List<String> badParameters = new ArrayList<String>(); 067 List<String> missingParameterNameFields = new ArrayList<String>(); 068 069 while (files.hasNext()) { 070 File file = files.next(); 071 String className = file.getPath(); 072 className = className.substring(14); 073 className = className.substring(0, className.length() - 5); 074 className = className.replace(File.separatorChar, '.'); 075 Class<?> cls = Class.forName(className); 076 Field[] fields = cls.getDeclaredFields(); 077 for (Field field : fields) { 078 if (ConfigurationParameterFactory.isConfigurationParameterField(field)) { 079 org.apache.uima.fit.descriptor.ConfigurationParameter annotation = field.getAnnotation(org.apache.uima.fit.descriptor.ConfigurationParameter.class); 080 String parameterName = annotation.name(); 081 String expectedName = field.getName(); 082 if (!expectedName.equals(parameterName)) { 083 badParameters.add("'" + parameterName + "' should be '" + expectedName + "'"); 084 } 085 086 expectedName = className+"."+field.getName(); 087 String fieldName = getParameterNameField(expectedName); 088 try { 089 Field fld = cls.getDeclaredField(fieldName); 090 if ((fld.getModifiers() & Modifier.PUBLIC) == 0 091 || (fld.getModifiers() & Modifier.FINAL) == 0 092 || (fld.getModifiers() & Modifier.PUBLIC) == 0) { 093 missingParameterNameFields.add(expectedName); 094 } else if (!fld.get(null).equals(expectedName.substring(expectedName.lastIndexOf(".")+1))) { 095 missingParameterNameFields.add(expectedName); 096 } 097 } catch (Exception e) { 098 missingParameterNameFields.add(expectedName); 099 } 100 } 101 } 102 } 103 104 if (badParameters.size() > 0 || missingParameterNameFields.size() > 0) { 105 String message = String.format( 106 "%d descriptor parameters with bad names and %d descriptor parameters with no name field. ", 107 badParameters.size(), 108 missingParameterNameFields.size()); 109 System.err.println(message); 110 System.err.println("descriptor parameters with bad names: "); 111 for (String badParameter : badParameters) { 112 System.err.println(badParameter); 113 } 114 System.err.println("each configuration parameter should have a public static final String that specifies its name. The missing fields are: "); 115 for (String missingParameterNameField : missingParameterNameFields) { 116 System.err.println(missingParameterNameField + " should be named by " 117 + missingParameterNameField.substring(0, missingParameterNameField.lastIndexOf('.')) 118 + "." + getParameterNameField(missingParameterNameField)); 119 } 120 Assert.fail(message); 121 } 122 } 123 124 private static String getParameterNameField(String parameterName) { 125 String parameterNameField = "PARAM"; 126 127 String fieldName = parameterName.substring(parameterName.lastIndexOf('.') + 1); 128 String[] fieldNameParts = fieldName.split("(?=[A-Z]++)"); 129 for (String fieldNamePart : fieldNameParts) { 130 parameterNameField += "_" + fieldNamePart.toUpperCase(); 131 } 132 return parameterNameField; 133 } 134 135}