1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 package org.openoffice.test.common; 23 24 import java.io.BufferedReader; 25 import java.io.File; 26 import java.io.FileReader; 27 import java.lang.annotation.Annotation; 28 import java.lang.annotation.ElementType; 29 import java.lang.annotation.Retention; 30 import java.lang.annotation.RetentionPolicy; 31 import java.lang.annotation.Target; 32 import java.lang.reflect.Field; 33 import java.util.ArrayList; 34 import java.util.Arrays; 35 import java.util.Collections; 36 import java.util.List; 37 38 import org.junit.runner.Runner; 39 import org.junit.runner.notification.RunNotifier; 40 import org.junit.runners.BlockJUnit4ClassRunner; 41 import org.junit.runners.Suite; 42 import org.junit.runners.model.FrameworkMethod; 43 import org.junit.runners.model.InitializationError; 44 import org.junit.runners.model.Statement; 45 46 public class FileProvider extends Suite { 47 48 private static final List<Runner> NO_RUNNERS = Collections.<Runner> emptyList(); 49 50 private final ArrayList<Runner> runners = new ArrayList<Runner>(); 51 52 private class TestClassRunnerForParameters extends BlockJUnit4ClassRunner { 53 54 private final Object[] parameters; 55 56 private int index; 57 TestClassRunnerForParameters(Class<?> type, Object[] parameters, int index)58 TestClassRunnerForParameters(Class<?> type, Object[] parameters, int index) throws InitializationError { 59 super(type); 60 this.parameters = parameters; 61 this.index = index; 62 } 63 64 @Override createTest()65 public Object createTest() throws Exception { 66 return getTestClass().getOnlyConstructor().newInstance(parameters); 67 } 68 69 @Override getName()70 protected String getName() { 71 return getTestClass().getJavaClass().getSimpleName() + "[" + index + "]" + Arrays.toString(parameters); 72 } 73 74 @Override testName(FrameworkMethod method)75 protected String testName(FrameworkMethod method) { 76 return method.getName() + "[" + index + "]" + Arrays.toString(parameters); 77 } 78 79 @Override validateConstructor(List<Throwable> errors)80 protected void validateConstructor(List<Throwable> errors) { 81 validateOnlyOneConstructor(errors); 82 } 83 84 @Override classBlock(RunNotifier notifier)85 protected Statement classBlock(RunNotifier notifier) { 86 return childrenInvoker(notifier); 87 } 88 89 @Override getRunnerAnnotations()90 protected Annotation[] getRunnerAnnotations() { 91 return new Annotation[0]; 92 } 93 } 94 95 @Retention(RetentionPolicy.RUNTIME) 96 @Target(ElementType.FIELD) 97 public static @interface FileRepos { 98 } 99 100 @Retention(RetentionPolicy.RUNTIME) 101 @Target(ElementType.FIELD) 102 public static @interface FileFilter { 103 104 } 105 106 @Retention(RetentionPolicy.RUNTIME) 107 @Target(ElementType.FIELD) 108 public static @interface FileRepeat { 109 110 } 111 FileProvider(Class<?> klass)112 public FileProvider(Class<?> klass) throws Throwable { 113 super(klass, NO_RUNNERS); 114 115 String repos = null; 116 String filter = null; 117 int repeat = 1; 118 Field fs[] = klass.getFields(); 119 for (Field f : fs) { 120 Annotation a = f.getAnnotation(FileRepos.class); 121 if (a != null) { 122 Object v = f.get(null); 123 if (!(v instanceof String)) 124 throw new InitializationError(String.format("Field annotated FileRepos '%s' must be String.", f.getName())); 125 126 repos = (String) v; 127 } 128 129 a = f.getAnnotation(FileFilter.class); 130 if (a != null) { 131 Object v = f.get(null); 132 if (v != null && !(v instanceof String)) 133 throw new InitializationError(String.format("Field annotated FileFilter '%s' must be String.", f.getName())); 134 filter = (String) v; 135 } 136 137 a = f.getAnnotation(FileRepeat.class); 138 if (a != null) { 139 Object v = f.get(null); 140 if (v != null && !(v instanceof Integer)) 141 throw new InitializationError(String.format("Field annotated FileFilter '%s' must be Integer.", f.getName())); 142 repeat = (Integer) v; 143 } 144 145 } 146 147 File reposFile = new File(repos); 148 // if (!reposFile.exists()) 149 // 150 // throw new InitializationError(String.format("repos '%s' does not exists ", repos)); 151 152 if(reposFile.exists()){ 153 ArrayList<ArrayList<String>> filterItems = new ArrayList<ArrayList<String>>(); 154 if (filter != null) { 155 String[] args = SystemUtil.parseCommandLine(filter); 156 ArrayList<String> filterItem = new ArrayList<String>(); 157 for (int i = 0; i < args.length; i++) { 158 String a = args[i]; 159 if (a.equals("-f")) { 160 if (filterItem.size() > 0) 161 filterItems.add(filterItem); 162 filterItem = new ArrayList<String>(); 163 } else { 164 filterItem.add(a); 165 } 166 } 167 168 if (filterItem.size() > 0) 169 filterItems.add(filterItem); 170 } 171 172 173 ArrayList<Object[]> list = new ArrayList<Object[]>(); 174 if (!collectFromFile(reposFile, list, filterItems)) 175 if (!collectFromFiles(reposFile, list, filterItems)) 176 collectFromDir(reposFile, list, filterItems); 177 178 for (int i = 0; i < list.size(); i++) { 179 Object[] t = list.get(i); 180 for (int j = 0; j < repeat; j++) { 181 TestClassRunnerForParameters runner = new TestClassRunnerForParameters(getTestClass().getJavaClass(), t, i * repeat + j); 182 runners.add(runner); 183 } 184 } 185 } 186 187 } 188 collectFromFiles(File dir, ArrayList<Object[]> list, ArrayList<ArrayList<String>> filterItems)189 private static boolean collectFromFiles(File dir, ArrayList<Object[]> list, ArrayList<ArrayList<String>> filterItems) { 190 if (!dir.isDirectory()) 191 return false; 192 193 boolean hasListFile = false; 194 File[] files = dir.listFiles(); 195 for (File f : files) { 196 if (f.isFile() && f.getName().endsWith(".files")) { 197 hasListFile = true; 198 collectFromFile(f, list, filterItems); 199 } 200 } 201 202 return hasListFile; 203 } 204 collectFromDir(File dir, ArrayList<Object[]> list, ArrayList<ArrayList<String>> filterItems)205 private static boolean collectFromDir(File dir, ArrayList<Object[]> list, ArrayList<ArrayList<String>> filterItems) { 206 if (!dir.isDirectory()) 207 return false; 208 209 File[] files = dir.listFiles(); 210 Arrays.sort(files); 211 for (File file : files) { 212 if (file.isDirectory()) { 213 collectFromDir(file, list, filterItems); 214 continue; 215 } 216 217 filter(file.getAbsolutePath(), list, filterItems); 218 } 219 220 return true; 221 } 222 collectFromFile(File file, ArrayList<Object[]> list, ArrayList<ArrayList<String>> filterItems)223 private static boolean collectFromFile(File file, ArrayList<Object[]> list, ArrayList<ArrayList<String>> filterItems) { 224 if (!file.isFile()) 225 return false; 226 227 BufferedReader reader = null; 228 try{ 229 reader = new BufferedReader(new FileReader(file)); 230 String line = null; 231 while((line = reader.readLine()) != null){ 232 filter(line, list, filterItems); 233 } 234 }catch(Exception e){ 235 //ignore 236 }finally{ 237 try{ 238 if(reader != null){ 239 reader.close(); 240 reader = null; 241 } 242 243 }catch(Exception io){ 244 //ignore; 245 } 246 } 247 248 return true; 249 } 250 filter(String filePath, ArrayList<Object[]> list, ArrayList<ArrayList<String>> filterItems)251 private static void filter(String filePath, ArrayList<Object[]> list, ArrayList<ArrayList<String>> filterItems) { 252 if (filterItems.size() == 0) { 253 Object[] data = { filePath}; 254 list.add(data); 255 return; 256 } 257 258 for (int i = 0; i < filterItems.size(); i++) { 259 ArrayList<String> filterItem = filterItems.get(i); 260 String pattern = filterItem.get(0); 261 if (pattern != null && filePath.matches(pattern)) { 262 Object[] data = new Object[filterItem.size()]; 263 data[0] = filePath; 264 for (int j = 1; j < filterItem.size(); j++) 265 data[j] = filterItem.get(j); 266 267 list.add(data); 268 } 269 } 270 } 271 272 273 @Override getChildren()274 protected List<Runner> getChildren() { 275 return runners; 276 } 277 } 278