
org.datanucleus.store.neo4j.fieldmanager.FetchFieldManager Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of datanucleus-neo4j Show documentation
Show all versions of datanucleus-neo4j Show documentation
Plugin providing persistence to Neo4j graph datastores.
The newest version!
/**********************************************************************
Copyright (c) 2012 Andy Jefferson and others. 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.
Contributors:
...
**********************************************************************/
package org.datanucleus.store.neo4j.fieldmanager;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Map.Entry;
import org.datanucleus.ClassLoaderResolver;
import org.datanucleus.ExecutionContext;
import org.datanucleus.exceptions.NucleusDataStoreException;
import org.datanucleus.exceptions.NucleusException;
import org.datanucleus.exceptions.NucleusUserException;
import org.datanucleus.metadata.AbstractClassMetaData;
import org.datanucleus.metadata.AbstractMemberMetaData;
import org.datanucleus.metadata.FieldPersistenceModifier;
import org.datanucleus.metadata.FieldRole;
import org.datanucleus.metadata.MetaDataUtils;
import org.datanucleus.metadata.RelationType;
import org.datanucleus.query.QueryUtils;
import org.datanucleus.state.ObjectProvider;
import org.datanucleus.store.fieldmanager.AbstractFetchFieldManager;
import org.datanucleus.store.fieldmanager.FieldManager;
import org.datanucleus.store.neo4j.Neo4jStoreManager;
import org.datanucleus.store.neo4j.Neo4jUtils;
import org.datanucleus.store.schema.table.MemberColumnMapping;
import org.datanucleus.store.schema.table.Table;
import org.datanucleus.store.types.SCOUtils;
import org.datanucleus.store.types.converters.MultiColumnConverter;
import org.datanucleus.store.types.converters.TypeConverter;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.PropertyContainer;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.RelationshipType;
/**
* Field Manager for retrieving values from Neo4j.
*/
public class FetchFieldManager extends AbstractFetchFieldManager
{
protected Table table;
protected PropertyContainer propObj;
boolean embedded = false;
public FetchFieldManager(ObjectProvider op, PropertyContainer node, Table table)
{
super(op);
this.table = table;
this.propObj = node;
if (ec.getOwnersForEmbeddedObjectProvider(op) != null)
{
embedded = true;
}
}
public FetchFieldManager(ExecutionContext ec, PropertyContainer node, AbstractClassMetaData cmd, Table table)
{
super(ec, cmd);
this.table = table;
this.propObj = node;
if (node == null)
{
throw new NucleusException("Attempt to create FetchFieldManager for " + op + " with null Neo4j Node!" +
" Generate a testcase that reproduces this and raise an issue");
}
}
protected MemberColumnMapping getColumnMapping(int fieldNumber)
{
return table.getMemberColumnMappingForMember(cmd.getMetaDataForManagedMemberAtAbsolutePosition(fieldNumber));
}
/* (non-Javadoc)
* @see org.datanucleus.store.fieldmanager.AbstractFieldManager#fetchBooleanField(int)
*/
@Override
public boolean fetchBooleanField(int fieldNumber)
{
return (Boolean)propObj.getProperty(getColumnMapping(fieldNumber).getColumn(0).getName());
}
/* (non-Javadoc)
* @see org.datanucleus.store.fieldmanager.AbstractFieldManager#fetchByteField(int)
*/
@Override
public byte fetchByteField(int fieldNumber)
{
return (Byte)propObj.getProperty(getColumnMapping(fieldNumber).getColumn(0).getName());
}
/* (non-Javadoc)
* @see org.datanucleus.store.fieldmanager.AbstractFieldManager#fetchCharField(int)
*/
@Override
public char fetchCharField(int fieldNumber)
{
return (Character)propObj.getProperty(getColumnMapping(fieldNumber).getColumn(0).getName());
}
/* (non-Javadoc)
* @see org.datanucleus.store.fieldmanager.AbstractFieldManager#fetchDoubleField(int)
*/
@Override
public double fetchDoubleField(int fieldNumber)
{
return (Double)propObj.getProperty(getColumnMapping(fieldNumber).getColumn(0).getName());
}
/* (non-Javadoc)
* @see org.datanucleus.store.fieldmanager.AbstractFieldManager#fetchFloatField(int)
*/
@Override
public float fetchFloatField(int fieldNumber)
{
return (Float)propObj.getProperty(getColumnMapping(fieldNumber).getColumn(0).getName());
}
/* (non-Javadoc)
* @see org.datanucleus.store.fieldmanager.AbstractFieldManager#fetchIntField(int)
*/
@Override
public int fetchIntField(int fieldNumber)
{
return (Integer)propObj.getProperty(getColumnMapping(fieldNumber).getColumn(0).getName());
}
/* (non-Javadoc)
* @see org.datanucleus.store.fieldmanager.AbstractFieldManager#fetchLongField(int)
*/
@Override
public long fetchLongField(int fieldNumber)
{
return (Long)propObj.getProperty(getColumnMapping(fieldNumber).getColumn(0).getName());
}
/* (non-Javadoc)
* @see org.datanucleus.store.fieldmanager.AbstractFieldManager#fetchShortField(int)
*/
@Override
public short fetchShortField(int fieldNumber)
{
return (Short)propObj.getProperty(getColumnMapping(fieldNumber).getColumn(0).getName());
}
/* (non-Javadoc)
* @see org.datanucleus.store.fieldmanager.AbstractFieldManager#fetchStringField(int)
*/
@Override
public String fetchStringField(int fieldNumber)
{
String propName = getColumnMapping(fieldNumber).getColumn(0).getName();
return propObj.hasProperty(propName) ? (String)propObj.getProperty(propName) : null;
}
/* (non-Javadoc)
* @see org.datanucleus.store.fieldmanager.AbstractFieldManager#fetchObjectField(int)
*/
@Override
public Object fetchObjectField(int fieldNumber)
{
AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(fieldNumber);
if (mmd.getPersistenceModifier() != FieldPersistenceModifier.PERSISTENT)
{
return op.provideField(fieldNumber);
}
ClassLoaderResolver clr = ec.getClassLoaderResolver();
RelationType relationType = mmd.getRelationType(clr);
if (relationType != RelationType.NONE)
{
if (MetaDataUtils.getInstance().isMemberEmbedded(ec.getMetaDataManager(), clr, mmd, relationType, null))
{
// Embedded field
if (RelationType.isRelationSingleValued(relationType))
{
// Embedded PC object
AbstractClassMetaData embcmd = ec.getMetaDataManager().getMetaDataForClass(mmd.getType(), clr);
if (embcmd == null)
{
throw new NucleusUserException("Field " + mmd.getFullFieldName() + " marked as embedded but no such metadata");
}
// TODO Cater for null (use embmd.getNullIndicatorColumn/Value)
// TODO Cater for inherited embedded objects (discriminator)
List embMmds = new ArrayList();
embMmds.add(mmd);
ObjectProvider embOP = ec.getNucleusContext().getObjectProviderFactory().newForEmbedded(ec, embcmd, op, fieldNumber);
FieldManager ffm = new FetchEmbeddedFieldManager(embOP, propObj, embMmds, table);
embOP.replaceFields(embcmd.getAllMemberPositions(), ffm);
return embOP.getObject();
}
else if (RelationType.isRelationMultiValued(relationType))
{
throw new NucleusUserException("Dont currently support embedded multivalued field : " + mmd.getFullFieldName());
}
}
}
return fetchNonEmbeddedObjectField(mmd, relationType, clr);
}
protected Object fetchNonEmbeddedObjectField(AbstractMemberMetaData mmd, RelationType relationType, ClassLoaderResolver clr)
{
int fieldNumber = mmd.getAbsoluteFieldNumber();
MemberColumnMapping mapping = getColumnMapping(fieldNumber);
boolean optional = false;
if (Optional.class.isAssignableFrom(mmd.getType()))
{
if (relationType != RelationType.NONE)
{
relationType = RelationType.ONE_TO_ONE_UNI;
}
optional = true;
}
if (RelationType.isRelationSingleValued(relationType))
{
if (!(propObj instanceof Node))
{
throw new NucleusUserException("Object " + op + " is mapped to a Relationship. Not yet supported");
}
Node node = (Node)propObj;
Object value = processSingleValuedRelationForNode(mmd, relationType, ec, clr, node);
return optional ? (value!=null ? Optional.of(value) : Optional.empty()) : value;
}
else if (RelationType.isRelationMultiValued(relationType))
{
if (!(propObj instanceof Node))
{
// Any object mapped as a Relationship cannot have multi-value relations, only a source and target
throw new NucleusUserException("Object " + op + " is mapped to a Relationship but has field " +
mmd.getFullFieldName() + " which is multi-valued. This is illegal");
}
Node node = (Node)propObj;
return processMultiValuedRelationForNode(mmd, relationType, ec, clr, node);
}
String propName = mapping.getColumn(0).getName(); // TODO Support multicol members
if (!propObj.hasProperty(propName))
{
return optional ? Optional.empty() : null;
}
Object value = propObj.getProperty(propName);
if (mmd.isSerialized())
{
if (value instanceof String)
{
TypeConverter conv = ec.getTypeManager().getTypeConverterForType(Serializable.class, String.class);
return conv.toMemberType((String) value);
}
throw new NucleusUserException("Field " + mmd.getFullFieldName() + " has a serialised value," +
" but we only support String serialisation and is " + value.getClass().getName());
}
Object returnValue = null;
if (mapping.getTypeConverter() != null)
{
TypeConverter conv = mapping.getTypeConverter();
if (mapping.getNumberOfColumns() > 1)
{
boolean isNull = true;
Object valuesArr = null;
Class[] colTypes = ((MultiColumnConverter)conv).getDatastoreColumnTypes();
if (colTypes[0] == int.class)
{
valuesArr = new int[mapping.getNumberOfColumns()];
}
else if (colTypes[0] == long.class)
{
valuesArr = new long[mapping.getNumberOfColumns()];
}
else if (colTypes[0] == double.class)
{
valuesArr = new double[mapping.getNumberOfColumns()];
}
else if (colTypes[0] == float.class)
{
valuesArr = new double[mapping.getNumberOfColumns()];
}
else if (colTypes[0] == String.class)
{
valuesArr = new String[mapping.getNumberOfColumns()];
}
// TODO Support other types
else
{
valuesArr = new Object[mapping.getNumberOfColumns()];
}
for (int i=0;i rels = node.getRelationships(type);
if (rels != null)
{
Iterator relIter = rels.iterator();
while (relIter.hasNext())
{
Relationship rel = relIter.next();
String memberName = (String) rel.getProperty(propNameKey);
if (memberName != null && memberName.equals(propNameValue))
{
Node relNode = rel.getOtherNode(node);
return Neo4jUtils.getObjectForPropertyContainer(relNode, Neo4jUtils.getClassMetaDataForPropertyContainer(relNode, ec, relCmd), ec, false);
}
}
}
return null;
}
protected Object processMultiValuedRelationForNode(AbstractMemberMetaData mmd, RelationType relationType, ExecutionContext ec, ClassLoaderResolver clr, Node node)
{
if (mmd.hasCollection())
{
Collection
© 2015 - 2025 Weber Informatics LLC | Privacy Policy