github.com/jbking/gohan@v0.0.0-20151217002006-b41ccf1c2a96/extension/otto/gohan_core.go (about)

     1  // Copyright (C) 2015 NTT Innovation Institute, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //    http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
    12  // implied.
    13  // See the License for the specific language governing permissions and
    14  // limitations under the License.
    15  
    16  package otto
    17  
    18  import (
    19  	"github.com/dop251/otto"
    20  
    21  	"github.com/cloudwan/gohan/schema"
    22  
    23  	"github.com/cloudwan/gohan/extension"
    24  	"github.com/op/go-logging"
    25  
    26  	l "github.com/cloudwan/gohan/log"
    27  )
    28  
    29  var log = logging.MustGetLogger(l.GetModuleName())
    30  
    31  func init() {
    32  	gohanInit := func(env *Environment) {
    33  		vm := env.VM
    34  		builtins := map[string]interface{}{
    35  			"require": func(call otto.FunctionCall) otto.Value {
    36  				VerifyCallArguments(&call, "require", 1)
    37  				moduleName := call.Argument(0).String()
    38  				value, _ := vm.ToValue(extension.RequireModule(moduleName))
    39  				return value
    40  			},
    41  			"gohan_schemas": func(call otto.FunctionCall) otto.Value {
    42  				VerifyCallArguments(&call, "gohan_schemas", 0)
    43  				manager := schema.GetManager()
    44  				response := []interface{}{}
    45  				for _, schema := range manager.OrderedSchemas() {
    46  					response = append(response, schema.RawData)
    47  				}
    48  				value, _ := vm.ToValue(response)
    49  				return value
    50  			},
    51  			"gohan_schema_url": func(call otto.FunctionCall) otto.Value {
    52  				VerifyCallArguments(&call, "gohan_schema_url", 1)
    53  				schemaID := call.Argument(0).String()
    54  				manager := schema.GetManager()
    55  				schema, ok := manager.Schema(schemaID)
    56  				if !ok {
    57  					ThrowOttoException(&call, unknownSchemaErrorMesssageFormat, schemaID)
    58  				}
    59  				value, _ := vm.ToValue(schema.URL)
    60  				return value
    61  			},
    62  			"gohan_policies": func(call otto.FunctionCall) otto.Value {
    63  				VerifyCallArguments(&call, "gohan_policies", 0)
    64  				manager := schema.GetManager()
    65  				response := []interface{}{}
    66  				for _, policy := range manager.Policies() {
    67  					response = append(response, policy.RawData)
    68  				}
    69  				value, _ := vm.ToValue(response)
    70  				return value
    71  			},
    72  		}
    73  
    74  		for name, object := range builtins {
    75  			vm.Set(name, object)
    76  		}
    77  
    78  		err := env.Load("<Gohan built-in exceptions>", `
    79  		function BaseException() {
    80  		  this.fields = ["name", "message"]
    81  		  this.message = "";
    82  		  this.name = "BaseException";
    83  
    84  		  this.toDict = function () {
    85  		    return _.reduce(this.fields, function(resp, field) {
    86  		      resp[field] = this[field];
    87  		      return resp;
    88  		    }, {}, this);
    89  		  };
    90  
    91  		  this.toString = function () {
    92  		    return this.name.concat("(").concat(this.message).concat(")");
    93  		  };
    94  		}
    95  
    96  		function CustomException(msg, code) {
    97  		  BaseException.call(this);
    98  		  this.message = msg;
    99  		  this.name = "CustomException";
   100  		  this.code = code;
   101  		  this.fields.push("code");
   102  		}
   103  		CustomException.prototype = Object.create(BaseException.prototype);
   104  
   105  		function ResourceException(msg, problem) {
   106  		  BaseException.call(this);
   107  		  this.message = msg;
   108  		  this.name = "ResourceException";
   109  		  this.problem = problem;
   110  		  this.fields.push("problem");
   111  		}
   112  		ResourceException.prototype = Object.create(BaseException.prototype);
   113  
   114  		function ExtensionException(msg, inner_exception) {
   115  		  BaseException.call(this);
   116  		  this.message = msg;
   117  		  this.name = "ExtensionException";
   118  		  this.inner_exception = inner_exception;
   119  		  this.fields.push("inner_exception");
   120  		}
   121  		ExtensionException.prototype = Object.create(BaseException.prototype);
   122  		`)
   123  		if err != nil {
   124  			log.Fatal(err)
   125  		}
   126  
   127  		err = env.Load("<Gohan built-ins>", `
   128  		var gohan_handler = {}
   129  		function gohan_register_handler(event_type, func){
   130  		  if(_.isUndefined(gohan_handler[event_type])){
   131  		    gohan_handler[event_type] = [];
   132  		  }
   133  		  gohan_handler[event_type].push(func)
   134  		}
   135  
   136  		function gohan_handle_event(event_type, context){
   137  		  if(_.isUndefined(gohan_handler[event_type])){
   138  		    return;
   139  		  }
   140  
   141  		  for (var i = 0; i < gohan_handler[event_type].length; ++i) {
   142  		    try {
   143  		      gohan_handler[event_type][i](context);
   144  		      //backwards compatibility
   145  		      if (!_.isUndefined(context.response_code)) {
   146  		        throw new CustomException(context.response, context.response_code);
   147  		      }
   148  		    } catch(e) {
   149  		      if (e instanceof BaseException) {
   150  		        context.exception = e.toDict();
   151  		        context.exception_message = event_type.concat(": ").concat(e.toString());
   152  		      } else {
   153  		        throw e;
   154  		      }
   155  		    }
   156  		  }
   157  		}
   158  		`)
   159  		if err != nil {
   160  			log.Fatal(err)
   161  		}
   162  	}
   163  	RegisterInit(gohanInit)
   164  }