package fr.inria.atlanmod.neo4emf.drivers.impl;
/**
* Copyright (c) 2013 Atlanmod INRIA LINA Mines Nantes
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Atlanmod INRIA LINA Mines Nantes - initial API and implementation
* Descritpion ! To come
* @author Amine BENELALLAM
* */
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.neo4j.graphdb.DynamicRelationshipType;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.RelationshipType;
import fr.inria.atlanmod.neo4emf.INeo4emfObject;
import fr.inria.atlanmod.neo4emf.INeo4emfResource;
import fr.inria.atlanmod.neo4emf.drivers.ILoader;
import fr.inria.atlanmod.neo4emf.drivers.IPersistenceManager;
import fr.inria.atlanmod.neo4emf.drivers.IPersistenceService;
import fr.inria.atlanmod.neo4emf.drivers.IPersistenceServiceFactory;
import fr.inria.atlanmod.neo4emf.drivers.IProxyManager;
import fr.inria.atlanmod.neo4emf.drivers.ISerializer;
import fr.inria.atlanmod.neo4emf.drivers.NEConfiguration;
import fr.inria.atlanmod.neo4emf.impl.Neo4emfObject;
import fr.inria.atlanmod.neo4emf.impl.Neo4emfResource;
import fr.inria.atlanmod.neo4emf.resourceUtil.Neo4emfResourceUtil;
public class PersistenceManager implements IPersistenceManager {
/**
* the persistence Backend {@link PersistenceService}
*/
protected IPersistenceService persistenceService;
/**
* The loader and eObjects builder {@link Loader}
*/
protected ILoader loader;
/**
* Serializer and nodes converter {@link Serializer}
*/
protected ISerializer serializer;
/**
* The resource {@link Neo4emfResource}
*/
protected INeo4emfResource resource;
/**
* The loaded elements manager {@link ProxyManager}
*/
protected IProxyManager proxyManager;
private int sessionId = 0;
/**
* Global constructor
*
* @param neo4emfResource
* {@link Neo4emfResource}
* @param storeDirectory
* {@link String}
* @param eRef2relType
* {@link Map}
*/
public PersistenceManager(INeo4emfResource neo4emfResource,
NEConfiguration configuration) {
this.resource = neo4emfResource;
this.persistenceService = IPersistenceServiceFactory.eINSTANCE
.createPersistenceService(configuration);
this.serializer = new Serializer(this,Integer.parseInt(configuration.options().get("transaction_count")));
this.proxyManager = new ProxyManager();
this.loader = new Loader(this);
}
@SuppressWarnings("unchecked")
@Override
public void save(Map<?, ?> options) {
try {
this.serializer.save((Map<String, Object>) options);
} catch (Exception e) {
shutdown();
e.printStackTrace();
}
}
@Override
public void load() {
load(null);
}
@Override
public void load(Map<?, ?> options) {
try {
loader.load(options);
} catch (Exception e) {
shutdown();
e.printStackTrace();
}
}
@Override
public void save() {
serializer.save(null);
}
@Override
public NETransaction createTransaction() {
return persistenceService.createTransaction();
}
@Override
public void cleanIndexes() {
persistenceService.cleanIndexes();
}
@Override
public void shutdown() {
persistenceService.shutdown();
}
//@Override
public Node getNodeById(EObject eObj) {
assert ((INeo4emfObject) eObj).getNodeId() >= 0 : "nodeId is > -1";
Node result = persistenceService.getNodeById(((INeo4emfObject) eObj)
.getNodeId());
if (result == null) {
throw new NullPointerException(" Cannot find the node ");
} else {
return result;
}
}
// @Override
public Node getAttributeNodeById(EObject eObj) {
assert ((INeo4emfObject)eObj).getAttributeNodeId() > -1 : "attribute node id is > -1";
Node result = persistenceService.getNodeById(((INeo4emfObject)eObj).getAttributeNodeId());
return result;
}
// @Override
public Node getAttributeNode(Node n) {
// Strange to have node here
Node result = persistenceService.getAttributeNode(n);
return result;
}
// @Override
public List<Relationship> getTmpRelationships() {
return persistenceService.getTmpRelationships();
}
// @Override
// public List<Node> getTmpNodes() {
// return persistenceService.getTmpNodes();
// }
//
// @Override
public void flushTmpRelationships(List<Relationship> rels) {
persistenceService.flushTmpRelationships(rels);
}
// @Override
// public Node createNodefromEObject(EObject eObject) {
// return persistenceService.createNodeFromEObject(eObject,false);
// }
// @Override
// public Node createNodefromEObject(EObject eObject, boolean isTemporary) {
// Node n = persistenceService.createNodeFromEObject(eObject,isTemporary);
// ((INeo4emfObject)eObject).setNodeId(n.getId());
// proxyManager.putToProxy((INeo4emfObject)eObject);
// return n;
// }
// @Override
public void deleteNodeFromEObject(INeo4emfObject eObject) {
persistenceService.deleteNodeFromEObject(eObject);
}
// @Override
public Node createAttributeNodeForEObject(INeo4emfObject eObject) {
return persistenceService.createAttributeNodeForEObject(eObject);
}
// @Override
public Relationship createAddLinkRelationship(INeo4emfObject from, INeo4emfObject to, EReference ref) {
// FIXME see if it is good (case of an old object that has references to an other one
// which hasn't been yet created). If this reference is not bidirectionnal there will be
// a problem
if(from.getSessionId() >= 0 && to.getSessionId() == -1 && ref.getEOpposite() == null) {
Relationship r = persistenceService.createAddLinkRelationship(from, to, ref);
if(r != null) {
to.setSessionId(sessionId);
}
}
else if(from.getSessionId() >= 0 && to.getSessionId() >= 0) {
return persistenceService.createAddLinkRelationship(from, to, ref);
}
return null;
}
// @Override
public Relationship createRemoveLinkRelationship(INeo4emfObject from, INeo4emfObject to, EReference ref) {
return persistenceService.createRemoveLinkRelationship(from, to, ref);
}
// @Override
public Relationship createDeleteRelationship(INeo4emfObject obj) {
return persistenceService.createDeleteRelationship(obj);
}
//@Override
public RelationshipType getRelTypefromERef(int classID, int referenceID) {
return persistenceService.getRelationshipFor(classID, referenceID);
}
public Node createNodefromEObject(INeo4emfObject eObject, boolean isTemporary) {
Node n = persistenceService.createNodeFromEObject(eObject,isTemporary);
eObject.setNodeId(n.getId());
eObject.setSessionId(sessionId);
proxyManager.putToProxy((INeo4emfObject)eObject);
return n;
}
public void createLink(INeo4emfObject from, INeo4emfObject to, EReference ref) {
persistenceService.createLink(from,to,ref);
}
public void removeLink(INeo4emfObject from, INeo4emfObject to, EReference ref) {
persistenceService.removeLink(from,to,ref);
}
//@Override
public List<Node> getAllRootNodes() {
return persistenceService.getAllRootNodes();
}
@Override
public void addObjectsToContents(List<INeo4emfObject> objects) {
resource.getContents().addAll(objects);
}
//@Override
public String getNodeType(Node n) {
return persistenceService.getNodeType(n);
}
//@Override
public String getNodeContainingPackage(Node n) {
return persistenceService.getContainingPackage(n);
}
@Override
public void fetchAttributes(EObject obj) {
Node node = getNodeById(obj);
// TODO find a way to avoid that call when appropriate (maybe
// if there is a non changed changelog)
Node attributeNode = null;
if(((Neo4emfObject)obj).getAttributeNodeId() > -1) {
attributeNode = getAttributeNodeById(obj);
// ((INeo4emfObject)obj).loadAllAttributesFrom(attributeNode);
// return;
}
// ((INeo4emfObject)obj).loadAllAttributesFrom(node);
loader.fetchAttributes(obj,node,attributeNode);
}
@Override
public void getOnDemand(EObject obj, int featureId) {
try {
EClass eClass = obj.eClass();
EStructuralFeature feature = eClass.getEStructuralFeature(featureId);
EClass parent = feature.getEContainingClass();
// EPackage ePackage = eClass.getEPackage();
// RelationshipType relationship = getRelTypefromERef(ePackage.getNsURI(),eClass.getClassifierID(), featureId);
RelationshipType relationship = null;
if ( relationship == null ) {
//throw new NullPointerException(" Cannot find the relationship ");
String stri = Neo4emfResourceUtil.formatRelationshipName(parent,feature);
relationship = DynamicRelationshipType.withName(stri);
}
List <Node> nodes= persistenceService.getNodesOnDemand(((INeo4emfObject)obj).getNodeId(),
relationship);
List<Node> addLinkNodes = persistenceService.getAddLinkNodesOnDemand(((INeo4emfObject)obj).getNodeId(), relationship);
List<Node> removeLinkNodes = persistenceService.getRemoveLinkNodesOnDemand(((INeo4emfObject)obj).getNodeId(), relationship);
nodes.addAll(addLinkNodes);
nodes.removeAll(removeLinkNodes);
loader.getObjectsOnDemand(obj, featureId,getNodeById(obj), nodes);
}catch(Exception e){
shutdown();
e.printStackTrace();
}
}
@Override
public EObject getContainerOnDemand(EObject eObject, int featureId) {
EObject eResult = null;
try {
List<Node> singleNode = persistenceService.getNodesOnDemand(
((INeo4emfObject) eObject).getNodeId(),
getRelTypefromERef(eObject.eClass().getClassifierID(),
featureId));
eResult = loader.getContainerOnDemand(eObject, featureId,
getNodeById(eObject), singleNode.get(0));
} catch (Exception e) {
shutdown();
e.printStackTrace();
}
return eResult;
}
public boolean isRootNode(Node node) {
return persistenceService.isRootNode(node);
}
@Override
public EList<INeo4emfObject> getAllInstancesOfType(EClass eClass) {
EList<EClass> classesList = ((Loader) loader).subClassesOf(eClass);
EList<INeo4emfObject> allInstances = new BasicEList<INeo4emfObject>();
List<Node> nodeList = new ArrayList<Node>();
try {
for (EClass eCls : classesList) {
nodeList = this.persistenceService.getAllNodesOfType(eCls);
if (nodeList.isEmpty()) {
continue;
}
allInstances
.addAll(this.loader.getAllInstances(eCls, nodeList));
}
} catch (Exception e) {
shutdown();
e.printStackTrace();
}
return allInstances;
}
public INeo4emfResource getResource() {
return resource;
}
@Override
public INeo4emfObject getObjectFromProxy(EClass eClassifier, Node n) {
return proxyManager.getObjectFromProxy(eClassifier, n.getId());
}
/**
* {@link IPersistenceManager#getProxyManager()}
*/
@Override
public IProxyManager getProxyManager() {
return proxyManager;
}
public void startNewSession() {
sessionId++;
}
}