VIVO-823 Create several ModelMaker decorators, with tests
This commit is contained in:
parent
553bd417f7
commit
04f763109e
10 changed files with 1690 additions and 0 deletions
|
@ -0,0 +1,96 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.modelaccess.adapters;
|
||||
|
||||
import com.hp.hpl.jena.graph.GraphMaker;
|
||||
import com.hp.hpl.jena.rdf.model.Model;
|
||||
import com.hp.hpl.jena.rdf.model.ModelMaker;
|
||||
import com.hp.hpl.jena.rdf.model.ModelReader;
|
||||
import com.hp.hpl.jena.util.iterator.ExtendedIterator;
|
||||
|
||||
/**
|
||||
* Extend this to add decorator functionality to a ModelMaker. The sub-class can
|
||||
* override specific methods as needed.
|
||||
*/
|
||||
public class AbstractModelMakerDecorator implements ModelMaker {
|
||||
private final ModelMaker inner;
|
||||
|
||||
public AbstractModelMakerDecorator(ModelMaker inner) {
|
||||
if (inner == null) {
|
||||
throw new NullPointerException("'inner' may not be null.");
|
||||
}
|
||||
this.inner = inner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model createDefaultModel() {
|
||||
return inner.createDefaultModel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model createFreshModel() {
|
||||
return inner.createFreshModel();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model openModel(String name) {
|
||||
return inner.openModel(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model openModelIfPresent(String string) {
|
||||
return inner.openModelIfPresent(string);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model getModel(String URL) {
|
||||
return inner.getModel(URL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model getModel(String URL, ModelReader loadIfAbsent) {
|
||||
return inner.getModel(URL, loadIfAbsent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model createModel(String name, boolean strict) {
|
||||
return inner.createModel(name, strict);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model createModel(String name) {
|
||||
return inner.createModel(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model openModel(String name, boolean strict) {
|
||||
return inner.openModel(name, strict);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeModel(String name) {
|
||||
inner.removeModel(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasModel(String name) {
|
||||
return inner.hasModel(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
inner.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphMaker getGraphMaker() {
|
||||
return inner.getGraphMaker();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExtendedIterator<String> listModels() {
|
||||
return inner.listModels();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.modelaccess.adapters;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import com.hp.hpl.jena.rdf.model.Model;
|
||||
import com.hp.hpl.jena.rdf.model.ModelMaker;
|
||||
import com.hp.hpl.jena.rdf.model.ModelReader;
|
||||
import com.hp.hpl.jena.util.iterator.ExtendedIterator;
|
||||
import com.hp.hpl.jena.util.iterator.WrappedIterator;
|
||||
|
||||
/**
|
||||
* This ModelMaker keeps a cached list of the available models.
|
||||
*
|
||||
* The methods that create a model must add its name to the list. The methods
|
||||
* that remove a model must remove its name from the list.
|
||||
*
|
||||
* This is a useful decorator for some ModelMakers where listModels() is a
|
||||
* costly operation.
|
||||
*/
|
||||
public class ListCachingModelMaker extends AbstractModelMakerDecorator {
|
||||
private final Set<String> modelNames;
|
||||
|
||||
public ListCachingModelMaker(ModelMaker inner) {
|
||||
super(inner);
|
||||
this.modelNames = new TreeSet<>(inner.listModels().toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasModel(String name) {
|
||||
return modelNames.contains(name);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExtendedIterator<String> listModels() {
|
||||
return WrappedIterator.create(modelNames.iterator());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model getModel(String URL) {
|
||||
Model m = super.getModel(URL);
|
||||
if (m != null) {
|
||||
modelNames.add(URL);
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model getModel(String URL, ModelReader loadIfAbsent) {
|
||||
Model m = super.getModel(URL, loadIfAbsent);
|
||||
modelNames.add(URL);
|
||||
return m;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model createModel(String name, boolean strict) {
|
||||
Model m = super.createModel(name, strict);
|
||||
modelNames.add(name);
|
||||
return m;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model createModel(String name) {
|
||||
return createModel(name, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model openModel(String name) {
|
||||
Model m = super.openModel(name);
|
||||
modelNames.add(name);
|
||||
return m;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model openModelIfPresent(String name) {
|
||||
Model m = super.openModelIfPresent(name);
|
||||
if (m != null) {
|
||||
modelNames.add(name);
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model openModel(String name, boolean strict) {
|
||||
Model m = super.openModel(name, strict);
|
||||
modelNames.add(name);
|
||||
return m;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeModel(String name) {
|
||||
super.removeModel(name);
|
||||
modelNames.remove(name);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.modelaccess.adapters;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.hp.hpl.jena.rdf.model.Model;
|
||||
import com.hp.hpl.jena.rdf.model.ModelMaker;
|
||||
import com.hp.hpl.jena.rdf.model.ModelReader;
|
||||
import com.hp.hpl.jena.shared.AlreadyExistsException;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelSynchronizer;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.adapters.VitroModelFactory;
|
||||
|
||||
/**
|
||||
* Provides fast read access to small models, by creating a "mapped" model in
|
||||
* memory.
|
||||
*
|
||||
* When updates are detected on the "mapped" model, they are propagated to the
|
||||
* base model.
|
||||
*/
|
||||
public class MemoryMappingModelMaker extends AbstractModelMakerDecorator {
|
||||
private final Map<String, Model> mappedModels;
|
||||
|
||||
public MemoryMappingModelMaker(ModelMaker inner,
|
||||
String... modelUrisForMapping) {
|
||||
super(inner);
|
||||
|
||||
this.mappedModels = new HashMap<>();
|
||||
for (String name : modelUrisForMapping) {
|
||||
mappedModels.put(name, createMemoryMapping(name));
|
||||
}
|
||||
}
|
||||
|
||||
private Model createMemoryMapping(String name) {
|
||||
Model externalModel = super.openModel(name);
|
||||
Model memoryModel = VitroModelFactory.createModel();
|
||||
memoryModel.add(externalModel);
|
||||
memoryModel.register(new ModelSynchronizer(externalModel, name));
|
||||
return memoryModel;
|
||||
}
|
||||
|
||||
private boolean isMapped(String name) {
|
||||
return mappedModels.containsKey(name);
|
||||
}
|
||||
|
||||
private Model getMapped(String name) {
|
||||
return mappedModels.get(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model openModel(String name) {
|
||||
return isMapped(name) ? getMapped(name) : super.openModel(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model openModelIfPresent(String name) {
|
||||
return isMapped(name) ? getMapped(name) : super
|
||||
.openModelIfPresent(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model getModel(String name) {
|
||||
return isMapped(name) ? getMapped(name) : super.getModel(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model getModel(String name, ModelReader loadIfAbsent) {
|
||||
return isMapped(name) ? getMapped(name) : super.getModel(name,
|
||||
loadIfAbsent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model createModel(String name, boolean strict) {
|
||||
if (isMapped(name)) {
|
||||
if (strict) {
|
||||
throw new AlreadyExistsException(name);
|
||||
} else {
|
||||
return getMapped(name);
|
||||
}
|
||||
} else {
|
||||
return super.createModel(name, strict);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model createModel(String name) {
|
||||
return isMapped(name) ? getMapped(name) : super.createModel(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model openModel(String name, boolean strict) {
|
||||
return isMapped(name) ? getMapped(name) : super.openModel(name, strict);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeModel(String name) {
|
||||
if (isMapped(name)) {
|
||||
Model m = mappedModels.remove(name);
|
||||
m.close();
|
||||
}
|
||||
super.removeModel(name);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.modelaccess.adapters;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import com.hp.hpl.jena.rdf.model.Model;
|
||||
import com.hp.hpl.jena.rdf.model.ModelMaker;
|
||||
import com.hp.hpl.jena.rdf.model.ModelReader;
|
||||
import com.hp.hpl.jena.util.iterator.ExtendedIterator;
|
||||
|
||||
/**
|
||||
* This model maker allows you to refer to the default model by a name.
|
||||
*/
|
||||
public class NamedDefaultModelMaker extends AbstractModelMakerDecorator {
|
||||
private static final Log log = LogFactory
|
||||
.getLog(NamedDefaultModelMaker.class);
|
||||
|
||||
private final String defaultModelUri;
|
||||
|
||||
public NamedDefaultModelMaker(ModelMaker inner, String defaultModelUri) {
|
||||
super(inner);
|
||||
this.defaultModelUri = defaultModelUri;
|
||||
}
|
||||
|
||||
private boolean isDefaultModel(String name) {
|
||||
return name != null && name.equals(defaultModelUri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model openModel(String name) {
|
||||
if (isDefaultModel(name)) {
|
||||
return super.createDefaultModel();
|
||||
} else {
|
||||
return super.openModel(name);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model openModelIfPresent(String name) {
|
||||
if (isDefaultModel(name)) {
|
||||
return super.createDefaultModel();
|
||||
} else {
|
||||
return super.openModelIfPresent(name);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model getModel(String name) {
|
||||
if (isDefaultModel(name)) {
|
||||
return super.createDefaultModel();
|
||||
} else {
|
||||
return super.getModel(name);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model getModel(String name, ModelReader loadIfAbsent) {
|
||||
if (isDefaultModel(name)) {
|
||||
return super.createDefaultModel();
|
||||
} else {
|
||||
return super.getModel(name, loadIfAbsent);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model createModel(String name, boolean strict) {
|
||||
if (isDefaultModel(name)) {
|
||||
return super.createDefaultModel();
|
||||
} else {
|
||||
return super.createModel(name, strict);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model createModel(String name) {
|
||||
if (isDefaultModel(name)) {
|
||||
return super.createDefaultModel();
|
||||
} else {
|
||||
return super.createModel(name);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model openModel(String name, boolean strict) {
|
||||
if (isDefaultModel(name)) {
|
||||
return super.createDefaultModel();
|
||||
} else {
|
||||
return super.openModel(name, strict);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeModel(String name) {
|
||||
if (isDefaultModel(name)) {
|
||||
log.warn("Attempting to remove the default model.");
|
||||
} else {
|
||||
super.removeModel(name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasModel(String name) {
|
||||
if (isDefaultModel(name)) {
|
||||
return true;
|
||||
} else {
|
||||
return super.hasModel(name);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExtendedIterator<String> listModels() {
|
||||
return super.listModels().andThen(
|
||||
Collections.singleton(this.defaultModelUri).iterator());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.modelaccess.adapters;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import com.hp.hpl.jena.graph.GraphMaker;
|
||||
import com.hp.hpl.jena.rdf.model.Model;
|
||||
import com.hp.hpl.jena.rdf.model.ModelMaker;
|
||||
import com.hp.hpl.jena.rdf.model.ModelReader;
|
||||
import com.hp.hpl.jena.util.iterator.ExtendedIterator;
|
||||
import com.hp.hpl.jena.util.iterator.WrappedIterator;
|
||||
|
||||
/**
|
||||
* Allow some models in the "shadowing" ModelMaker to hide the corresponding
|
||||
* models in the "shadowed" ModelMaker.
|
||||
*
|
||||
* Specify both ModelMakers, and the list of URIs for the shadowing models.
|
||||
*/
|
||||
public class ShadowingModelMaker extends AbstractModelMakerDecorator {
|
||||
private final ModelMaker shadowing;
|
||||
private final Set<String> shadowUris;
|
||||
|
||||
public ShadowingModelMaker(ModelMaker shadowed, ModelMaker shadowing,
|
||||
String... shadowUris) {
|
||||
super(shadowed);
|
||||
this.shadowing = shadowing;
|
||||
this.shadowUris = new HashSet<>(Arrays.asList(shadowUris));
|
||||
}
|
||||
|
||||
private boolean isShadow(String name) {
|
||||
return shadowUris.contains(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model createDefaultModel() {
|
||||
return super.createDefaultModel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model createFreshModel() {
|
||||
return super.createFreshModel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model openModel(String name) {
|
||||
if (isShadow(name)) {
|
||||
return shadowing.openModel(name);
|
||||
} else {
|
||||
return super.openModel(name);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model openModelIfPresent(String name) {
|
||||
if (isShadow(name)) {
|
||||
return shadowing.openModelIfPresent(name);
|
||||
} else {
|
||||
return super.openModelIfPresent(name);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model getModel(String name) {
|
||||
if (isShadow(name)) {
|
||||
return shadowing.getModel(name);
|
||||
} else {
|
||||
return super.getModel(name);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model getModel(String name, ModelReader loadIfAbsent) {
|
||||
if (isShadow(name)) {
|
||||
return shadowing.getModel(name, loadIfAbsent);
|
||||
} else {
|
||||
return super.getModel(name, loadIfAbsent);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model createModel(String name, boolean strict) {
|
||||
if (isShadow(name)) {
|
||||
return shadowing.createModel(name, strict);
|
||||
} else {
|
||||
return super.createModel(name, strict);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model createModel(String name) {
|
||||
if (isShadow(name)) {
|
||||
return shadowing.createModel(name);
|
||||
} else {
|
||||
return super.createModel(name);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model openModel(String name, boolean strict) {
|
||||
if (isShadow(name)) {
|
||||
return shadowing.openModel(name, strict);
|
||||
} else {
|
||||
return super.openModel(name, strict);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeModel(String name) {
|
||||
if (isShadow(name)) {
|
||||
shadowing.removeModel(name);
|
||||
} else {
|
||||
super.removeModel(name);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasModel(String name) {
|
||||
if (isShadow(name)) {
|
||||
return shadowing.hasModel(name);
|
||||
} else {
|
||||
return super.hasModel(name);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
shadowing.close();
|
||||
super.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExtendedIterator<String> listModels() {
|
||||
Set<String> allNames = super.listModels().toSet();
|
||||
allNames.addAll(shadowUris);
|
||||
return WrappedIterator.create(allNames.iterator());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,249 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.modelaccess.adapters;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.hp.hpl.jena.rdf.model.Model;
|
||||
import com.hp.hpl.jena.rdf.model.ModelMaker;
|
||||
import com.hp.hpl.jena.rdf.model.ModelReader;
|
||||
import com.hp.hpl.jena.shared.AlreadyExistsException;
|
||||
import com.hp.hpl.jena.util.iterator.ExtendedIterator;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.adapters.VitroModelFactory;
|
||||
|
||||
/**
|
||||
* This ModelMaker decorator creates one or more "union models" over the models
|
||||
* provided to it by the inner ModelMaker.
|
||||
*
|
||||
* Each union model contains all of the triples of both its base model and its
|
||||
* "plus" model. Any changes to the union model are delegated to the base model.
|
||||
* If changes are desired in the "plus" model, it must be accessed directly.
|
||||
*
|
||||
* This can create surprises, since the union model will claim to have a given
|
||||
* statement that is part of the plus model, but an attempt to delete that
|
||||
* statement from the union model has no effect.
|
||||
*/
|
||||
public class UnionModelsModelMaker extends AbstractModelMakerDecorator {
|
||||
private final Map<String, UnionSpec> unionModelsMap;
|
||||
|
||||
/**
|
||||
* Create it like this:
|
||||
*
|
||||
* <pre>
|
||||
* new UnionModelsModelMaker(inner,
|
||||
* UnionSpec.base("baseUri").plus("plusUri").yields("unionUri"),
|
||||
* ...);
|
||||
* </pre>
|
||||
*/
|
||||
public UnionModelsModelMaker(ModelMaker inner, UnionSpec... unionModelSpecs) {
|
||||
super(inner);
|
||||
|
||||
this.unionModelsMap = new HashMap<>();
|
||||
|
||||
for (UnionSpec spec : unionModelSpecs) {
|
||||
String unionUri = spec.getUnionUri();
|
||||
if (unionModelsMap.containsKey(unionUri)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Two UnionSpecs may not have the same union URI: "
|
||||
+ spec + ", " + unionModelsMap.get(unionUri));
|
||||
}
|
||||
this.unionModelsMap.put(unionUri, spec);
|
||||
}
|
||||
|
||||
for (UnionSpec spec1 : unionModelsMap.values()) {
|
||||
if (unionModelsMap.containsKey(spec1.getBaseUri())
|
||||
|| unionModelsMap.containsKey(spec1.getPlusUri())) {
|
||||
throw new IllegalArgumentException(
|
||||
"A UnionSpec may not build on another UnionSpec: "
|
||||
+ spec1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasUnionModel(String name) {
|
||||
return unionModelsMap.containsKey(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* The union models use lazy initialization, so there is no overhead if the
|
||||
* model is never requested.
|
||||
*/
|
||||
private Model getUnionModel(String name) {
|
||||
UnionSpec spec = unionModelsMap.get(name);
|
||||
synchronized (spec) {
|
||||
if (spec.getUnionModel() == null) {
|
||||
Model baseModel = super.openModel(spec.getBaseUri());
|
||||
Model plusModel = super.openModel(spec.getPlusUri());
|
||||
spec.setUnionModel(VitroModelFactory.createUnion(baseModel,
|
||||
plusModel));
|
||||
}
|
||||
}
|
||||
return spec.getUnionModel();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Overridden methods.
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public Model createModel(String name) {
|
||||
return createModel(name, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model createModel(String name, boolean strict) {
|
||||
if (hasUnionModel(name)) {
|
||||
if (strict) {
|
||||
throw new AlreadyExistsException(name);
|
||||
} else {
|
||||
return getUnionModel(name);
|
||||
}
|
||||
} else {
|
||||
return super.createModel(name, strict);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model openModel(String name, boolean strict) {
|
||||
if (hasUnionModel(name)) {
|
||||
return getUnionModel(name);
|
||||
} else {
|
||||
return super.openModel(name, strict);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model openModel(String name) {
|
||||
if (hasUnionModel(name)) {
|
||||
return getUnionModel(name);
|
||||
} else {
|
||||
return super.openModel(name);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model openModelIfPresent(String name) {
|
||||
if (hasUnionModel(name)) {
|
||||
return getUnionModel(name);
|
||||
} else {
|
||||
return super.openModelIfPresent(name);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasModel(String name) {
|
||||
if (hasUnionModel(name)) {
|
||||
return true;
|
||||
} else {
|
||||
return super.hasModel(name);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExtendedIterator<String> listModels() {
|
||||
return super.listModels().andThen(unionModelsMap
|
||||
.keySet().iterator());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeModel(String name) {
|
||||
if (hasUnionModel(name)) {
|
||||
unionModelsMap.remove(name);
|
||||
} else {
|
||||
super.removeModel(name);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model getModel(String URL) {
|
||||
if (hasUnionModel(URL)) {
|
||||
return getUnionModel(URL);
|
||||
} else {
|
||||
return super.getModel(URL);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model getModel(String URL, ModelReader loadIfAbsent) {
|
||||
if (hasUnionModel(URL)) {
|
||||
return getUnionModel(URL);
|
||||
} else {
|
||||
return super.getModel(URL, loadIfAbsent);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// UnionSpec and builder classes.
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
public static class UnionSpec {
|
||||
public static UnionSpecBase base(String baseUri) {
|
||||
return new UnionSpecBase(baseUri);
|
||||
}
|
||||
|
||||
private final String baseUri;
|
||||
private final String plusUri;
|
||||
private final String unionUri;
|
||||
private Model unionModel;
|
||||
|
||||
public UnionSpec(String baseUri, String plusUri, String unionUri) {
|
||||
this.baseUri = baseUri;
|
||||
this.plusUri = plusUri;
|
||||
this.unionUri = unionUri;
|
||||
}
|
||||
|
||||
public Model getUnionModel() {
|
||||
return unionModel;
|
||||
}
|
||||
|
||||
public void setUnionModel(Model unionModel) {
|
||||
this.unionModel = unionModel;
|
||||
}
|
||||
|
||||
public String getBaseUri() {
|
||||
return baseUri;
|
||||
}
|
||||
|
||||
public String getPlusUri() {
|
||||
return plusUri;
|
||||
}
|
||||
|
||||
public String getUnionUri() {
|
||||
return unionUri;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "UnionSpec[baseUri=" + baseUri + ", plusUri=" + plusUri
|
||||
+ ", unionUri=" + unionUri + "]";
|
||||
}
|
||||
}
|
||||
|
||||
public static class UnionSpecBase {
|
||||
private final String baseUri;
|
||||
|
||||
UnionSpecBase(String baseUri) {
|
||||
this.baseUri = baseUri;
|
||||
}
|
||||
|
||||
public UnionSpecPair plus(String plusUri) {
|
||||
return new UnionSpecPair(baseUri, plusUri);
|
||||
}
|
||||
}
|
||||
|
||||
public static class UnionSpecPair {
|
||||
private final String baseUri;
|
||||
private final String plusUri;
|
||||
|
||||
public UnionSpecPair(String baseUri, String plusUri) {
|
||||
this.baseUri = baseUri;
|
||||
this.plusUri = plusUri;
|
||||
}
|
||||
|
||||
public UnionSpec yields(String unionUri) {
|
||||
return new UnionSpec(baseUri, plusUri, unionUri);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue