Project

General

Profile

Download (8.13 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
 * Copyright (C) 2015 EDIT
3
 * European Distributed Institute of Taxonomy
4
 * http://www.e-taxonomy.eu
5
 *
6
 * The contents of this file are subject to the Mozilla Public License Version 1.1
7
 * See LICENSE.TXT at the top of this package for the full license terms.
8
 */
9
package org.cybertaxonomy.utis.query;
10

    
11
import java.net.URI;
12
import java.net.URISyntaxException;
13
import java.util.ArrayList;
14
import java.util.NoSuchElementException;
15

    
16
import org.apache.jena.rdf.model.Resource;
17
import org.apache.jena.rdf.model.StmtIterator;
18
import org.cybertaxonomy.utis.checklist.EEA_BDC_Client.RdfSchema;
19
import org.cybertaxonomy.utis.store.Neo4jStore;
20
import org.neo4j.graphdb.Node;
21
import org.neo4j.graphdb.index.AutoIndexer;
22
import org.neo4j.graphdb.index.IndexHits;
23
import org.openrdf.query.BindingSet;
24
import org.openrdf.query.QueryEvaluationException;
25
import org.openrdf.query.TupleQueryResult;
26
import org.openrdf.repository.RepositoryException;
27
import org.openrdf.repository.sail.SailRepositoryConnection;
28
import org.slf4j.Logger;
29
import org.slf4j.LoggerFactory;
30

    
31
import com.tinkerpop.blueprints.Direction;
32
import com.tinkerpop.blueprints.Graph;
33
import com.tinkerpop.blueprints.Vertex;
34
import com.tinkerpop.blueprints.impls.neo4j2.Neo4j2Graph;
35
import com.tinkerpop.blueprints.impls.neo4j2.Neo4j2Vertex;
36
import com.tinkerpop.blueprints.oupls.sail.GraphSail;
37
import com.tinkerpop.gremlin.java.GremlinPipeline;
38
import com.tinkerpop.pipes.util.FastNoSuchElementException;
39

    
40
/**
41
 *
42
 * Developer links:
43
 * <ul>
44
 * <li>https://github.com/tinkerpop/blueprints/wiki/Sail-Ouplementation</li>
45
 * <li>https://github.com/tinkerpop/gremlin/wiki</li>
46
 * <li>
47
 * http://rdf4j.org/sesame/2.7/docs/users.docbook?view#section-repository-api3</li>
48
 * <li>https://github.com/tinkerpop/gremlin/wiki/SPARQL-vs.-Gremlin</li>
49
 * <li>https://github.com/tinkerpop/gremlin/wiki/Using-Gremlin-through-Java</li>
50
 * <li>
51
 * http://markorodriguez.com/2011/06/15/graph-pattern-matching-with-gremlin-1-1/
52
 * </li>
53
 * <li>https://github.com/datablend/neo4j-sail-test</li>
54
 * </ul>
55
 *
56
 * @author a.kohlbecker
57
 * @date Sep 30, 2015
58
 *
59
 */
60
public class TinkerPopClient implements IQueryClient {
61

    
62
    protected Logger logger = LoggerFactory.getLogger(TinkerPopClient.class);
63

    
64
    private Neo4jStore graphStore = null;
65

    
66
    /**
67
     * @param store
68
     */
69
    public TinkerPopClient(Neo4jStore store) {
70
        this.graphStore = store;
71
    }
72

    
73
    public Graph graph() {
74
        return graphStore.graph();
75
    }
76

    
77
    /**
78
     * See {@link org.openrdf.repository.sail.SailRepository#getConnection()}
79
     *
80
     * @return
81
     * @throws RepositoryException
82
     */
83
    public SailRepositoryConnection connection() throws RepositoryException {
84
        SailRepositoryConnection connection = graphStore.getSailRepo().getConnection();
85
        return connection;
86
    }
87

    
88
    /**
89
     * Returns the first Vertex of the edge with the property specified by
90
     * <code>nameSpace</code> and <code>localName</code>. Both, directions
91
     * of edges are taken into account whereas the OUT edge is tested first.
92
     *
93
     * @param v
94
     * @param nameSpace
95
     * @param localName
96
     * @return
97
     */
98
    public Vertex relatedVertex(Vertex v, RdfSchema nameSpace, String localName) {
99
        Vertex relatedV = null;
100
        try {
101
            relatedV = v.getEdges(Direction.OUT, nameSpace.property(localName)).iterator().next().getVertex(Direction.IN);
102
        } catch (NoSuchElementException e) {
103
            try {
104
                relatedV = v.getEdges(Direction.IN, nameSpace.property(localName)).iterator().next().getVertex(Direction.OUT);
105
            } catch (NoSuchElementException e2) {
106
                logger.error("No taxonomy information for " + v.toString());
107
            }
108
        }
109
        return relatedV;
110
    }
111

    
112
    /**
113
     * Returns the <code>value</code> property of the first Vertex of the edge with the property specified by
114
     * <code>nameSpace</code> and <code>localName</code>. Both, directions
115
     * of edges are taken into account whereas the OUT edge is tested first.
116
     *
117
     * @param pipe
118
     * @param nameSpace
119
     * @param localName
120
     * @return
121
     */
122
    public String relatedVertexValue(GremlinPipeline<Graph, Vertex> pipe, RdfSchema nameSpace, String localName) {
123
        String txt = null;
124
        String edgeLabel = nameSpace.property(localName);
125
        try {
126
            txt = pipe.outE(1, edgeLabel).inV().next().getProperty("value");
127
        } catch (FastNoSuchElementException e) {
128
            try {
129
                txt = pipe.inE(1, edgeLabel).inV().next().getProperty("value");
130
            } catch (FastNoSuchElementException e1) {
131
                logger.warn("edge with '" + edgeLabel + "' not found");
132
                if (logger.isDebugEnabled()) {
133
                    logger.debug("Vertices in pipe:");
134
                    StringBuffer out = new StringBuffer();
135
                    for (Vertex v : pipe.toList()) {
136
                        logger.debug("    " + v);
137
                    }
138
                }
139
            }
140
        }
141

    
142
        return txt;
143
    }
144

    
145
    /**
146
     * Returns the <code>value</code> property of the first Vertex of the edge with the property specified by
147
     * <code>nameSpace</code> and <code>localName</code>. Both, directions
148
     * of edges are taken into account whereas the OUT edge is tested first.
149
     *
150
     * @param v
151
     * @param nameSpace
152
     * @param localName
153
     * @return
154
     */
155
    public String relatedVertexValue(Vertex v, RdfSchema nameSpace, String localName) {
156
        String txt = null;
157
        String edgeLabel = nameSpace.property(localName);
158
        try {
159
            txt = v.getEdges(Direction.OUT, edgeLabel).iterator().next().getVertex(Direction.IN)
160
                    .getProperty(GraphSail.VALUE);
161
        } catch (NoSuchElementException e) {
162
            try {
163
                txt = v.getEdges(Direction.IN, edgeLabel).iterator().next().getVertex(Direction.OUT)
164
                        .getProperty(GraphSail.VALUE);
165
            } catch (NoSuchElementException e1) {
166
                logger.warn("edge with '" + edgeLabel + "' not found for " + v);
167

    
168
            }
169
        }
170

    
171
        return txt;
172
    }
173

    
174
    /**
175
     * @param subject
176
     * @param nameSpace
177
     * @param localName
178
     * @return
179
     */
180
    public URI vertexURI(Vertex v, RdfSchema nameSpace, String localName) {
181
        URI uri = null;
182
        try {
183
            if (v.getProperty(GraphSail.KIND).equals(GraphSail.URI)) {
184
                uri = new URI(v.getProperty(GraphSail.VALUE).toString());
185
            } else {
186
                logger.warn("vertex of '" + v.toString() + "' is not an URI");
187
            }
188
        } catch (URISyntaxException e) {
189
            logger.error("Invalid URI id in " + v, e);
190
        }
191

    
192
        return uri;
193
    }
194

    
195
    /**
196
     * by using the Neo4j index directly it is possible to
197
     * take full advantage of the underlying Lucene search engine
198
     *
199
     * @param luceneQuery
200
     * @return
201
     */
202
    public ArrayList<Vertex> vertexIndexQuery(String luceneQuery) {
203
        Neo4j2Graph graph = (Neo4j2Graph)graph();
204
        AutoIndexer<Node> nodeAutoIndex = graph.getRawGraph().index().getNodeAutoIndexer();
205
        graph.autoStartTransaction(false);
206
        IndexHits<Node> nodes = nodeAutoIndex.getAutoIndex().query(luceneQuery);
207
        ArrayList<Vertex> hitVs = new ArrayList<Vertex>();
208
        while(nodes.hasNext()) {
209
            hitVs.add(new Neo4j2Vertex(nodes.next(), graph));
210
        }
211
        graph.commit();
212
        return hitVs;
213
    }
214

    
215
    /**
216
     * @param subject
217
     */
218
    private void printProperties(Resource subject) {
219
        for (StmtIterator it = subject.listProperties(); it.hasNext();) {
220
            System.err.println(it.next().toString());
221
        }
222
    }
223

    
224
    public void showResults(TupleQueryResult result) throws QueryEvaluationException {
225
        int i = 0;
226
        while (result.hasNext()) {
227
            System.err.println(".");
228
            BindingSet bindingSet = result.next();
229
            System.err.println("+");
230
            for (String colName : result.getBindingNames()) {
231
                System.err.println(colName + ":" + bindingSet.getValue(colName));
232
            }
233
            System.err.println("|");
234
            i++;
235
        }
236
        System.err.println("We found " + i + " results");
237
        System.err.flush();
238
    }
239
}
(6-6/6)