root/BH13SPARQLBuilder/src/hozo/sparql/PlainSparqlAccessor.java @ 234

リビジョン 17, 14.7 KB (コミッタ: kozaki, 11 年 前)

Commitし直します.

  • 属性 svn:mime-type の設定値 text/plain
行番号 
1package hozo.sparql;
2
3import java.io.BufferedReader;
4import java.io.InputStreamReader;
5import java.net.HttpURLConnection;
6import java.net.URL;
7import java.net.URLEncoder;
8import java.util.ArrayList;
9import java.util.HashMap;
10import java.util.List;
11import java.util.Map;
12
13import com.hp.hpl.jena.query.Query;
14import com.hp.hpl.jena.query.QueryExecution;
15import com.hp.hpl.jena.query.QueryExecutionFactory;
16import com.hp.hpl.jena.query.QueryFactory;
17import com.hp.hpl.jena.query.QuerySolution;
18import com.hp.hpl.jena.query.ResultSet;
19import com.hp.hpl.jena.query.ResultSetFactory;
20import com.hp.hpl.jena.rdf.model.RDFNode;
21import com.hp.hpl.jena.rdf.model.impl.ResourceImpl;
22/**
23 * Sparql縺ィ縺ョ繝��繧ソ
24 * @author kato
25 *
26 */
27public class PlainSparqlAccessor implements ThreadedSparqlAccessor {
28
29        private EndpointSettings setting;
30
31        private SparqlQueryListener queryListener;
32
33        public PlainSparqlAccessor(EndpointSettings endpoint, SparqlQueryListener queryListener){
34                this.queryListener = queryListener;
35
36                this.setting = endpoint;
37        }
38
39        public PlainSparqlAccessor(EndpointSettings endpoint){
40                this(endpoint, null);
41        }
42
43
44        public EndpointSettings getSetting(){
45                return this.setting;
46        }
47        /**
48         * query繧貞娼縺�※邨先棡繧定ソ斐☆
49         * @param query
50         * @return
51         */
52        protected QueryExecution makeQuery(String queryString){
53System.out.println("query:["+queryString+"]");
54                Query query = QueryFactory.create(queryString);
55                QueryExecution qe = QueryExecutionFactory.sparqlService(getSetting().getEndpoint(), query);
56
57                return qe;
58        }
59
60        /**
61         * Thread繧定オキ蜍輔@縺ヲquery螳溯。後r陦後≧縲らオ先棡縺ッlistener縺ォ霑斐k縲�
62         * @param queryString   query
63         * @param resultListener                邨先棡繧貞女縺大叙繧詰istener
64         */
65        public boolean executeQuery(String queryString, SparqlResultListener resultListener){
66
67                Thread thread = new QueryThread(queryString, resultListener){
68                        public void run(){
69                                try {
70                                        getSparqlResultListener().resultReceived(new SparqlResultSet(executeQuery(getQueryString())));
71                                } catch (Exception e) {
72                                        throw new RuntimeException(e);
73                                }
74                        }
75                };
76                thread.setUncaughtExceptionHandler(resultListener);
77                thread.start();
78                return true;
79        }
80
81
82        /**
83         * query螳溯。後r陦後≧縲らオ先棡縺ッ謌サ繧雁€、縺ィ縺励※霑斐k縲�
84         * @param queryString
85         * @return
86         * @throws Exception
87         */
88        public List<Map<String, RDFNode>> executeQuery(String queryString) throws Exception{
89
90                List<Map<String, RDFNode>> ret = new ArrayList<Map<String, RDFNode>>();
91                QueryExecution qe = makeQuery(queryString);
92
93                if (qe == null){
94                        throw new Exception("Can't connect to endpoint");
95                }
96
97                try {
98//                      System.out.println("query:"+queryString);
99                        if (this.queryListener != null){
100                                queryListener.sparqlExecuted(queryString);
101                        }
102                        ResultSet results = null;
103                        try {
104                                if (!setting.isUseCustomParam()){
105                                        results = qe.execSelect();
106                                } else {
107                                        results = customQuery(queryString);
108                                }
109                                List<String> keys = results.getResultVars();
110                                while(results.hasNext()){
111                                        QuerySolution result = results.next();
112                                        HashMap<String, RDFNode> map = new HashMap<String, RDFNode>();
113                                        for (String key : keys){
114                                                RDFNode node = result.get(key);
115                                                map.put(key, node);
116                                        }
117                                        ret.add(map);
118                                }
119                        } catch(Exception e){
120                                e.printStackTrace();
121//                              results = customQuery(queryString);
122                        }
123                } catch(Exception e){
124                        e.printStackTrace();
125                        throw e;
126                } finally {
127                        qe.close();
128                }
129
130                return ret;
131        }
132
133        private ResultSet customQuery(String query) throws Exception {
134
135                URL url = new URL(this.setting.getEndpoint() + "?" +setting.getQueryKey() + "=" + URLEncoder.encode(query, setting.getEncoding()) + "&" + setting.getOption());//POST縺吶k繝��繧ソ
136                HttpURLConnection conn = (HttpURLConnection)url.openConnection();
137                conn.setRequestProperty("Accept-Language", "ja");// 繝倥ャ繝€繧定ィュ螳�
138                conn.setRequestProperty("Referer", setting.getEndpoint());// 繝倥ャ繝€繧定ィュ螳�
139
140                int resultType = setting.getResultType();
141                ResultSet ret = null;
142
143                if (resultType == EndpointSettings.RESULT_TYPE_JSON){
144                        ret = ResultSetFactory.fromJSON(conn.getInputStream());
145                } else if (resultType == EndpointSettings.RESULT_TYPE_XML){
146                        ret = ResultSetFactory.fromXML(conn.getInputStream());
147                } else if (resultType == EndpointSettings.RESULT_TYPE_SSE){
148                        ret = ResultSetFactory.fromSSE(conn.getInputStream());
149                } else if (resultType == EndpointSettings.RESULT_TYPE_TSV){
150                        ret = ResultSetFactory.fromTSV(conn.getInputStream());
151                }
152                conn.disconnect();
153
154                return ret;
155        }
156
157
158        /**
159         * word譁�ュ怜�繧貞性繧€subject繧貞叙蠕励@縺ヲ霑斐☆
160         * @param word
161         * @param fullMatch     螳悟�荳€閾エ讀懃エ「縺�
162         * @param limit         讀懃エ「譛€螟ァ謨ー
163         * @param offset        讀懃エ「繧ェ繝輔そ繝�ヨ
164         * @param type  讀懃エ「蟇セ雎。遞ョ蛻・
165         * @return
166         * @throws Exception
167         */
168        public SparqlResultSet findSubject(String word, boolean fullMatch, Integer limit, Integer offset, int type, String[] propList) throws Exception{
169                String query;
170                word = word.replace(" ", "%20");
171
172                if (!fullMatch){
173                        if (type == PlainSparqlAccessor.FIND_TARGET_SUBJECT){
174                                query =
175                                        "select distinct ?s where {\n" +
176                                        "?s <http://www.w3.org/2000/01/rdf-schema#label> ?o \n" +
177                                        "FILTER(regex(str(?s), \""+word+"\", \"m\"))\n" +
178                                        "}";
179                        } else if (type == PlainSparqlAccessor.FIND_TARGET_OBJECT){
180                                query =
181                                        "select distinct ?s where {\n" +
182                                        "?s ?p ?o \n" +
183                                        "FILTER(regex(str(?o), \""+word+"\", \"m\"))\n" +
184                                        "}";
185                        } else if (type == PlainSparqlAccessor.FIND_TARGET_SPECIFIC_OBJECT){
186                                query =
187                                        "select distinct ?s where {\n";
188                                query += getPropertySparql(propList);
189                                query += "FILTER(regex(str(?o), \""+word+"\", \"m\"))\n" +
190                                        "}";
191                        } else {
192                                // TODO
193                                query =
194                                        "select distinct ?s where {\n";
195                                query += getPropertySparql(propList);
196                                query += "FILTER(regex(str(?o), \""+word+"\", \"m\"))\n" +
197                                        "}";
198                        }
199                } else {
200                        if (type == PlainSparqlAccessor.FIND_TARGET_OBJECT){
201                                query =
202                                        "select distinct ?s where \n{" +
203                                        "{?s ?p \""+word+"\"} UNION \n" +
204                                        "{?s ?p \""+word+"\"@en} UNION \n" +
205                                        "{?s ?p \""+word+"\"@ja} ";
206                                String[] namespaces = setting.getNamespaceList();
207                                if (namespaces != null && namespaces.length > 0){
208                                        query += "UNION \n";
209                                }
210                                for (int i=0; i<namespaces.length; i++){
211                                        String ns = namespaces[i];
212                                        query += "{?s ?p <"+ns+"/"+word+">} ";
213                                        if (i != namespaces.length-1){
214                                                query += "UNION \n";
215                                        } else {
216                                                query += "\n";
217                                        }
218                                }
219
220                                query += "}";
221                        } else if (type == PlainSparqlAccessor.FIND_TARGET_SPECIFIC_OBJECT){
222                                query = // TODO
223                                        "select distinct ?s where \n{";
224                                query += getPropertySparql(propList, word);
225                                query += "}";
226                        } else if (type == PlainSparqlAccessor.FIND_TARGET_SUBJECT){
227                                String[] namespaces = setting.getNamespaceList();
228
229                                List<Map<String, RDFNode>> ret = new ArrayList<Map<String,RDFNode>>();
230                                for (int i=0; i<namespaces.length; i++){
231                                        String ns = namespaces[i];
232                                        query = "select ?o where {\n"+
233                                        "<"+ns+"/"+word+"> ?p ?o \n";
234                                        query += "}";
235                                        List<Map<String, RDFNode>> temp = executeQuery(query);
236                                        if (temp != null && temp.size() > 0){
237                                                HashMap<String, RDFNode> node = new HashMap<String, RDFNode>();
238                                                node.put("s", new ResourceImpl(ns+"/"+word));
239                                                ret.add(node);
240                                        }
241
242                                }
243                                // TODO 邨先棡縺ョ譛€螟ァ謨ー縺ッnamespaces.size縺ェ縺ョ縺ァ蜴ウ蟇�↓縺ッLIMIT, OFFSET繧ょョ夂セゥ縺ァ縺阪k繧医≧縺ォ縺励※縺翫>縺滓婿縺瑚憶縺�
244                                return new SparqlResultSet(ret, false);
245                        } else {
246                                // TODO
247                                query =
248                                        "select distinct ?s where {\n";
249                                query += getPropertySparql(propList, word);
250                                query += "}";
251                        }
252                }
253                if (limit != null && limit > 0){
254                        query +="\n LIMIT " + String.valueOf(limit+1);
255                }
256                if (offset != null && offset > 0){
257                        query += "\n OFFSET " + String.valueOf(offset);
258                }
259
260                List<Map<String, RDFNode>> result = executeQuery(query);
261                SparqlResultSet ret = new SparqlResultSet(result);
262                if (limit != null){
263                        if (result != null && result.size() > limit){
264                                result = result.subList(0, limit);
265                                ret.setDefaultResult(result);
266                                ret.setHasNext(true);
267                        }
268                }
269
270                return ret;
271        }
272
273        private String getPropertySparql(String[] propList){
274                StringBuilder sb = new StringBuilder();
275                if (propList == null){
276                        // 蠢オ縺ョ縺溘a
277                        propList = new String[]{"http://www.w3.org/2000/01/rdf-schema#label"};
278                }
279
280                if (propList.length == 1){
281                        sb.append("?s <");
282                        sb.append(propList[0]);
283                        sb.append("> ?o \n");
284                } else {
285                        sb.append("{\n");
286                        for (int i=0; i<propList.length; i++){
287                                sb.append("{?s <");
288                                sb.append(propList[i]);
289                                sb.append("> ?o ");
290                                if (i == propList.length-1){
291                                        sb.append("}\n");
292                                } else {
293                                        sb.append("} UNION \n");
294                                }
295                        }
296
297                        sb.append("}");
298                }
299                return sb.toString();
300        }
301
302        private String getPropertySparql(String[] propList, String word){
303                StringBuilder sb = new StringBuilder();
304                if (propList == null){
305                        // 蠢オ縺ョ縺溘a
306                        propList = new String[]{"http://www.w3.org/2000/01/rdf-schema#label"};
307                }
308
309                sb.append("{\n");
310                for (int i=0; i<propList.length; i++){
311
312                        sb.append("{?s <" +propList[i] + "> \""+word+"\"} UNION \n");
313                        sb.append("{?s <" +propList[i] + "> \""+word+"\"@en} UNION \n");
314                        sb.append("{?s <" +propList[i] + "> \""+word+"\"@ja");
315                        if (i == propList.length-1){
316                                sb.append("}\n");
317                        } else {
318                                sb.append("} UNION \n");
319                        }
320                }
321
322                sb.append("}");
323                return sb.toString();
324
325        }
326
327
328        /**
329         * Thread繧定オキ蜍輔@縺ヲword譁�ュ怜�繧貞性繧€subject繧貞叙蠕励@縺ヲ霑斐☆縲らオ先棡縺ッlistener縺ォ霑斐k縲�
330         * @param word                  讀懃エ「譁�ュ怜�
331         * @param resultListener                邨先棡繧貞女縺大叙繧詰istener
332         */
333        public boolean findSubject(String word, boolean fullMatch, Integer limit, Integer offset, int type, String[] propList, SparqlResultListener resultListener){
334
335                Thread thread = new QueryThread(word, new Object[]{new Boolean(fullMatch), limit, offset, new Integer(type), propList}, resultListener){
336                        public void run(){
337                                try {
338                                        Boolean fullMatch = (Boolean)((Object[])getOption())[0];
339                                        Integer limit = (Integer)((Object[])getOption())[1];
340                                        Integer offset = (Integer)((Object[])getOption())[2];
341                                        Integer type = (Integer)((Object[])getOption())[3];
342                                        String[] propList = (String[])((Object[])getOption())[4];
343                                        getSparqlResultListener().resultReceived(findSubject(getQueryString(), fullMatch, limit, offset, type, propList));
344                                } catch(Exception e){
345                                        throw new RuntimeException(e);
346                                }
347                        }
348                };
349                thread.setUncaughtExceptionHandler(resultListener);
350                thread.start();
351                return true;
352
353        }
354
355        /**
356         * 謖�ョ壹&繧後◆subject繧呈戟縺、triple��ubject縺ッ遒コ螳壹@縺ヲ縺�k縺ョ縺ァproperty縺ィobject縺ョ縺ソ�峨r霑斐☆
357         * @param triple
358         * @return
359         * @throws Exception
360         */
361        public List<Map<String, RDFNode>> findTripleFromSubject(String subject) throws Exception{
362                subject = subject.replace(" ", "%20");
363                String query =
364                        "select ?p ?o where {\n" +
365                        "<" + subject + "> ?p ?o\n"+
366                        "}";
367
368                return executeQuery(query);
369        }
370
371        public boolean findTripleFromSubject(String subject, SparqlResultListener listener){
372
373                Thread thread = new QueryThread(subject, listener){
374                        public void run(){
375                                try {
376                                        getSparqlResultListener().resultReceived(new SparqlResultSet(findTripleFromSubject(getQueryString())));
377                                } catch(Exception e){
378                                        throw new RuntimeException(e);
379                                }
380                        }
381                };
382                thread.setUncaughtExceptionHandler(listener);
383                thread.start();
384                return true;
385
386        }
387
388
389        @Override
390        public List<Map<String, RDFNode>> findPropertyList() throws Exception {
391                // TODO 譛ャ譚・縺ッdistinct縺ォ縺励◆縺�′縺昴l縺縺ィ驥阪>endpoint縺後≠繧�
392                List<Map<String, RDFNode>> ret = new ArrayList<Map<String,RDFNode>>();
393                Map<String, RDFNode> result = new HashMap<String, RDFNode>();
394                ret.add(result);
395                String query =
396                        "select ?s {\n" +
397                        "?s ?p ?o\n"+
398                        "} LIMIT 10";
399                List<Map<String, RDFNode>> subjects = executeQuery(query);
400                for (Map<String, RDFNode> subjectMap : subjects){
401                        RDFNode subject = subjectMap.get("s");
402                        query =
403                                "select distinct ?p where {\n" +
404                                "<" + subject + "> ?p ?o\n"+
405                                "}";
406                        List<Map<String, RDFNode>> properties = executeQuery(query);
407                        for (Map<String, RDFNode> propertyMap : properties){
408                                RDFNode property = propertyMap.get("p");
409                                // property縺ョ蝣エ蜷医�縲∵綾繧翫�Map縺ョ蠖「蠑上r螟峨∴繧�
410                                // key:隕∫エ遞ョ蛻・縲�value:隕∫エ縲€縺ァ縺ッ縺ェ縺上€�
411                                // key:隕∫エ縺ョ譁�ュ怜�陦ィ迴セ縲�value:隕∫エ縲€縺ィ縺吶k縲�
412                                // �郁ヲ∫エ遞ョ蛻・縺檎「コ螳壹@縺ヲ縺�k縺ョ縺ィ縲∬ヲ∫エ縺ョ驥崎、�r蜑企勁縺吶k縺溘a��
413                                result.put(property.toString(), property);
414System.out.println("p["+property.toString()+"]");
415                        }
416                }
417
418                return ret;
419        }
420
421        @Override
422        public boolean findPropertyList(SparqlResultListener listener) {
423                Thread thread = new QueryThread(null, listener){
424                        public void run(){
425                                try {
426                                        getSparqlResultListener().resultReceived(new SparqlResultSet(findPropertyList()));
427                                } catch(Exception e){
428                                        throw new RuntimeException(e);
429                                }
430                        }
431                };
432                thread.setUncaughtExceptionHandler(listener);
433                thread.start();
434                return true;
435        }
436
437
438        public static void main(String[] args){
439
440                try {
441                        URL url = new URL("http://www.wikipediaontology.org/query/?q=" + URLEncoder.encode("select * {?s ?p ?o}", "UTF-8") + "&type=xml&LIMIT=100");//POST縺吶k繝��繧ソ
442                        HttpURLConnection conn = (HttpURLConnection)url.openConnection();
443                        conn.setRequestProperty("User-Agent", "test");// 繝倥ャ繝€繧定ィュ螳�
444                        conn.setRequestProperty("Accept-Language", "ja");// 繝倥ャ繝€繧定ィュ螳�
445                        conn.setRequestProperty("Referer", "http://www.wikipediaontology.org/query/");// 繝倥ャ繝€繧定ィュ螳�
446                        InputStreamReader isr = new java.io.InputStreamReader(conn.getInputStream(), "UTF-8");
447                        BufferedReader br = new java.io.BufferedReader(isr);
448
449                        // 蜿嶺ソ。縺励◆繧ケ繝医Μ繝シ繝繧定。ィ遉コ
450                        String line = null;
451                        while (null != (line = br.readLine())) {
452                            System.out.println(line);
453                        }
454
455                        // 繧ケ繝医Μ繝シ繝縺ェ繧峨�縺ォ謗・邯壹r繧ッ繝ュ繝シ繧コ
456                        br.close();
457                        conn.disconnect();
458                } catch(Exception e){
459                        e.printStackTrace();
460                }
461
462        }
463}
464
465class QueryThread extends Thread {
466
467        private String queryString;
468        private Object option;
469        private SparqlResultListener listener;
470
471        public QueryThread(String queryString, Object option, SparqlResultListener listener){
472                this.queryString = queryString;
473                this.option = option;
474                this.listener = listener;
475        }
476
477        public QueryThread(String queryString, SparqlResultListener listener){
478                this(queryString, null, listener);
479        }
480
481        protected String getQueryString(){
482                return this.queryString;
483        }
484
485        protected Object getOption(){
486                return this.option;
487        }
488
489        protected SparqlResultListener getSparqlResultListener(){
490                return this.listener;
491        }
492
493}
494
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。