1 package jp.sourceforge.stigmata;
7 import java.beans.PropertyChangeEvent;
8 import java.beans.PropertyChangeListener;
9 import java.util.ArrayList;
10 import java.util.Arrays;
11 import java.util.HashMap;
12 import java.util.HashSet;
13 import java.util.Iterator;
14 import java.util.List;
18 import javax.imageio.spi.ServiceRegistry;
20 import jp.sourceforge.stigmata.digger.ClasspathContext;
21 import jp.sourceforge.stigmata.filter.ComparisonPairFilterManager;
22 import jp.sourceforge.stigmata.resolvers.StigmataHomeManager;
23 import jp.sourceforge.stigmata.result.history.ExtractedBirthmarkServiceManager;
24 import jp.sourceforge.stigmata.spi.BirthmarkSpi;
25 import jp.sourceforge.stigmata.utils.WellknownClassManager;
28 * This class represents the context for extracting/comparing birthmarks.
30 * @author Haruaki TAMADA
33 public class BirthmarkEnvironment{
35 * Default environment. All instance of this class is based on default environment.
37 private static BirthmarkEnvironment DEFAULT_ENVIRONMENT = new BirthmarkEnvironment(true);
40 * home directory path.
42 private static StigmataHomeManager stigmataHome = new StigmataHomeManager();
45 * parent of this environment.
47 private BirthmarkEnvironment parent;
50 * context for classpath.
52 private ClasspathContext classpathContext;
55 * wellknown class manager. This object judge a class is user made class or
58 private WellknownClassManager manager;
61 * collection of services.
63 private Map<String, BirthmarkSpi> services = new HashMap<String, BirthmarkSpi>();
68 private Map<String, String> properties = new HashMap<String, String>();
71 * listeners for updating properties.
73 private List<PropertyChangeListener> propertyListeners = new ArrayList<PropertyChangeListener>();
78 private ComparisonPairFilterManager filterManager;
83 private ExtractedBirthmarkServiceManager historyManager;
88 private ClassLoader loader;
91 * constructor for root environment
93 private BirthmarkEnvironment(boolean flag){
94 manager = new WellknownClassManager();
95 classpathContext = new ClasspathContext();
96 filterManager = new ComparisonPairFilterManager(this);
97 historyManager = new ExtractedBirthmarkServiceManager(this);
101 * constructor for specifying parent environment.
103 public BirthmarkEnvironment(BirthmarkEnvironment parent){
104 this.parent = parent;
105 this.manager = new WellknownClassManager(parent.getWellknownClassManager());
106 this.classpathContext = new ClasspathContext(parent.getClasspathContext());
107 this.filterManager = new ComparisonPairFilterManager(this, parent.getFilterManager());
108 this.historyManager = new ExtractedBirthmarkServiceManager(this, parent.getHistoryManager());
112 * returns the default birthmark environment.
114 public static final BirthmarkEnvironment getDefaultEnvironment(){
115 return DEFAULT_ENVIRONMENT;
118 public static synchronized final String getStigmataHome(){
119 return stigmataHome.getStigmataHome();
122 static void resetSettings(){
123 DEFAULT_ENVIRONMENT = new BirthmarkEnvironment(false);
126 public BirthmarkEnvironment getParent(){
131 * remove property mapped given key.
133 public void removeProperty(String key){
134 String old = properties.get(key);
135 properties.remove(key);
136 firePropertyEvent(new PropertyChangeEvent(this, key, old, null));
140 * add given property.
142 public void addProperty(String key, String value){
143 boolean contains = properties.containsKey(key);
144 String old = getProperty(key);
145 properties.put(key, value);
148 if(!((old != null && old.equals(value)) ||
149 (contains && old == null && value == null))){
150 firePropertyEvent(new PropertyChangeEvent(this, key, old, value));
155 * returns the property mapped given key
157 public String getProperty(String key){
158 String value = properties.get(key);
159 if(value == null && parent != null){
160 value = parent.getProperty(key);
166 * fire property change event to listeners.
167 * @param e Event object.
169 private void firePropertyEvent(PropertyChangeEvent e){
170 for(PropertyChangeListener listener: propertyListeners){
171 listener.propertyChange(e);
176 * add listener for updating properties.
178 public void addPropertyListener(PropertyChangeListener listener){
179 propertyListeners.add(listener);
183 * remove specified listener.
185 public void removePropertyListener(PropertyChangeListener listener){
186 propertyListeners.remove(listener);
189 public void clearProperties(){
193 public Iterator<String> propertyKeys(){
194 Set<String> set = new HashSet<String>();
196 for(Iterator<String> i = parent.propertyKeys(); i.hasNext(); ){
200 set.addAll(properties.keySet());
201 return set.iterator();
205 * returns the classpath context.
207 public ClasspathContext getClasspathContext(){
208 return classpathContext;
212 * add given birthmark service to this environment.
214 public synchronized void addService(BirthmarkSpi service){
215 if(parent == null || parent.getService(service.getType()) == null){
216 services.put(service.getType(), service);
221 * remove given birthmark service from this environment.
223 public void removeService(String type){
224 services.remove(type);
228 * return birthmark service registered with given birthmark type.
230 public BirthmarkSpi getService(String type){
231 BirthmarkSpi service = services.get(type);
232 if(service == null && parent != null){
233 service = parent.getService(type);
239 * return all birthmark services searching traverse to root environment.
241 public synchronized BirthmarkSpi[] getServices(){
242 List<BirthmarkSpi> list = getServiceList();
243 BirthmarkSpi[] services = list.toArray(new BirthmarkSpi[list.size()]);
244 Arrays.sort(services, new BirthmarkSpiComparator());
249 public <T> Iterator<T> lookupProviders(Class<T> providerClass){
250 Iterator<T> iterator;
252 iterator = ServiceRegistry.lookupProviders(providerClass, loader);
255 iterator = ServiceRegistry.lookupProviders(providerClass);
261 * return birthmark services lookup from current class path.
263 public synchronized BirthmarkSpi[] findServices(){
264 List<BirthmarkSpi> list = getServiceList();
266 for(Iterator<BirthmarkSpi> i = lookupProviders(BirthmarkSpi.class); i.hasNext(); ){
267 BirthmarkSpi spi = i.next();
268 if(getService(spi.getType()) == null){
272 BirthmarkSpi[] services = list.toArray(new BirthmarkSpi[list.size()]);
273 Arrays.sort(services, new BirthmarkSpiComparator());
279 * return wellknown class manager.
281 public WellknownClassManager getWellknownClassManager(){
285 public ComparisonPairFilterManager getFilterManager(){
286 return filterManager;
289 public ExtractedBirthmarkServiceManager getHistoryManager(){
290 return historyManager;
293 void setClassLoader(ClassLoader loader){
294 this.loader = loader;
298 * find the all birthmark services searching to root environment.
300 private List<BirthmarkSpi> getServiceList(){
301 List<BirthmarkSpi> list = new ArrayList<BirthmarkSpi>();
303 for(BirthmarkSpi spi: parent.getServices()){
307 for(String key : services.keySet()){
308 list.add(services.get(key));