001: /*****************************************************************************
002: * Source code information
003: * -----------------------
004: * Original author Ian Dickinson, HP Labs Bristol
005: * Author email Ian.Dickinson@hp.com
006: * Package Jena 2
007: * Web http://sourceforge.net/projects/jena/
008: * Created 4 Mar 2003
009: * Filename $RCSfile: Polyadic.java,v $
010: * Revision $Revision: 1.20 $
011: * Release status $State: Exp $
012: *
013: * Last modified on $Date: 2008/01/02 12:10:19 $
014: * by $Author: andy_seaborne $
015: *
016: * (c) Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
017: * (see footer for full conditions)
018: *****************************************************************************/package com.hp.hpl.jena.graph.compose;
019:
020: // Imports
021: ///////////////
022: import com.hp.hpl.jena.graph.*;
023: import com.hp.hpl.jena.graph.impl.WrappedBulkUpdateHandler;
024: import com.hp.hpl.jena.shared.*;
025: import com.hp.hpl.jena.util.iterator.*;
026:
027: import java.util.*;
028:
029: /**
030: * <p>
031: * A base class for composition graphs that are composed from zero or more
032: * sub-graphs (thus providing a basis for polyadic composition operators).
033: * A distinguished graph is the designated graph for additions to the union.
034: * By default, this is the first sub-graph of the composition, however any
035: * of the graphs in the composition can be nominated to be the distinguished
036: * graph.
037: * </p>
038: *
039: * @author Ian Dickinson, HP Labs
040: * (<a href="mailto:Ian.Dickinson@hp.com" >email</a>)
041: * @version CVS $Id: Polyadic.java,v 1.20 2008/01/02 12:10:19 andy_seaborne Exp $
042: */
043: public abstract class Polyadic extends CompositionBase {
044: // Constants
045: //////////////////////////////////
046:
047: // Static variables
048: //////////////////////////////////
049:
050: // Instance variables
051: //////////////////////////////////
052:
053: /** A list of the sub-graphs that this composition contains */
054: protected List m_subGraphs = new ArrayList();
055:
056: /** The distinguished graph for adding to. If null, use the 0'th graph in the list. */
057: protected Graph m_baseGraph = null;
058:
059: // Constructors
060: //////////////////////////////////
061:
062: /**
063: * <p>
064: * Construct a composition of exactly no sub graphs.
065: * </p>
066: */
067: public Polyadic() {
068: }
069:
070: /**
071: * <p>
072: * Construct a composition of all of the given graphs
073: * </p>
074: *
075: * @param graphs An array of the sub-graphs of this composition
076: */
077: public Polyadic(Graph[] graphs) {
078: for (int i = 0; i < graphs.length; i++) {
079: m_subGraphs.add(graphs[i]);
080: }
081: }
082:
083: private PrefixMapping pm;
084:
085: public PrefixMapping getPrefixMapping() {
086: if (pm == null)
087: pm = new PolyadicPrefixMappingImpl(this );
088: return pm;
089: }
090:
091: /**
092: * <p>
093: * Construct a composition of all of the given graphs.
094: * </p>
095: *
096: * @param graphs An iterator of the sub-graphs of this composition. If graphs is
097: * a closable iterator, it will be automatically closed.
098: */
099: public Polyadic(Iterator graphs) {
100: while (graphs.hasNext()) {
101: m_subGraphs.add(graphs.next());
102: }
103:
104: if (graphs instanceof ClosableIterator) {
105: ((ClosableIterator) graphs).close();
106: }
107: }
108:
109: // External signature methods
110: //////////////////////////////////
111:
112: /**
113: * <p>
114: * Close the graph by closing all of the sub-graphs.
115: * </p>
116: *
117: * @see com.hp.hpl.jena.graph.Graph#close()
118: */
119: public void close() {
120: for (Iterator i = m_subGraphs.iterator(); i.hasNext();) {
121: ((Graph) i.next()).close();
122: }
123: super .close();
124: }
125:
126: /**
127: * <p>
128: * Answer true if this graph contains the given graph as a sub-component.
129: * </p>
130: *
131: * @param graph A graph to test
132: * @return True if the graph is this graph, or is a sub-graph of this one.
133: * @see com.hp.hpl.jena.graph.Graph#dependsOn(Graph)
134: */
135: public boolean dependsOn(Graph graph) {
136: return (graph == this ) || m_subGraphs.contains(graph);
137: }
138:
139: /**
140: * <p>
141: * Add the given graph to this composition.
142: * </p>
143: *
144: * @param graph A sub-graph to add to this composition
145: */
146: public void addGraph(Graph graph) {
147: m_subGraphs.add(graph);
148: }
149:
150: /**
151: * <p>
152: * Remove the given graph from this composition. If the removed graph is the
153: * designated updateable graph, the updatable graph goes back to the default
154: * for this composition.
155: * </p>
156: *
157: * @param graph A sub-graph to remove from this composition
158: */
159: public void removeGraph(Graph graph) {
160: m_subGraphs.remove(graph);
161:
162: if (m_baseGraph == graph) {
163: m_baseGraph = null;
164: }
165: }
166:
167: /**
168: * <p>
169: * Answer the distinguished graph for the composition, which will be the graph
170: * that receives triple adds and deletes. If no base graph is defined,
171: * return null.
172: * </p>
173: *
174: * @return The distinguished updateable graph, or null if there are no graphs
175: * in this composition
176: */
177: public Graph getBaseGraph() {
178: if (m_baseGraph == null) {
179: // no designated graph, so default to the first graph on the list
180: return (m_subGraphs.size() == 0) ? null
181: : ((Graph) m_subGraphs.get(0));
182: } else {
183: return m_baseGraph;
184: }
185: }
186:
187: /**
188: * <p>
189: * Answer the distinguished graph for the composition, which will be the graph
190: * that receives triple adds and deletes. If no base graph is defined, throw
191: * a {@link JenaException}.
192: * </p>
193: *
194: * @return The distinguished updateable graph, or null if there are no graphs
195: * in this composition
196: */
197: public Graph getRequiredBaseGraph() {
198: Graph base = getBaseGraph();
199: if (base == null) {
200: throw new JenaException(
201: "This polyadic graph should have a base graph, but none is defined");
202: } else {
203: return base;
204: }
205: }
206:
207: /**
208: * <p>
209: * Set the designated updateable graph for this composition.
210: * </p>
211: *
212: * @param graph One of the graphs currently in this composition to be the
213: * designated graph to receive udpates
214: * @exception IllegalArgumentException if graph is not one of the members of
215: * the composition
216: */
217: public void setBaseGraph(Graph graph) {
218: if (m_subGraphs.contains(graph)) {
219: m_baseGraph = graph;
220: bulkHandler = null;
221: } else {
222: throw new IllegalArgumentException(
223: "The updateable graph must be one of the graphs from the composition");
224: }
225: }
226:
227: /**
228: * <p>
229: * Answer a list of the graphs other than the updateable (base) graph
230: * </p>
231: *
232: * @return A list of all of the sub-graphs, excluding the base graph.
233: */
234: public List getSubGraphs() {
235: List sg = new ArrayList(m_subGraphs);
236:
237: if (getBaseGraph() != null) {
238: sg.remove(getBaseGraph());
239: }
240:
241: return sg;
242: }
243:
244: public BulkUpdateHandler getBulkUpdateHandler() {
245: if (bulkHandler == null)
246: bulkHandler = new WrappedBulkUpdateHandler(this ,
247: getRequiredBaseGraph().getBulkUpdateHandler());
248: return bulkHandler;
249: }
250:
251: // the following methods all delegate handling capabilities to the base graph
252: // TODO: this needs to be integrated with WrappedGraph, but we don't have time to do so before Jena 2.0 release
253:
254: public TransactionHandler getTransactionHandler() {
255: return (getBaseGraph() == null) ? super .getTransactionHandler()
256: : getBaseGraph().getTransactionHandler();
257: }
258:
259: public Capabilities getCapabilities() {
260: return (getBaseGraph() == null) ? super .getCapabilities()
261: : getBaseGraph().getCapabilities();
262: }
263:
264: }
265:
266: /*
267: (c) Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
268: All rights reserved.
269:
270: Redistribution and use in source and binary forms, with or without
271: modification, are permitted provided that the following conditions
272: are met:
273:
274: 1. Redistributions of source code must retain the above copyright
275: notice, this list of conditions and the following disclaimer.
276:
277: 2. Redistributions in binary form must reproduce the above copyright
278: notice, this list of conditions and the following disclaimer in the
279: documentation and/or other materials provided with the distribution.
280:
281: 3. The name of the author may not be used to endorse or promote products
282: derived from this software without specific prior written permission.
283:
284: THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
285: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
286: OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
287: IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
288: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
289: NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
290: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
291: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
292: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
293: THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
294: */
|