github.com/jbking/gohan@v0.0.0-20151217002006-b41ccf1c2a96/extension/extension.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 extension
    17  
    18  import (
    19  	"fmt"
    20  
    21  	"github.com/cloudwan/gohan/schema"
    22  )
    23  
    24  var modules = map[string]interface{}{}
    25  
    26  //GoCallback is type for go based callback
    27  type GoCallback func(event string, context map[string]interface{}) error
    28  
    29  var goCallbacks = map[string]GoCallback{}
    30  
    31  //Environment is a interface for extension environment
    32  type Environment interface {
    33  	Load(source, code string) error
    34  	RegisterObject(objectID string, object interface{})
    35  	LoadExtensionsForPath(extensions []*schema.Extension, path string) error
    36  	HandleEvent(event string, context map[string]interface{}) error
    37  	Clone() Environment
    38  }
    39  
    40  var manager *Manager
    41  
    42  //Manager takes care of mapping schemas to Environments.
    43  //This is a singleton class.
    44  type Manager struct {
    45  	environments map[string]Environment
    46  }
    47  
    48  //RegisterEnvironment registers a new environment for the given schema ID
    49  func (manager *Manager) RegisterEnvironment(schemaID string, env Environment) error {
    50  	if _, ok := manager.environments[schemaID]; ok {
    51  		return fmt.Errorf("Environment already registered for this schema")
    52  	}
    53  	manager.environments[schemaID] = env
    54  	return nil
    55  }
    56  
    57  //UnRegisterEnvironment removes an environment registered for the given schema ID
    58  func (manager *Manager) UnRegisterEnvironment(schemaID string) error {
    59  	if _, ok := manager.environments[schemaID]; !ok {
    60  		return fmt.Errorf("No environment registered for this schema")
    61  	}
    62  	delete(manager.environments, schemaID)
    63  	return nil
    64  }
    65  
    66  //GetEnvironment returns the environment registered for the given schema ID
    67  func (manager *Manager) GetEnvironment(schemaID string) (env Environment, ok bool) {
    68  	env, ok = manager.environments[schemaID]
    69  	if ok {
    70  		env = env.Clone()
    71  	}
    72  	return
    73  }
    74  
    75  //GetManager gets manager
    76  func GetManager() *Manager {
    77  	if manager == nil {
    78  		manager = &Manager{
    79  			environments: map[string]Environment{},
    80  		}
    81  	}
    82  	return manager
    83  }
    84  
    85  //ClearManager clears manager
    86  func ClearManager() {
    87  	manager = nil
    88  }
    89  
    90  //RegisterModule registers modules
    91  func RegisterModule(name string, module interface{}) {
    92  	modules[name] = module
    93  }
    94  
    95  //RequireModule returns module
    96  func RequireModule(name string) interface{} {
    97  	module, ok := modules[name]
    98  	if ok {
    99  		return module
   100  	}
   101  	return nil
   102  }
   103  
   104  //RegisterGoCallback register go call back
   105  func RegisterGoCallback(name string, callback GoCallback) {
   106  	goCallbacks[name] = callback
   107  }
   108  
   109  //GetGoCallback returns registered go callback
   110  func GetGoCallback(name string) GoCallback {
   111  	callback, ok := goCallbacks[name]
   112  	if !ok {
   113  		return nil
   114  	}
   115  	return callback
   116  }
   117  
   118  // Error is created when a problem has occured during event handling. It contains the information
   119  // required to reraise the javascript exception that caused this error.
   120  type Error struct {
   121  	error
   122  	ExceptionInfo map[string]interface{}
   123  }
   124  
   125  //HandleEvent handles the event in the given environment
   126  func HandleEvent(context map[string]interface{}, environment Environment, event string) error {
   127  	if err := environment.HandleEvent(event, context); err != nil {
   128  		return fmt.Errorf("extension error: %s", err)
   129  	}
   130  	exceptionInfoRaw, ok := context["exception"]
   131  	if !ok {
   132  		return nil
   133  	}
   134  	exceptionInfo, ok := exceptionInfoRaw.(map[string]interface{})
   135  	if !ok {
   136  		return fmt.Errorf("extension returned invalid error information")
   137  	}
   138  	exceptionMessage := context["exception_message"]
   139  	return Error{fmt.Errorf("%v", exceptionMessage), exceptionInfo}
   140  }