OSDN Git Service

add menu item `open setting dir\'
[stigmata/stigmata-core.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.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;
15 import java.util.Map;
16 import java.util.Set;
17
18 import javax.imageio.spi.ServiceRegistry;
19
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;
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 StigmataHomeManager stigmataHome = new StigmataHomeManager();
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         return stigmataHome.getStigmataHome();
120     }
121
122     static void resetSettings(){
123         DEFAULT_ENVIRONMENT = new BirthmarkEnvironment(false);
124     }
125
126     public BirthmarkEnvironment getParent(){
127         return parent;
128     }
129
130     /**
131      * remove property mapped given key.
132      */
133     public void removeProperty(String key){
134         String old = properties.get(key);
135         properties.remove(key);
136         firePropertyEvent(new PropertyChangeEvent(this, key, old, null));
137     }
138
139     /**
140      * add given property.
141      */
142     public void addProperty(String key, String value){
143         boolean contains = properties.containsKey(key);
144         String old = getProperty(key);
145         properties.put(key, value);
146
147         // value is updated?
148         if(!((old != null && old.equals(value)) ||
149              (contains && old == null && value == null))){
150             firePropertyEvent(new PropertyChangeEvent(this, key, old, value));
151         }
152     }
153
154     /**
155      * returns the property mapped given key
156      */
157     public String getProperty(String key){
158         String value = properties.get(key);
159         if(value == null && parent != null){
160             value = parent.getProperty(key);
161         }
162         return value;
163     }
164
165     /**
166      * fire property change event to listeners.
167      * @param e Event object.
168      */
169     private void firePropertyEvent(PropertyChangeEvent e){
170         for(PropertyChangeListener listener: propertyListeners){
171             listener.propertyChange(e);
172         }
173     }
174
175     /**
176      * add listener for updating properties.
177      */
178     public void addPropertyListener(PropertyChangeListener listener){
179         propertyListeners.add(listener);
180     }
181
182     /**
183      * remove specified listener.
184      */
185     public void removePropertyListener(PropertyChangeListener listener){
186         propertyListeners.remove(listener);
187     }
188
189     public void clearProperties(){
190         properties.clear();
191     }
192
193     public Iterator<String> propertyKeys(){
194         Set<String> set = new HashSet<String>();
195         if(parent != null){
196             for(Iterator<String> i = parent.propertyKeys(); i.hasNext(); ){
197                 set.add(i.next());
198             }
199         }
200         set.addAll(properties.keySet());
201         return set.iterator();
202     }
203
204     /**
205      * returns the classpath context.
206      */
207     public ClasspathContext getClasspathContext(){
208         return classpathContext;
209     }
210
211     /**
212      * add given birthmark service to this environment.
213      */
214     public synchronized void addService(BirthmarkSpi service){
215         if(parent == null || parent.getService(service.getType()) == null){
216             services.put(service.getType(), service);
217         }
218     }
219
220     /**
221      * remove given birthmark service from this environment.
222      */
223     public void removeService(String type){
224         services.remove(type);
225     }
226
227     /**
228      * return birthmark service registered with given birthmark type.
229      */
230     public BirthmarkSpi getService(String type){
231         BirthmarkSpi service = services.get(type);
232         if(service == null && parent != null){
233             service = parent.getService(type);
234         }
235         return service;
236     }
237
238     /**
239      * return all birthmark services searching traverse to root environment.
240      */
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());
245
246         return services;
247     }
248
249     public <T> Iterator<T> lookupProviders(Class<T> providerClass){
250         Iterator<T> iterator;
251         if(loader != null){
252             iterator = ServiceRegistry.lookupProviders(providerClass, loader);
253         }
254         else{
255             iterator = ServiceRegistry.lookupProviders(providerClass);
256         }
257         return iterator;
258     }
259
260     /**
261      * return birthmark services lookup from current class path.
262      */
263     public synchronized BirthmarkSpi[] findServices(){
264         List<BirthmarkSpi> list = getServiceList();
265
266         for(Iterator<BirthmarkSpi> i = lookupProviders(BirthmarkSpi.class); i.hasNext(); ){
267             BirthmarkSpi spi = i.next();
268             if(getService(spi.getType()) == null){
269                 list.add(spi);
270             }
271         }
272         BirthmarkSpi[] services = list.toArray(new BirthmarkSpi[list.size()]);
273         Arrays.sort(services, new BirthmarkSpiComparator());
274
275         return services;
276     }
277
278     /**
279      * return wellknown class manager.
280      */
281     public WellknownClassManager getWellknownClassManager(){
282         return manager;
283     }
284
285     public ComparisonPairFilterManager getFilterManager(){
286         return filterManager;
287     }
288
289     public ExtractedBirthmarkServiceManager getHistoryManager(){
290         return historyManager;
291     }
292
293     void setClassLoader(ClassLoader loader){
294         this.loader = loader;
295     }
296
297     /**
298      * find the all birthmark services searching to root environment.
299      */
300     private List<BirthmarkSpi> getServiceList(){
301         List<BirthmarkSpi> list = new ArrayList<BirthmarkSpi>();
302         if(parent != null){
303             for(BirthmarkSpi spi: parent.getServices()){
304                 list.add(spi);
305             }
306         }
307         for(String key : services.keySet()){
308             list.add(services.get(key));
309         }
310         return list;
311     }
312 }