001: /*
002: * Copyright Aduna (http://www.aduna-software.com/) (c) 2007.
003: *
004: * Licensed under the Aduna BSD-style license.
005: */
006: package org.openrdf.model.impl;
007:
008: import java.io.IOException;
009: import java.io.ObjectInputStream;
010: import java.io.ObjectOutputStream;
011: import java.util.AbstractCollection;
012: import java.util.Collection;
013: import java.util.Iterator;
014: import java.util.LinkedList;
015:
016: import info.aduna.collections.iterators.FilterIterator;
017:
018: import org.openrdf.OpenRDFUtil;
019: import org.openrdf.model.Graph;
020: import org.openrdf.model.Resource;
021: import org.openrdf.model.Statement;
022: import org.openrdf.model.URI;
023: import org.openrdf.model.Value;
024: import org.openrdf.model.ValueFactory;
025:
026: /**
027: * @author Arjohn Kampman
028: */
029: public class GraphImpl extends AbstractCollection<Statement> implements
030: Graph {
031:
032: /**
033: *
034: */
035: private static final long serialVersionUID = -5307095904382050478L;
036:
037: protected LinkedList<Statement> statements;
038:
039: transient protected ValueFactory valueFactory;
040:
041: public GraphImpl(ValueFactory valueFactory) {
042: super ();
043: statements = new LinkedList<Statement>();
044: setValueFactory(valueFactory);
045: }
046:
047: public GraphImpl() {
048: this (new ValueFactoryImpl());
049: }
050:
051: public GraphImpl(ValueFactory valueFactory,
052: Collection<? extends Statement> statements) {
053: this (valueFactory);
054: addAll(statements);
055: }
056:
057: public GraphImpl(Collection<? extends Statement> statements) {
058: this (new ValueFactoryImpl(), statements);
059: }
060:
061: public ValueFactory getValueFactory() {
062: return valueFactory;
063: }
064:
065: public void setValueFactory(ValueFactory valueFactory) {
066: this .valueFactory = valueFactory;
067: }
068:
069: @Override
070: public Iterator<Statement> iterator() {
071: return statements.iterator();
072: }
073:
074: @Override
075: public int size() {
076: return statements.size();
077: }
078:
079: @Override
080: public boolean add(Statement st) {
081: return statements.add(st);
082: }
083:
084: public boolean add(Resource subj, URI pred, Value obj,
085: Resource... contexts) {
086: OpenRDFUtil.verifyContextNotNull(contexts);
087:
088: boolean graphChanged = false;
089:
090: if (contexts.length == 0) {
091: graphChanged = add(valueFactory.createStatement(subj, pred,
092: obj));
093: } else {
094: for (Resource context : contexts) {
095: graphChanged |= add(valueFactory.createStatement(subj,
096: pred, obj, context));
097: }
098: }
099:
100: return graphChanged;
101: }
102:
103: public Iterator<Statement> match(Resource subj, URI pred,
104: Value obj, Resource... contexts) {
105: OpenRDFUtil.verifyContextNotNull(contexts);
106: return new PatternIterator(iterator(), subj, pred, obj,
107: contexts);
108: }
109:
110: private void writeObject(ObjectOutputStream out) throws IOException {
111: out.defaultWriteObject();
112: }
113:
114: private void readObject(ObjectInputStream in) throws IOException,
115: ClassNotFoundException {
116: in.defaultReadObject();
117: setValueFactory(new ValueFactoryImpl());
118: }
119:
120: /*-----------------------------*
121: * Inner class PatternIterator *
122: *-----------------------------*/
123:
124: private static class PatternIterator extends
125: FilterIterator<Statement> {
126:
127: private Resource subj;
128:
129: private URI pred;
130:
131: private Value obj;
132:
133: private Resource[] contexts;
134:
135: public PatternIterator(Iterator<? extends Statement> iter,
136: Resource subj, URI pred, Value obj,
137: Resource... contexts) {
138: super (iter);
139: this .subj = subj;
140: this .pred = pred;
141: this .obj = obj;
142: this .contexts = contexts;
143: }
144:
145: @Override
146: protected boolean accept(Statement st) {
147: if (subj != null && !subj.equals(st.getSubject())) {
148: return false;
149: }
150: if (pred != null && !pred.equals(st.getPredicate())) {
151: return false;
152: }
153: if (obj != null && !obj.equals(st.getObject())) {
154: return false;
155: }
156:
157: if (contexts.length == 0) {
158: // Any context matches
159: return true;
160: } else {
161: // Accept if one of the contexts from the pattern matches
162: Resource stContext = st.getContext();
163:
164: for (Resource context : contexts) {
165: if (context == null && stContext == null) {
166: return true;
167: }
168: if (context != null && context.equals(stContext)) {
169: return true;
170: }
171: }
172:
173: return false;
174: }
175: }
176: }
177: }
|