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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,223 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.modelaccess.adapters;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import stubs.com.hp.hpl.jena.rdf.model.ModelMaker.ModelMakerStub;
|
||||||
|
|
||||||
|
import com.hp.hpl.jena.rdf.model.Model;
|
||||||
|
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
||||||
|
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.shared.CannotCreateException;
|
||||||
|
import com.hp.hpl.jena.shared.DoesNotExistException;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
*/
|
||||||
|
public class ListCachingModelMakerTest extends AbstractTestClass {
|
||||||
|
private static final String URI_ONE = "http://model.one";
|
||||||
|
private static final String URI_TWO = "http://model.two";
|
||||||
|
private static final String URI_NONE = "http://model.does.not.exist";
|
||||||
|
|
||||||
|
private static final Model MODEL_ONE = createModel();
|
||||||
|
private static final Model MODEL_TWO = createModel();
|
||||||
|
private static final Model MODEL_DEFAULT = createModel();
|
||||||
|
private static final Model MODEL_FRESH = createModel();
|
||||||
|
|
||||||
|
private ModelMaker rigorous;
|
||||||
|
private ModelMaker relaxed;
|
||||||
|
private ModelMaker mm;
|
||||||
|
private ModelReader modelReader;
|
||||||
|
|
||||||
|
private static Model createModel() {
|
||||||
|
return ModelFactory.createDefaultModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() {
|
||||||
|
rigorous = ModelMakerStub.rigorous(MODEL_DEFAULT, MODEL_FRESH)
|
||||||
|
.put(URI_ONE, MODEL_ONE).put(URI_TWO, MODEL_TWO);
|
||||||
|
relaxed = ModelMakerStub.relaxed(MODEL_DEFAULT, MODEL_FRESH)
|
||||||
|
.put(URI_ONE, MODEL_ONE).put(URI_TWO, MODEL_TWO);
|
||||||
|
relaxed(); // call rigorous() to override, if desired.
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// The tests
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@Test(expected = NullPointerException.class)
|
||||||
|
public void nullInnerModel() {
|
||||||
|
new ListCachingModelMaker(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void listModels() {
|
||||||
|
assertList(URI_ONE, URI_TWO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void hasModelExist() {
|
||||||
|
assertTrue(mm.hasModel(URI_ONE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void hasModelNonExist() {
|
||||||
|
assertFalse(mm.hasModel(URI_NONE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createModelExist() {
|
||||||
|
assertEquals(MODEL_ONE, mm.createModel(URI_ONE));
|
||||||
|
assertList(URI_ONE, URI_TWO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createModelNonExist() {
|
||||||
|
assertEquals(MODEL_FRESH, mm.createModel(URI_NONE));
|
||||||
|
assertList(URI_ONE, URI_TWO, URI_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = AlreadyExistsException.class)
|
||||||
|
public void createModelStrictExist() {
|
||||||
|
mm.createModel(URI_ONE, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createModelStrictNonExist() {
|
||||||
|
assertEquals(MODEL_FRESH, mm.createModel(URI_NONE, true));
|
||||||
|
assertList(URI_ONE, URI_TWO, URI_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void openModelExist() {
|
||||||
|
assertEquals(MODEL_TWO, mm.openModel(URI_TWO));
|
||||||
|
assertList(URI_ONE, URI_TWO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = DoesNotExistException.class)
|
||||||
|
public void openModelRigorousNonExist() {
|
||||||
|
rigorous();
|
||||||
|
mm.openModel(URI_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void openModelRelaxedNonExist() {
|
||||||
|
assertEquals(MODEL_FRESH, mm.openModel(URI_NONE));
|
||||||
|
assertList(URI_ONE, URI_TWO, URI_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void openModelIfPresentExist() {
|
||||||
|
assertEquals(MODEL_TWO, mm.openModelIfPresent(URI_TWO));
|
||||||
|
assertList(URI_ONE, URI_TWO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void openModelIfPresentNonExist() {
|
||||||
|
assertNull(mm.openModelIfPresent(URI_NONE));
|
||||||
|
assertList(URI_ONE, URI_TWO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void openModelStrictExist() {
|
||||||
|
assertEquals(MODEL_ONE, mm.openModel(URI_ONE, true));
|
||||||
|
assertList(URI_ONE, URI_TWO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void openModelNonStrictExist() {
|
||||||
|
assertEquals(MODEL_ONE, mm.openModel(URI_ONE, false));
|
||||||
|
assertList(URI_ONE, URI_TWO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void openModelNonStrictNonExist() {
|
||||||
|
assertEquals(MODEL_FRESH, mm.openModel(URI_NONE, false));
|
||||||
|
assertList(URI_ONE, URI_TWO, URI_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void removeModelExist() {
|
||||||
|
mm.removeModel(URI_ONE);
|
||||||
|
assertList(URI_TWO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = DoesNotExistException.class)
|
||||||
|
public void removeModelNonExist() {
|
||||||
|
mm.removeModel(URI_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getModelExist() {
|
||||||
|
assertEquals(MODEL_TWO, mm.getModel(URI_TWO));
|
||||||
|
assertList(URI_ONE, URI_TWO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getModelRigorousNonExist() {
|
||||||
|
rigorous();
|
||||||
|
assertNull(mm.getModel(URI_NONE));
|
||||||
|
assertList(URI_ONE, URI_TWO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getModelRelaxedNonExist() {
|
||||||
|
assertEquals(MODEL_FRESH, mm.getModel(URI_NONE));
|
||||||
|
assertList(URI_ONE, URI_TWO, URI_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getModelLoadIfAbsentExist() {
|
||||||
|
assertEquals(MODEL_TWO, mm.getModel(URI_TWO, modelReader));
|
||||||
|
assertList(URI_ONE, URI_TWO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = CannotCreateException.class)
|
||||||
|
public void getModelLoadIfAbsentRigorousNonExist() {
|
||||||
|
rigorous();
|
||||||
|
mm.getModel(URI_NONE, modelReader);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getModelLoadIfAbsentRelaxedNonExist() {
|
||||||
|
assertEquals(MODEL_FRESH, mm.getModel(URI_NONE, modelReader));
|
||||||
|
assertList(URI_ONE, URI_TWO, URI_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Helper methods
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
private void relaxed() {
|
||||||
|
mm = new ListCachingModelMaker(relaxed);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void rigorous() {
|
||||||
|
mm = new ListCachingModelMaker(rigorous);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertList(String... expectedArray) {
|
||||||
|
Set<String> expected = new HashSet<>(Arrays.asList(expectedArray));
|
||||||
|
Set<String> actual = mm.listModels().toSet();
|
||||||
|
assertEquals(expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,174 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.modelaccess.adapters;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.StringReader;
|
||||||
|
import java.lang.reflect.InvocationHandler;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.lang.reflect.Proxy;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import stubs.com.hp.hpl.jena.rdf.model.ModelMaker.ModelMakerStub;
|
||||||
|
|
||||||
|
import com.hp.hpl.jena.graph.Graph;
|
||||||
|
import com.hp.hpl.jena.graph.impl.CollectionGraph;
|
||||||
|
import com.hp.hpl.jena.rdf.model.Model;
|
||||||
|
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
||||||
|
import com.hp.hpl.jena.rdf.model.Property;
|
||||||
|
import com.hp.hpl.jena.rdf.model.Resource;
|
||||||
|
import com.hp.hpl.jena.rdf.model.ResourceFactory;
|
||||||
|
import com.hp.hpl.jena.rdf.model.Statement;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
*/
|
||||||
|
public class MemoryMappingModelMakerTest extends AbstractTestClass {
|
||||||
|
private static final String URI_MAPPED = "http://memory.mapped.model";
|
||||||
|
private static final String URI_UNMAPPED = "http://unmapped.model";
|
||||||
|
private static final String MODEL_CONTENTS = "@prefix : <http://z#> . \n"
|
||||||
|
+ ":a :b :c .";
|
||||||
|
|
||||||
|
private GraphModelStructure unmapped;
|
||||||
|
private GraphModelStructure mapped;
|
||||||
|
private ModelMakerStub innerModelMaker;
|
||||||
|
private MemoryMappingModelMaker mmmm;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() {
|
||||||
|
unmapped = new GraphModelStructure(URI_UNMAPPED, MODEL_CONTENTS);
|
||||||
|
mapped = new GraphModelStructure(URI_MAPPED, MODEL_CONTENTS);
|
||||||
|
|
||||||
|
innerModelMaker = ModelMakerStub.rigorous(createModel(), createModel());
|
||||||
|
innerModelMaker.put(mapped.uri, mapped.model);
|
||||||
|
innerModelMaker.put(unmapped.uri, unmapped.model);
|
||||||
|
|
||||||
|
mmmm = new MemoryMappingModelMaker(innerModelMaker, mapped.uri);
|
||||||
|
|
||||||
|
unmapped.methodCalls.clear();
|
||||||
|
mapped.methodCalls.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// tests
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void unmappedRead() {
|
||||||
|
assertModelContents(unmapped, "[http://z#a, http://z#b, http://z#c]");
|
||||||
|
assertMethodCalls(unmapped, "find");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mappedRead() {
|
||||||
|
assertModelContents(mapped, "[http://z#a, http://z#b, http://z#c]");
|
||||||
|
assertMethodCalls(mapped);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void unmappedWrite() {
|
||||||
|
mmmm.openModel(URI_UNMAPPED).add(newStatement());
|
||||||
|
assertModelContents(unmapped, "[http://z#a, http://z#b, http://z#c]",
|
||||||
|
"[http://z#new, http://z#to, http://z#you]");
|
||||||
|
assertMethodCalls(unmapped, "add", "find");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mappedWrite() {
|
||||||
|
mmmm.openModel(URI_MAPPED).add(newStatement());
|
||||||
|
assertModelContents(mapped, "[http://z#a, http://z#b, http://z#c]",
|
||||||
|
"[http://z#new, http://z#to, http://z#you]");
|
||||||
|
assertMethodCalls(mapped, "add");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Helper methods
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
private static Model createModel() {
|
||||||
|
return ModelFactory.createDefaultModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertModelContents(GraphModelStructure gms,
|
||||||
|
String... expected) {
|
||||||
|
Set<Statement> stmts = mmmm.openModel(gms.uri).listStatements().toSet();
|
||||||
|
assertStatements(stmts, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertStatements(Set<Statement> stmts, String... expected) {
|
||||||
|
Set<String> actual = new HashSet<>();
|
||||||
|
for (Statement stmt : stmts) {
|
||||||
|
actual.add(stmt.toString());
|
||||||
|
}
|
||||||
|
assertEquals(new HashSet<>(Arrays.asList(expected)), actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertMethodCalls(GraphModelStructure gms, String... expected) {
|
||||||
|
assertEquals(Arrays.asList(expected), gms.methodCalls);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Statement newStatement() {
|
||||||
|
Resource s = ResourceFactory.createResource("http://z#new");
|
||||||
|
Property p = ResourceFactory.createProperty("http://z#to");
|
||||||
|
Resource o = ResourceFactory.createResource("http://z#you");
|
||||||
|
return ResourceFactory.createStatement(s, p, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Helper classes
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
private static class GraphModelStructure {
|
||||||
|
final String uri;
|
||||||
|
final Graph graph;
|
||||||
|
final List<String> methodCalls;
|
||||||
|
final RecordingInvocationHandler handler;
|
||||||
|
final Graph proxy;
|
||||||
|
final Model model;
|
||||||
|
|
||||||
|
public GraphModelStructure(String uri, String contents) {
|
||||||
|
this.uri = uri;
|
||||||
|
graph = new CollectionGraph();
|
||||||
|
methodCalls = new ArrayList<>();
|
||||||
|
handler = new RecordingInvocationHandler(graph, methodCalls);
|
||||||
|
proxy = wrapGraph();
|
||||||
|
model = ModelFactory.createModelForGraph(proxy);
|
||||||
|
model.read(new StringReader(contents), null, "TURTLE");
|
||||||
|
}
|
||||||
|
|
||||||
|
private Graph wrapGraph() {
|
||||||
|
ClassLoader classLoader = Model.class.getClassLoader();
|
||||||
|
Class<?>[] interfaces = new Class<?>[] { Graph.class };
|
||||||
|
return (Graph) Proxy.newProxyInstance(classLoader, interfaces,
|
||||||
|
handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class RecordingInvocationHandler implements
|
||||||
|
InvocationHandler {
|
||||||
|
private final Object inner;
|
||||||
|
private final List<String> methodCalls;
|
||||||
|
|
||||||
|
public RecordingInvocationHandler(Object inner, List<String> methodCalls) {
|
||||||
|
this.inner = inner;
|
||||||
|
this.methodCalls = methodCalls;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object invoke(Object proxy, Method method, Object[] args)
|
||||||
|
throws Throwable {
|
||||||
|
methodCalls.add(method.getName());
|
||||||
|
return method.invoke(inner, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,259 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.modelaccess.adapters;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import stubs.com.hp.hpl.jena.rdf.model.ModelMaker.ModelMakerStub;
|
||||||
|
|
||||||
|
import com.hp.hpl.jena.rdf.model.Model;
|
||||||
|
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
||||||
|
import com.hp.hpl.jena.rdf.model.ModelMaker;
|
||||||
|
import com.hp.hpl.jena.shared.AlreadyExistsException;
|
||||||
|
import com.hp.hpl.jena.shared.CannotCreateException;
|
||||||
|
import com.hp.hpl.jena.shared.DoesNotExistException;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.modelaccess.adapters.UnionModelsModelMaker.UnionSpec;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test the functionality of the UnionModelsModelMaker.
|
||||||
|
*/
|
||||||
|
public class UnionModelsModelMakerTest extends AbstractTestClass {
|
||||||
|
private static final String URI_ONE = "http://model.one";
|
||||||
|
private static final String URI_TWO = "http://model.two";
|
||||||
|
private static final String URI_THREE = "http://model.three";
|
||||||
|
private static final String URI_UNION = "http://model.union";
|
||||||
|
private static final String URI_NONE = "http://model.does.not.exist";
|
||||||
|
|
||||||
|
private static final Model MODEL_ONE = createModel();
|
||||||
|
private static final Model MODEL_TWO = createModel();
|
||||||
|
private static final Model MODEL_THREE = createModel();
|
||||||
|
private static final Model MODEL_DEFAULT = createModel();
|
||||||
|
private static final Model MODEL_FRESH = createModel();
|
||||||
|
|
||||||
|
private static Model createModel() {
|
||||||
|
return ModelFactory.createDefaultModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ModelMaker inner;
|
||||||
|
private ModelMaker mm;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() {
|
||||||
|
/*
|
||||||
|
* Use a rigorous inner model maker, but it doesn't make much difference.
|
||||||
|
*/
|
||||||
|
inner = ModelMakerStub.rigorous(MODEL_DEFAULT, MODEL_FRESH)
|
||||||
|
.put(URI_ONE, MODEL_ONE).put(URI_TWO, MODEL_TWO)
|
||||||
|
.put(URI_THREE, MODEL_THREE);
|
||||||
|
|
||||||
|
mm = new UnionModelsModelMaker(inner, UnionSpec.base(URI_ONE)
|
||||||
|
.plus(URI_TWO).yields(URI_UNION));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@Test(expected = NullPointerException.class)
|
||||||
|
public void nullInnerModel() {
|
||||||
|
new UnionModelsModelMaker(null, UnionSpec.base(URI_ONE).plus(URI_TWO)
|
||||||
|
.yields(URI_UNION));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void duplicateUnionUri() {
|
||||||
|
new UnionModelsModelMaker(inner, UnionSpec.base(URI_ONE).plus(URI_TWO)
|
||||||
|
.yields(URI_UNION), UnionSpec.base(URI_ONE).plus(URI_THREE)
|
||||||
|
.yields(URI_UNION));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void nestedUnions() {
|
||||||
|
new UnionModelsModelMaker(inner, UnionSpec.base(URI_ONE).plus(URI_TWO)
|
||||||
|
.yields(URI_UNION), UnionSpec.base(URI_UNION).plus(URI_THREE)
|
||||||
|
.yields("http://nestedUnion"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void hasModelActual() {
|
||||||
|
assertTrue(mm.hasModel(URI_ONE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void hasModelNone() {
|
||||||
|
assertFalse(mm.hasModel(URI_NONE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void hasModelUnion() {
|
||||||
|
assertTrue(mm.hasModel(URI_UNION));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void listModels() {
|
||||||
|
assertExpectedModelsList(URI_ONE, URI_TWO, URI_THREE, URI_UNION);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createModelActual() {
|
||||||
|
assertEquals(MODEL_ONE, mm.createModel(URI_ONE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createModelNone() {
|
||||||
|
assertEquals(MODEL_FRESH, mm.createModel(URI_NONE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createModelUnion() {
|
||||||
|
assertTrue(isUnionModel(mm.createModel(URI_UNION)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = AlreadyExistsException.class)
|
||||||
|
public void createModelActualStrict() {
|
||||||
|
mm.createModel(URI_ONE, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createModelNoneStrict() {
|
||||||
|
assertEquals(MODEL_FRESH, mm.createModel(URI_NONE, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = AlreadyExistsException.class)
|
||||||
|
public void createModelUnionStrict() {
|
||||||
|
mm.createModel(URI_UNION, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void openModelActual() {
|
||||||
|
assertEquals(MODEL_ONE, mm.openModel(URI_ONE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = DoesNotExistException.class)
|
||||||
|
public void openModelNone() {
|
||||||
|
mm.openModel(URI_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void openModelUnion() {
|
||||||
|
assertTrue(isUnionModel(mm.openModel(URI_UNION)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void openModelActualStrict() {
|
||||||
|
assertEquals(MODEL_ONE, mm.openModel(URI_ONE, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = DoesNotExistException.class)
|
||||||
|
public void openModelNoneStrict() {
|
||||||
|
mm.openModel(URI_NONE, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void openModelUnionStrict() {
|
||||||
|
assertTrue(isUnionModel(mm.openModel(URI_UNION, true)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void openModelIfPresentActual() {
|
||||||
|
assertEquals(MODEL_ONE, mm.openModelIfPresent(URI_ONE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void openModelIfPresentNone() {
|
||||||
|
assertNull(mm.openModelIfPresent(URI_NONE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void openModelIfPresentUnion() {
|
||||||
|
assertTrue(isUnionModel(mm.openModelIfPresent(URI_UNION)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void removeModelActual() {
|
||||||
|
mm.removeModel(URI_ONE);
|
||||||
|
assertExpectedModelsList(URI_TWO, URI_THREE, URI_UNION);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = DoesNotExistException.class)
|
||||||
|
public void removeModelNone() {
|
||||||
|
mm.removeModel(URI_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void removeModelUnion() {
|
||||||
|
mm.removeModel(URI_UNION);
|
||||||
|
assertExpectedModelsList(URI_ONE, URI_TWO, URI_THREE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getModelActual() {
|
||||||
|
assertEquals(MODEL_ONE, mm.getModel(URI_ONE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getModelNone() {
|
||||||
|
assertEquals(null, mm.getModel(URI_NONE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getModelUnion() {
|
||||||
|
assertTrue(isUnionModel(mm.getModel(URI_UNION)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getModelLoadIfAbsentActual() {
|
||||||
|
assertEquals(MODEL_ONE, mm.getModel(URI_ONE, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = CannotCreateException.class)
|
||||||
|
public void getModelLoadIfAbsentNone() {
|
||||||
|
mm.getModel(URI_NONE, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getModelLoadIfAbsentUnion() {
|
||||||
|
assertTrue(isUnionModel(mm.getModel(URI_UNION, null)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Helper methods
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No easy way to assert that this is actually the union model, but we can
|
||||||
|
* assert that it is not null, and not any model we know of.
|
||||||
|
*/
|
||||||
|
private boolean isUnionModel(Model m) {
|
||||||
|
Model[] knownModels = { MODEL_ONE, MODEL_TWO, MODEL_THREE,
|
||||||
|
MODEL_DEFAULT, MODEL_FRESH };
|
||||||
|
if (m == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Model knownModel : knownModels) {
|
||||||
|
if (m == knownModel) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertExpectedModelsList(String... uris) {
|
||||||
|
Set<String> expected = new HashSet<>(Arrays.asList(uris));
|
||||||
|
assertEquals(expected, mm.listModels().toSet());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,223 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package stubs.com.hp.hpl.jena.rdf.model.ModelMaker;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.hp.hpl.jena.graph.GraphMaker;
|
||||||
|
import com.hp.hpl.jena.graph.impl.SimpleGraphMaker;
|
||||||
|
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.shared.CannotCreateException;
|
||||||
|
import com.hp.hpl.jena.shared.DoesNotExistException;
|
||||||
|
import com.hp.hpl.jena.util.iterator.ExtendedIterator;
|
||||||
|
import com.hp.hpl.jena.util.iterator.WrappedIterator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A ModelMaker stub, but is it strict or relaxed? Choose one of the
|
||||||
|
* sub-classes.
|
||||||
|
*
|
||||||
|
* The only difference between strict and relaxed is on a call to
|
||||||
|
* openModel(name), when no such model exists. The relaxed ModelMaker will
|
||||||
|
* create a fresh model and associate it with the name. The strict modelMaker
|
||||||
|
* will throw a DoesNotExistException.
|
||||||
|
*
|
||||||
|
* Warning: the "fresh model" is the same every time, so calling
|
||||||
|
* createFreshModel() more than once during a test will give illusory results.
|
||||||
|
*/
|
||||||
|
public abstract class ModelMakerStub implements ModelMaker {
|
||||||
|
protected final Model defaultModel;
|
||||||
|
protected final Model freshModel;
|
||||||
|
protected final Map<String, Model> models = new HashMap<>();
|
||||||
|
protected final GraphMaker graphMaker = new SimpleGraphMaker();
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Factory methods
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
public static ModelMakerStub rigorous(Model defaultModel, Model freshModel) {
|
||||||
|
return new ModelMakerRigorousStub(defaultModel, freshModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ModelMakerStub relaxed(Model defaultModel, Model freshModel) {
|
||||||
|
return new ModelMakerRelaxedStub(defaultModel, freshModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// The abstract class
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
protected ModelMakerStub(Model defaultModel, Model freshModel) {
|
||||||
|
this.defaultModel = defaultModel;
|
||||||
|
this.freshModel = freshModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ModelMakerStub put(String uri, Model model) {
|
||||||
|
models.put(uri, model);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GraphMaker getGraphMaker() {
|
||||||
|
return graphMaker;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
// Nothing to close.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasModel(String name) {
|
||||||
|
return models.containsKey(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExtendedIterator<String> listModels() {
|
||||||
|
return WrappedIterator.create(models.keySet().iterator());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Model createModel(String name) {
|
||||||
|
return createModel(name, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Model createModel(String name, boolean strict) {
|
||||||
|
if (hasModel(name)) {
|
||||||
|
if (strict) {
|
||||||
|
throw new AlreadyExistsException(name);
|
||||||
|
} else {
|
||||||
|
return models.get(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return freshModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Model createDefaultModel() {
|
||||||
|
return defaultModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Model createFreshModel() {
|
||||||
|
return freshModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Model openModel(String name, boolean strict) {
|
||||||
|
if (strict && !hasModel(name)) {
|
||||||
|
throw new DoesNotExistException(name);
|
||||||
|
} else {
|
||||||
|
return openModel(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Model openModelIfPresent(String name) {
|
||||||
|
return models.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeModel(String name) {
|
||||||
|
if (hasModel(name)) {
|
||||||
|
models.remove(name);
|
||||||
|
} else {
|
||||||
|
throw new DoesNotExistException(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Concrete sub-classes
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* "Relaxed" means that if they ask for a model that doesn't exist, we
|
||||||
|
* create one.
|
||||||
|
*
|
||||||
|
* Note: should return a new model, instead of the "fresh" model.
|
||||||
|
*/
|
||||||
|
private static class ModelMakerRelaxedStub extends ModelMakerStub {
|
||||||
|
public ModelMakerRelaxedStub(Model defaultModel, Model freshModel) {
|
||||||
|
super(defaultModel, freshModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Model openModel(String name) {
|
||||||
|
if (hasModel(name)) {
|
||||||
|
return models.get(name);
|
||||||
|
} else {
|
||||||
|
return freshModel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Model getModel(String name) {
|
||||||
|
if (hasModel(name)) {
|
||||||
|
return models.get(name);
|
||||||
|
} else {
|
||||||
|
return freshModel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: Rather than having this part of "relaxed" or "rigorous", the
|
||||||
|
* result should depend on the ModelReader.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Model getModel(String name, ModelReader loadIfAbsent) {
|
||||||
|
if (hasModel(name)) {
|
||||||
|
return models.get(name);
|
||||||
|
} else {
|
||||||
|
return freshModel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* "Rigorous" means that if they ask for a model that doesn't exist, we
|
||||||
|
* return null or throw an exception.
|
||||||
|
*/
|
||||||
|
private static class ModelMakerRigorousStub extends ModelMakerStub {
|
||||||
|
public ModelMakerRigorousStub(Model defaultModel, Model freshModel) {
|
||||||
|
super(defaultModel, freshModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Model openModel(String name) {
|
||||||
|
if (hasModel(name)) {
|
||||||
|
return models.get(name);
|
||||||
|
} else {
|
||||||
|
throw new DoesNotExistException(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Model getModel(String name) {
|
||||||
|
if (hasModel(name)) {
|
||||||
|
return models.get(name);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: Rather than having this part of "relaxed" or "rigorous", the
|
||||||
|
* result should depend on the ModelReader.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Model getModel(String name, ModelReader loadIfAbsent) {
|
||||||
|
if (hasModel(name)) {
|
||||||
|
return models.get(name);
|
||||||
|
} else {
|
||||||
|
throw new CannotCreateException(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue