001: package org.ontoware.rdf2go.model.impl;
002:
003: import java.util.ArrayList;
004: import java.util.HashMap;
005: import java.util.List;
006: import java.util.Map;
007:
008: import org.ontoware.aifbcommons.collection.ClosableIterator;
009: import org.ontoware.rdf2go.exception.ModelRuntimeException;
010: import org.ontoware.rdf2go.model.DiffReader;
011: import org.ontoware.rdf2go.model.Model;
012: import org.ontoware.rdf2go.model.ModelChangedListener;
013: import org.ontoware.rdf2go.model.ModelSet;
014: import org.ontoware.rdf2go.model.NotifyingModelSet;
015: import org.ontoware.rdf2go.model.QuadPattern;
016: import org.ontoware.rdf2go.model.Statement;
017: import org.ontoware.rdf2go.model.node.URI;
018: import org.ontoware.rdf2go.model.node.Variable;
019:
020: /**
021: * Adds notifying capabilites to existing models.
022: *
023: * Reads from streams and readers are not detectable.
024: *
025: * @author voelkel
026: *
027: */
028: public class NotifyingModelSetLayer extends DelegatingModelSet
029: implements NotifyingModelSet {
030:
031: public NotifyingModelSetLayer(ModelSet modelset) {
032: super (modelset);
033: }
034:
035: // //////////////////////////////////
036: // implement NotifyingModelSet
037:
038: private Map<ModelChangedListener, QuadPattern> modelsetChangeListener = new HashMap<ModelChangedListener, QuadPattern>();
039:
040: public void addModelSetChangedListener(ModelChangedListener listener) {
041: this .modelsetChangeListener
042: .put(listener, new QuadPatternImpl(Variable.ANY,
043: Variable.ANY, Variable.ANY, Variable.ANY));
044: }
045:
046: public void addModelSetChangedListener(
047: ModelChangedListener listener, QuadPattern pattern) {
048: this .modelsetChangeListener.put(listener, pattern);
049: }
050:
051: public void removeModelSetChangedListener(
052: ModelChangedListener listener) {
053: this .modelsetChangeListener.remove(listener);
054: }
055:
056: // //////////////////////////
057: // override ModelSet methods to enalbe listening
058:
059: @Override
060: public boolean addModel(Model model) {
061: // first check for listeners
062: for (Map.Entry<ModelChangedListener, QuadPattern> entry : this .modelsetChangeListener
063: .entrySet()) {
064: // if pattern.context matches model.context
065: if (entry.getValue().getContext() == Variable.ANY
066: || entry.getValue().getContext().equals(
067: model.getContextURI())) {
068: // filter model
069: for (Statement stmt : model) {
070: if (entry.getValue().matches(stmt)) {
071: entry.getKey().addedStatement(stmt);
072: }
073: }
074: }
075: }
076: // then add
077: return super .addModel(model);
078: }
079:
080: @Override
081: public void addStatement(Statement statement)
082: throws ModelRuntimeException {
083: // inspect
084: for (Map.Entry<ModelChangedListener, QuadPattern> entry : this .modelsetChangeListener
085: .entrySet()) {
086: if (entry.getValue().matches(statement)) {
087: entry.getKey().addedStatement(statement);
088: }
089: }
090: // delegate
091: super .addStatement(statement);
092: }
093:
094: @Override
095: public Model getDefaultModel() {
096: Model model = super .getDefaultModel();
097: NotifyingModelLayer notifyingModel = new NotifyingModelLayer(
098: model);
099: for (Map.Entry<ModelChangedListener, QuadPattern> entry : this .modelsetChangeListener
100: .entrySet()) {
101: // only if listening for (*, x,y,z) changes in default model are
102: // detected
103: if (entry.getValue().getContext() == Variable.ANY) {
104: notifyingModel.addModelChangedListener(entry.getKey(),
105: entry.getValue());
106: }
107: }
108: return notifyingModel;
109: }
110:
111: @Override
112: public Model getModel(URI contextURI) {
113: Model model = super .getModel(contextURI);
114: NotifyingModelLayer notifyingModel = new NotifyingModelLayer(
115: model);
116: for (Map.Entry<ModelChangedListener, QuadPattern> entry : this .modelsetChangeListener
117: .entrySet()) {
118: if (entry.getValue().getContext() == Variable.ANY
119: || entry.getValue().getContext().equals(contextURI)) {
120: notifyingModel.addModelChangedListener(entry.getKey(),
121: entry.getValue());
122: }
123: }
124: return notifyingModel;
125: }
126:
127: @Override
128: public ClosableIterator<Model> getModels() {
129: List<Model> models = new ArrayList<Model>();
130: ClosableIterator<? extends Model> it = super .getModels();
131: // wrap all into NotifyingModels
132: while (it.hasNext()) {
133: Model model = it.next();
134: NotifyingModelLayer notifyingModel = new NotifyingModelLayer(
135: model);
136: for (Map.Entry<ModelChangedListener, QuadPattern> entry : this .modelsetChangeListener
137: .entrySet()) {
138: notifyingModel.addModelChangedListener(entry.getKey(),
139: entry.getValue());
140: }
141: models.add(notifyingModel);
142: }
143: it.close();
144: return new PseudoClosableIterator<Model>(models.iterator());
145: }
146:
147: @Override
148: public void removeStatement(Statement statement)
149: throws ModelRuntimeException {
150: // inspect
151: for (Map.Entry<ModelChangedListener, QuadPattern> entry : this .modelsetChangeListener
152: .entrySet()) {
153: if (entry.getValue().matches(statement)) {
154: entry.getKey().removedStatement(statement);
155: }
156: }
157: // delegate
158: super .removeStatement(statement);
159: }
160:
161: @Override
162: public void update(DiffReader diff) throws ModelRuntimeException {
163: // inspect
164: for (Map.Entry<ModelChangedListener, QuadPattern> entry : this .modelsetChangeListener
165: .entrySet()) {
166: entry.getKey().performedUpdate(diff);
167: }
168: // delegate
169: super.update(diff);
170: }
171:
172: }
|