1 package jp.sourceforge.stigmata;
3 import java.beans.PropertyChangeEvent;
4 import java.beans.PropertyChangeListener;
5 import java.util.ArrayList;
6 import java.util.Arrays;
7 import java.util.HashMap;
8 import java.util.HashSet;
9 import java.util.Iterator;
10 import java.util.List;
12 import java.util.ServiceLoader;
15 import javax.imageio.spi.ServiceRegistry;
17 import jp.sourceforge.stigmata.digger.ClasspathContext;
18 import jp.sourceforge.stigmata.filter.ComparisonPairFilterManager;
19 import jp.sourceforge.stigmata.resolvers.StigmataHomeManager;
20 import jp.sourceforge.stigmata.result.history.ExtractedBirthmarkServiceManager;
21 import jp.sourceforge.stigmata.spi.BirthmarkSpi;
22 import jp.sourceforge.stigmata.utils.WellknownClassManager;
25 * This class represents the context for extracting/comparing birthmarks.
27 * @author Haruaki TAMADA
29 public class BirthmarkEnvironment{
31 * Default environment. All instance of this class is based on default environment.
33 private static BirthmarkEnvironment DEFAULT_ENVIRONMENT = new BirthmarkEnvironment(true);
36 * home directory path.
38 private static StigmataHomeManager stigmataHome = new StigmataHomeManager();
41 * parent of this environment.
43 private BirthmarkEnvironment parent;
46 * context for classpath.
48 private ClasspathContext classpathContext;
51 * wellknown class manager. This object judge a class is user made class or
54 private WellknownClassManager manager;
57 * collection of services.
59 private Map<String, BirthmarkSpi> services = new HashMap<String, BirthmarkSpi>();
64 private Map<String, String> properties = new HashMap<String, String>();
67 * listeners for updating properties.
69 private List<PropertyChangeListener> propertyListeners = new ArrayList<PropertyChangeListener>();
74 private ComparisonPairFilterManager filterManager;
79 private ExtractedBirthmarkServiceManager historyManager;
84 private ClassLoader loader;
87 * constructor for root environment
89 private BirthmarkEnvironment(boolean flag){
90 manager = new WellknownClassManager();
91 classpathContext = new ClasspathContext();
92 filterManager = new ComparisonPairFilterManager(this);
93 historyManager = new ExtractedBirthmarkServiceManager(this);
97 * constructor for specifying parent environment.
99 public BirthmarkEnvironment(BirthmarkEnvironment parent){
100 this.parent = parent;
101 this.manager = new WellknownClassManager(parent.getWellknownClassManager());
102 this.classpathContext = new ClasspathContext(parent.getClasspathContext());
103 this.filterManager = new ComparisonPairFilterManager(this, parent.getFilterManager());
104 this.historyManager = new ExtractedBirthmarkServiceManager(this, parent.getHistoryManager());
108 * returns the default birthmark environment.
110 public static final BirthmarkEnvironment getDefaultEnvironment(){
111 return DEFAULT_ENVIRONMENT;
114 public static synchronized final String getStigmataHome(){
115 return stigmataHome.getStigmataHome();
118 static void resetSettings(){
119 DEFAULT_ENVIRONMENT = new BirthmarkEnvironment(false);
122 public BirthmarkEnvironment getParent(){
127 * remove property mapped given key.
129 public void removeProperty(String key){
130 String old = properties.get(key);
131 properties.remove(key);
132 firePropertyEvent(new PropertyChangeEvent(this, key, old, null));
136 * add given property.
138 public void addProperty(String key, String value){
139 boolean contains = properties.containsKey(key);
140 String old = getProperty(key);
141 properties.put(key, value);
144 if(!((old != null && old.equals(value)) ||
145 (contains && old == null && value == null))){
146 firePropertyEvent(new PropertyChangeEvent(this, key, old, value));
151 * returns the property mapped given key
153 public String getProperty(String key){
154 String value = properties.get(key);
155 if(value == null && parent != null){
156 value = parent.getProperty(key);
162 * fire property change event to listeners.
163 * @param e Event object.
165 private void firePropertyEvent(PropertyChangeEvent e){
166 for(PropertyChangeListener listener: propertyListeners){
167 listener.propertyChange(e);
172 * add listener for updating properties.
174 public void addPropertyListener(PropertyChangeListener listener){
175 propertyListeners.add(listener);
179 * remove specified listener.
181 public void removePropertyListener(PropertyChangeListener listener){
182 propertyListeners.remove(listener);
185 public void clearProperties(){
189 public Iterator<String> propertyKeys(){
190 Set<String> set = new HashSet<String>();
192 for(Iterator<String> i = parent.propertyKeys(); i.hasNext(); ){
196 set.addAll(properties.keySet());
197 return set.iterator();
201 * returns the classpath context.
203 public ClasspathContext getClasspathContext(){
204 return classpathContext;
208 * add given birthmark service to this environment.
210 public synchronized void addService(BirthmarkSpi service){
211 if(parent == null || parent.getService(service.getType()) == null){
212 services.put(service.getType(), service);
217 * remove given birthmark service from this environment.
219 public void removeService(String type){
220 services.remove(type);
224 * return birthmark service registered with given birthmark type.
226 public BirthmarkSpi getService(String type){
227 BirthmarkSpi service = services.get(type);
228 if(service == null && parent != null){
229 service = parent.getService(type);
235 * return all birthmark services searching traverse to root environment.
237 public synchronized BirthmarkSpi[] getServices(){
238 List<BirthmarkSpi> list = getServiceList();
239 BirthmarkSpi[] services = list.toArray(new BirthmarkSpi[list.size()]);
240 Arrays.sort(services, new BirthmarkSpiComparator());
245 public <T> Iterator<T> lookupProviders(Class<T> providerClass){
246 Iterator<T> iterator;
248 ServiceLoader<T> services = ServiceLoader.load(providerClass, loader);
249 iterator = services.iterator();
252 iterator = ServiceRegistry.lookupProviders(providerClass);
258 * return birthmark services lookup from current class path.
260 public synchronized BirthmarkSpi[] findServices(){
261 List<BirthmarkSpi> list = getServiceList();
263 for(Iterator<BirthmarkSpi> i = lookupProviders(BirthmarkSpi.class); i.hasNext(); ){
264 BirthmarkSpi spi = i.next();
265 if(getService(spi.getType()) == null){
269 BirthmarkSpi[] services = list.toArray(new BirthmarkSpi[list.size()]);
270 Arrays.sort(services, new BirthmarkSpiComparator());
276 * return wellknown class manager.
278 public WellknownClassManager getWellknownClassManager(){
282 public ComparisonPairFilterManager getFilterManager(){
283 return filterManager;
286 public ExtractedBirthmarkServiceManager getHistoryManager(){
287 return historyManager;
290 void setClassLoader(ClassLoader loader){
291 this.loader = loader;
295 * find the all birthmark services searching to root environment.
297 private List<BirthmarkSpi> getServiceList(){
298 List<BirthmarkSpi> list = new ArrayList<BirthmarkSpi>();
300 for(BirthmarkSpi spi: parent.getServices()){
304 for(String key : services.keySet()){
305 list.add(services.get(key));