<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [ <!ENTITY copyrightDates '1999,2000,2001'> <!ENTITY % METACOSM SYSTEM "../en.metacosm.ent"> %METACOSM; ]> <article lang="EN"> <articleinfo> <title>RFC - Properties</title> <corpauthor>&author;</corpauthor> <revhistory> <revision> <revnumber>M1</revnumber> <date>July, 15th 2001</date> <revremark>Conversion to DocBook SGML. Field definition and interface. StringKey replaced by String.</revremark> </revision> <revision> <revnumber>0.1</revnumber> <date>April, 30th 2001</date> <authorinitials>Ruffy</authorinitials> <revremark>Based on a meeting report</revremark> </revision> </revhistory> <abstract> <simpara>This document describes Properties as used in Entity-RFC.</simpara> </abstract> </articleinfo> &license; &project; <sect1> <title>Definition</title> <para>Properties describe a particular aspect of an Entity. A Property is defined by a name and a value, which can be limited to some field. There are two main types of Properties: numeric ones and non-numeric ones.</para> <note><para>we haven't found some useful example where a 'null' value could be useful, so 'null' value is tested against.</para></note> <para>Implementation: <programlisting> abstract class Property { Property( String name) throws IllegalArgument; // IllegalArgument if null value final String getName(); Object getValue(); } </programlisting> </para> </sect1> <sect1> <title>Numeric Properties</title> <para>A Numeric Properties contains a numeric value.</para> <para>Idea 1: we mainly need numeric values only defined in some field (for example, [3,18] for the sum of 3 dices).</para> <para>Idea 2: the field could be defined with intervals, sets or regular expressions.</para> <para>The value of a Numeric Property is always limited to some field. We couldn't find useful examples for using sets or regular expressions (moreover the last ones are complex to implement and to use). So we'll only use intervals. We couldn't find useful examples for using intersections, unions or exclusions of intervals to define the field. So we'll only use one interval. The interval should contain one or more numbers.</para> <para>If no interval is given, the interval with the min and max values for this value type are used.</para> <para>If a interval is given (a min and a max values), both values should be legal (not 'NaN' for a real, for example), and correctly put in order.</para> <para>We'll need at least some Properties both for integers and real values. To start, we'll defined Properties with 'long' and 'double' values.</para> <para>Implementation: <programlisting> class LongProperty extends Property { LongProperty( String name, long value) throws IllegalArgument; // IllegalArgument if null name // field defaulted to [Long.MIN_VALUE, Long.MAX_VALUE] LongProperty( String name, long value, long min, long max) throws IllegalArgument; // IllegalArgument if null name or max < min long getLongValue(); long getMinValue(); long getMaxValue(); void applyModifier( AbsoluteModifier modifier); void applyModifier( RelativeModifier modifier); void removeModifier( AbsoluteModifier modifier); void removeModifier( RelativeModifier modifier); } class DoubleProperty extends Property { DoubleProperty( String name, double value) throws IllegalArgument; // IllegalArgument if null name or NaN value // field defaulted to [Double.MIN_VALUE, Double.MAX_VALUE] DoubleProperty( String name, double value, double min, double max) throws IllegalArgument // IllegalArgument if null name or NaN value, min or max, or max < min double getDoubleValue(); double getMinValue(); double getMaxValue(); void applyModifier( AbsoluteModifier modifier); void applyModifier( RelativeModifier modifier); void removeModifier( AbsoluteModifier modifier); void removeModifier( RelativeModifier modifier); } </programlisting> </para> <note><para>for implementation, min and max values can be stored in a memory-friendly way. They aren't stored as two long or double values but as a special immutable Interval object (in fact a reference to this object). A hashtable links (min, max) couples to IntervalManager objects, so for a given interval, only one Interval exists.</para></note> <para>Old solution's memory requirements: two values * number of such Properties.</para> <para>New solution's memory requirements: a reference * number of such Properties + Interval object with two values (+ hashtable)</para> <para>Implementation: <programlisting> final class LongInterval { LongInterval( long min, long max); // no control here long getMin(); long getMax(); boolean isInInterval( long value); // return (min <= value && value <= max) long boundedValue( long value); // min if value < min, max if value > max, otherwise value } final class DoubleInterval { DoubleInterval( double min, double max); // no control here double getMin(); double getMax(); boolean isInInterval( double value); // return (min <= value && value <= max) double boundedValue( long value); // min if value < min, max if value > max, otherwise value } </programlisting> </para> </sect1> <sect1> <title>Non-numeric Properties</title> <para>A Non-numeric Properties contains a non-numeric value (i.e. an object).</para> <para>Idea 1: the value can be in a field or not If it has a field, the Property can't have a value outside the field (i.e. must have a value from the field).</para> <para>Idea 2: the field could be defined with sets or regular expressions.<para> <para>A Non-Numeric Property could or not be limited to some field. We couldn't find useful examples for using regular expressions. So we'll only use sets.</para> <para>We couldn't find useful examples for using intersections, unions or exclusions of sets to define the field. So we'll only use one set (or none). The set should contain one or more values (i.e. a field is a non-null and non-empty set of distinct non-null Objects).</para> <para>Implementation: <programlisting> class NonNumericProperty extends Property { NonNumericProperty( String name, Object value) throws IllegalArgument; // IllegalArgument if name or value are null // no field NonNumericProperty( String name, Object value, Field field); // IllegalArgument if name or value or field are null void setValue( Object value) throws IllegalArgument; // IllegalArgument if null value or not in field void noField(); void addToField( Object value); // IllegalArgument if null value // no error if value already in the field void removeFromField( Object value) throws IllegalArgument; // IllegalArgument if null value or current value equals to value // no error if value is not in the field } // immutable class Field { Field( Object value) throws IllegalArgument; // IllegalArgument if value is null Field( Object[] values) throws IllegalArgument; // IllegalArgument if values is null or one value is null // if multiple occurrences, stores only one static Field add( Field field, Object value) throws IllegalArgument; // IllegalArgument if value is null // no error if value already in the field // returns a new Field static Field add( Field field, Object[] values); // IllegalArgument if values or one value is null // no error if a value is already in the field // if multiple occurrences, stores only one // returns a new Field static Field remove( Field field, Object value); // IllegalArgument if value is null // no error if value is not in the field // returns a new Field or null if empty static Field remove( Field field, Object[] values); // IllegalArgument if values or one value is null // no error if value is not in the field // returns a new Field or null if empty } </programlisting> </para> </sect1> </article>