summaryrefslogtreecommitdiff
path: root/includes/js/dojox/wire/ml/Invocation.js
blob: 3d366235d85507965599da292e7a5253bb66269f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
if(!dojo._hasResource["dojox.wire.ml.Invocation"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dojox.wire.ml.Invocation"] = true;
dojo.provide("dojox.wire.ml.Invocation");

dojo.require("dojox.wire.ml.Action");

dojo.declare("dojox.wire.ml.Invocation", dojox.wire.ml.Action, {
	//	summary:
	//		A widget to invoke a method or publish a topic
	//	description:
	//		This widget represents a controller task to invoke a method or
	//		publish a topic when an event (a function) or a topic is issued.
	//	object:
	//		A scope of a method to invoke
	//	method:
	//		A name of a method to invoke
	//	topic:
	//		A name of a topic to publish
	//	parameters:
	//		Arguments for the method or the topic
	//	result:
	//		A property to store a return value of the method call
	//	error:
	//		A property to store an error on the method call
	object: "",
	method: "",
	topic: "",
	parameters: "",
	result: "",
	error: "",

	_run: function(){
		//	summary:
		//		Invoke a method or publish a topic
		//	description:
		//		If 'topic' is specified, the topic is published with arguments
		//		specified to 'parameters'.
		//		If 'method' and 'object' are specified, the method is invoked
		//		with arguments specified to 'parameters' and set the return
		//		value to a property specified to 'result'.
		//		'object', 'parameters' and 'result' can specify properties of
		//		a widget or an DOM element with the dotted notation.
		//		If 'parameters' are omitted, the arguments to this method are
		//		passed as is.
		if(this.topic){
			var args = this._getParameters(arguments);
			try{
				dojo.publish(this.topic, args);
				this.onComplete();
			}catch(e){
				this.onError(e);
			}
		}else if(this.method){
			var scope = (this.object ? dojox.wire.ml._getValue(this.object) : dojo.global);
			if(!scope){
				return; //undefined
			}
			var args = this._getParameters(arguments);
			var func = scope[this.method];
			if(!func){
				func = scope.callMethod;
				if(!func){
					return; //undefined
				}
				args = [this.method, args];
			}
			try{
				var connected = false;
				if(scope.getFeatures){
					var features = scope.getFeatures();
					if((this.method == "fetch" && features["dojo.data.api.Read"]) ||
						(this.method == "save" && features["dojo.data.api.Write"])){
						var arg = args[0];
						if(!arg.onComplete){
							arg.onComplete = function(){};
						}
						//dojo.connect(arg, "onComplete", this, "onComplete");
						this.connect(arg, "onComplete", "onComplete");
                        if(!arg.onError){
							arg.onError = function(){};
						}
						//dojo.connect(arg, "onError", this, "onError");
						this.connect(arg, "onError", "onError");
                        connected = true;
					}
				}
				var r = func.apply(scope, args);
				if(!connected){
					if(r && (r instanceof dojo.Deferred)){
						var self = this;
						r.addCallbacks(
							function(result){self.onComplete(result);},
							function(error){self.onError(error);}
						);
					}else{
						this.onComplete(r);
					}
				}
			}catch(e){
				this.onError(e);
			}
		}
	},

	onComplete: function(/*anything*/result){
		//	summary:
		//		A function called when the method or the topic publish
		//		completed
		//	description:
		//		If 'result' attribute is specified, the result object also set
		//		to the specified property.
		//	result:
		//		The return value of a method or undefined for a topic
		if(this.result){
			dojox.wire.ml._setValue(this.result, result);
		}
		if(this.error){ // clear error
			dojox.wire.ml._setValue(this.error, "");
		}
	},

	onError: function(/*anything*/error){
		//	summary:
		//		A function called on an error occurs
		//	description:
		//		If 'error' attribute is specified, the error object also set to
		//		the specified property.
		//	error:
		//		The exception or error occurred
		if(this.error){
			if(error && error.message){
				error = error.message;
			}
			dojox.wire.ml._setValue(this.error, error);
		}
	},

	_getParameters: function(/*Array*/args){
		//	summary:
		//		Returns arguments to a method or topic to invoke
		//	description:
		//		This method retunrs an array of arguments specified by
		//		'parameters' attribute, a comma-separated list of IDs and
		//		their properties in a dotted notation.
		//		If 'parameters' are omitted, the original arguments are
		//		used.
		//	args:
		//		Arguments to a trigger event or topic
		if(!this.parameters){
		 	// use arguments as is
			return args; //Array
		}
		var parameters = [];
		var list = this.parameters.split(",");
		if(list.length == 1){
			var parameter = dojox.wire.ml._getValue(dojo.trim(list[0]), args);
			if(dojo.isArray(parameter)){
				parameters = parameter;
			}else{
				parameters.push(parameter);
			}
		}else{
			for(var i in list){
				parameters.push(dojox.wire.ml._getValue(dojo.trim(list[i]), args));
			}
		}
		return parameters; //Array
	}
});

}