001: /*
002: (c) Copyright 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
003: All rights reserved - see end of file.
004: $Id: QueryTriple.java,v 1.11 2008/01/02 12:07:57 andy_seaborne Exp $
005: */
006: package com.hp.hpl.jena.graph.query;
007:
008: import java.util.*;
009:
010: import com.hp.hpl.jena.graph.*;
011: import com.hp.hpl.jena.shared.BrokenException;
012:
013: /**
014: A QueryTriple is a composite of three QueryNodes derived from a
015: single source triple. QueryTriple knows how to classify a triple
016: into a QueryTriple based on the classification of that triple's elements.
017: A QueryTriple can create a specific <code>Matcher</code> which
018: will do the minimal amount of work to match triples that have been
019: generated by <code>find</code> on the finder of that QueryTriple.
020:
021: @author hedgehog
022: */
023: public class QueryTriple {
024: public final QueryNode S;
025: public final QueryNode P;
026: public final QueryNode O;
027:
028: public QueryTriple(QueryNode S, QueryNode P, QueryNode O) {
029: this .S = S;
030: this .P = P;
031: this .O = O;
032: }
033:
034: public String toString() {
035: return "<qt " + S.toString() + " " + P.toString() + " "
036: + O.toString() + ">";
037: }
038:
039: public static QueryTriple[] classify(QueryNodeFactory f, Mapping m,
040: Triple[] t) {
041: QueryTriple[] result = f.createArray(t.length);
042: for (int i = 0; i < t.length; i += 1)
043: result[i] = classify(f, m, t[i]);
044: return result;
045: }
046:
047: public static QueryTriple classify(QueryNodeFactory f, Mapping m,
048: Triple t) {
049: HashSet fresh = new HashSet();
050: return f.createTriple(QueryNode.classify(f, m, fresh, t
051: .getSubject()), QueryNode.classify(f, m, fresh, t
052: .getPredicate()), QueryNode.classify(f, m, fresh, t
053: .getObject()));
054: }
055:
056: public Applyer createApplyer(final Graph g) {
057: return new SimpleApplyer(g, this );
058: }
059:
060: public Matcher createMatcher() {
061: final int SMATCH = 4, PMATCH = 2, OMATCH = 1, NOMATCH = 0;
062: int bits = (S.mustMatch() ? SMATCH : 0)
063: + (P.mustMatch() ? PMATCH : 0)
064: + (O.mustMatch() ? OMATCH : 0);
065: switch (bits) {
066: case SMATCH + PMATCH + OMATCH:
067: return new Matcher() {
068: public boolean match(Domain d, Triple t) {
069: return S.match(d, t.getSubject())
070: && P.match(d, t.getPredicate())
071: && O.match(d, t.getObject());
072: }
073: };
074:
075: case SMATCH + OMATCH:
076: return new Matcher() {
077: public boolean match(Domain d, Triple t) {
078: return S.match(d, t.getSubject())
079: && O.match(d, t.getObject());
080: }
081: };
082:
083: case SMATCH + PMATCH:
084: return new Matcher() {
085: public boolean match(Domain d, Triple t) {
086: return S.match(d, t.getSubject())
087: && P.match(d, t.getPredicate());
088: }
089: };
090:
091: case PMATCH + OMATCH:
092: return new Matcher() {
093: public boolean match(Domain d, Triple t) {
094: return P.match(d, t.getPredicate())
095: && O.match(d, t.getObject());
096: }
097: };
098:
099: case SMATCH:
100: return new Matcher() {
101: public boolean match(Domain d, Triple t) {
102: return S.match(d, t.getSubject());
103: }
104: };
105:
106: case PMATCH:
107: return new Matcher() {
108: public boolean match(Domain d, Triple t) {
109: return P.match(d, t.getPredicate());
110: }
111: };
112:
113: case OMATCH:
114: return new Matcher() {
115: public boolean match(Domain d, Triple t) {
116: return O.match(d, t.getObject());
117: }
118: };
119:
120: case NOMATCH:
121: return Matcher.always;
122:
123: }
124: throw new BrokenException("uncatered-for case in optimisation");
125: }
126:
127: public static class SimpleApplyer extends Applyer {
128: protected final Graph g;
129: protected final QueryNode s;
130: protected final QueryNode p;
131: protected final QueryNode o;
132:
133: protected SimpleApplyer(Graph g, QueryTriple qt) {
134: this .g = g;
135: this .o = qt.O;
136: this .p = qt.P;
137: this .s = qt.S;
138: }
139:
140: public Iterator find(Domain d) {
141: return g.find(s.finder(d), p.finder(d), o.finder(d));
142: }
143:
144: public void applyToTriples(Domain d, Matcher m,
145: StageElement next) {
146: Iterator it = find(d);
147: while (it.hasNext())
148: if (m.match(d, (Triple) it.next()))
149: next.run(d);
150: }
151: }
152: }
153: /*
154: * (c) Copyright 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
155: * All rights reserved.
156: *
157: * Redistribution and use in source and binary forms, with or without
158: * modification, are permitted provided that the following conditions
159: * are met:
160: * 1. Redistributions of source code must retain the above copyright
161: * notice, this list of conditions and the following disclaimer.
162: * 2. Redistributions in binary form must reproduce the above copyright
163: * notice, this list of conditions and the following disclaimer in the
164: * documentation and/or other materials provided with the distribution.
165: * 3. The name of the author may not be used to endorse or promote products
166: * derived from this software without specific prior written permission.
167: *
168: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
169: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
170: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
171: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
172: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
173: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
174: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
175: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
176: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
177: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
178: */
|