[17] | 1 | package hozo.sparql;
|
---|
[9] | 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 | }
|
---|