/************************************************************************ * Copyright (c) 2014-2015 IoT-Solutions e.U. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ************************************************************************/ package iot.jcypher.graph; import iot.jcypher.concurrency.Locking; import iot.jcypher.database.IDBAccess; import iot.jcypher.query.result.JcError; import iot.jcypher.query.result.util.ResultHandler; import iot.jcypher.transaction.ITransaction; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; public class Graph { private ResultHandler resultHandler; private SyncState syncState; Graph(ResultHandler resultHandler) { super(); this.resultHandler = resultHandler; } /** * create an empty graph * @param dbAccess the database on which to perform updates of the graph * @return the empty graph model */ public static Graph create(IDBAccess dbAccess) { ResultHandler rh = new ResultHandler(dbAccess); Graph ret = rh.getGraph(); ret.setSyncState(SyncState.NEW); return ret; } /** * Set the locking strategy (e.g. Locking.OPTIMISTIC, ...). * @param locking * @return the Graph (self) to allow fluent method concatenation. */ public Graph setLockingStrategy(Locking locking) { this.resultHandler.setLockingStrategy(locking); return this; } /** * create a node in the graph * @return a GrNode */ public GrNode createNode() { return this.resultHandler.getLocalElements().createNode(); } /** * create a relation in the graph * @param type * @param startNode * @param endNode * @return a GrRelation */ public GrRelation createRelation(String type, GrNode startNode, GrNode endNode) { return this.resultHandler.getLocalElements().createRelation(type, startNode, endNode); } /** * @return true, if the graph contains new or modified elements, * or if elements of the graph were removed. */ public boolean isModified() { if (this.syncState == SyncState.NEW) return !this.resultHandler.getLocalElements().isEmpty(); return this.syncState != SyncState.SYNC; } /** * Update the underlying database with changes made on the graph * @return a list of errors, which is empty if no errors occurred */ public List<JcError> store() { return store(null); } /** * Update the underlying database with changes made on the graph * @return a list of errors, which is empty if no errors occurred */ List<JcError> store(Map<Long, Integer> elementVersionsMap) { List<JcError> ret = null; ITransaction txToClose = null; try { if (isModified()) { txToClose = this.resultHandler.createLockingTxIfNeeded(); ret = this.resultHandler.store(elementVersionsMap); } else ret = Collections.emptyList(); } finally { if (txToClose != null) { // we have created the transaction if (ret == null) ret = new ArrayList<JcError>(); ret.addAll(txToClose.close()); } } return ret; } SyncState getSyncState() { return syncState; } void setSyncState(SyncState syncState) { this.syncState = syncState; } void setDBAccess(IDBAccess dbAccess) { this.resultHandler.setDbAccess(dbAccess); } }