package com.dooapp.gaedo.blueprints;
import java.io.ObjectStreamException;
import java.io.Serializable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Map;
import com.dooapp.gaedo.finders.FinderCrudService;
import com.dooapp.gaedo.finders.repository.ServiceRepository;
import com.dooapp.gaedo.patterns.WriteReplaceable;
import com.dooapp.gaedo.properties.Property;
import com.tinkerpop.blueprints.pgm.Edge;
import com.tinkerpop.blueprints.pgm.Vertex;
public class CollectionLazyLoader implements InvocationHandler, /* MethodHandler,*/ Serializable {
private transient Property property;
private transient Vertex rootVertex;
// Internal storage collection (not to be confused with external visible collection)
private Collection collection;
private transient ServiceRepository repository;
private boolean loaded = false;
private ClassLoader classLoader;
private Map<String, Object> objectsBeingAccessed;
/**
* Serialization constructor
*/
public CollectionLazyLoader() {
}
public CollectionLazyLoader(ClassLoader classLoader, ServiceRepository repository, Property p, Vertex objectVertex, Collection<Object> targetCollection, Map<String, Object> objectsBeingAccessed) {
this.classLoader = classLoader;
this.repository = repository;
this.property = p;
this.rootVertex = objectVertex;
this.collection = targetCollection;
this.objectsBeingAccessed = objectsBeingAccessed;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if(!loaded) {
loadCollection(collection, objectsBeingAccessed);
}
if(method.getDeclaringClass().equals(WriteReplaceable.class)) {
// there is only writeReplace there, so writeReplace !
return collection;
}
return method.invoke(collection, args);
}
public void loadCollection(Collection collection, Map<String, Object> objectsBeingAccessed) {
try {
for(Edge e : rootVertex.getOutEdges(GraphUtils.getEdgeNameFor(property))) {
Vertex value = e.getInVertex();
Object temporaryValue = GraphUtils.createInstance(classLoader, value, repository);
if(repository.containsKey(temporaryValue.getClass())) {
FinderCrudService service = repository.get(temporaryValue.getClass());
if (service instanceof BluePrintsBackedFinderService) {
BluePrintsBackedFinderService blueprints= (BluePrintsBackedFinderService) service;
collection.add(blueprints.loadObject(value, objectsBeingAccessed));
}
} else {
// Instance should be OK, as createinstance should support everything getVertexForBasicObject supports
collection.add(temporaryValue);
}
}
} finally {
loaded = true;
}
}
/*
@Override
public Object invoke(Object self, Method thisMethod, Method proceed, Object[] args) throws Throwable {
Collection used = collection;
if(!loaded) {
loadCollection((Collection) used);
}
if(thisMethod.getName().equals("writeReplace")) {
return used;
}
return thisMethod.invoke(used, args);
}
*/
private Object writeReplace() throws ObjectStreamException {
throw new UnsupportedOperationException("that's the proxy that should call writeReplace !");
}
}