/**
* Copyright (C) 2010-2017 Structr GmbH
*
* This file is part of Structr <http://structr.org>.
*
* Structr is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* Structr is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Structr. If not, see <http://www.gnu.org/licenses/>.
*/
package org.structr.neo4j.wrapper;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import org.neo4j.graphdb.DynamicLabel;
import org.neo4j.graphdb.DynamicRelationshipType;
import org.structr.api.NotFoundException;
import org.structr.api.NotInTransactionException;
import org.structr.api.graph.Direction;
import org.structr.api.graph.Label;
import org.structr.api.graph.Node;
import org.structr.api.graph.PropertyContainer;
import org.structr.api.graph.Relationship;
import org.structr.api.graph.RelationshipType;
import org.structr.neo4j.Neo4jDatabaseService;
/**
*
*/
public abstract class EntityWrapper<T extends org.neo4j.graphdb.PropertyContainer> implements PropertyContainer {
protected Map<String, Boolean> hasCache = new HashMap<>();
protected Map<String, Object> cache = new HashMap<>();
protected Neo4jDatabaseService graphDb = null;
protected boolean deleted = false;
protected T entity = null;
public EntityWrapper(final Neo4jDatabaseService graphDb, final T entity) {
this.graphDb = graphDb;
this.entity = entity;
}
@Override
public boolean hasProperty(final String name) {
assertNotDeleted();
Boolean hasProperty = hasCache.get(name);
if (hasProperty == null) {
try {
hasProperty = entity.hasProperty(name);
hasCache.put(name, hasProperty);
} catch (org.neo4j.graphdb.NotInTransactionException t) {
throw new NotInTransactionException(t);
} catch (Throwable t) {
throw new NotFoundException(t);
}
}
return hasProperty;
}
@Override
public Object getProperty(final String name) {
assertNotDeleted();
Object value = cache.get(name);
if (value == null) {
try {
value = entity.getProperty(name);
if (value != null) {
cache.put(name, value);
}
} catch (org.neo4j.graphdb.NotInTransactionException t) {
throw new NotInTransactionException(t);
} catch (Throwable t) {
throw new NotFoundException(t);
}
}
return value;
}
@Override
public Object getProperty(final String name, final Object defaultValue) {
final Object value = getProperty(name);
if (value == null) {
return defaultValue;
}
return value;
}
@Override
public void setProperty(final String name, final Object value) {
assertNotDeleted();
try {
TransactionWrapper.getCurrentTransaction().registerModified(this);
entity.setProperty(name, value);
cache.put(name, value);
hasCache.put(name, Boolean.TRUE);
} catch (org.neo4j.graphdb.NotInTransactionException t) {
throw new NotInTransactionException(t);
} catch (Throwable t) {
throw new NotFoundException(t);
}
}
@Override
public void setProperties(final Map<String, Object> values) {
for (final Entry<String, Object> entry : values.entrySet()) {
setProperty(entry.getKey(), entry.getValue());
}
}
@Override
public void removeProperty(final String name) {
assertNotDeleted();
try {
TransactionWrapper.getCurrentTransaction().registerModified(this);
entity.removeProperty(name);
cache.remove(name);
hasCache.put(name, Boolean.FALSE);
} catch (org.neo4j.graphdb.NotInTransactionException t) {
throw new NotInTransactionException(t);
} catch (Throwable t) {
throw new NotFoundException(t);
}
}
@Override
public Iterable<String> getPropertyKeys() {
assertNotDeleted();
try {
return entity.getPropertyKeys();
} catch (org.neo4j.graphdb.NotInTransactionException t) {
throw new NotInTransactionException(t);
} catch (Throwable t) {
throw new NotFoundException(t);
}
}
// ----- helper methods -----
public org.neo4j.graphdb.Node unwrap(final Node node) {
if (node instanceof NodeWrapper) {
return ((NodeWrapper)node).unwrap();
}
throw new RuntimeException("Invalid node type " + node.getClass());
}
public org.neo4j.graphdb.Relationship unwrap(final Relationship relationship) {
if (relationship instanceof RelationshipWrapper) {
return ((RelationshipWrapper)relationship).unwrap();
}
throw new RuntimeException("Invalid relationship type " + relationship.getClass());
}
public org.neo4j.graphdb.RelationshipType unwrap(final RelationshipType relationshipType) {
if (relationshipType instanceof RelationshipTypeWrapper) {
return ((RelationshipTypeWrapper)relationshipType).unwrap();
}
return DynamicRelationshipType.withName(relationshipType.name());
}
public org.neo4j.graphdb.Label unwrap(final Label label) {
if (label instanceof LabelWrapper) {
return ((LabelWrapper)label).unwrap();
}
return DynamicLabel.label(label.name());
}
public org.neo4j.graphdb.Direction unwrap(final Direction direction) {
switch (direction) {
case BOTH:
return org.neo4j.graphdb.Direction.BOTH;
case INCOMING:
return org.neo4j.graphdb.Direction.INCOMING;
case OUTGOING:
return org.neo4j.graphdb.Direction.OUTGOING;
}
return null;
}
public void clearCaches() {
cache.clear();
hasCache.clear();
}
// ----- private methods -----
private void assertNotDeleted() {
if (deleted) {
throw new NotFoundException("Entity with ID " + getId() + " has been deleted");
}
}
}