001: /******************************************************************
002: * File: TempNodeCache.java
003: * Created by: Dave Reynolds
004: * Created on: 09-Jul-2003
005: *
006: * (c) Copyright 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
007: * [See end of file]
008: * $Id: TempNodeCache.java,v 1.11 2008/01/02 12:06:15 andy_seaborne Exp $
009: *****************************************************************/package com.hp.hpl.jena.reasoner.rulesys.impl;
010:
011: import java.util.*;
012:
013: import com.hp.hpl.jena.graph.Node;
014: import com.hp.hpl.jena.reasoner.InfGraph;
015: import com.hp.hpl.jena.util.OneToManyMap;
016:
017: /**
018: * In some rules we need to be able to create temporary property values
019: * which are inferred from ontology constraints but not present in the ground
020: * data. This structure is used to manage a pool of such temporary nodes.
021: * It is only needed in situations where the data can not be added directly
022: * to a deductions graph due to the risk of concurrent access.
023: *
024: * @author <a href="mailto:der@hplb.hpl.hp.com">Dave Reynolds</a>
025: * @version $Revision: 1.11 $ on $Date: 2008/01/02 12:06:15 $
026: */
027:
028: // Implementation note: We need to map from a pair of values (instance and prop).
029: // The current implementation in terms on NodePair will turn over storage during
030: // lookup. Could replace this with a cascaded hash table.
031: public class TempNodeCache {
032:
033: /** Map from instance+property to value */
034: protected OneToManyMap ipMap = new OneToManyMap();
035:
036: /** Map from temp to RDF class, if any */
037: protected Map classMap = new HashMap();
038:
039: /**
040: * Cosntructor.
041: * @param infgraph Parent inference graph, used to be needed for synchronization, don't think
042: * we need it any more
043: */
044: public TempNodeCache(InfGraph infgraph) {
045: }
046:
047: /**
048: * Retrieve or create a bNode representing an inferred property value.
049: * @param instance the base instance node to which the property applies
050: * @param prop the property node whose value is being inferred
051: * @param pclass the (optional, can be null) class for the inferred value.
052: * @return the bNode representing the property value
053: */
054: public synchronized Node getTemp(Node instance, Node prop,
055: Node pclass) {
056: NodePair ip = new NodePair(instance, prop);
057: Node result = null;
058: for (Iterator i = ipMap.getAll(ip); i.hasNext();) {
059: Node t = (Node) i.next();
060: if (pclass != null) {
061: Object tClass = classMap.get(t);
062: if (tClass != null && tClass.equals(pclass)) {
063: result = t;
064: break;
065: }
066: } else {
067: result = t;
068: break;
069: }
070: }
071: if (result == null) {
072: // No value yet, so create one
073: result = Node.createAnon();
074: ipMap.put(ip, result);
075: if (pclass != null) {
076: classMap.put(result, pclass);
077: }
078: }
079: return result;
080: }
081:
082: /**
083: * Inner class used to hold and hash a node pair.
084: */
085: public static class NodePair {
086: /** first node in the pair */
087: protected Node first;
088:
089: /** second node in the pair */
090: protected Node second;
091:
092: /** Constructor */
093: public NodePair(Node first, Node second) {
094: this .first = first;
095: this .second = second;
096: }
097:
098: /**
099: * Return the first node in the pair.
100: */
101: public Node getFirst() {
102: return first;
103: }
104:
105: /**
106: * Return the second node in the pair.
107: */
108: public Node getSecond() {
109: return second;
110: }
111:
112: /**
113: * Equality of each component.
114: */
115: public boolean equals(Object o) {
116: return o instanceof NodePair
117: && first.equals(((NodePair) o).first)
118: && second.equals(((NodePair) o).second);
119: }
120:
121: /**
122: * Simple combined hashcode.
123: */
124: public int hashCode() {
125: return first.hashCode() ^ (second.hashCode() << 1);
126: }
127:
128: }
129:
130: }
131:
132: /*
133: (c) Copyright 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
134: All rights reserved.
135:
136: Redistribution and use in source and binary forms, with or without
137: modification, are permitted provided that the following conditions
138: are met:
139:
140: 1. Redistributions of source code must retain the above copyright
141: notice, this list of conditions and the following disclaimer.
142:
143: 2. Redistributions in binary form must reproduce the above copyright
144: notice, this list of conditions and the following disclaimer in the
145: documentation and/or other materials provided with the distribution.
146:
147: 3. The name of the author may not be used to endorse or promote products
148: derived from this software without specific prior written permission.
149:
150: THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
151: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
152: OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
153: IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
154: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
155: NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
156: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
157: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
158: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
159: THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
160: */
|