Java tutorial
/** * Copyright 2011 the original author or authors. * * 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 org.springframework.data.neo4j.support; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.neo4j.graphdb.*; import org.neo4j.graphdb.index.Index; import org.neo4j.graphdb.index.IndexManager; import org.neo4j.helpers.collection.ClosableIterable; import org.neo4j.index.impl.lucene.LuceneIndexImplementation; import org.neo4j.kernel.AbstractGraphDatabase; import org.springframework.core.convert.ConversionService; import org.springframework.data.neo4j.annotation.Indexed; import org.springframework.data.neo4j.core.*; import javax.transaction.Status; import javax.transaction.SystemException; import javax.transaction.TransactionManager; import javax.validation.Validator; import java.util.Map; /** * Mediator class for the graph related services like the {@link GraphDatabaseService}, the used * {@link org.springframework.data.neo4j.core.TypeRepresentationStrategy}, entity instantiators for nodes and relationships as well as a spring conversion service. * * It delegates the appropriate methods to those services. The services are not intended to be accessible from outside. * * @author Michael Hunger * @since 13.09.2010 */ public class GraphDatabaseContext { private static final Log log = LogFactory.getLog(GraphDatabaseContext.class); public static final String DEFAULT_NODE_INDEX_NAME = "node"; public static final String DEFAULT_RELATIONSHIP_INDEX_NAME = "relationship"; private GraphDatabaseService graphDatabaseService; private ConversionService conversionService; private Validator validator; private NodeTypeRepresentationStrategy nodeTypeRepresentationStrategy; private RelationshipTypeRepresentationStrategy relationshipTypeRepresentationStrategy; public <S extends PropertyContainer, T extends GraphBacked<S>> Index<S> getIndex(Class<T> type) { return getIndex(type, null); } public <S extends PropertyContainer, T extends GraphBacked<S>> Index<S> getIndex(Class<T> type, String indexName) { return getIndex(type, indexName, false); } public <S extends PropertyContainer, T extends GraphBacked<S>> Index<S> getIndex(Class<T> type, String indexName, boolean fullText) { if (indexName == null) indexName = Indexed.Name.get(type); Map<String, String> config = fullText ? LuceneIndexImplementation.FULLTEXT_CONFIG : null; if (NodeBacked.class.isAssignableFrom(type)) return (Index<S>) getIndexManager().forNodes(indexName, config); if (RelationshipBacked.class.isAssignableFrom(type)) return (Index<S>) getIndexManager().forRelationships(indexName, config); throw new IllegalArgumentException( "Wrong index type supplied: " + type + " expected Node- or Relationship-Entity"); } /** * @return true if a transaction manager is available and a transaction is currently running */ public boolean transactionIsRunning() { if (!(graphDatabaseService instanceof AbstractGraphDatabase)) { return true; // assume always running tx (e.g. for REST or other remotes) } try { final TransactionManager txManager = ((AbstractGraphDatabase) graphDatabaseService).getConfig() .getTxModule().getTxManager(); return txManager.getStatus() != Status.STATUS_NO_TRANSACTION; } catch (SystemException e) { log.error("Error accessing TransactionManager", e); return false; } } public <T extends GraphBacked<? extends PropertyContainer>> ClosableIterable<T> findAll( final Class<T> entityClass) { return getTypeRepresentationStrategy(entityClass).findAll(entityClass); } public <T extends GraphBacked<? extends PropertyContainer>> long count(final Class<T> entityClass) { return getTypeRepresentationStrategy(entityClass).count(entityClass); } public <S extends PropertyContainer, T extends GraphBacked<S>> T createEntityFromStoredType(S state) { return getTypeRepresentationStrategy(state).createEntity(state); } public <S extends PropertyContainer, T extends GraphBacked<S>> T createEntityFromState(S state, Class<T> type) { if (state == null) throw new IllegalArgumentException("state has to be either a Node or Relationship, not null"); return getTypeRepresentationStrategy(state, type).createEntity(state, type); } public <S extends PropertyContainer, T extends GraphBacked<S>> T projectTo(GraphBacked<S> entity, Class<T> targetType) { S state = entity.getPersistentState(); return getTypeRepresentationStrategy(state, targetType).projectEntity(state, targetType); } public <S extends PropertyContainer, T extends GraphBacked<S>> void postEntityCreation(S node, Class<T> entityClass) { getTypeRepresentationStrategy(node, entityClass).postEntityCreation(node, entityClass); } public void removeNodeEntity(NodeBacked entity) { Node node = entity.getPersistentState(); if (node == null) return; nodeTypeRepresentationStrategy.preEntityRemoval(node); for (Relationship relationship : node.getRelationships()) { removeRelationship(relationship); } removeFromIndexes(node); node.delete(); } public void removeRelationshipEntity(RelationshipBacked entity) { Relationship relationship = entity.getPersistentState(); if (relationship == null) return; removeRelationship(relationship); } private void removeRelationship(Relationship relationship) { relationshipTypeRepresentationStrategy.preEntityRemoval(relationship); removeFromIndexes(relationship); relationship.delete(); } private void removeFromIndexes(Node node) { IndexManager indexManager = getIndexManager(); for (String indexName : indexManager.nodeIndexNames()) { indexManager.forNodes(indexName).remove(node); } } private void removeFromIndexes(Relationship relationship) { IndexManager indexManager = getIndexManager(); for (String indexName : indexManager.relationshipIndexNames()) { indexManager.forRelationships(indexName).remove(relationship); } } private IndexManager getIndexManager() { return graphDatabaseService.index(); } @SuppressWarnings("unchecked") private <T extends GraphBacked<? extends PropertyContainer>> TypeRepresentationStrategy<?, T> getTypeRepresentationStrategy( Class<T> type) { if (NodeBacked.class.isAssignableFrom(type)) { return (TypeRepresentationStrategy<?, T>) nodeTypeRepresentationStrategy; } else if (RelationshipBacked.class.isAssignableFrom(type)) { return (TypeRepresentationStrategy<?, T>) relationshipTypeRepresentationStrategy; } throw new IllegalArgumentException("Type is not NodeBacked nor RelationshipBacked."); } @SuppressWarnings("unchecked") private <S extends PropertyContainer, T extends GraphBacked<S>> TypeRepresentationStrategy<S, T> getTypeRepresentationStrategy( S state, Class<T> type) { if (state instanceof Node && NodeBacked.class.isAssignableFrom(type)) { return (TypeRepresentationStrategy<S, T>) nodeTypeRepresentationStrategy; } else if (state instanceof Relationship && RelationshipBacked.class.isAssignableFrom(type)) { return (TypeRepresentationStrategy<S, T>) relationshipTypeRepresentationStrategy; } throw new IllegalArgumentException("Type " + type + " is not NodeBacked nor RelationshipBacked."); } @SuppressWarnings("unchecked") private <S extends PropertyContainer, T extends GraphBacked<S>> TypeRepresentationStrategy<S, T> getTypeRepresentationStrategy( S state) { if (state instanceof Node) { return (TypeRepresentationStrategy<S, T>) nodeTypeRepresentationStrategy; } else if (state instanceof Relationship) { return (TypeRepresentationStrategy<S, T>) relationshipTypeRepresentationStrategy; } throw new IllegalArgumentException("Type is not NodeBacked nor RelationshipBacked."); } /** * Delegates to {@link GraphDatabaseService} */ public Node createNode() { return graphDatabaseService.createNode(); } /** * Delegates to {@link GraphDatabaseService} */ public Node getNodeById(final long nodeId) { return graphDatabaseService.getNodeById(nodeId); } /** * Delegates to {@link GraphDatabaseService} */ public Node getReferenceNode() { return graphDatabaseService.getReferenceNode(); } /** * Delegates to {@link GraphDatabaseService} */ public Iterable<? extends Node> getAllNodes() { return graphDatabaseService.getAllNodes(); } /** * Delegates to {@link GraphDatabaseService} */ public Transaction beginTx() { return graphDatabaseService.beginTx(); } /** * Delegates to {@link GraphDatabaseService} */ public Relationship getRelationshipById(final long id) { return graphDatabaseService.getRelationshipById(id); } public GraphDatabaseService getGraphDatabaseService() { return graphDatabaseService; } public void setGraphDatabaseService(GraphDatabaseService graphDatabaseService) { this.graphDatabaseService = graphDatabaseService; } public NodeTypeRepresentationStrategy getNodeTypeRepresentationStrategy() { return nodeTypeRepresentationStrategy; } public void setNodeTypeRepresentationStrategy(NodeTypeRepresentationStrategy nodeTypeRepresentationStrategy) { this.nodeTypeRepresentationStrategy = nodeTypeRepresentationStrategy; } public RelationshipTypeRepresentationStrategy getRelationshipTypeRepresentationStrategy() { return relationshipTypeRepresentationStrategy; } public void setRelationshipTypeRepresentationStrategy( RelationshipTypeRepresentationStrategy relationshipTypeRepresentationStrategy) { this.relationshipTypeRepresentationStrategy = relationshipTypeRepresentationStrategy; } public ConversionService getConversionService() { return conversionService; } public void setConversionService(ConversionService conversionService) { this.conversionService = conversionService; } public Validator getValidator() { return validator; } public void setValidator(Validator validatorFactory) { this.validator = validatorFactory; } }