1 package jp.sourceforge.stigmata;
7 import java.beans.PropertyChangeEvent;
8 import java.beans.PropertyChangeListener;
10 import java.util.ArrayList;
11 import java.util.Arrays;
12 import java.util.HashMap;
13 import java.util.HashSet;
14 import java.util.Iterator;
15 import java.util.List;
19 import javax.imageio.spi.ServiceRegistry;
21 import jp.sourceforge.stigmata.filter.ComparisonPairFilterManager;
22 import jp.sourceforge.stigmata.reader.ClasspathContext;
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 String HOME_DIRECTORY_PATH;
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 if(HOME_DIRECTORY_PATH == null){
120 String stigmataHome = System.getProperty("stigmata.home");
121 if(stigmataHome == null){
122 stigmataHome = System.getenv("STIGMATA_HOME");
124 if(stigmataHome == null){
125 String parent = System.getProperty("user.home");
127 parent = System.getenv("HOME");
133 if(parent.startsWith("C:\\Documents and Settings\\")){
134 stigmataHome = parent + File.separator + "Application Data" + File.separator + "stigmata";
137 stigmataHome = parent + File.separator + ".stigmata";
140 HOME_DIRECTORY_PATH = stigmataHome;
142 return HOME_DIRECTORY_PATH;
145 static void resetSettings(){
146 DEFAULT_ENVIRONMENT = new BirthmarkEnvironment(false);
149 public BirthmarkEnvironment getParent(){
154 * remove property mapped given key.
156 public void removeProperty(String key){
157 String old = properties.get(key);
158 properties.remove(key);
159 firePropertyEvent(new PropertyChangeEvent(this, key, old, null));
163 * add given property.
165 public void addProperty(String key, String value){
166 boolean contains = properties.containsKey(key);
167 String old = getProperty(key);
168 properties.put(key, value);
171 if(!((old != null && old.equals(value)) ||
172 (contains && old == null && value == null))){
173 firePropertyEvent(new PropertyChangeEvent(this, key, old, value));
178 * returns the property mapped given key
180 public String getProperty(String key){
181 String value = properties.get(key);
182 if(value == null && parent != null){
183 value = parent.getProperty(key);
189 * fire property change event to listeners.
190 * @param e Event object.
192 private void firePropertyEvent(PropertyChangeEvent e){
193 for(PropertyChangeListener listener: propertyListeners){
194 listener.propertyChange(e);
199 * add listener for updating properties.
201 public void addPropertyListener(PropertyChangeListener listener){
202 propertyListeners.add(listener);
206 * remove specified listener.
208 public void removePropertyListener(PropertyChangeListener listener){
209 propertyListeners.remove(listener);
212 public void clearProperties(){
216 public Iterator<String> propertyKeys(){
217 Set<String> set = new HashSet<String>();
219 for(Iterator<String> i = parent.propertyKeys(); i.hasNext(); ){
223 set.addAll(properties.keySet());
224 return set.iterator();
228 * returns the classpath context.
230 public ClasspathContext getClasspathContext(){
231 return classpathContext;
235 * add given birthmark service to this environment.
237 public synchronized void addService(BirthmarkSpi service){
238 if(parent == null || parent.getService(service.getType()) == null){
239 services.put(service.getType(), service);
244 * remove given birthmark service from this environment.
246 public void removeService(String type){
247 services.remove(type);
251 * return birthmark service registered with given birthmark type.
253 public BirthmarkSpi getService(String type){
254 BirthmarkSpi service = services.get(type);
255 if(service == null && parent != null){
256 service = parent.getService(type);
262 * return all birthmark services searching traverse to root environment.
264 public synchronized BirthmarkSpi[] getServices(){
265 List<BirthmarkSpi> list = getServiceList();
266 BirthmarkSpi[] services = list.toArray(new BirthmarkSpi[list.size()]);
267 Arrays.sort(services, new BirthmarkSpiComparator());
272 public <T> Iterator<T> lookupProviders(Class<T> providerClass){
273 Iterator<T> iterator;
275 iterator = ServiceRegistry.lookupProviders(providerClass, loader);
278 iterator = ServiceRegistry.lookupProviders(providerClass);
284 * return birthmark services lookup from current class path.
286 public synchronized BirthmarkSpi[] findServices(){
287 List<BirthmarkSpi> list = getServiceList();
289 for(Iterator<BirthmarkSpi> i = lookupProviders(BirthmarkSpi.class); i.hasNext(); ){
290 BirthmarkSpi spi = i.next();
291 if(getService(spi.getType()) == null){
295 BirthmarkSpi[] services = list.toArray(new BirthmarkSpi[list.size()]);
296 Arrays.sort(services, new BirthmarkSpiComparator());
302 * return wellknown class manager.
304 public WellknownClassManager getWellknownClassManager(){
308 public ComparisonPairFilterManager getFilterManager(){
309 return filterManager;
312 public ExtractedBirthmarkServiceManager getHistoryManager(){
313 return historyManager;
316 void setClassLoader(ClassLoader loader){
317 this.loader = loader;
321 * find the all birthmark services searching to root environment.
323 private List<BirthmarkSpi> getServiceList(){
324 List<BirthmarkSpi> list = new ArrayList<BirthmarkSpi>();
326 for(BirthmarkSpi spi : parent.getServices()){
330 for(String key : services.keySet()){
331 list.add(services.get(key));