OSDN Git Service

BirthmarkSpi -> BirthmarkService
[stigmata/stigmata.git] / src / main / java / jp / sourceforge / stigmata / utils / ConfigFileImporter.java
1 package jp.sourceforge.stigmata.utils;
2
3 import java.io.IOException;
4 import java.io.InputStream;
5 import java.net.MalformedURLException;
6 import java.net.URL;
7 import java.util.HashMap;
8 import java.util.Map;
9
10 import javax.xml.parsers.ParserConfigurationException;
11 import javax.xml.parsers.SAXParser;
12 import javax.xml.parsers.SAXParserFactory;
13
14 import jp.sourceforge.stigmata.BirthmarkEnvironment;
15 import jp.sourceforge.stigmata.ComparisonPairFilter;
16 import jp.sourceforge.stigmata.ComparisonPairFilterSet;
17 import jp.sourceforge.stigmata.Stigmata;
18 import jp.sourceforge.stigmata.spi.BirthmarkService;
19 import jp.sourceforge.stigmata.spi.ReflectedBirthmarkService;
20
21 import org.xml.sax.Attributes;
22 import org.xml.sax.SAXException;
23 import org.xml.sax.helpers.DefaultHandler;
24
25 /**
26  * configuration file parser.
27  * 
28  * @author Haruaki TAMADA
29  */
30 public class ConfigFileImporter{
31     private BirthmarkEnvironment environment;
32
33     public ConfigFileImporter(BirthmarkEnvironment environment){
34         this.environment = environment;
35     }
36
37     public BirthmarkEnvironment parse(InputStream in) throws IOException{
38         try{
39             SAXParserFactory factory = SAXParserFactory.newInstance();
40             SAXParser parser = factory.newSAXParser();
41             Handler handler = new Handler(getEnvironment());
42             parser.parse(in, handler);
43             this.environment = handler.getEnvironment();
44
45             return environment;
46         }catch(ParserConfigurationException e){
47             throw new IOException(e.getMessage());
48         }catch(SAXException e){
49             throw new IOException(e.getMessage());
50         }
51     }
52
53     public BirthmarkEnvironment getEnvironment(){
54         return environment;
55     }
56
57     private static enum Part{
58         WELLKNOWN_CLASSES, PROPERTIES, CLASSPATH, SERVICES, FILTER_SET, FILTER_DEFINITION,
59     }
60
61     private static class Handler extends DefaultHandler{
62         private BirthmarkEnvironment environment;
63         private WellknownClassManager manager;
64         private Map<String, String> serviceMap;
65         private ComparisonPairFilterSet filter;
66         private Part part;
67         private boolean exclude;
68         private WellknownClassJudgeRule.MatchType matchType;
69         private WellknownClassJudgeRule.MatchPartType partType;
70         private String qname;
71         private String key;
72         private String filterType, filterCriterion, attributeName;
73         private Map<String, String> filterAttributes = new HashMap<String, String>();
74
75         public Handler(BirthmarkEnvironment environment){
76             if(environment == null){
77                 environment = Stigmata.getInstance().createEnvironment();
78             }
79             this.environment = environment;
80             this.manager = environment.getWellknownClassManager();
81         }
82
83         public BirthmarkEnvironment getEnvironment(){
84             return environment;
85         }
86
87         @Override
88         public void startElement(String uri, String localName, String qname,
89                                  Attributes attributes) throws SAXException{
90             this.qname = qname;
91
92             if(qname.equals("wellknown-classes")){
93                 part = Part.WELLKNOWN_CLASSES;
94             }
95             else if(qname.equals("property")){
96                 part = Part.PROPERTIES;
97             }
98             else if(qname.equals("classpath-list")){
99                 part = Part.CLASSPATH;
100             }
101             else if(qname.equals("birthmark-service")){
102                 part = Part.SERVICES;
103             }
104             else if(qname.equals("filterset-list")){
105                 part = Part.FILTER_SET;
106             }
107
108             if(part == Part.FILTER_SET){
109                 if(qname.equals("filterset")){
110                     filter = new ComparisonPairFilterSet();
111                 }
112                 else if(qname.equals("filter")){
113                     part = Part.FILTER_DEFINITION;
114                     filterAttributes.clear();
115                 }
116             }
117             else if(part == Part.WELLKNOWN_CLASSES){
118                 if(qname.equals("exclude")){
119                     exclude = true;
120                 }
121                 else if(qname.equals("package-name")){
122                     partType = WellknownClassJudgeRule.MatchPartType.PACKAGE_NAME;
123                 }
124                 else if(qname.equals("class-name")){
125                     partType = WellknownClassJudgeRule.MatchPartType.CLASS_NAME;
126                 }
127                 else if(qname.equals("fully-name")){
128                     partType = WellknownClassJudgeRule.MatchPartType.FULLY_NAME;
129                 }
130                 else if(qname.equals("suffix")){
131                     matchType = WellknownClassJudgeRule.MatchType.SUFFIX;
132                 }
133                 else if(qname.equals("prefix")){
134                     matchType = WellknownClassJudgeRule.MatchType.PREFIX;
135                 }
136                 else if(qname.equals("match")){
137                     matchType = WellknownClassJudgeRule.MatchType.EXACT;
138                 }
139                 else if(qname.equals("not-match")){
140                     matchType = WellknownClassJudgeRule.MatchType.NOT_MATCH;
141                 }
142             }
143         }
144
145         @Override
146         public void characters(char[] data, int offset, int length) throws SAXException{
147             String value = new String(data, offset, length).trim();
148
149             if(value.length() > 0){
150                 if(part == Part.PROPERTIES){
151                     if(qname.equals("name")){
152                         key = value;
153                     }
154                     else if(qname.equals("value")){
155                         environment.addProperty(key, value);
156                     }
157                 }
158                 else if(part == Part.WELLKNOWN_CLASSES
159                         && (qname.equals("suffix") || qname.equals("prefix") || qname.equals("match"))){
160                     manager.add(new WellknownClassJudgeRule(value, matchType, partType, exclude));
161                     exclude = false;
162                 }
163                 else if(part == Part.CLASSPATH && qname.equals("classpath")){
164                     try{
165                         environment.getClasspathContext().addClasspath(new URL(value));
166                     }catch(MalformedURLException e){
167                         throw new SAXException(e);
168                     }
169                 }
170                 else if(part == Part.SERVICES){
171                     if(serviceMap == null){
172                         serviceMap = new HashMap<String, String>();
173                     }
174                     serviceMap.put(qname, value);
175                 }
176                 else if(part == Part.FILTER_SET){
177                     if(qname.equals("name")){
178                         filter.setName(value);
179                     }
180                     else if(qname.equals("match")){
181                         if(value.equals("all")){
182                             filter.setMatchAll();
183                         }
184                         else{
185                             filter.setMatchAny();
186                         }
187                     }
188                 }
189                 else if(part == Part.FILTER_DEFINITION){
190                     if(qname.equals("filter-type")){
191                         filterType = value;
192                     }
193                     else if(qname.equals("criterion")){
194                         filterCriterion = value;
195                     }
196                     else if(qname.equals("name")){
197                         attributeName = value;
198                     }
199                     else{
200                         filterAttributes.put(attributeName, value);
201                     }
202                 }
203             }
204         }
205
206         @Override
207         public void endElement(String uri, String localname, String qname){
208             if(part == Part.SERVICES && qname.equals("birthmark-service")){
209                 BirthmarkService service = new ReflectedBirthmarkService(
210                     serviceMap.get("type"),
211                     serviceMap.get("description"),
212                     serviceMap.get("extractor"),
213                     serviceMap.get("comparator")
214                 );
215                 environment.addService(service);
216             }
217             else if(part == Part.FILTER_DEFINITION && qname.equals("filter")){
218                 ComparisonPairFilter f = environment.getFilterManager().buildFilter(
219                     filterType, filterCriterion, filterAttributes
220                 );
221                 filter.addFilter(f);
222                 part = Part.FILTER_SET;
223             }
224             else if(part == Part.FILTER_SET && qname.equals("filterset")){
225                 environment.getFilterManager().addFilterSet(filter);
226             }
227         }
228     }
229 }