package org.neo4j.meta.model; import java.text.ParseException; import org.neo4j.graphdb.Transaction; /** * The range of a property, i.e. a properties expected value type. F.ex. it * could be a String, an integer or a {@link MetaModelClass} (which * would refer to a {@link Node} which has a relationship to that class). */ public abstract class PropertyRange extends Range<PropertyRange> { protected static void removeRange( MetaModelRestrictable<PropertyRange> owner ) { PropertyRange range = loadRange( owner ); if ( range != null ) { owner.node().removeProperty( KEY_RANGE_IMPL ); range.internalRemove( owner ); } } protected void store( MetaModelRestrictable<PropertyRange> owner ) { // MP: This isn't very good, should be in the constructor, but we can't // really trust the developer to supply the correct property instance. // So we do this internally when the MetaStructureProperty#setRange // method is called. Possible cause of bugs/errors. this.owner = owner; Transaction tx = graphDb( owner.model() ).beginTx(); try { removeRange( owner ); owner.node().setProperty( KEY_RANGE_IMPL, getClass().getName() ); internalStore( owner ); tx.success(); } finally { tx.finish(); } } protected static PropertyRange loadRange( MetaModelRestrictable<PropertyRange> owner ) { Transaction tx = graphDb( owner.model() ).beginTx(); try { String rangeType = ( String ) owner.node().getProperty( KEY_RANGE_IMPL, null ); if ( rangeType == null ) { return null; } Class<?> cls = Class.forName( rangeType ); PropertyRange result = ( PropertyRange ) cls.newInstance(); result.owner = owner; result.internalLoad( owner ); tx.success(); return result; } catch ( Exception e ) { throw new RuntimeException( e ); } finally { tx.finish(); } } protected static void setOrRemoveRange( MetaModelRestrictable<PropertyRange> owner, PropertyRange range ) { Transaction tx = graphDb( owner.model() ).beginTx(); try { PropertyRange.removeRange( owner ); if ( range != null ) { range.store( owner ); } tx.success(); } finally { tx.finish(); } } /** * Performs a string-to-object conversion to a fundamental value, f.ex. * a string, a date or a number of some sort. * @param value the plain literal value to convert into a real java object. * @return the converted value. * @throws ParseException if the {@code value} has some format error of * some sort. */ public abstract Object rdfLiteralToJavaObject( String value ) throws ParseException; /** * Performs a object-to-string conversion from a fundamental value, f.ex. * a string, a date or a number of some sort. * @param value the object to get the string representation of. * @return the string representation of {@code value}. */ public abstract String javaObjectToRdfLiteral( Object value ); /** * @return wether the expected value of this property range is a datatype, * i.e. plain fundamental values. */ public abstract boolean isDatatype(); }