org.mmbase.applications.dove
Class Dove

Package class diagram package Dove
java.lang.Object
  extended by org.mmbase.applications.dove.AbstractDove
      extended by org.mmbase.applications.dove.Dove

public class Dove
extends AbstractDove

This class handles Remote Procedure Calls described using a DOM model. The original data is received in xml, likely through a specialized servlet such as the DoveServlet (but this is not required. it may, for instance, be possible to use this class in conjunction with SOAP or even outside a servlet context). The call should result in a new DOM tree (see the EditWizard API for details).
XXX: Currently, this class performs some type of validation on the xml received. If errors occur, they are included in the response, at the place where they occur. This means that the <error > tag can occur anywhere in the response, which is not very neat.
Errors have three types:
parser : the xml given is invalid or does not follow the grammar. This likely means there is a bug in the client code.
server : the code invoked is either not yet implemented or another, server-related, error occurred (such as no memory, bad configuration, etc.). Server errors entirely fail a request.
client : The data requested could not be retrieved or values specified were invalid. I.e. a requested node does not exist (any more), or a put failed due to locking or invalid data.

This is ONLY for debugging purposes! XML validation should occur at the parser and be captured early. If we reach consensus that we must always validate, the xml-checking can be left out, as we can then assumes a correct model. This will optimize processing.

Since:
MMBase-1.5
Version:
$Id: Dove.java 35335 2009-05-21 08:14:41Z michiel $
Author:
Pierre van Rooden

Field Summary
 
Fields inherited from class org.mmbase.applications.dove.AbstractDove
DESCENDANT, DESCENDANTS, DESCRIPTION, doc, DOCTYPE_REQUEST, DOCTYPE_RESPONSE, ELM_CONTEXT, ELM_CREATEDIR, ELM_DESTINATION, ELM_DESTINATIONTYPE, ELM_DIRECTIONS, ELM_ENCODING, ELM_HREF, ELM_ID, ELM_LANG, ELM_MAYDELETE, ELM_MAYWRITE, ELM_NAME, ELM_NUMBER, ELM_OLDNUMBER, ELM_ORDERBY, ELM_ROLE, ELM_SEARCHDIR, ELM_SEARCHTYPE, ELM_SIZE, ELM_SOURCE, ELM_SOURCETYPE, ELM_STATUS, ELM_TYPE, ELM_WHERE, ELM_XPATH, ERROR, FIELD, FIELDS, GETCONSTRAINTS, GETDATA, GETLIST, GETNEW, GETNEWRELATION, GETRELATIONS, GUINAME, GUITYPE, IS_CLIENT, IS_FALSE, IS_PARSER, IS_SERVER, IS_TRUE, MAXLENGTH, NEW, OBJECT, ORIGINAL, PARENT, PLURALNAME, PUT, QUERY, RELATION, RELATIONS, REQUEST, REQUIRED, RESPONSE, SECURITY, SECURITY_CLOUD, SECURITY_METHOD, SECURITY_NAME, SECURITY_PASSWORD, SINGULARNAME, TYPE_DESCRIPTIONS
 
Constructor Summary
Dove(Document doc)
          Constructor
 
Method Summary
protected  Element addField(Element out, NodeManager nm, Field f, Node node)
           
protected  void addRelationNodes(Element relation, Element out, Node nd)
          Retrieves the relations of a node and adds its content to a DOM element.
 void doRequest(Element in, Element out, Cloud cloud, Map<String,byte[]> repository)
          Handles a request running one or more RPCs.
protected  boolean fillFields(String alias, Node node, Element objectelement, Map<String,Object> values)
          Fills the fields of the specified node with the supplied values.
protected  boolean fillFields(String alias, Node node, Element out, Map<String,Object> values, Map<String,Object> originalValues)
          Fills the fields of the specified node with the supplied values.
 void getConstraints(Element in, Element out, Cloud cloud)
          Handles a getconstraints call.
 void getData(Element in, Element out, Cloud cloud)
          Handles a getdata call, by obtaining data for each node specified.
 void getDataNode(Element in, Element out, Cloud cloud)
          Handles a node by retrieving its data and storing its content in a DOM element.
 void getDataNode(Element in, Element out, Node node)
          Handles a node storing its content in a DOM element.
 void getList(Element in, Element out, Cloud cloud)
          Handles a getlist call.
 void getNew(Element in, Element out, Cloud cloud)
          Handles a getnew call, by obtaining data for the new node of a specified type.
 void getNewRelation(Element in, Element out, Cloud cloud)
          Handles a getnewrelation call, by obtaining data for the new node of a specified type.
protected  String getNodeReferenceFromValue(String name, Map<String,Object> values, Map<String,Integer> aliases)
          Converts the value of a field to a node reference (either a temporary id or an object alias or number).
 void getRelations(Element in, Element out, Cloud cloud)
          Handles a getrelations call, by obtaining relations for each node specified.
 void getRelationsNodes(Element in, Element out, Cloud cloud)
          Handles a node by retrieving its relations and storing its content in a DOM element.
protected  boolean mergeClouds(Map<String,Map<String,Object>> originalNodes, Map<String,Map<String,Object>> newNodes, Map<String,Map<String,Object>> originalRelations, Map<String,Map<String,Object>> newRelations, Map<Node,Element> addedNodes, Map<Relation,Element> addedRelations, Element out, Cloud cloud)
          Performs the put within a transaction.
 void put(Element in, Element out, Cloud cloud, Map<String,byte[]> repository)
          Handles a put call.
protected  boolean putChangeNode(String alias, Map<String,Object> values, Map<String,Object> originalValues, Map<String,Integer> aliases, Element out, Cloud cloud)
          Changes a node.
protected  boolean putChangeRelation(String alias, Map values, Map originalValues, Map aliases, Element out, Cloud cloud)
          Changes a relation
protected  boolean putDeleteNode(String alias, Map<String,Object> originalValues, Element out, Cloud cloud)
          Deletes a node.
protected  boolean putDeleteRelation(String alias, Map<String,Object> originalValues, Element out, Cloud cloud)
          Deletes a relation.
protected  boolean putNewNode(String alias, Map<String,Object> values, Map<String,Integer> aliases, Map<Node,Element> addedNodes, Element out, Cloud cloud)
          Creates a new node.
protected  boolean putNewRelation(String alias, Map<String,Object> values, Map<String,Integer> aliases, Map<Relation,Element> addedRelations, Element out, Cloud cloud)
          Creates a new relation.
 
Methods inherited from class org.mmbase.applications.dove.AbstractDove
addContentElement, doRequest, executeRequest, executeRequest, getFirstElement, getFirstElement, getNextElement, getNextElement, getTypeDescription
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

Dove

public Dove(Document doc)
Constructor

Parameters:
doc - the Document that is constructed. This should only be used to construct new DOM elements. New (child) nodes should not be added to this document, but to the out element.
Method Detail

addField

protected Element addField(Element out,
                           NodeManager nm,
                           Field f,
                           Node node)
Since:
MMBase-1.8.4

getDataNode

public void getDataNode(Element in,
                        Element out,
                        Node node)
Handles a node storing its content in a DOM element. This method accepts a object to store, as well as a DOM element, which may contain as it child nodes elements describing the fields to retrieve. The tagname of these elements should be 'field'. Each element should have a 'name' attribute that identifies the field. The result of this call should be a list of DOM elements describing each field, which are appended to the out element. If the 'in' node has no field elements, all fields are returned, with the exception of some system-specific fields.

Parameters:
in - the element that described the getdata call. The childnodes should describe the nodes to retrieve.
out - the element that described the getdata result. Retrieved nodes should be added as childs to this element.
node - The node to store in out.
To Do:
Currently, the Dove does not return values for binary (byte) fields - a binary field is always returned empty. This is done for optimization of the editwizards, which would otherwise eat a lot of memory, but that DO need a reference to a bytefield. Future versions of Dove should handle a better mechanism for handling binary fields.

getDataNode

public void getDataNode(Element in,
                        Element out,
                        Cloud cloud)
Handles a node by retrieving its data and storing its content in a DOM element. This method accepts a DOM element (describing a node), which may contain as it child nodes elements describing the fields to retrieve. The tagname of these elements should be 'field'. Each element should have a 'name' attribute that identifies the field. The result of this call should be a list of DOM elements describing each field, which are appended to the out element. If the 'in' node has no field elements, all fields are returned, with the exception of some system-specific fields.
Note also that if no name was given for a field, a NullPointer exception is thrown.

Parameters:
in - the element that described the getdata call. The childnodes should describe the nodes to retrieve.
out - the element that described the getdata result. Retrieved nodes should be added as childs to this element.
cloud - the cloud to work on

addRelationNodes

protected void addRelationNodes(Element relation,
                                Element out,
                                Node nd)
Retrieves the relations of a node and adds its content to a DOM element. This method accepts a DOM element (describing a relation), which may contain as it child nodes elements describing the fields as well as the related object to retrieve.

Parameters:
relation - the element that described the relation The childnodes (if present) should describe the fields to retrieve, and possibly a description of the related object.
out - the element that describes the source node. Retrieved relations should be added as childs to this element.
nd - the MMBase node that shoudl eb sued to query the relations

getRelationsNodes

public void getRelationsNodes(Element in,
                              Element out,
                              Cloud cloud)
Handles a node by retrieving its relations and storing its content in a DOM element. This method accepts a DOM element (describing a node), which may contain as it child nodes elements describing the relations to retrieve. The tagname of these elements should be 'relation'. If the 'in' node has no relation elements, all relations are returned.

Parameters:
in - the element that described the getdata call. The childnodes should describe the nodes to retrieve.
out - the element that described the getdata result. Retrieved nodes should be added as childs to this element.
cloud - the cloud to work on

getData

public void getData(Element in,
                    Element out,
                    Cloud cloud)
Handles a getdata call, by obtaining data for each node specified. This method accepts a DOM element, which should contain as it child nodes elements describing the nodes to retrieve. The tagname of these elements should be 'object'. Each element should have an 'number' attribute that described the number or alias of the node to retrieve. The result of this call should be a list of DOM elements describing each node, which are appended to the out element.

Parameters:
in - the element that described the getdata call. The childnodes should describe the nodes to retrieve.
out - the element that described the getdata result. Retrieved nodes should be added as childs to this element.
cloud - the cloud to work on

getNew

public void getNew(Element in,
                   Element out,
                   Cloud cloud)
Handles a getnew call, by obtaining data for the new node of a specified type. This method accepts a DOM element, which should contain as it's attribute the type of the node to return. The result of this call should be DOM element describing a new node, which is appended to the out element.

Parameters:
in - the element that described the getnew call.
out - the element that described the getnew result. The new node should be added as a child to this element.
cloud - the cloud to work on

getNewRelation

public void getNewRelation(Element in,
                           Element out,
                           Cloud cloud)
Handles a getnewrelation call, by obtaining data for the new node of a specified type. This method accepts a DOM element, which should contain as it's attribute the role of the relation to return. The result of this call should be DOM element describing a new node, which is appended to the out element.

Parameters:
in - the element that described the getnew call.
out - the element that described the getnew result. The new node should be added as a child to this element.
cloud - the cloud to work on

getRelations

public void getRelations(Element in,
                         Element out,
                         Cloud cloud)
Handles a getrelations call, by obtaining relations for each node specified. This method accepts a DOM element, which should contain as it child nodes elements describing the nodes to retrieve the relations from. The tagname of these elements should be 'object'. Each element should have an 'number' attribute that described the number or alias of the node to retrieve. The result of this call should be a list of DOM elements with a data element for each node,which are appended to the out element. The node element's children are the relations.

Parameters:
in - the element that described the getrelations call. The childnodes should describe the nodes to retrieve the relations from.
out - the element that described the getrelations result. Retrieved nodes and their relations should be added as childs to this element.
cloud - the cloud to work on

getConstraints

public void getConstraints(Element in,
                           Element out,
                           Cloud cloud)
Handles a getconstraints call.

Parameters:
in - the element that described the getconstraints call. The childnodes should describe the node types to retrieve the constraints of.
out - the element that described the getconstraints result. Retrieved constraints should be added as childs to this element.
cloud - the cloud to work on

getList

public void getList(Element in,
                    Element out,
                    Cloud cloud)
Handles a getlist call. This method accepts a DOM element, which should contain as it child nodes elements describing the queries to retrieve the nodes with. The tagname of these elements should be 'query'. Each element should have a 'xpath' attribute to indicate the nodemanager to run the list on, and optionally a 'where' that contains the constraints. The result of this call should be a list of DOM elements with a data element for each query, which are appended to the out element. The node element's children are the nodes from the list.

Parameters:
in - the element that described the getlist call. The childnodes should describe the queries to run.
out - the element that described the getlist result. Retrieved nodes should be added as childs to this element.
cloud - the cloud to work on

put

public void put(Element in,
                Element out,
                Cloud cloud,
                Map<String,byte[]> repository)
Handles a put call. This method accepts a DOM element, which should contain as it child nodes elements describing the original and the new cloud.

Parameters:
in - the element that described the put call. The childnodes should describe the old and the new cloud.
out - the element that described the put result. The result of the put (an error or the resulting cloud) should be added as childs to this element.
cloud - the cloud to work on
repository - Repository that contains the blobs

getNodeReferenceFromValue

protected String getNodeReferenceFromValue(String name,
                                           Map<String,Object> values,
                                           Map<String,Integer> aliases)
Converts the value of a field to a node reference (either a temporary id or an object alias or number). Used for determing values of the snumber and dnumber relation fields.

Parameters:
name - the name of the field
values - a Map with field values
aliases - a Map with mappings from XML aliases to node reference values
Returns:
the node reference value

fillFields

protected boolean fillFields(String alias,
                             Node node,
                             Element objectelement,
                             Map<String,Object> values)
Fills the fields of the specified node with the supplied values. The node's XML element is upadeytd with the affected field elements. This method does not validate whether a node's values have changed since the transaction started.

Parameters:
alias - the node alias in the put tree
node - the node to fill
objectelement - the XML element to fill with the changed data for feedback
values - a Map with new node values
Returns:
true if succesful, false if an error ocurred

fillFields

protected boolean fillFields(String alias,
                             Node node,
                             Element out,
                             Map<String,Object> values,
                             Map<String,Object> originalValues)
Fills the fields of the specified node with the supplied values. The node's XML element is updated with the affected field elements. This method validates whether a node's values have changed since the transaction started, and fails if this was teh acse.

Parameters:
alias - the node alias in the put tree
node - the node to fill
out - the XML element to fill with the changed data for feedback
values - a Map with new node values
originalValues - a Map with the original values of the node, needed for checking. if null, no checking takes place
Returns:
true if succesful, false if an error ocurred

putNewNode

protected boolean putNewNode(String alias,
                             Map<String,Object> values,
                             Map<String,Integer> aliases,
                             Map<Node,Element> addedNodes,
                             Element out,
                             Cloud cloud)
Creates a new node.

Parameters:
alias - the node alias in the put tree
values - a Map with new node values
aliases - a Map with mappings from XML aliases to node reference values
addedNodes - a Map used to keep associations between xml elements and newly created nodes, needed for resolving new node numbers
out - the element that describes 'new' cloud. The result of the put (an error or the resulting cloud) should be added as childs to this element.
cloud - the cloud to work on
Returns:
true if succesful, false if an error ocurred

putNewRelation

protected boolean putNewRelation(String alias,
                                 Map<String,Object> values,
                                 Map<String,Integer> aliases,
                                 Map<Relation,Element> addedRelations,
                                 Element out,
                                 Cloud cloud)
Creates a new relation.

Parameters:
alias - the node alias in the put tree
values - a Map with new node values
aliases - a Map with mappings from XML aliases to node reference values
addedRelations - a Map used to keep associations between xml elements and newly created relations, needed for resolving new node numbers and references
out - the element that describes 'new' cloud. The result of the put (an error or the resulting cloud) should be added as childs to this element.
cloud - the cloud to work on
Returns:
true if succesful, false if an error ocurred

putDeleteNode

protected boolean putDeleteNode(String alias,
                                Map<String,Object> originalValues,
                                Element out,
                                Cloud cloud)
Deletes a node.

Parameters:
alias - the node alias in the put tree
originalValues - a Map with the original values of the node
out - the element that describes 'new' cloud. The result of the put (an error or the resulting cloud) should be added as childs to this element.
cloud - the cloud to work on
Returns:
true if succesful, false if an error ocurred

putDeleteRelation

protected boolean putDeleteRelation(String alias,
                                    Map<String,Object> originalValues,
                                    Element out,
                                    Cloud cloud)
Deletes a relation.

Parameters:
alias - the node alias in the put tree
originalValues - a Map with the original values of the relation
out - the element that describes 'new' cloud. The result of the put (an error or the resulting cloud) should be added as childs to this element.
cloud - the cloud to work on
Returns:
true if succesful, false if an error ocurred

putChangeRelation

protected boolean putChangeRelation(String alias,
                                    Map values,
                                    Map originalValues,
                                    Map aliases,
                                    Element out,
                                    Cloud cloud)
Changes a relation

Parameters:
alias - the node alias in the put tree
values - a Map with new node values
originalValues - a Map with original node values, used for validation
aliases - a Map with mappings from XML aliases to node reference values
out - the element that describes 'new' cloud. The result of the put (an error or the resulting cloud) should be added as childs to this element.
cloud - the cloud to work on
Returns:
true if succesful, false if an error ocurred

putChangeNode

protected boolean putChangeNode(String alias,
                                Map<String,Object> values,
                                Map<String,Object> originalValues,
                                Map<String,Integer> aliases,
                                Element out,
                                Cloud cloud)
Changes a node.

Parameters:
alias - the node alias in the put tree
values - a Map with new node values
originalValues - a Map with original node values, used for validation
aliases - a Map with mappings from XML aliases to node reference values
out - the element that describes 'new' cloud. The result of the put (an error or the resulting cloud) should be added as childs to this element.
cloud - the cloud to work on
Returns:
true if succesful, false if an error ocurred

mergeClouds

protected boolean mergeClouds(Map<String,Map<String,Object>> originalNodes,
                              Map<String,Map<String,Object>> newNodes,
                              Map<String,Map<String,Object>> originalRelations,
                              Map<String,Map<String,Object>> newRelations,
                              Map<Node,Element> addedNodes,
                              Map<Relation,Element> addedRelations,
                              Element out,
                              Cloud cloud)
Performs the put within a transaction.

Parameters:
originalNodes - the nodes in the original cloud, used in validation
newNodes - the nodes in the new cloud
originalRelations - the relations in the original cloud, used in validation
newRelations - the relations in the new cloud
addedNodes - a Map used to keep associations between xml elements and newly created nodes, needed for resolving new node numbers and references
addedRelations - a Map used to keep associations between xml elements and newly created relations, needed for resolving new node numbers and references
out - the element that described the put result. The result of the put (an error or the resulting cloud) should be added as childs to this element.
cloud - the cloud to work on

doRequest

public void doRequest(Element in,
                      Element out,
                      Cloud cloud,
                      Map<String,byte[]> repository)
Handles a request running one or more RPCs. This method accepts a root DOM element, which should contain as it child nodes elements describing the call(s) to perform. Each element is an xml element with as the tagname the name of the call to run. Valid calls are getdata, getrelations, getlist, getconstraints, getnew, and put. The calls are redirected to the appropriate encapsulating method in this class. The end result of each call should be a DOM tree, built using the given parameters, which is then appended to the out element.
XXX:This method runs all commands in order of entrance. It does not currently check whether all child nodes refer to the same call. This means that it is possible to mix 'getdata' and 'getrelations' calls in one request. Ina dditon, it ignores calls it does not know how to handle. as described above, this should be handled by the xml parser. Note also that if no id was given for a call, a NullPointer exception is thrown.

Specified by:
doRequest in class AbstractDove
Parameters:
in - the element that described the request (or input). The childnodes should describe the calls to perform.
out - the element that described the response (or return value). Results of calls should be added as childs to this element.
cloud - the cloud to work on - if null, a cloud will be created by the Dove class
repository - Repository that contains the blobs


MMBase Dove 2.0-SNAPSHOT - 2013-11-29T11:13