OSDN Git Service

update command line interface, and introduce command pattern in Main class
[stigmata/stigmata.git] / src / main / java / jp / sourceforge / stigmata / BirthmarkEnvironment.java
1 package jp.sourceforge.stigmata;
2
3 /*
4  * $Id$
5  */
6
7 import java.beans.PropertyChangeEvent;
8 import java.beans.PropertyChangeListener;
9 import java.io.File;
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;
16 import java.util.Map;
17 import java.util.Set;
18
19 import javax.imageio.spi.ServiceRegistry;
20
21 import jp.sourceforge.stigmata.digger.ClasspathContext;
22 import jp.sourceforge.stigmata.filter.ComparisonPairFilterManager;
23 import jp.sourceforge.stigmata.result.history.ExtractedBirthmarkServiceManager;
24 import jp.sourceforge.stigmata.spi.BirthmarkSpi;
25 import jp.sourceforge.stigmata.utils.WellknownClassManager;
26
27 /**
28  * This class represents the context for extracting/comparing birthmarks.
29  * 
30  * @author  Haruaki TAMADA
31  * @version  $Revision$
32  */
33 public class BirthmarkEnvironment{
34     /**
35      * Default environment. All instance of this class is based on default environment.
36      */
37     private static BirthmarkEnvironment DEFAULT_ENVIRONMENT = new BirthmarkEnvironment(true);
38
39     /**
40      * home directory path.
41      */
42     private static String HOME_DIRECTORY_PATH;
43
44     /**
45      * parent of this environment.
46      */
47     private BirthmarkEnvironment parent;
48
49     /**
50      * context for classpath.
51      */
52     private ClasspathContext classpathContext;
53
54     /**
55      * wellknown class manager. This object judge a class is user made class or
56      * wellknown class.
57      */
58     private WellknownClassManager manager;
59
60     /**
61      * collection of services.
62      */
63     private Map<String, BirthmarkSpi> services = new HashMap<String, BirthmarkSpi>();
64
65     /**
66      * properties manager.
67      */
68     private Map<String, String> properties = new HashMap<String, String>();
69
70     /**
71      * listeners for updating properties.
72      */
73     private List<PropertyChangeListener> propertyListeners = new ArrayList<PropertyChangeListener>();
74
75     /**
76      * filter manager.
77      */
78     private ComparisonPairFilterManager filterManager;
79
80     /**
81      * history manager.
82      */
83     private ExtractedBirthmarkServiceManager historyManager;
84
85     /**
86      * 
87      */
88     private ClassLoader loader;
89
90     /**
91      * constructor for root environment
92      */
93     private BirthmarkEnvironment(boolean flag){
94         manager = new WellknownClassManager();
95         classpathContext = new ClasspathContext();
96         filterManager = new ComparisonPairFilterManager(this);
97         historyManager = new ExtractedBirthmarkServiceManager(this);
98     }
99
100     /**
101      * constructor for specifying parent environment.
102      */
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());
109     }
110
111     /**
112      * returns the default birthmark environment.
113      */
114     public static final BirthmarkEnvironment getDefaultEnvironment(){
115         return DEFAULT_ENVIRONMENT;
116     }
117
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");
123             }
124             if(stigmataHome == null){
125                 String parent = System.getProperty("user.home");
126                 if(parent == null){
127                     parent = System.getenv("HOME");
128                 }
129                 if(parent == null){
130                     parent = ".";
131                 }
132                 // for windows
133                 if(parent.startsWith("C:\\Documents and Settings\\")){
134                     stigmataHome = parent + File.separator + "Application Data" + File.separator + "stigmata";
135                 }
136                 else{
137                     stigmataHome = parent + File.separator + ".stigmata";
138                 }
139             }
140             HOME_DIRECTORY_PATH = stigmataHome;
141         }
142         return HOME_DIRECTORY_PATH;
143     }
144
145     static void resetSettings(){
146         DEFAULT_ENVIRONMENT = new BirthmarkEnvironment(false);
147     }
148
149     public BirthmarkEnvironment getParent(){
150         return parent;
151     }
152
153     /**
154      * remove property mapped given key.
155      */
156     public void removeProperty(String key){
157         String old = properties.get(key);
158         properties.remove(key);
159         firePropertyEvent(new PropertyChangeEvent(this, key, old, null));
160     }
161
162     /**
163      * add given property.
164      */
165     public void addProperty(String key, String value){
166         boolean contains = properties.containsKey(key);
167         String old = getProperty(key);
168         properties.put(key, value);
169
170         // value is updated?
171         if(!((old != null && old.equals(value)) ||
172              (contains && old == null && value == null))){
173             firePropertyEvent(new PropertyChangeEvent(this, key, old, value));
174         }
175     }
176
177     /**
178      * returns the property mapped given key
179      */
180     public String getProperty(String key){
181         String value = properties.get(key);
182         if(value == null && parent != null){
183             value = parent.getProperty(key);
184         }
185         return value;
186     }
187
188     /**
189      * fire property change event to listeners.
190      * @param e Event object.
191      */
192     private void firePropertyEvent(PropertyChangeEvent e){
193         for(PropertyChangeListener listener: propertyListeners){
194             listener.propertyChange(e);
195         }
196     }
197
198     /**
199      * add listener for updating properties.
200      */
201     public void addPropertyListener(PropertyChangeListener listener){
202         propertyListeners.add(listener);
203     }
204
205     /**
206      * remove specified listener.
207      */
208     public void removePropertyListener(PropertyChangeListener listener){
209         propertyListeners.remove(listener);
210     }
211
212     public void clearProperties(){
213         properties.clear();
214     }
215
216     public Iterator<String> propertyKeys(){
217         Set<String> set = new HashSet<String>();
218         if(parent != null){
219             for(Iterator<String> i = parent.propertyKeys(); i.hasNext(); ){
220                 set.add(i.next());
221             }
222         }
223         set.addAll(properties.keySet());
224         return set.iterator();
225     }
226
227     /**
228      * returns the classpath context.
229      */
230     public ClasspathContext getClasspathContext(){
231         return classpathContext;
232     }
233
234     /**
235      * add given birthmark service to this environment.
236      */
237     public synchronized void addService(BirthmarkSpi service){
238         if(parent == null || parent.getService(service.getType()) == null){
239             services.put(service.getType(), service);
240         }
241     }
242
243     /**
244      * remove given birthmark service from this environment.
245      */
246     public void removeService(String type){
247         services.remove(type);
248     }
249
250     /**
251      * return birthmark service registered with given birthmark type.
252      */
253     public BirthmarkSpi getService(String type){
254         BirthmarkSpi service = services.get(type);
255         if(service == null && parent != null){
256             service = parent.getService(type);
257         }
258         return service;
259     }
260
261     /**
262      * return all birthmark services searching traverse to root environment.
263      */
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());
268
269         return services;
270     }
271
272     public <T> Iterator<T> lookupProviders(Class<T> providerClass){
273         Iterator<T> iterator;
274         if(loader != null){
275             iterator = ServiceRegistry.lookupProviders(providerClass, loader);
276         }
277         else{
278             iterator = ServiceRegistry.lookupProviders(providerClass);
279         }
280         return iterator;
281     }
282
283     /**
284      * return birthmark services lookup from current class path.
285      */
286     public synchronized BirthmarkSpi[] findServices(){
287         List<BirthmarkSpi> list = getServiceList();
288
289         for(Iterator<BirthmarkSpi> i = lookupProviders(BirthmarkSpi.class); i.hasNext(); ){
290             BirthmarkSpi spi = i.next();
291             if(getService(spi.getType()) == null){
292                 list.add(spi);
293             }
294         }
295         BirthmarkSpi[] services = list.toArray(new BirthmarkSpi[list.size()]);
296         Arrays.sort(services, new BirthmarkSpiComparator());
297
298         return services;
299     }
300
301     /**
302      * return wellknown class manager.
303      */
304     public WellknownClassManager getWellknownClassManager(){
305         return manager;
306     }
307
308     public ComparisonPairFilterManager getFilterManager(){
309         return filterManager;
310     }
311
312     public ExtractedBirthmarkServiceManager getHistoryManager(){
313         return historyManager;
314     }
315
316     void setClassLoader(ClassLoader loader){
317         this.loader = loader;
318     }
319
320     /**
321      * find the all birthmark services searching to root environment.
322      */
323     private List<BirthmarkSpi> getServiceList(){
324         List<BirthmarkSpi> list = new ArrayList<BirthmarkSpi>();
325         if(parent != null){
326             for(BirthmarkSpi spi: parent.getServices()){
327                 list.add(spi);
328             }
329         }
330         for(String key : services.keySet()){
331             list.add(services.get(key));
332         }
333         return list;
334     }
335 }