Форк Rambox
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

257 lines
9.7 KiB

// @tag enterprise
/**
* Reader class to access v1.1 SOAP (Simple Object Access Protocol) services.
*/
Ext.define('Ext.data.soap.Reader', {
extend: 'Ext.data.reader.Xml',
alias: 'reader.soap',
getData: function(data) {
var envelope = data.documentElement,
// we can't always assume that the Body element's namespace prefix is "soap",
// but we can assume that it is the same as the envelope's namespace prefix
prefix = envelope.prefix;
return Ext.DomQuery.selectNode(prefix + '|Body', data);
}
});
// @tag enterprise
/**
* The SOAP Proxy class is an {@link Ext.data.proxy.Ajax Ajax Proxy} to access v1.1 SOAP
* (Simple Object Access Protocol) services. SOAP Proxy constructs a SOAP Envelope and
* submits an AJAX request to load a SOAP response from the server.
*
* For help getting started please refer to the [Soap Guide](#/guide/soap).
*
* **Note: ** _This functionality is only available with the purchase of
* Sencha Complete. For more information about using this class, please visit
* our [Sencha Complete](https://www.sencha.com/products/complete/) product page._
*
* @class Ext.data.soap.Proxy
*/
Ext.define('Ext.data.soap.Proxy', {
extend: 'Ext.data.proxy.Ajax',
alias: 'proxy.soap',
requires: [
'Ext.data.soap.Reader'
],
config: {
/**
* @cfg {Object} api
* An object containing "create", "read", "update" and "destroy" properties that define
* SOAP operations for each CRUD action method. These operations will be appended to
* the {@link #url} as the {@link #operationParam} for each request type.
*
* api: {
* create: undefined,
* read: undefined,
* update: undefined,
* destroy: undefined
* }
*
* At least one operation is required, but additional operations do not need to be configured
* if they will not be used. For example, if this proxy is only used for read operations
* the following configuration will be sufficient:
*
* api: {
* read: 'Foo'
* }
*/
/**
* @cfg {Object} soapAction
* An object containing "create", "read", "update" and "destroy" properties that define
* the [SOAPAction](http://www.w3.org/TR/2000/NOTE-SOAP-20000508/#_Toc478383528) header
* for each CRUD action method. A soapAction must be specified for each operation
* configured in {@link #api} Defaults to:
*
* soapAction: {
* create: undefined,
* read: undefined,
* update: undefined,
* destroy: undefined
* }
*/
soapAction: {},
/**
* @cfg {String} [operationParam='op']
* The name of the operation parameter to be appened to the SOAP endpoint url
*/
operationParam: 'op',
/**
* @cfg {Object/String/Ext.data.soap.Reader} [reader='soap']
* The {@link Ext.data.soap.Reader} to use to decode the server's response. This can
* either be a SOAP Reader instance, a SOAP Reader config object or 'soap'.
*/
reader: 'soap',
/**
* @cfg {String} url
* The SOAP endpoint url that this proxy will use to request the SOAP data. This can
* be a proxied url to work around same-origin policy if the SOAP endpoint url is on
* a different domain from your application.
*/
url: '',
/**
* @cfg [envelopeTpl=undefined]
* The template used to create the SOAP envelope. Defaults to:
*
* [
* '<?xml version="1.0" encoding="utf-8" ?>',
* '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">',
* '{[values.bodyTpl.apply(values)]}',
* '</soap:Envelope>'
* ]
*/
envelopeTpl: [
'<?xml version="1.0" encoding="utf-8" ?>',
'<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">',
'{[values.bodyTpl.apply(values)]}',
'</soap:Envelope>'
],
/**
* @cfg {Ext.XTemplate/Array} createBodyTpl
* The template used to create the SOAP body for the "create" action. If not specified
* {@link #writeBodyTpl} will be used for the "create" action.
*/
createBodyTpl: null,
/**
* @cfg {Ext.XTemplate/Array} [readBodyTpl=undefined]
* The template used to create the SOAP body for the "read" action. Defaults to:
*
* [
* '<soap:Body>',
* '<{operation} xmlns="{targetNamespace}">',
* '<tpl foreach="params">',
* '<{$}>{.}</{$}>',
* '</tpl>',
* '</{operation}>',
* '</soap:Body>'
* ]
*/
readBodyTpl: [
'<soap:Body>',
'<{operation} xmlns="{targetNamespace}">',
'<tpl foreach="params">',
'<{$}>{.}</{$}>',
'</tpl>',
'</{operation}>',
'</soap:Body>'
],
/**
* @cfg {Ext.XTemplate/Array} updateBodyTpl
* The template used to create the SOAP body for the "update" action. If not specified
* {@link #writeBodyTpl} will be used for the "update" action.
*/
updateBodyTpl: null,
/**
* @cfg {Ext.XTemplate/Array} destroyBodyTpl
* The template used to create the SOAP body for the "destroy" action. If not specified
* {@link #writeBodyTpl} will be used for the "destroy" action.
*/
destroyBodyTpl: null,
/**
* @cfg {Ext.XTemplate/Array} [writeBodyTpl=undefined]
* The default template used to create the SOAP body for write actions (create, update,
* and destroy). The individual body templates for each write action can be configured
* using {@link #createBodyTpl}, {@link #updateBodyTpl}, and {@link #destroyBodyTpl}.
* Defaults to:
*
* [
* '<soap:Body>',
* '<{operation} xmlns="{targetNamespace}">',
* '<tpl for="records">',
* '{% var recordName=values.modelName.split(".").pop(); %}',
* '<{[recordName]}>',
* '<tpl for="fields">',
* '<{name}>{[parent.get(values.name)]}</{name}>',
* '</tpl>',
* '</{[recordName]}>',
* '</tpl>',
* '</{operation}>',
* '</soap:Body>'
* ]
*/
writeBodyTpl: [
'<soap:Body>',
'<{operation} xmlns="{targetNamespace}">',
'<tpl for="records">',
'{% var recordName=values.modelName.split(".").pop(); %}',
'<{[recordName]}>',
'<tpl for="fields">',
'<{name}>{[parent.get(values.name)]}</{name}>',
'</tpl>',
'</{[recordName]}>',
'</tpl>',
'</{operation}>',
'</soap:Body>'
],
/**
* @cfg {String} targetNamespace
* namespace URI used by {@link #createBodyTpl}, {@link #readBodyTpl}, {@link #updateBodyTpl},
* and {@link #destroyBodyTpl} as the "xmlns" attribute for the operation element.
*/
targetNamespace: ''
},
applyEnvelopeTpl: function(tpl) {
return this.createTpl(tpl);
},
applyCreateBodyTpl: function(tpl) {
return this.createTpl(tpl);
},
applyReadBodyTpl: function(tpl) {
return this.createTpl(tpl);
},
applyUpdateBodyTpl: function(tpl) {
return this.createTpl(tpl);
},
applyDestroyBodyTpl: function(tpl) {
return this.createTpl(tpl);
},
applyWriteBodyTpl: function(tpl) {
return this.createTpl(tpl);
},
createTpl: function(tpl) {
if (tpl && !tpl.isTpl) {
tpl = new Ext.XTemplate(tpl);
}
return tpl;
},
/**
* @property {Object} actionMethods
* @readonly
* Mapping of action name to HTTP request method. All SOAP actions are mapped to 'POST'
*/
doRequest: function(operation) {
var me = this,
action = operation.getAction(),
soapOperation = me.getApi()[action],
params = Ext.applyIf(operation.getParams() || {}, me.getExtraParams() || {}),
xmlData = me.getEnvelopeTpl().apply({
operation: soapOperation,
targetNamespace: me.getTargetNamespace(),
params: params,
records: operation.getRecords(),
bodyTpl: me.getBodyTpl(action)
}),
request = new Ext.data.Request({
url: me.getUrl() + '?' + me.getOperationParam() + '=' + soapOperation,
method: 'POST',
action: action,
operation: operation,
xmlData: xmlData,
headers: Ext.apply({
SOAPAction: me.getSoapAction()[action]
}, me.getHeaders()),
timeout: me.getTimeout(),
scope: me,
disableCaching: false
});
// explicitly set it to false, ServerProxy handles caching
request.setCallback(me.createRequestCallback(request, operation));
return me.sendRequest(request);
},
getBodyTpl: function(action) {
action = Ext.String.capitalize(action);
var tpl = this['get' + action + 'BodyTpl']();
return tpl || this.getWriteBodyTpl();
}
});