1 | package jp.ac.osaka_u.sanken.sparql;
|
---|
2 |
|
---|
3 | import java.util.ArrayList;
|
---|
4 | import java.util.LinkedHashMap;
|
---|
5 | import java.util.List;
|
---|
6 | import java.util.Map;
|
---|
7 |
|
---|
8 | import com.hp.hpl.jena.rdf.model.RDFNode;
|
---|
9 |
|
---|
10 | public class CrossSparqlAccessor implements ThreadedSparqlAccessor {
|
---|
11 |
|
---|
12 | private List<EndpointSettings> settings;
|
---|
13 |
|
---|
14 | private Map<EndpointSettings, SparqlAccessor> accessorHash;
|
---|
15 |
|
---|
16 | private Map<Integer, CrossOffset> crossOffsetMap;
|
---|
17 |
|
---|
18 | public CrossSparqlAccessor(List<EndpointSettings> settings, SparqlQueryListener listener){
|
---|
19 | accessorHash = new LinkedHashMap<EndpointSettings, SparqlAccessor>();
|
---|
20 | for (EndpointSettings setting : settings){
|
---|
21 | accessorHash.put(setting, SparqlAccessorFactory.createSparqlAccessor(setting, listener));
|
---|
22 | }
|
---|
23 |
|
---|
24 | this.settings = settings;
|
---|
25 |
|
---|
26 | init();
|
---|
27 | }
|
---|
28 |
|
---|
29 | public CrossSparqlAccessor(List<EndpointSettings> settings){
|
---|
30 | accessorHash = new LinkedHashMap<EndpointSettings, SparqlAccessor>();
|
---|
31 | for (EndpointSettings setting : settings){
|
---|
32 | accessorHash.put(setting, SparqlAccessorFactory.createSparqlAccessor(setting));
|
---|
33 | }
|
---|
34 | this.settings = settings;
|
---|
35 |
|
---|
36 | init();
|
---|
37 | }
|
---|
38 |
|
---|
39 | private void init(){
|
---|
40 | crossOffsetMap = new LinkedHashMap<Integer, CrossSparqlAccessor.CrossOffset>();
|
---|
41 | }
|
---|
42 |
|
---|
43 | @Override
|
---|
44 | public List<Map<String, RDFNode>> executeQuery(String queryString)
|
---|
45 | throws Exception {
|
---|
46 |
|
---|
47 | // TODO 譛ェ蟇セ蠢懊〒濶ッ縺�シ� |
---|
48 | throw new UnsupportedOperationException("Can't Execute Query");
|
---|
49 | }
|
---|
50 |
|
---|
51 | @Override
|
---|
52 | public SparqlResultSet findSubject(String word, boolean fullMatch,
|
---|
53 | Integer limit, Integer offset, int type, String[] propList) throws Exception {
|
---|
54 | SparqlResultSet ret = new SparqlResultSet(new ArrayList<Map<String, RDFNode>>());
|
---|
55 | Integer limit_ = limit;
|
---|
56 | Integer offset_ = offset;
|
---|
57 |
|
---|
58 | CrossOffset cOffset = null;
|
---|
59 | if (offset != null){
|
---|
60 | crossOffsetMap.get(new Integer(offset));
|
---|
61 | if (cOffset == null){
|
---|
62 | cOffset = new CrossOffset(0, offset);
|
---|
63 | }
|
---|
64 | }
|
---|
65 |
|
---|
66 | for (int i=0; i<settings.size(); i++){
|
---|
67 | if (cOffset != null){
|
---|
68 | i = cOffset.endpointIndex;
|
---|
69 | }
|
---|
70 | EndpointSettings setting = settings.get(i);
|
---|
71 | SparqlAccessor sa = accessorHash.get(setting);
|
---|
72 | SparqlResultSet set = sa.findSubject(word, fullMatch, limit_, (cOffset == null ? null : cOffset.offset), type, propList);
|
---|
73 | ret.addResult(setting.getEndpoint(), set.getDefaultResult());
|
---|
74 | if (cOffset != null){
|
---|
75 | if (ret.getDefaultResult().size() < limit){
|
---|
76 | limit_ = limit - set.getDefaultResult().size();
|
---|
77 | offset_ = 0;
|
---|
78 | } else {
|
---|
79 | cOffset = new CrossOffset(i, limit_ + offset_);
|
---|
80 | crossOffsetMap.put(new Integer(limit + offset), cOffset);
|
---|
81 | break;
|
---|
82 | }
|
---|
83 | if (i == settings.size() - 1 && set.isHasNext()){
|
---|
84 | ret.setHasNext(true);
|
---|
85 | }
|
---|
86 | }
|
---|
87 | }
|
---|
88 |
|
---|
89 | return ret;
|
---|
90 | }
|
---|
91 |
|
---|
92 | @Override
|
---|
93 | public List<Map<String, RDFNode>> findTripleFromSubject(String subject)
|
---|
94 | throws Exception {
|
---|
95 | List<Map<String, RDFNode>> ret = new ArrayList<Map<String,RDFNode>>();
|
---|
96 |
|
---|
97 | for (EndpointSettings setting : settings){
|
---|
98 | boolean hit = false;
|
---|
99 | for (String ns : setting.getNamespaceList()){
|
---|
100 | if (subject.startsWith(ns)){
|
---|
101 | hit = true;
|
---|
102 | }
|
---|
103 | }
|
---|
104 | if (hit){
|
---|
105 | SparqlAccessor sa = accessorHash.get(setting);
|
---|
106 | List<Map<String, RDFNode>> set = sa.findTripleFromSubject(subject);
|
---|
107 | ret.addAll(set);
|
---|
108 | }
|
---|
109 |
|
---|
110 | }
|
---|
111 |
|
---|
112 | return ret;
|
---|
113 | }
|
---|
114 |
|
---|
115 | private boolean isThereTargetEndpoint(String subject){
|
---|
116 | for (EndpointSettings setting : settings){
|
---|
117 | for (String ns : setting.getNamespaceList()){
|
---|
118 | if (subject.startsWith(ns)){
|
---|
119 | return true;
|
---|
120 | }
|
---|
121 | }
|
---|
122 | }
|
---|
123 | return false;
|
---|
124 | }
|
---|
125 |
|
---|
126 | @Override
|
---|
127 | public boolean executeQuery(String queryString,
|
---|
128 | SparqlResultListener resultListener) {
|
---|
129 | // TODO 譛ェ蟇セ蠢懊〒濶ッ縺�シ� |
---|
130 | throw new UnsupportedOperationException("Can't Execute Query");
|
---|
131 |
|
---|
132 | }
|
---|
133 |
|
---|
134 | @Override
|
---|
135 | public boolean findSubject(String word, boolean fullMatch, Integer limit,
|
---|
136 | Integer offset, int type, String[] propList, SparqlResultListener resultListener) {
|
---|
137 | Thread thread = new QueryThread(word, new Object[]{new Boolean(fullMatch), limit, offset, new Integer(type), propList}, resultListener){
|
---|
138 | public void run(){
|
---|
139 | try {
|
---|
140 | Boolean fullMatch = (Boolean)((Object[])getOption())[0];
|
---|
141 | Integer limit = (Integer)((Object[])getOption())[1];
|
---|
142 | Integer offset = (Integer)((Object[])getOption())[2];
|
---|
143 | Integer type = (Integer)((Object[])getOption())[3];
|
---|
144 | String[] propList = (String[])((Object[])getOption())[4];
|
---|
145 | getSparqlResultListener().resultReceived(findSubject(getQueryString(), fullMatch, limit, offset, type, propList));
|
---|
146 | } catch(Exception e){
|
---|
147 | throw new RuntimeException(e);
|
---|
148 | }
|
---|
149 | }
|
---|
150 | };
|
---|
151 | thread.setUncaughtExceptionHandler(resultListener);
|
---|
152 | thread.start();
|
---|
153 |
|
---|
154 | return true;
|
---|
155 | }
|
---|
156 |
|
---|
157 | @Override
|
---|
158 | public boolean findTripleFromSubject(String subject,
|
---|
159 | SparqlResultListener listener) {
|
---|
160 | if (!isThereTargetEndpoint(subject)){
|
---|
161 | // 蟇セ雎。endpoint縺ェ縺� |
---|
162 | return false;
|
---|
163 | }
|
---|
164 |
|
---|
165 | Thread thread = new QueryThread(subject, listener){
|
---|
166 | public void run(){
|
---|
167 | try {
|
---|
168 | getSparqlResultListener().resultReceived(new SparqlResultSet(findTripleFromSubject(getQueryString())));
|
---|
169 | } catch(Exception e){
|
---|
170 | throw new RuntimeException(e);
|
---|
171 | }
|
---|
172 | }
|
---|
173 | };
|
---|
174 | thread.setUncaughtExceptionHandler(listener);
|
---|
175 | thread.start();
|
---|
176 | return true;
|
---|
177 |
|
---|
178 | }
|
---|
179 |
|
---|
180 |
|
---|
181 | @Override
|
---|
182 | public List<Map<String, RDFNode>> findPropertyList() throws Exception {
|
---|
183 | List<Map<String, RDFNode>> ret = new ArrayList<Map<String,RDFNode>>();
|
---|
184 | Map<String, RDFNode> result = new LinkedHashMap<String, RDFNode>();
|
---|
185 | ret.add(result);
|
---|
186 | for (EndpointSettings setting : settings){
|
---|
187 | SparqlAccessor sa = accessorHash.get(setting);
|
---|
188 | List<Map<String, RDFNode>> set = sa.findPropertyList();
|
---|
189 | for (Map<String, RDFNode> r : set){
|
---|
190 | for (String key : r.keySet()){
|
---|
191 | result.put(key, r.get(key));
|
---|
192 | }
|
---|
193 | }
|
---|
194 | }
|
---|
195 |
|
---|
196 | return ret;
|
---|
197 | }
|
---|
198 |
|
---|
199 | @Override
|
---|
200 | public boolean findPropertyList(SparqlResultListener listener) {
|
---|
201 | Thread thread = new QueryThread(null, listener){
|
---|
202 | public void run(){
|
---|
203 | try {
|
---|
204 | getSparqlResultListener().resultReceived(new SparqlResultSet(findPropertyList()));
|
---|
205 | } catch(Exception e){
|
---|
206 | throw new RuntimeException(e);
|
---|
207 | }
|
---|
208 | }
|
---|
209 | };
|
---|
210 | thread.setUncaughtExceptionHandler(listener);
|
---|
211 | thread.start();
|
---|
212 | return true;
|
---|
213 | }
|
---|
214 |
|
---|
215 | private class CrossOffset {
|
---|
216 |
|
---|
217 | public int endpointIndex;
|
---|
218 | public int offset;
|
---|
219 |
|
---|
220 | public CrossOffset(int endpointIndex, int offset){
|
---|
221 | this.endpointIndex = endpointIndex;
|
---|
222 | this.offset = offset;
|
---|
223 | }
|
---|
224 | }
|
---|
225 |
|
---|
226 | }
|
---|