Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(86)

Unified Diff: third_party/gsutil/third_party/protorpc/experimental/javascript/protorpc.js

Issue 1377933002: [catapult] - Copy Telemetry's gsutilz over to third_party. (Closed) Base URL: https://github.com/catapult-project/catapult.git@master
Patch Set: Rename to gsutil. Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/gsutil/third_party/protorpc/experimental/javascript/protorpc.js
diff --git a/third_party/gsutil/third_party/protorpc/experimental/javascript/protorpc.js b/third_party/gsutil/third_party/protorpc/experimental/javascript/protorpc.js
new file mode 100644
index 0000000000000000000000000000000000000000..476e530857fd62353db4824c617ca343da845045
--- /dev/null
+++ b/third_party/gsutil/third_party/protorpc/experimental/javascript/protorpc.js
@@ -0,0 +1,371 @@
+// Copyright 2011 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @fileoverview Javascript client implementation for ProtoRpc services.
+ * @author joetyson@gmail.com (Joe Tyson)
+ */
+
+goog.provide('ProtoRpc.RPC');
+goog.provide('ProtoRpc.RPC.State');
+goog.provide('ProtoRpc.ServiceStub');
+
+goog.require('ProtoRpc.EnumDescriptor');
+goog.require('ProtoRpc.Message');
+
+goog.require('goog.json');
+goog.require('goog.net.XmlHttp');
+
+
+/**
+ * Represents a client side RPC.
+ *
+ * @export
+ * @param {string} service_path Relative URI where service lives.
+ * @param {string} method_name Name of method being invoked.
+ * @param {Object} request The request.
+ * @param {Function} success Function to call when RPC completes.
+ * @param {Function=} error Function to call when RPC has an error.
+ * @constructor
+ */
+ProtoRpc.RPC = function(service_path, method_name, request, success, error) {
+ this.successCallback_ = success;
+ this.errorCallback_ = error || null;
+
+ this.request_ = request;
+
+ var xhr = new goog.net.XmlHttp();
+
+ /**
+ * Try to open an XMLHttpRequest. If an error occurs, it's generally
+ * due to a permission issue.
+ * @preserveTry
+ */
+ try {
+ xhr.open('POST', service_path + '.' + method_name, true);
+ } catch (err) {
+ this.setState_(ProtoRpc.RPC.State.REQUEST_ERROR);
+ }
+
+ xhr.setRequestHeader('Content-Type', ProtoRpc.RPC.CONTENT_TYPE);
+
+ /**
+ * Send request or catch error.
+ * @preserveTry
+ */
+ try {
+ xhr.onreadystatechange = goog.bind(this.onReadyStateChange_, this);
+ // TODO: What if serialization fails?
+ xhr.send(goog.json.serialize(request));
+ } catch (err) {
+ this.setState_(ProtoRpc.RPC.State.REQUEST_ERROR);
+ }
+
+ this.xhr_ = xhr;
+};
+
+
+/**
+ * Rpc States.
+ * @enum {string}
+ */
+ProtoRpc.RPC.State = {
+ OK: 'OK',
+ RUNNING: 'RUNNING',
+ REQUEST_ERROR: 'REQUEST_ERROR',
+ SERVER_ERROR: 'SERVER_ERROR',
+ NETWORK_ERROR: 'NETWORK_ERROR',
+ APPLICATION_ERROR: 'APPLICATION_ERROR'
+};
+
+
+/**
+ * Content-Type to use when making remote calls.
+ * @const
+ */
+ProtoRpc.RPC.CONTENT_TYPE = 'application/json;charset=utf-8';
+
+
+/**
+ * Reference to an XMLHttpRequest object being used for RPC.
+ * @type {XMLHttpRequest}
+ * @private
+ */
+ProtoRpc.RPC.prototype.xhr_ = null;
+
+
+/**
+ * Functon to call when RPC completes successfully.
+ * @type {Function}
+ * @private
+ */
+ProtoRpc.RPC.prototype.successCallback_ = null;
+
+
+/**
+ * Function to call when an error happens.
+ * @type {Function}
+ * @private
+ */
+ProtoRpc.RPC.prototype.errorCallback_ = null;
+
+
+/**
+ * The Rpc's request message.
+ * @type {Object}
+ * @private
+ */
+ProtoRpc.RPC.prototype.request_ = null;
+
+
+/**
+ * The Rpc's response from the server.
+ * @type {Object}
+ * @private
+ */
+ProtoRpc.RPC.prototype.response_ = null;
+
+
+/**
+ * The current state of the Rpc.
+ * @type {ProtoRpc.RPC.State}
+ * @private
+ */
+ProtoRpc.RPC.prototype.state_ = ProtoRpc.RPC.State.RUNNING;
+
+
+/**
+ * The Rpc's Error Message, if error.
+ * @type {string}
+ * @private
+ */
+ProtoRpc.RPC.prototype.errorMessage_ = '';
+
+
+/**
+ * The Rpc's Error Name, if error.
+ * @type {string}
+ * @private
+ */
+ProtoRpc.RPC.prototype.errorName_ = '';
+
+
+/**
+ * Method invoked when RPC's xhr readyState is changed.
+ * @private
+ */
+ProtoRpc.RPC.prototype.onReadyStateChange_ = function() {
+ if (this.state_ != ProtoRpc.RPC.State.RUNNING) {
+ return;
+ }
+
+ if (this.xhr_.readyState != goog.net.XmlHttp.ReadyState.COMPLETE) {
+ return;
+ }
+
+ var status = this.xhr_.status;
+ var statusText = this.xhr_.statusText;
+ var content = this.xhr_.responseText;
+
+ if (status >= 400) {
+ /**
+ * Try to parse RpcStatus from message.
+ * @preserveTry
+ */
+ try {
+ var rpcStatus = goog.json.parse(content);
+ this.errorName_ = rpcStatus['error_name'] || null;
+ this.errorMessage_ = rpcStatus['error_message'] || null;
+ // TODO(joe): More robust RpcStatus handling...
+ this.setState_(rpcStatus['state']);
+ } catch (err) {
+ this.errorName_ = 'Unknown Error.';
+ this.setState_(ProtoRpc.RPC.State.REQUEST_ERROR);
+ }
+ return;
+ }
+
+ // TODO: validation
+ // TODO: What if parsing fails?
+ this.response_ = goog.json.parse(content);
+ this.setState_(ProtoRpc.RPC.State.OK);
+};
+
+
+/**
+ * Set the Rpc's state.
+ * @param {ProtoRpc.RPC.State} state The Rpc State to set.
+ * @private
+ */
+ProtoRpc.RPC.prototype.setState_ = function(state) {
+ // TODO: Bitmask "allowed" transitions?
+ this.state_ = state;
+ if (state != ProtoRpc.RPC.State.OK) {
+ this.callErrorHandler_();
+ return;
+ }
+ this.callSuccessHandler_();
+};
+
+
+/** @private */
+ProtoRpc.RPC.prototype.callErrorHandler_ = function() {
+ // TODO: optional context/this?
+ this.errorCallback_(this);
+};
+
+
+/** @private */
+ProtoRpc.RPC.prototype.callSuccessHandler_ = function() {
+ // TODO: optional context/this?
+ this.successCallback_(this);
+};
+
+
+/**
+ * Get the response from a completed RPC.
+ * Throws {@code ProtoRpc.RpcError} if an error occured while
+ * running the RPC.
+ * @return {Object} The response message from RPC.
+ * @export
+ */
+ProtoRpc.RPC.prototype.getResponse = function() {
+ if (this.state_ != ProtoRpc.RPC.State.OK) {
+ throw this.getError();
+ }
+ return this.response_;
+};
+
+
+/**
+ * Get the error from a failed RPC. This may be any of the appropriate
+ * error types which can be associated with an RPC.
+ * @export
+ * @return {Error} The Error associated with RPC.
+ */
+ProtoRpc.RPC.prototype.getError = function() {
+ // TODO: if not in error, do something.
+ var error = new Error(this.errorName_);
+ error.message = this.errorMessage_;
+ error.type = this.state_;
+ return error;
+};
+
+
+/**
+ * Represents a Service Stub for a given service name, path, and set
+ * of methods.
+ * @param {string} path The path where the service accepts method calls.
+ * @param {Array.<ProtoRpc.MethodDescriptor>} methods An array of method
+ * descriptors.
+ * @constructor
+ */
+ProtoRpc.ServiceStub = function(path, methods) {
+ this.path_ = path;
+ var l = methods.length;
+ for (var i = 0; i < l; i++) {
+ this.addMethod_(methods[i]);
+ }
+};
+
+
+/**
+ * Add a method to the service.
+ * @param {ProtoRpc.MethodDescriptor} method_descriptor The method descriptor.
+ * @private
+ */
+ProtoRpc.ServiceStub.prototype.addMethod_ = function(method_descriptor) {
+ var method_name = method_descriptor.name;
+ this[method_name] = this.makeMethod_(method_name, this.path_);
+};
+
+/**
+ * Helper to make methods.
+ * @param {string} name Method name.
+ * @param {string} path Service path.
+ * @return {function({request: Object,
+ * success: function(ProtoRpc.RPC),
+ * error: function(ProtoRpc.RPC)})}
+ * @private
+ */
+ProtoRpc.ServiceStub.prototype.makeMethod_ = function(name, path) {
+ return function(kwargs) {
+ var request = kwargs['request'] || {};
+ var success = kwargs['success'];
+ var error = kwargs['error'] || null;
+
+ if (!goog.isFunction(success)) {
+ throw Error('Success callback needs to be a function!');
+ }
+
+ if (error && !goog.isFunction(error)) {
+ throw Error('Error callback needs to be a function!');
+ }
+
+ return new ProtoRpc.RPC(path, name, request, success, error);
+ };
+};
+
+/**
+ * Protojson Specific Serializer.
+ * @constructor
+ */
+ProtoRpc.Serializer = function() {
+ // TODO: Have option for using key's as field number vs. field name.
+};
+
+ProtoRpc.Serializer.prototype.serialize = function(message) {
+ var descriptor = message.getDescriptor();
+ var fields = descriptor['fields'];
+
+ var obj = {};
+
+ for (var i = 0; i < fields.length; i++) {
+ var field = fields[i];
+
+ if (message.has(field)) {
+ if (field['label'] == 'REPEATED') {
+ var arr = [];
+ obj[field.toString()] = arr;
+
+ var repeatedValues = message.get(field);
+ for (var j = 0; j < repeatedValues.length; j++) {
+ arr.push(this.serialize_(field, repeatedValues[j]));
+ }
+ } else {
+ obj[field.toString()] = message.get(field);
+ }
+ } else {
+ // Default values
+ }
+ }
+};
+
+
+/**
+ * @param {ProtoRpc.FieldDescriptor} field Field Descriptor of value.
+ * @param {*} value Field's unserialized value.
+ */
+ProtoRpc.Serializer.prototype.serialize_ = function(field, value) {
+ switch (field['variant']) {
+ case ProtoRpc.Variant.MESSAGE:
+ return this.serializeMessage_(value);
+ break;
+ case ProtoRpc.Variant.ENUM:
+ return this.serializeEnum_(value);
+ break;
+ default:
+ return value;
+ }
+};

Powered by Google App Engine
This is Rietveld 408576698