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 }