View Javadoc

1   /*
2    * Copyright James Leigh (c) 2006, 2007.
3    *
4    * Licensed under the Aduna BSD-style license.
5    */
6   package org.openrdf.repository.augur.helpers;
7   
8   import org.openrdf.model.Resource;
9   import org.openrdf.model.URI;
10  import org.openrdf.model.Value;
11  import org.openrdf.model.impl.URIImpl;
12  import org.openrdf.query.algebra.Join;
13  import org.openrdf.query.algebra.Projection;
14  import org.openrdf.query.algebra.ProjectionElem;
15  import org.openrdf.query.algebra.TupleExpr;
16  import org.openrdf.query.parser.ParsedQuery;
17  import org.openrdf.repository.RepositoryConnection;
18  import org.openrdf.repository.augur.model.AResource;
19  import org.openrdf.repository.augur.model.AugurNode;
20  import org.openrdf.repository.augur.model.AugurObjectNode;
21  import org.openrdf.repository.augur.model.AugurStatementNode;
22  import org.openrdf.repository.augur.model.AugurSubjectNode;
23  
24  /**
25   * Retrives or creates AugurNodes for a statement parttern.
26   * 
27   * @author James Leigh
28   * 
29   */
30  public class AugurNodeFactory {
31  	/** Used to match child AugurNodes */
32  	private static final URIImpl CARRIED = new URIImpl("http://elmo.openrdf.org/rdf/2007/augur/carriedOver");
33  
34  	private static enum Position {
35  		NO_POSITION, SUBJECT, OBJECT
36  	}
37  
38  	private RepositoryConnection _connection;
39  
40  	public AugurNodeFactory(RepositoryConnection connection) {
41  		this._connection = connection;
42  	}
43  
44  	public AugurNode createAugurNode(ParsedQuery query, boolean includeInferred) {
45  		AugurNode node = new AugurNode();
46  		node.setConnection(_connection);
47  		node.setIncludeInferred(includeInferred);
48  		TupleExpr tupleExpr = getTupleExpr(query);
49  		node.setTupleExpr(tupleExpr);
50  		return node;
51  	}
52  
53  	private TupleExpr getTupleExpr(ParsedQuery query) {
54  		TupleExpr tupleExpr = query.getTupleExpr();
55  		if (tupleExpr instanceof Projection) {
56  			Projection proj = (Projection) tupleExpr;
57  			for (ProjectionElem e : proj.getProjectionElemList().getElements()) {
58  				if (!e.getSourceName().equals(e.getTargetName()))
59  					return proj;
60  			}
61  			return proj.getArg();
62  		}
63  		return tupleExpr;
64  	}
65  
66  	public AugurStatementNode createAugurStatementNode(Resource subj, URI pred, Value obj, boolean includeInferred, Resource... contexts) {
67  		AResource carried;
68  		AugurNode parent = null;
69  		Position position = findCarriedOverPosition(subj, obj,
70  				includeInferred);
71  		switch (position) {
72  		case SUBJECT:
73  			carried = (AResource) subj;
74  			subj = CARRIED;
75  			obj = raw(obj);
76  			break;
77  		case OBJECT:
78  			carried = (AResource) obj;
79  			subj = raw(subj);
80  			obj = CARRIED;
81  			break;
82  		default:
83  			carried = null;
84  		}
85  		pred = raw(pred);
86  		for (int i=0; i<contexts.length; i++) {
87  			contexts[i] = raw(contexts[i]);
88  		}
89  		if (carried != null) {
90  			parent = carried.getAugurNode();
91  			AugurStatementNode child;
92  			child = parent.getChildNode(subj, pred, obj, contexts);
93  			if (child != null)
94  				return child;
95  		}
96  		AugurStatementNode node;
97  		TupleExpr sp;
98  		if (parent == null) {
99  			node = new AugurStatementNode();
100 			sp = node.setStatementPattern(subj, pred, obj, contexts);
101 		} else {
102 			switch (position) {
103 			case SUBJECT:
104 				node = new AugurSubjectNode();
105 				node.setDepth(parent.getDepth() + 1);
106 				sp = node.setStatementPattern(carried, pred, obj, contexts);
107 				break;
108 			default:
109 				assert position == Position.OBJECT;
110 				node = new AugurObjectNode();
111 				node.setDepth(parent.getDepth() + 1);
112 				sp = node.setStatementPattern(subj, pred, carried, contexts);
113 			}
114 		}
115 		node.setConnection(_connection);
116 		node.setIncludeInferred(includeInferred);
117 		if (parent == null) {
118 			node.setTupleExpr(sp);
119 		} else {
120 			node.setTupleExpr(new Join(parent.getTupleExpr(), sp));
121 			parent.addChildNode(node, subj, pred, obj, contexts);
122 		}
123 		return node;
124 	}
125 
126 	private Position findCarriedOverPosition(Resource subj,
127 			Value obj, boolean includeInferred) {
128 		if (subj instanceof AResource) {
129 			AugurNode node = ((AResource) subj).getAugurNode();
130 			if (node != null && node.getConnection().equals(_connection)
131 					&& node.isIncludeInferred() == includeInferred) {
132 				return Position.SUBJECT;
133 			}
134 		}
135 		if (obj instanceof AResource) {
136 			AugurNode node = ((AResource) obj).getAugurNode();
137 			if (node != null && node.getConnection().equals(_connection)
138 					&& node.isIncludeInferred() == includeInferred) {
139 				return Position.OBJECT;
140 			}
141 		}
142 		return Position.NO_POSITION;
143 	}
144 
145 	@SuppressWarnings("unchecked")
146 	private <T extends Value> T raw(T value) {
147 		if (value instanceof AResource)
148 			return (T) ((AResource) value).getValue();
149 		return value;
150 	}
151 }