Interacting with the Server

by Tanja Buttler

In the last sections of this tutorial you have learnt how to plug in a component into ActionCenters, how to render that component, and how to provide configuration options for the collaboration engineer. Within the next steps of this tutorial we are going to show you how to communicate with the server, particularly how to create, update, and delete contributions and how to receive messages from the server about these events.

The communication between client and server is based on a publisher subscriber mechanism. Subscribers can register themselves to different channels, each channel publishing updates about one contribution. Separate channels are available depending on the type of change made to a contribution. For example, information about adding relationships, about updating properties, and about deleting contributions is published to separate channels. You can more information about the channels in the Technical References.

ActionCenters uses CometD to handle the exchange with the server. These messages contain JSON objects describing the changes.For the purposes of this tutorial we do not need to know the details of how this communication works. ActionCenters provides some JavaScript objects that support us in handling the communication with the server.

In the remainder of this section we are working with attachments as our contributions. Attachments are files that can be attached to any kind of contribution. We build an attachment service responsible for loading a list of attachments and for creating, updating, and deleting attachments. In addition, this service supports us in adding subscribers to channels publishing updates about attachments and about their superior contributions. Basically, this service encapsulates all interactions with the server side that rely on CometD.

Attachment Meta-Model

Before we start building the attachment service we have to determine the properties of an attachment. Every property consists of a key and value. The key is determined by the component, whereas the value contains the user input.
First, every attachment has a filename that is displayed to a user. This filename should be displayed in the outliner component, provided the outliner has the same population rule as the attachment component. The outliner uses the key name to identify the text labels of a contribution. We therefore take the keyword name to refer to the filename.
Second, every attachment should have a reference to the file itself. Here we are free to choose the key ourselves and settle on file. The following listing shows to methods of the attachment service wrapping a value into a configuration object representing the filename and the reference to the file respectively.

        
	this.createNameProperty = function(fileName) {
		return {
			name : fileName
		};
	};
	
	this.createBinaryProperty = function(fileId) {
		return {file : fileId};
	};
	
        

Finally, every attachment has type. This type is specified by the collaboration engineer by configuring the population rule for the attachment component.

Starting with the attachment service

An attachment service needs to work with a superior contribution and the population rules in order to create new attachments. ActionCenters requires every contribution made by a user to be in a parent-child relationship with superior contribution. The superior contribution can be the dataset in which a population rule is defined or it can be a superior population rule. A population rules parser helps us to access the content of the population rule. The following listing shows an almost empty AttachmentsService with the superior contribution and accompanying population rules.

        
var AttachmentsService = function(superiorContribution, popRules) {
	
	var populationRules = new acPopulationRulesParser(popRules);
	this.actionCenterListener = new ActionCenterListener();
	this.parentContribution = superiorContribution;

	this.getPopulationRule = function() {
		return populationRules;
	};
};

	
        

Adding contributions

In order to add a contribution we need to add a relationship between the new contribution and its superior contribution (see previous subsection). ActionCenters provides an actionCenterAPI containing static methods that support us in sending messages to the server. The method addRelationship adds the relationship between a new contribution and its superior contribution. We have to hand in the type of the new contribution, the type of the relationship, and the properties of the new contribution. The file property takes up a special place in that it is handed in as a binary property. A binary property tells the server that there has to be a matching binary file in its database as well. Some optional parameters are afterContributionId and beforeContributionId; these two IDs allow us to define a sorting of contributions on the server side. For the attachment component we will not use this option, however. Finally the method also expects an ID of the new contribution. However, since we have just added a new contribution we set this property to null. The server will provide us with an ID for the contribution in its reply. The following listing shows the method addContribution of the attachment service.

        
	this.addContribution = function(fileId, fileName) {
		//properties of the new contribution
		//ensure compatibility with the outliner - use the name keyword
		var binaryProperties = this.createBinaryProperty(fileId);
		var subordinateContributionId = null;//we are creating the subordinate - therefore this value is null
		//ordering - we don not specify any order of the attachments
		var afterContributionId = null;
		var beforeContributionId = null;
		//the parent of the new contribution
		var superiorContributionId = this.parentContribution.getId();
		//the relationship to the parent
		var childType = populationRules.getAllChildTypeList()[0];
		var subordinateContributionType = childType.type;
		var relationshipType = childType.relationship;
		//adding the relationship - we do not specify any callback methods
		actionCenterAPI.addRelationship(superiorContributionId,
				subordinateContributionId, relationshipType,
				afterContributionId, beforeContributionId,
				subordinateContributionType, this.createNameProperty(fileName),
				null, null, binaryProperties);
	};
	
        

Changing properties

Changing properties of an existing attachment works similarly to adding a new attachment. We also work with the actionCenterAPI and use its method editContribution. We have to hand in the ID of the contribution and the new property. The following listing shows the method of the attachment service changing the label of the attachment.

        
	this.changeAttachmentLabel = function(newLabel, contributionId) {
		actionCenterAPI.editContribution(contributionId,
				this.createNameProperty(newLabel));
	};

	
        

Deleting contributions

In order to delete a contribution we have to hand in the ID of this contribution into the method deleteContribution of the actionCenterAPI:

        
	this.destroyContribution = function(contributionId) {
		actionCenterAPI.deleteContribution(contributionId);
	};
	
        

Fetching a list of existing contributions

When opening the attachment component a user expects to see a list of existing attachments. For us this means that we have to fetch a list of attachments from the server when a component is instantiated. actionCenterAPI provides a method getContributionsMatchingPelationships. This method allows us to fetch all contributions that are the child of a given parent contribution, are in a specified relationship with that contribution, and are of a specific type. The server sends a reply to the querying client, ActionCenters relays the reply to a callback object and method. The following listing shows how to fetch a list of attachments from the server.

        
	/*
	 * Calls the server to fetch attachments of the superior contribution. The
	 * receiving object is called with receivingObject.receivingMethod(results).
	 * 
	 * @param {Object} receivingObject
	 * @param {Object} receivingMethod
	 * @memberOf {AttachmentsService} 
	 */
	this.fetchAttachments = function(receivingObject, receivingMethod) {
		var me = this;
		var childType = populationRules.getAllChildTypeList()[0];
		actionCenterAPI.getContributionsMatchingRelationships(
				[ me.parentContribution.getId() ], [ childType.relationship ],
				childType.type, false, receivingObject, receivingMethod);
	};