Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Talk:SMILA/Documentation/2011.Simplification/Data Model and Serialization Formats

Revision as of 04:29, 11 March 2011 by Tmenzel.brox.de (Talk | contribs) (counter proposal: new section)

TM: I have just briefly looked @ the new DM and had some ideas/remarks which I just put down in all brevity as a bullet list. At times these are formulated rather strongly as "should be" and not as a question. So plz. be not offended and just comment on why this is not a good idea or does not work for Smila.

  • TM: AnyMap should extend Map interface
  • TM: AnySeq should extend List
  • TM: isValue -> isContainer, isLiteral
Reason: also a Map, Seq is a Value, albeit a complex one hence isValue is not really that telling IMO
  • TM: what is the distinction between Date and DateTime other than the use case? i.e. do we treat its value differently, e.g. truncate the time part in case we say asDate()
  • TM: why have a Value class and not use java native objects directly? e.g. Boolean, Integer, …
  • TM: Value.asXXX() I see that they throw exceptions, depending on what u want to do this is good or just bothersome.
I would also provide a version that silently returns NULL (in C# the cast operator "as" behaves like so, and I miss it sometimes in java) OR
a default value in case datatype doesn’t match – or even convert automatically.
this could be done by overloading with a parameter that takes the default value, a flag that controls return null vs. throw exception or having 2 sets of methods
  • TM: Record.getMetadata() -> Record.getValueMap()
reason: sometimes we don’t have attachments at all and anly use the "meta data" which is the not just meta, e.g. in case of search
  • TM: are we still going to have some Path object or smth equivalent? I kind of liked that…
  • TM: Attachments, the record should always have an indicator of all attachments and tell if the attachement has been filtered out. that way we don’t need a trip to the BB and ask that.

counter proposal

This is my idea on how a simple model might look like.

This class is an all-in-one approach and models a tree like structure with anonymous and named children of type Any. In that sense Any is a node that may have a literal value and Any-children. The model is somewhat similar to DOM, but much simpler; it borrows these the two key features:

  • ordered children (that may have a name)
  • allows to have >1 same named children

This effectively provides List and multi-valued map (Bag) semantic, which have their own objects in the original proposal. For more details read the comments in the interface.

So far (i did this in 1.5h time this morning) i haven thought of a serialization model for this but thing that it is not a problem. the only mismatch is that the serialized version probably will have an own construct (i.e. special child) for the Literal of a node whereas the Any is modeled to be a literal itself. But this can be changed to make the object model more close to the serialization model. see also the comment in code.


/**
 * The Interface Any.
 * Counter proposal for simplification of smila.
 */
interface Any extends Iterable<Any>, List<Any> {
 
  // #################################################################################
  // literal
  /**
   * this models that the Any is also a Literal. another flavor is to model the Literal as a seperate value object and
   * move all the following methods to that object.
   * 
   * TODO | TM |
   * 
   * <pre>
   * the asXXX methods will always return null in case of a miss or error, while the toXXX will throw an exception if the type doesnt fit.
   * asXXX()
   * asXXX(T defaultValue)
   * toXXX()
   * toXXX(T defaultValue)  //NOTE: this will overwrite the Object.toString() and is not so nice but i think i can live with that
   * </pre>
   * 
   * | TM @ Mar 11, 2011
   *
   * @return the string
   */
  // #################################################################################
  /**
   * @return The string representation
   */
  String asString();
 
  /**
   * As double.
   *
   * @return The double representation, an InvalidValueTypeException is thrown if the value is not of type double.
   */
  Double asDouble();
 
  /**
   * As long.
   *
   * @return The long representation, an InvalidValueTypeException is thrown if the value is not of type long.
   */
  Long asLong();
 
  /**
   * As boolean.
   *
   * @return The boolean representation, an InvalidValueTypeException is thrown if the value is not of type boolean.
   */
  Boolean asBoolean();
 
  /**
   * As date.
   *
   * @return The date representation, an InvalidValueTypeException is thrown if the value is not of type date.
   */
  Date asDate();
 
  /**
   * As date time.
   *
   * @return The date time representation, an InvalidValueTypeException is thrown if the value is not of type date time.
   */
  Date asDateTime();
 
  /**
   * Enumeration with the possible value types.
   * 
   */
  enum LiteralType {
 
    /** The STRING. */
    STRING, 
 /** The DOUBLE. */
 DOUBLE, 
 /** The BOOLEAN. */
 BOOLEAN, 
 /** The LONG. */
 LONG, 
 /** The DATE. */
 DATE, 
 /** The DATETIME. */
 DATETIME
  };
 
  /**
   * sets the value, the type is deducted must be one of the allowed ones.
   * 
   * @param <T>
   *          the generic type
   * @param literal
   *          the literal
   * @return the a possibly previosly set literal
   * @throws ClassCastException
   *           the class cast exception
   * @throws InvalidValueTypeException
   *           in case the given literal is not an allowed type
   * @note there might be the rare case where one wants to set another type. in this case one just would have to work
   *       with castsa like so:<br/>
   *       <code>Date date = (Date) _any.setLiteral((Object) "Tue 1st, Dec");</code>
   */
  <T> T setLiteral(T literal) throws ClassCastException, InvalidValueTypeException;
 
  /**
   * Gets the literal type.
   *
   * @return value type
   */
  LiteralType getLiteralType();
 
  /**
   * Checks for literal.
   * 
   * @return true, if this Any's literal is not null
   */
  boolean hasLiteral();
 
  /**
   * Checks if is string.
   *
   * @return true if value is of type string
   */
  boolean isString();
 
  /**
   * Checks if is double.
   *
   * @return true if value is of type double
   */
  boolean isDouble();
 
  /**
   * Checks if is boolean.
   *
   * @return true if value is of type boolean
   */
  boolean isBoolean();
 
  /**
   * Checks if is long.
   *
   * @return true if value is of type long
   */
  boolean isLong();
 
  /**
   * Checks if is date.
   *
   * @return true if value is of type date
   */
  boolean isDate();
 
  /**
   * Checks if is date time.
   *
   * @return true if value is of type date time
   */
  boolean isDateTime();
 
  /**
   * Gets the factory.
   *
   * @return data factory to create Anys of the same kind.
   */
  DataFactory getFactory();
 
  /**
   * Size.
   *
   * @return size of Any. For {@link Value} this is always 1.
   */
  int size();
 
  // #################################################################################
  // name
  // #################################################################################
 
  /**
   * Gets the name of this AnyValue. Note that it may be empty ("")! Any objects created with a blank String are trimmed
   * to empty. Any objects with an empty name are called anonymous children
   * 
   * @return the name
   */
  String getName();
 
  /**
   * Checks if is anonymous name.
   *
   * @return true, if is anonymous name
   */
  boolean isAnonymousName();
 
  // #################################################################################
  // child accessors
  /**
   * the children are held in a list and that is the primary form of their keeping. that is: they mantain their order
   * when retrieved (get, iterator). The Any object has a name which may be used to access the child item(s). However,
   * the name needs not be unique and hence there can be >1 children with the same name (Bag semantic).
   *
   * @return the iterator
   */
  // #################################################################################
  /**
   * @return iterates over underlying list in order.
   */
  @Override
  Iterator<Any> iterator();
 
  /** {@inheritDoc}
   * @see java.util.List#get(int)
   */
  Any get(int index);
 
  /**
   * Gets the first.
   *
   * @param name the name
   * @return the first
   */
  Any getFirst(String name);
 
  /**
   * Gets the.
   *
   * @param name the name
   * @return the list
   */
  List<Any> get(String name);
 
  /**
   * Gets the as array.
   *
   * @param name the name
   * @return the as array
   */
  Any[] getAsArray(String name);
 
  /**
   * Gets the all.
   *
   * @return the all
   */
  Map<String, List<Any>> getAll();
 
  /**
   * inserts the values at the given position.
   *
   * @param index the index
   * @param value the value
   */
  void add(int index, Any... value);
 
  /**
   * replaces the same amount of Any values with the given ones. If there are less to be replaced than to be added then
   * the excess will be appended.
   * 
   * @param index
   *          the index
   * @param value
   *          the value
   * @return the replaced any values
   */
  List<Any> set(int index, Any... value);
 
  /**
   * appends the new value.
   * 
   * @param value
   *          the value
   */
  void add(Any... value);
 
  /**
   * replaces existing values with the same name at their index position; given values for which no replacement exists
   * are appended.
   * 
   * @param value
   *          the value
   * @return the replaced values
   */
  List<Any> set(Any... value);
 
}

Copyright © Eclipse Foundation, Inc. All Rights Reserved.