001/*-------------------------------------------------------------------------+ 002| | 003| Copyright 2005-2011 The ConQAT Project | 004| | 005| Licensed under the Apache License, Version 2.0 (the "License"); | 006| you may not use this file except in compliance with the License. | 007| You may obtain a copy of the License at | 008| | 009| http://www.apache.org/licenses/LICENSE-2.0 | 010| | 011| Unless required by applicable law or agreed to in writing, software | 012| distributed under the License is distributed on an "AS IS" BASIS, | 013| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 014| See the License for the specific language governing permissions and | 015| limitations under the License. | 016+-------------------------------------------------------------------------*/ 017package org.conqat.lib.commons.test; 018 019import java.util.Collections; 020import java.util.HashMap; 021import java.util.HashSet; 022import java.util.List; 023import java.util.Map; 024import java.util.Set; 025 026import org.conqat.lib.commons.resources.Resource; 027import org.conqat.lib.commons.resources.ResourceUtils; 028import org.conqat.lib.commons.string.StringUtils; 029 030/** 031 * Support class for loading and identifying unused test data files. This class 032 * provides a method to access test data resources. Unused resources are 033 * reported via {@link UnusedResourcesChecker} after tests have finished. 034 * 035 * The class should only be used by {@link ManagedTestData} therefore package 036 * visibility. 037 */ 038/* package */ public class TestDataManager { 039 040 /** Map of all instances (which is indexed by managed directory). */ 041 private static Map<Class<?>, TestDataManager> instances = new HashMap<>(); 042 043 /** Returns the instance of the test data manager for the given class. */ 044 public static synchronized TestDataManager getInstance(Class<?> contextClass) { 045 if (!instances.containsKey(contextClass)) { 046 instances.put(contextClass, new TestDataManager(contextClass)); 047 } 048 return instances.get(contextClass); 049 } 050 051 /** 052 * The set of all test resources that would have been reachable from the context 053 * classes that have been used to load resources. 054 */ 055 private static final Set<Resource> ALL_DATA_FILES = Collections.synchronizedSet(new HashSet<>()); 056 057 /** 058 * The set of used test resources that have actually been loaded. This is just 059 * needed to determine which of the resources are unused. 060 */ 061 private static final Set<Resource> USED_DATA_FILES = Collections.synchronizedSet(new HashSet<>()); 062 063 /** The class this manager was instantiated for. */ 064 private final Class<?> contextClass; 065 066 /** Private constructor. */ 067 private TestDataManager(Class<?> contextClass) { 068 this.contextClass = contextClass; 069 ALL_DATA_FILES.addAll(ResourceUtils.listResourcesRecursively(contextClass, StringUtils.EMPTY_STRING)); 070 } 071 072 /** Checks whether a resource with the given name exists. */ 073 public boolean hasResource(String fileName) { 074 return Resource.exists(contextClass, fileName); 075 } 076 077 /** 078 * Marks the given resource as used and returns it. 079 */ 080 public Resource getResource(String fileName) { 081 Resource resource = Resource.of(contextClass, fileName); 082 markUsed(resource); 083 return resource; 084 } 085 086 /** 087 * Lists the resources contained in the given directory and marks them all as 088 * used. 089 */ 090 public List<Resource> listResources(String directory) { 091 List<Resource> resources = ResourceUtils.listResources(contextClass, directory); 092 resources.forEach(this::markUsed); 093 return resources; 094 } 095 096 /** 097 * Lists the resources contained in the given directory recursively and marks 098 * them all as used. 099 */ 100 public List<Resource> listResourcesRecursively(String directory) { 101 List<Resource> resources = ResourceUtils.listResourcesRecursively(contextClass, directory); 102 resources.forEach(this::markUsed); 103 return resources; 104 } 105 106 /** Stored the given resource as used. */ 107 private synchronized void markUsed(Resource resource) { 108 USED_DATA_FILES.add(resource); 109 } 110 111 /** Returns a set of all unused resources. */ 112 /* package */ static Set<Resource> getUnusedResources() { 113 Set<Resource> unusedDataFiles = new HashSet<>(ALL_DATA_FILES); 114 unusedDataFiles.removeAll(USED_DATA_FILES); 115 return unusedDataFiles; 116 } 117}