/* * Copyright (c) 2011, Niclas Hedhman. All Rights Reserved. * * 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.qi4j.entitystore.neo4j; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.neo4j.graphdb.Direction; import org.neo4j.graphdb.DynamicRelationshipType; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Relationship; import org.qi4j.api.entity.EntityReference; import org.qi4j.spi.entity.NamedAssociationState; import org.qi4j.spi.entity.association.NamedEntityReference; public class NeoNamedAssociationState implements NamedAssociationState { static final String COUNT = "count"; private final Node underlyingNode; private final NeoEntityState entity; private final NeoEntityStoreUnitOfWork uow; NeoNamedAssociationState( NeoEntityStoreUnitOfWork uow, NeoEntityState entity, Node node ) { this.uow = uow; this.entity = entity; this.underlyingNode = node; } public void put( String name, EntityReference entityReference ) { Node entityNode = uow.getEntityStateNode( entityReference ); DynamicRelationshipType relationshipType = DynamicRelationshipType.withName( name ); Relationship relationship = underlyingNode.getSingleRelationship( relationshipType, Direction.OUTGOING ); if( relationship != null ) { // It already exist, do nothing. return; } underlyingNode.createRelationshipTo( entityNode, relationshipType ); incrementCount(); entity.setUpdated(); } public boolean containsKey( String name ) { DynamicRelationshipType relationshipType = DynamicRelationshipType.withName( name ); Relationship relationship = underlyingNode.getSingleRelationship( relationshipType, Direction.OUTGOING ); return relationship != null; } public String contains( EntityReference entityReference ) { Node entityNode = uow.getEntityStateNode( entityReference ); for( Relationship rel : underlyingNode.getRelationships( Direction.OUTGOING ) ) { if( rel.getEndNode().equals( entityNode ) ) { return rel.getType().name(); } } return null; } public int count() { return (Integer) underlyingNode.getProperty( COUNT ); } public EntityReference get( String name ) { DynamicRelationshipType relationshipType = DynamicRelationshipType.withName( name ); Relationship relationship = underlyingNode.getSingleRelationship( relationshipType, Direction.OUTGOING ); if( relationship == null ) { return null; } String id = (String) relationship.getEndNode().getProperty( NeoEntityState.ENTITY_ID ); return new EntityReference( id ); } @Override public Iterable<String> names() { ArrayList<String> result = new ArrayList<String>(); for( Relationship relationship : underlyingNode.getRelationships( Direction.OUTGOING ) ) { result.add( relationship.getType().name() ); } return result; } public boolean remove( String name ) { DynamicRelationshipType relationshipType = DynamicRelationshipType.withName( name ); Relationship relationship = underlyingNode.getSingleRelationship( relationshipType, Direction.OUTGOING ); if( relationship != null ) { relationship.delete(); decrementCount(); entity.setUpdated(); } return true; } public Iterator<NamedEntityReference> iterator() { List<NamedEntityReference> list = new ArrayList<NamedEntityReference>( count() ); for( Relationship rel : underlyingNode.getRelationships( Direction.OUTGOING ) ) { String name = rel.getType().name(); String id = (String) rel.getEndNode().getProperty( NeoEntityState.ENTITY_ID ); list.add( new NamedEntityReference( name, new EntityReference( id ) ) ); } return list.iterator(); } private void incrementCount() { int count = (Integer) underlyingNode.getProperty( "count" ); underlyingNode.setProperty( COUNT, count + 1 ); } private void decrementCount() { int count = (Integer) underlyingNode.getProperty( "count" ); underlyingNode.setProperty( COUNT, --count ); } }