unageanu-jiji 1.1.4 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (233) hide show
  1. data/ChangeLog +24 -1
  2. data/README +0 -0
  3. data/base/shared_lib/moving_average.rb +34 -33
  4. data/base/shared_lib/system/cross.rb +76 -0
  5. data/base/shared_lib/system/position_manager.rb +160 -0
  6. data/base/shared_lib/system/signal.rb +347 -0
  7. data/html/css/datatable.css +4 -4
  8. data/html/css/default.css +57 -5
  9. data/html/css/treeview.css +205 -0
  10. data/html/img/bin_closed.png +0 -0
  11. data/html/img/bin_empty.png +0 -0
  12. data/html/img/button_add_small.gif +0 -0
  13. data/html/img/button_add_small_gray.gif +0 -0
  14. data/html/img/button_add_small_over.gif +0 -0
  15. data/html/img/button_mkcol.gif +0 -0
  16. data/html/img/button_mkcol_gray.gif +0 -0
  17. data/html/img/button_mkcol_over.gif +0 -0
  18. data/html/img/button_remove_small.gif +0 -0
  19. data/html/img/button_remove_small_gray.gif +0 -0
  20. data/html/img/button_remove_small_over.gif +0 -0
  21. data/html/img/button_rename.gif +0 -0
  22. data/html/img/button_rename_gray.gif +0 -0
  23. data/html/img/button_rename_over.gif +0 -0
  24. data/html/img/control_play.png +0 -0
  25. data/html/img/control_play_blue.png +0 -0
  26. data/html/img/folder.png +0 -0
  27. data/html/img/folder_brick.png +0 -0
  28. data/html/img/folder_user.png +0 -0
  29. data/html/{js/codepress/images → img}/line-numbers.png +0 -0
  30. data/html/img/page_white_ruby.png +0 -0
  31. data/html/img/sidebar_agent_edit.png +0 -0
  32. data/html/img/sidebar_agent_edit_over.png +0 -0
  33. data/html/img/sidebar_agent_edit_s.png +0 -0
  34. data/html/img/yui/treeview-sprite.gif +0 -0
  35. data/html/index.html +34 -18
  36. data/html/js/agent-editor/agent-editor-page.js +324 -0
  37. data/html/js/agent-editor/agent-editor.js +363 -0
  38. data/html/js/agent-editor/agent-list-tree.js +251 -0
  39. data/html/js/agent-selector.js +23 -28
  40. data/html/js/app.js +63 -91
  41. data/html/js/bt-create-page.js +25 -19
  42. data/html/js/container-min.js +1 -1
  43. data/html/js/container.js +944 -0
  44. data/html/js/edit_area/autocompletion.js +11 -13
  45. data/html/js/edit_area/edit_area.css +79 -40
  46. data/html/js/edit_area/edit_area.js +255 -226
  47. data/html/js/edit_area/edit_area_compressor.php +4 -4
  48. data/html/js/edit_area/edit_area_full.gz +0 -0
  49. data/html/js/edit_area/edit_area_full.js +31 -31
  50. data/html/js/edit_area/edit_area_full_with_plugins.gz +0 -0
  51. data/html/js/edit_area/edit_area_full_with_plugins.js +31 -31
  52. data/html/js/edit_area/edit_area_functions.js +448 -341
  53. data/html/js/edit_area/edit_area_loader.js +409 -397
  54. data/html/js/edit_area/elements_functions.js +120 -123
  55. data/html/js/edit_area/highlight.js +305 -197
  56. data/html/js/edit_area/images/goto.png +0 -0
  57. data/html/js/edit_area/images/help.png +0 -0
  58. data/html/js/edit_area/images/redo.png +0 -0
  59. data/html/js/edit_area/images/save.png +0 -0
  60. data/html/js/edit_area/images/search.png +0 -0
  61. data/html/js/edit_area/images/undo.png +0 -0
  62. data/html/js/edit_area/images/word_wrap.gif +0 -0
  63. data/html/js/edit_area/keyboard.js +5 -5
  64. data/html/js/edit_area/langs/bg.js +73 -0
  65. data/html/js/edit_area/langs/cs.js +2 -0
  66. data/html/js/edit_area/langs/de.js +2 -0
  67. data/html/js/edit_area/langs/dk.js +2 -0
  68. data/html/js/edit_area/langs/en.js +2 -0
  69. data/html/js/edit_area/langs/eo.js +2 -0
  70. data/html/js/edit_area/langs/es.js +2 -0
  71. data/html/js/edit_area/langs/fi.js +67 -0
  72. data/html/js/edit_area/langs/fr.js +2 -0
  73. data/html/js/edit_area/langs/hr.js +2 -0
  74. data/html/js/edit_area/langs/it.js +2 -0
  75. data/html/js/edit_area/langs/ja.js +2 -0
  76. data/html/js/edit_area/langs/mk.js +2 -0
  77. data/html/js/edit_area/langs/nl.js +2 -0
  78. data/html/js/edit_area/langs/pl.js +2 -0
  79. data/html/js/edit_area/langs/pt.js +2 -0
  80. data/html/js/edit_area/langs/ru.js +2 -0
  81. data/html/js/edit_area/langs/sk.js +2 -0
  82. data/html/js/edit_area/langs/zh.js +67 -0
  83. data/html/js/edit_area/manage_area.js +362 -205
  84. data/html/js/edit_area/plugins/charmap/langs/bg.js +12 -0
  85. data/html/js/edit_area/plugins/charmap/langs/zh.js +6 -0
  86. data/html/js/edit_area/plugins/test/langs/bg.js +10 -0
  87. data/html/js/edit_area/plugins/test/langs/zh.js +4 -0
  88. data/html/js/edit_area/reg_syntax/java.js +56 -0
  89. data/html/js/edit_area/reg_syntax/ruby.js +9 -9
  90. data/html/js/edit_area/reg_syntax.js +15 -13
  91. data/html/js/edit_area/regexp.js +36 -32
  92. data/html/js/edit_area/resize_area.js +43 -47
  93. data/html/js/edit_area/search_replace.js +29 -29
  94. data/html/js/edit_area/template.html +6 -4
  95. data/html/js/json-broker-client.js +23 -17
  96. data/html/js/result-page.js +107 -57
  97. data/html/js/rt-setting-page.js +38 -15
  98. data/html/js/sidebar.js +41 -27
  99. data/html/js/templates.js +167 -32
  100. data/html/js/utils.js +143 -7
  101. data/html/js/yui/treeview.js +3671 -0
  102. data/html/swf/chart.swf +0 -0
  103. data/html/test/agent_editor_spec.js +815 -0
  104. data/html/test/index.html +40 -0
  105. data/html/test/jsspec/JSSpec.css +224 -0
  106. data/html/test/jsspec/JSSpec.js +1549 -0
  107. data/html/test/jsspec/diff_match_patch.js +1 -0
  108. data/html/test/utils_spec.js +111 -0
  109. data/lib/jiji/agent/agent.rb +69 -12
  110. data/lib/jiji/agent/agent_manager.rb +18 -12
  111. data/lib/jiji/agent/agent_registry.rb +35 -121
  112. data/lib/jiji/collector.rb +16 -6
  113. data/lib/jiji/command.rb +46 -5
  114. data/lib/jiji/dao/file_system_dao.rb +158 -0
  115. data/lib/jiji/dao/timed_data_dao.rb +2 -0
  116. data/lib/jiji/dao/trade_result_dao.rb +1 -1
  117. data/lib/jiji/error.rb +24 -8
  118. data/lib/jiji/migration/migrator1_2_0.rb +67 -0
  119. data/lib/jiji/models.rb +82 -24
  120. data/lib/jiji/operator.rb +55 -51
  121. data/lib/jiji/output.rb +85 -29
  122. data/lib/jiji/output_manager.rb +84 -0
  123. data/lib/jiji/plugin/embedded/single_click_client.rb +2 -2
  124. data/lib/jiji/plugin/securities_plugin.rb +0 -1
  125. data/lib/jiji/process.rb +229 -208
  126. data/lib/jiji/process_manager.rb +190 -96
  127. data/lib/jiji/registry.rb +87 -19
  128. data/lib/jiji/server.rb +1 -0
  129. data/lib/jiji/service/agent_service.rb +147 -48
  130. data/lib/jiji/service/output_service.rb +37 -17
  131. data/lib/jiji/service/process_service.rb +3 -5
  132. data/lib/jiji/service/trade_result_service.rb +4 -5
  133. data/lib/jiji/util/file_lock.rb +4 -4
  134. data/lib/jiji/util/include_proxy.rb +17 -0
  135. data/lib/jiji/util/json_broker.rb +6 -4
  136. data/lib/jiji/util/util.rb +1 -1
  137. data/swf/chart/fx/chart/Chart.as +7 -0
  138. data/swf/chart/fx/chart/ui/graph/GraphManager.as +15 -2
  139. data/test/ProcessTest/agents/foo.rb +10 -0
  140. data/test/ProcessTest/conf/configuration.yaml +3 -0
  141. data/test/agent/agent_tests.rb +10 -0
  142. data/test/agent/test_AgentManager.rb +28 -12
  143. data/test/agent/test_AgentRegistry.rb +194 -99
  144. data/test/agent/test_PeriodicallyAgent.rb +1 -2
  145. data/test/agent/test_Permitter.rb +1 -2
  146. data/test/all_tests.rb +7 -19
  147. data/test/dao/dao_tests.rb +9 -0
  148. data/test/dao/test_FileSystemDao.rb +431 -0
  149. data/test/dao/test_RateDao.rb +5 -7
  150. data/test/dao/test_TradeResultDao.rb +1 -2
  151. data/test/migration/migration_tests.rb +10 -0
  152. data/test/migration/migrator1_2_0test_data/basic/out/M2NlOTA2ODEtZDdlNi00NWU1LWIwNDQtMjBmODY2ZGNkNzBj/56e75YuV5bmz5Z2H57ea/meta.yaml +8 -0
  153. data/test/migration/migrator1_2_0test_data/basic/out/MDVhYzcxMjYtMGFlMS00Mzk0LWEyNmUtYjVjZjgwNDA0ZmE2/56e75YuV5bmz5Z2H57ea/meta.yaml +8 -0
  154. data/test/migration/migrator1_2_0test_data/basic/out/MzA1YTk0NDgtNzhjNi00NDk3LTk2NTktYzE1ZjBhNzdiYjNj/56e75YuV5bmz5Z2H57ea/meta.yaml +8 -0
  155. data/test/migration/migrator1_2_0test_data/basic/out/YjRkOTI1MzEtZTM4MS00YjQwLTg1ZTQtMWFmZDRlNDUwMzBm/56e75YuV5bmz5Z2H57ea/meta.yaml +9 -0
  156. data/test/migration/migrator1_2_0test_data/basic/props.yaml +85 -0
  157. data/test/migration/migrator1_2_0test_data/illegal_props/out/M2NlOTA2ODEtZDdlNi00NWU1LWIwNDQtMjBmODY2ZGNkNzBj/56e75YuV5bmz5Z2H57ea/meta.yaml +8 -0
  158. data/test/migration/migrator1_2_0test_data/illegal_props/out/MDVhYzcxMjYtMGFlMS00Mzk0LWEyNmUtYjVjZjgwNDA0ZmE2/56e75YuV5bmz5Z2H57ea/meta.yaml +8 -0
  159. data/test/migration/migrator1_2_0test_data/illegal_props/out/MzA1YTk0NDgtNzhjNi00NDk3LTk2NTktYzE1ZjBhNzdiYjNj/56e75YuV5bmz5Z2H57ea/meta.yaml +8 -0
  160. data/test/migration/migrator1_2_0test_data/illegal_props/out/YjRkOTI1MzEtZTM4MS00YjQwLTg1ZTQtMWFmZDRlNDUwMzBm/56e75YuV5bmz5Z2H57ea/meta.yaml +9 -0
  161. data/test/migration/migrator1_2_0test_data/illegal_props/props.yaml +1 -0
  162. data/test/migration/migrator1_2_0test_data/no_outs/props.yaml +85 -0
  163. data/test/migration/migrator1_2_0test_data/no_props/out/M2NlOTA2ODEtZDdlNi00NWU1LWIwNDQtMjBmODY2ZGNkNzBj/56e75YuV5bmz5Z2H57ea/meta.yaml +8 -0
  164. data/test/migration/migrator1_2_0test_data/no_props/out/MDVhYzcxMjYtMGFlMS00Mzk0LWEyNmUtYjVjZjgwNDA0ZmE2/56e75YuV5bmz5Z2H57ea/meta.yaml +8 -0
  165. data/test/migration/migrator1_2_0test_data/no_props/out/MzA1YTk0NDgtNzhjNi00NDk3LTk2NTktYzE1ZjBhNzdiYjNj/56e75YuV5bmz5Z2H57ea/meta.yaml +8 -0
  166. data/test/migration/migrator1_2_0test_data/no_props/out/YjRkOTI1MzEtZTM4MS00YjQwLTg1ZTQtMWFmZDRlNDUwMzBm/56e75YuV5bmz5Z2H57ea/meta.yaml +9 -0
  167. data/test/migration/test_Migrator.rb +1 -1
  168. data/test/migration/test_Migrator1_0_3.rb +1 -1
  169. data/test/migration/test_Migrator1_1_0.rb +1 -1
  170. data/test/migration/test_Migrator1_2_0.rb +94 -0
  171. data/test/plugin/embedded/test_SingleClickClient.rb +1 -2
  172. data/test/plugin/plugin_tests.rb +8 -0
  173. data/test/plugin/test_Loader.rb +1 -1
  174. data/test/shared/rate.csv +144 -0
  175. data/test/shared/shared_tests.rb +9 -0
  176. data/test/shared/test_Cross.rb +144 -0
  177. data/test/shared/test_PositionManager.rb +285 -0
  178. data/test/shared/test_Signal.rb +65 -0
  179. data/test/test_Output.rb +28 -21
  180. data/test/test_OutputManager.rb +162 -0
  181. data/test/test_Output_registry.rb +6 -17
  182. data/test/test_Process.rb +434 -222
  183. data/test/test_ProcessManager.rb +458 -101
  184. data/test/test_utils.rb +71 -8
  185. data/test/util/test_BlockToSession.rb +1 -2
  186. data/test/util/test_CSV.rb +1 -2
  187. data/test/util/test_SynchronizeInterceptor.rb +1 -2
  188. data/test/util/util_tests.rb +9 -0
  189. metadata +127 -47
  190. data/html/js/agent-editor-page.js +0 -440
  191. data/html/js/codepress/codepress.css +0 -21
  192. data/html/js/codepress/codepress.html +0 -35
  193. data/html/js/codepress/codepress.js +0 -138
  194. data/html/js/codepress/engines/gecko.js +0 -293
  195. data/html/js/codepress/engines/khtml.js +0 -0
  196. data/html/js/codepress/engines/msie.js +0 -304
  197. data/html/js/codepress/engines/older.js +0 -0
  198. data/html/js/codepress/engines/opera.js +0 -260
  199. data/html/js/codepress/images/line-numbers.gif +0 -0
  200. data/html/js/codepress/index.html +0 -443
  201. data/html/js/codepress/languages/asp.css +0 -71
  202. data/html/js/codepress/languages/asp.js +0 -117
  203. data/html/js/codepress/languages/autoit.css +0 -13
  204. data/html/js/codepress/languages/autoit.js +0 -32
  205. data/html/js/codepress/languages/csharp.css +0 -9
  206. data/html/js/codepress/languages/csharp.js +0 -25
  207. data/html/js/codepress/languages/css.css +0 -10
  208. data/html/js/codepress/languages/css.js +0 -23
  209. data/html/js/codepress/languages/generic.css +0 -9
  210. data/html/js/codepress/languages/generic.js +0 -25
  211. data/html/js/codepress/languages/html.css +0 -13
  212. data/html/js/codepress/languages/html.js +0 -59
  213. data/html/js/codepress/languages/java.css +0 -7
  214. data/html/js/codepress/languages/java.js +0 -24
  215. data/html/js/codepress/languages/javascript.css +0 -8
  216. data/html/js/codepress/languages/javascript.js +0 -30
  217. data/html/js/codepress/languages/perl.css +0 -11
  218. data/html/js/codepress/languages/perl.js +0 -27
  219. data/html/js/codepress/languages/php.css +0 -12
  220. data/html/js/codepress/languages/php.js +0 -61
  221. data/html/js/codepress/languages/ruby.css +0 -10
  222. data/html/js/codepress/languages/ruby.js +0 -26
  223. data/html/js/codepress/languages/sql.css +0 -10
  224. data/html/js/codepress/languages/sql.js +0 -30
  225. data/html/js/codepress/languages/text.css +0 -5
  226. data/html/js/codepress/languages/text.js +0 -9
  227. data/html/js/codepress/languages/vbscript.css +0 -71
  228. data/html/js/codepress/languages/vbscript.js +0 -117
  229. data/html/js/codepress/languages/xsl.css +0 -15
  230. data/html/js/codepress/languages/xsl.js +0 -103
  231. data/html/js/codepress/license.txt +0 -458
  232. data/html/js/edit_area/images/Thumbs.db +0 -0
  233. data/test/plugin/test_gem/a/lib/jiji_plugin_test.rb +0 -6
@@ -0,0 +1,944 @@
1
+ // ネームスペース
2
+ if ( typeof container == "undefined" ) {
3
+ container = {};
4
+ }
5
+
6
+ container.VERSION = "0.4.0";
7
+
8
+ /**
9
+ * コンテナ
10
+ * @param {Function} module コンポーネント定義を行う関数。
11
+ */
12
+ container.Container = function ( module ) {
13
+ var binder = new container.Binder( {} );
14
+ module( binder );
15
+ this.defs = binder.defs;
16
+
17
+ // 循環生成防止用のフィールド。作成中のモジュールの一覧が入る。
18
+ this.creating = [];
19
+
20
+ // 名前でキャッシュを作っておく。
21
+ // EagerSingletonなオブジェクトがあれば生成。
22
+ this.typeCache = {};
23
+ this.nameCache = {};
24
+ var thiz = this;
25
+ this.eachComponentDef( function( def ) {
26
+ if ( def && def[container.Annotation.Container]
27
+ && def[container.Annotation.Container][container.Annotation.Scope] == container.Scope.EagerSingleton ) {
28
+ thiz.create( def );
29
+ }
30
+ // 名前でキャッシュ
31
+ if ( def && def[container.Annotation.Container]
32
+ && def[container.Annotation.Container][container.Annotation.Name] ) {
33
+ var name = def[container.Annotation.Container][container.Annotation.Name];
34
+ if ( !thiz.nameCache[name] ) {
35
+ thiz.nameCache[name] = []
36
+ }
37
+ thiz.nameCache[name].push( def );
38
+ }
39
+ });
40
+ }
41
+ container.Container.prototype = {
42
+ /**
43
+ * コンポーネント名またはcontainer.Typeに対応するオブジェクトを取得します。
44
+ *
45
+ * @param {String or container.Type} nameOrType コンポーネント名またはcontainer.Type
46
+ * @return 対応するオブジェクト。複数のコンポーネントがマッチした場合、最初の1つを返します。
47
+ */
48
+ get: function( nameOrType ){
49
+ if ( nameOrType instanceof container.Type ) {
50
+ // キャッシュがなければスキャン
51
+ if ( !this.typeCache[nameOrType] ) {
52
+ this._createTypeCahce( nameOrType );
53
+ }
54
+ if ( this.typeCache[nameOrType].length > 0 ) {
55
+ return this.create( this.typeCache[nameOrType][0]);
56
+ } else {
57
+ throw container.createError( new Error(),
58
+ container.ErrorCode.ComponentNotFound,
59
+ "component not found.name=" + nameOrType, {"nameOrType":nameOrType} );
60
+ }
61
+ } else {
62
+ if ( this.nameCache[nameOrType] && this.nameCache[nameOrType].length > 0 ) {
63
+ return this.create( this.nameCache[nameOrType][0]);
64
+ } else {
65
+ throw container.createError( new Error(),
66
+ container.ErrorCode.ComponentNotFound,
67
+ "component not found.name=" + nameOrType, {"nameOrType":nameOrType} );
68
+ }
69
+ }
70
+ },
71
+ /**
72
+ * コンポーネント名またはcontainer.Typeに対応するオブジェクトをすべて取得します。
73
+ *
74
+ * @param {String or container.Type} nameOrType コンポーネント名またはcontainer.Type
75
+ * @return 対応するオブジェクトの配列
76
+ */
77
+ gets: function( nameOrType ){
78
+ var objects = [];
79
+ if ( nameOrType instanceof container.Type ) {
80
+ // キャッシュがなければスキャン
81
+ if ( !this.typeCache[nameOrType] ) {
82
+ this._createTypeCahce( nameOrType );
83
+ }
84
+ var defs = this.typeCache[nameOrType]
85
+ for ( var i=0; i < defs.length; i++ ) {
86
+ objects.push( this.create( defs[i]) );
87
+ }
88
+ } else {
89
+ if ( this.nameCache[nameOrType] ) {
90
+ var defs = this.nameCache[nameOrType];
91
+ for ( var i=0; i < defs.length; i++ ) {
92
+ objects.push( this.create( defs[i]) );
93
+ }
94
+ }
95
+ }
96
+ return objects;
97
+ },
98
+ /**
99
+ * コンテナを破棄します。
100
+ */
101
+ destroy: function( ) {
102
+ var thiz = this;
103
+ this.eachComponentDef( function( def ) {
104
+ if ( !def.instance ){ return; }
105
+ var obj = def.instance;
106
+ var config = def[container.Annotation.Container];
107
+ if ( !config || !config[container.Annotation.Destroy] ) { return; }
108
+ var destroy = config[container.Annotation.Destroy];
109
+ if ( typeof destroy == "string" ) {
110
+ obj[destroy].apply( obj, [this] );
111
+ } else if ( typeof destroy == "function" ) {
112
+ destroy( obj, thiz );
113
+ } else {
114
+ throw container.createError( new Error(),
115
+ container.ErrorCode.IllegalDefinition,
116
+ "illegal destroy method. string or function is supported.", {"def":def} );
117
+ }
118
+ def.instance = null;
119
+ });
120
+ },
121
+
122
+ /**
123
+ * コンポーネント定義からコンポーネントを生成する。
124
+ * @param {Hash} def コンポーネント定義
125
+ */
126
+ create: function( def ) {
127
+
128
+ // 既に作成済みのインスタンスがあればそれを返す。
129
+ if ( def.instance ) { return def.instance; }
130
+
131
+ // 循環チェック
132
+ if ( this._isCreating(def) ) {
133
+ throw container.createError( new Error(),
134
+ container.ErrorCode.CircularReference,
135
+ "circulative component creation.", {"def":def} );
136
+ }
137
+
138
+ try {
139
+ this.creating.push( def );
140
+
141
+ var obj = def.constractor( this ); // 生成
142
+ def.instance = obj; // キャッシュ
143
+
144
+ // アノーテョンで指定した設定とコンテナのコンポーネント設定をマージ
145
+ var config = def[container.Annotation.Container] || {};
146
+
147
+ // 自動インジェクション
148
+ if ( config[container.Annotation.AutoInjection] != false ) {
149
+ for ( var property in obj ) {
150
+ if ( obj[property] instanceof container.inner.Component ) {
151
+ obj[property] = this.get( obj[property].name );
152
+ } else if ( obj[ property] instanceof container.inner.Components ) {
153
+ obj[property] = this.gets( obj[property].name );
154
+ } else if ( obj[ property] === container.Inject ) {
155
+ obj[property] = this.get( property );
156
+ } else if ( obj[ property] === container.Injects ) {
157
+ obj[property] = this.gets( property );
158
+ }
159
+ }
160
+ }
161
+
162
+ // プロパティインジェクション
163
+ if ( config[container.Annotation.Inject] ) {
164
+ var inject = config[container.Annotation.Inject];
165
+ for ( var f in inject ) {
166
+ if ( inject[f] instanceof container.inner.Component ) {
167
+ obj[f] = this.get( inject[f].name );
168
+ } else if ( inject[f] instanceof container.inner.Components ) {
169
+ obj[f] = this.gets( inject[f].name );
170
+ } else if ( inject[f] instanceof container.inner.Provider ) {
171
+ obj[f] = inject[f].func( obj, this );
172
+ } else {
173
+ obj[f] = inject[f];
174
+ }
175
+ }
176
+ }
177
+
178
+ // 初期化関数の実行
179
+ if ( config[container.Annotation.Initialize] ) {
180
+ var initialize = config[container.Annotation.Initialize];
181
+ if ( typeof initialize == "string" ) {
182
+ obj[initialize].apply( obj, [this] );
183
+ } else if ( typeof initialize == "function" ) {
184
+ initialize( obj, this );
185
+ } else {
186
+ throw container.createError( new Error(),
187
+ container.ErrorCode.IllegalDefinition,
188
+ "illegal initialize method. string or function is supported.", {"def":def} );
189
+ }
190
+ }
191
+
192
+ // インターセプタの設定
193
+ if ( config[container.Annotation.Intercept] ) {
194
+ var interceptors = config[container.Annotation.Intercept];
195
+ for ( var i=0; i < interceptors.length; i++ ) {
196
+ this.applyInterceptor( obj, interceptors[i][0], interceptors[i][1] );
197
+ }
198
+ }
199
+
200
+ // グローバルインターセプタの設定
201
+ if ( this.defs.interceptors && def.componentType != "function" ) { // バインドメソッドには適用しない。
202
+ for ( var i=0; i < this.defs.interceptors.length; i++ ) {
203
+ var insterceptor = this.defs.interceptors[i];
204
+ if ( !insterceptor.nameMatcher) { continue; }
205
+ if ( insterceptor.nameMatcher instanceof container.Type
206
+ && insterceptor.nameMatcher.isImplementor(obj) ) {
207
+ this.applyInterceptor( obj, insterceptor.interceptor, insterceptor.methodMatcher );
208
+ } else if ( insterceptor.nameMatcher instanceof container.Matcher
209
+ && config[container.Annotation.Name]
210
+ && insterceptor.nameMatcher.match( config[container.Annotation.Name] )) {
211
+ this.applyInterceptor( obj, insterceptor.interceptor, insterceptor.methodMatcher );
212
+ }
213
+ }
214
+ }
215
+
216
+ // シングルトンの場合、次回同じインスタンスを返すのでコンポーネント定義にキャッシュしたままにしておく。
217
+ // プロトタイプの場合破棄
218
+ if ( config[container.Annotation.Scope] == container.Scope.Prototype ) {
219
+ def.instance = undefined;
220
+ }
221
+ return obj;
222
+ } catch ( error ) {
223
+ def.instance = undefined; // エラーの場合破棄
224
+ throw error;
225
+ } finally {
226
+ this.creating.pop();
227
+ }
228
+ },
229
+ /**
230
+ * インターセプターを適用する。
231
+ * @param {Object} target 適用対象のオブジェクト
232
+ */
233
+ applyInterceptor: function( target, interceptor, matcher ) {
234
+ if ( !interceptor || !matcher ) { return; }
235
+ for ( var f in target ) {
236
+ if ( typeof target[f] == "function" && matcher.match( f ) ) {
237
+ (function() { // f をローカル化するため関数で。
238
+ var x = f;
239
+ var original = target[x];
240
+ target[x] = function( ) {
241
+ // インターセプターを実行する関数に置き換える。
242
+ var mi = new container.MethodInvocation( x, original, target, arguments );
243
+ return interceptor( mi );
244
+ }
245
+ })();
246
+ }
247
+ }
248
+ },
249
+ /**
250
+ * コンポーネント定義を列挙する。
251
+ * @param {Function} block 列挙先。第1引数でコンポーネント定義が渡される。
252
+ */
253
+ eachComponentDef : function( block ) {
254
+ for ( var i = 0; i < this.defs.objects.length; i++ ) {
255
+ if ( block ) {
256
+ block.apply( null, [this.defs.objects[i]] );
257
+ }
258
+ }
259
+ },
260
+ _createTypeCahce: function( nameOrType ) {
261
+ var list = [];
262
+ var self = this;
263
+ this.eachComponentDef( function( def ){
264
+ // 循環する場合は対象に含めない。
265
+ if ( self._isCreating(def) && !def.instance ) { return }
266
+ var obj = self.create( def );
267
+ if ( nameOrType.isImplementor( obj ) ) {
268
+ list.push( def );
269
+ }
270
+ });
271
+ this.typeCache[nameOrType] = list;
272
+ },
273
+ _isCreating: function(def) {
274
+ for ( var i=0; i < this.creating.length; i++ ) {
275
+ if ( def === this.creating[i] ) {
276
+ return true;
277
+ }
278
+ }
279
+ return false;
280
+ }
281
+ }
282
+
283
+ /**
284
+ * バインダー
285
+ * @param {Hash} defs コンポーネント定義
286
+ * @param {String} namespace ネームスペース
287
+ */
288
+ container.Binder = function( defs, namespace ){
289
+ this.defs = defs;
290
+ this.namespace = namespace;
291
+ }
292
+ container.Binder.prototype = {
293
+
294
+ /**
295
+ * コンポーネントを登録する
296
+ * @param {Function} clazz コンポーネントクラス
297
+ * @return コンポーネント定義オブジェクト
298
+ */
299
+ bind: function( clazz ) {
300
+ return this._bind( "object", clazz.prototype.meta, function() {
301
+ return new clazz();
302
+ });
303
+ },
304
+
305
+ /**
306
+ * 条件にマッチするコンポーネントメソッドを登録する。
307
+ *
308
+ * - Typeまたは名前にマッチするコンポーネントの指定したメソッドをコンポーネントとして登録する。
309
+ * - 複数のコンポーネントがある場合、最初に見つかったTypeまたは名前にマッチするコンポーネントのメソッドが登録される。
310
+ *
311
+ * @param {String or container.Type} nameOrType コンポーネント名またはcontainer.Type
312
+ * @param {String} methodName メソッド名
313
+ * @return コンポーネント定義オブジェクト
314
+ */
315
+ bindMethod: function( nameOrType, methodName ) {
316
+ var self = this;
317
+ return this._bind( "function", null, function( container ) {
318
+ var obj = container.get( nameOrType );
319
+ if (!obj) {
320
+ throw container.createError( new Error(),
321
+ container.ErrorCode.ComponentNotFound,
322
+ "component not found.name=" + nameOrType, {"nameOrType":nameOrType} );
323
+ }
324
+ return self._createBindMethod( obj, methodName );
325
+ });
326
+ },
327
+
328
+
329
+ /**
330
+ * 条件にマッチするコンポーネントメソッドの配列を登録する。
331
+ *
332
+ * - Typeまたは名前にマッチするコンポーネントの指定したメソッドをコンポーネントとして登録する。
333
+ * - 複数のコンポーネントがある場合、Typeまたは名前にマッチするコンポーネントメソッドの配列が登録される。
334
+ *
335
+ * @param {String or container.Type} nameOrType コンポーネント名またはcontainer.Type
336
+ * @param {String} methodName メソッド名
337
+ * @return コンポーネント定義オブジェクト
338
+ */
339
+ bindMethods: function( nameOrType, methodName ) {
340
+ var self = this;
341
+ return this._bind( "function", null, function( container ) {
342
+ var objs = container.gets( nameOrType );
343
+ var list = [];
344
+ for ( var i=0; i<objs.length;i++ ) {
345
+ list.push( self._createBindMethod( objs[i], methodName ) );
346
+ }
347
+ return list;
348
+ });
349
+ },
350
+
351
+ /**
352
+ * プロバイダが返す値をコンポーネントとして登録する。
353
+ * @param {function} provider プロバイダ関数。第一引数としてcontainer.Containerが渡される。
354
+ * @return コンポーネント定義オブジェクト
355
+ */
356
+ bindProvider: function( provider ) {
357
+ return this._bind( "object", null, provider );
358
+ },
359
+
360
+ /**
361
+ * インスタンスをコンポーネントとして登録する。
362
+ * @param {Object} instance インスタンス
363
+ * @return コンポーネント定義オブジェクト
364
+ */
365
+ bindInstance: function( instance ) {
366
+ return this._bind( "object", instance.meta, function() {
367
+ return instance;
368
+ } );
369
+ },
370
+
371
+ /**
372
+ * すべてのコンポーネントを対象とするインターセプタを登録する。
373
+ * @param {Fucntion} interceptor インターセプタ関数
374
+ * @param {container.Matcher or container.Type} インターセプタを適用するコンポーネントを選択するcontainer.Matcher or container.Type
375
+ * @param {container.Matcher} インターセプタを適用するメソッド名を選択するMatcher
376
+ */
377
+ bindInterceptor: function( interceptor, nameMatcherOrType, methodMatcher ) {
378
+ var interceptors = this._getInterceptorDefs();
379
+ interceptors.push( {
380
+ "interceptor": interceptor,
381
+ "nameMatcher": nameMatcherOrType,
382
+ "methodMatcher": methodMatcher
383
+ } );
384
+ },
385
+ /**
386
+ * ネームスペースを作成する。
387
+ * @param {String} namespace ネームスペース
388
+ * @param {Function} module コンポーネント定義を行う関数
389
+ */
390
+ ns: function( namespace, module ) {
391
+ if ( this.namespace ) {
392
+ namespace = this.namespace + "." + namespace;
393
+ }
394
+ module( new container.Binder( this.defs, namespace ) );
395
+ },
396
+
397
+ _bind: function( type, meta, constractor ) {
398
+ var objectDef = this._clone( meta );
399
+ objectDef.constractor = constractor;
400
+ objectDef.componentType = type;
401
+ var list = this._getObjectDefs();
402
+ list.push( objectDef );
403
+ return new container.Builder( objectDef, this.namespace );
404
+ },
405
+ _getObjectDefs: function( ) {
406
+ if ( !this.defs.objects ) {
407
+ this.defs.objects = [];
408
+ }
409
+ return this.defs.objects;
410
+ },
411
+ _getInterceptorDefs: function( ) {
412
+ if ( !this.defs.interceptors ) {
413
+ this.defs.interceptors = [];
414
+ }
415
+ return this.defs.interceptors;
416
+ },
417
+ _createBindMethod: function(obj, methodName) {
418
+ return function() { return obj[methodName].apply( obj, arguments );}
419
+ },
420
+ _clone: function(org) {
421
+ var tmp = {};
422
+ if ( org && org[container.Annotation.Container] ) {
423
+ org = org[container.Annotation.Container];
424
+ for ( var i in container.Annotation) {
425
+ var a = container.Annotation[i]
426
+ if ( a != container.Annotation.Intercept
427
+ && a != container.Annotation.Container ) {
428
+ tmp[a] = org[a];
429
+ }
430
+ }
431
+ tmp[container.Annotation.Intercept] = [];
432
+ if ( org[container.Annotation.Intercept] ) {
433
+ var list = org[container.Annotation.Intercept];
434
+ for ( var i=0; i < list.length; i++ ) {
435
+ tmp[container.Annotation.Intercept].push( list[i] );
436
+ }
437
+ }
438
+ }
439
+ var res = {};
440
+ res[container.Annotation.Container] = tmp;
441
+ return res;
442
+ }
443
+ }
444
+ container.Builder = function( def, namespace ){
445
+ if ( !def[ container.Annotation.Container ] ) {
446
+ def[ container.Annotation.Container ] = {};
447
+ }
448
+ this.def = def[ container.Annotation.Container ];
449
+ if ( !this.def[container.Annotation.Intercept] ) {
450
+ this.def[container.Annotation.Intercept] = [];
451
+ }
452
+ this.namespace = namespace;
453
+ }
454
+ container.Builder.prototype = {
455
+ /**
456
+ * コンポーネントの名前を設定する。
457
+ * @param {String} name コンポーネント名
458
+ * @return 自身のインスタンス
459
+ */
460
+ to: function( name ) {
461
+ if (this.namespace) {
462
+ name = this.namespace + "." + name;
463
+ }
464
+ this.def[container.Annotation.Name] = name;
465
+ return this;
466
+ },
467
+ /**
468
+ * コンポーネントに注入するプロパティを設定する。
469
+ * @param {Hash} injectionParameter コンポーネントに注入するプロパティ
470
+ * @return 自身のインスタンス
471
+ */
472
+ inject: function( injectionParameter ) {
473
+ this.def[container.Annotation.Inject] = injectionParameter;
474
+ return this;
475
+ },
476
+ /**
477
+ * コンポーネント生成時に実行される初期化関数を設定する。
478
+ * @param {Function or String} initializeFunctionOrName 初期化関数または初期化時に呼び出す関数名
479
+ * @return 自身のインスタンス
480
+ */
481
+ initialize:function( initializeFunctionOrName ) {
482
+ this.def[container.Annotation.Initialize] = initializeFunctionOrName;
483
+ return this;
484
+ },
485
+ /**
486
+ * コンテナの破棄時にに実行される破棄関数を設定する。
487
+ *
488
+ * 注意:破棄関数が呼ばれるのは、SingletonまたはEagerSingletonコンポーネントのみです。
489
+ *
490
+ * @param {Function or String} destroyFunctionOrName 破棄関数または破棄時に呼び出す関数名
491
+ */
492
+ destroy:function( destroyFunctionOrName ) {
493
+ this.def[container.Annotation.Destroy] = destroyFunctionOrName;
494
+ return this;
495
+ },
496
+ /**
497
+ * コンポーネントのスコープを設定する。
498
+ * @param {String} scope スコープ。container.Scopeの値が指定可能
499
+ */
500
+ scope:function( scope ) {
501
+ this.def[container.Annotation.Scope] = scope;
502
+ return this;
503
+ },
504
+ /**
505
+ * コンポーネントにインターセプタを追加する。
506
+ * @param {Function} interceptor インターセプタ関数
507
+ * @param {container.Matcher} matcher フックするメソッド名を示すcontainer.Matcher
508
+ */
509
+ intercept:function( interceptor, matcher ) {
510
+ this.def[container.Annotation.Intercept].push( [ interceptor, matcher ] );
511
+ return this;
512
+ }
513
+ }
514
+
515
+ /**
516
+ * 指定した条件にマッチするか評価するオブジェクト。
517
+ * @param {RegExp} or {Array<RegExp>} or {Function} includes
518
+ * マッチ条件。
519
+ * 正規表現、正規表現の配列、または関数で指定する。
520
+ * -正規表現 .. 値が正規表現にマッチするか
521
+ * -正規表現の配列 .. 値が正規表現のいずれかにマッチするか
522
+ * -関数 .. 関数の実行結果がtrueであるか。(引数として評価対象の値が渡される。)
523
+ * @param {RegExp} or {Array<RegExp>} or {Function} excludes
524
+ * マッチ対象外を指定する条件。includeに含まれていてもexcludeにマッチする場合、マッチしないと見なされる。
525
+ * 正規表現、正規表現の配列、または関数で指定する。
526
+ * -正規表現 .. 値が正規表現にマッチするか
527
+ * -正規表現の配列 .. 値が正規表現のいずれかにマッチするか
528
+ * -関数 .. 関数の実行結果がtrueであるか。(引数として評価対象の値が渡される。)
529
+ */
530
+ container.Matcher = function ( includes, excludes ){
531
+
532
+ if ( includes && !(includes instanceof Array
533
+ || includes instanceof RegExp
534
+ || includes instanceof Function )){
535
+ throw container.createError( new Error(),
536
+ container.ErrorCode.IllegalArgument,
537
+ "Illegal includes.", {} );
538
+ }
539
+ if ( excludes && !(excludes instanceof Array
540
+ || excludes instanceof RegExp
541
+ || excludes instanceof Function )){
542
+ throw container.createError( new Error(),
543
+ container.ErrorCode.IllegalArgument,
544
+ "Illegal excludes.", {} );
545
+ }
546
+ this.excludes = excludes;
547
+ this.includes = includes;
548
+ }
549
+ container.Matcher.prototype = {
550
+
551
+ /**
552
+ * 評価値が条件にマッチするか評価する。
553
+ * @param {String} value 評価値
554
+ * @return マッチする場合true
555
+ */
556
+ match: function( value ){
557
+ if ( this.excludes && this.getEvaluator( this.excludes)(value) ) {
558
+ return false;
559
+ }
560
+ if ( this.includes && this.getEvaluator( this.includes)(value) ) {
561
+ return true;
562
+ }
563
+ return false
564
+ },
565
+ getEvaluator: function( includes ) {
566
+ if ( includes instanceof Array ){
567
+ return function( value ) {
568
+ for (var i=0; i<includes.length; i++) {
569
+ if ( includes[i] instanceof RegExp && includes[i].test( value )){
570
+ return true;
571
+ }
572
+ }
573
+ return false;
574
+ };
575
+ } else if ( includes instanceof RegExp ){
576
+ return function( value ) {
577
+ return includes.test( value );
578
+ };
579
+ } else if ( includes instanceof Function ){
580
+ return includes;
581
+ }
582
+ }
583
+ }
584
+
585
+ /**
586
+ * インターセプタの引数として渡されるオブジェクト
587
+ * @param {String} name インターセプトされた関数名
588
+ * @param {Function} original インターセプトされたオリジナルの関数
589
+ * @param {Object} target インターセプトされたオブジェクト
590
+ * @param {Object} arg 関数に渡された引数(arguments)
591
+ */
592
+ container.MethodInvocation = function( name, original, target, arg ) {
593
+ this.name = name;
594
+ this.original = original;
595
+ this.arg = arg;
596
+ this.target = target;
597
+ }
598
+ container.MethodInvocation.prototype = {
599
+
600
+ /**
601
+ * インターセプトされたオブジェクトを取得する。
602
+ * @return インターセプトされたオブジェクト
603
+ */
604
+ getThis: function() { return this.target; },
605
+
606
+ /**
607
+ * 現在の引数を使用して、オリジナルの関数を実行する。
608
+ * 引数を改変するには、getArguments()の戻り値を直接編集する。
609
+ * @return オリジナルの関数の実行結果
610
+ */
611
+ proceed: function() {
612
+ return this.original.apply( this.target, this.arg );
613
+ },
614
+ /**
615
+ * 関数に渡された引数を取得する。
616
+ * @return 関数に渡された引数。
617
+ */
618
+ getArguments: function() { return this.arg; },
619
+ /**
620
+ * オリジナルの関数を取得する。
621
+ * @return オリジナルの関数
622
+ */
623
+ getOriginalMethod: function() { return this.original; },
624
+ /**
625
+ * インターセプトされた関数名を取得する。
626
+ * @return インターセプトされた関数名
627
+ */
628
+ getMethodName: function() { return this.name; }
629
+ }
630
+
631
+ /**
632
+ * 内部クラス。
633
+ */
634
+ container.inner = {}
635
+ container.inner.Component = function( name ) {
636
+ this.name = name;
637
+ }
638
+ container.inner.Components = function( name ) {
639
+ this.name = name;
640
+ }
641
+ container.inner.Provider = function( func ) {
642
+ this.func = func;
643
+ }
644
+
645
+ /**
646
+ * 例外にメッセージ等を設定する。
647
+ * @param {Error} エラー
648
+ * @param {int} code エラーコード。container.Exception.ErrorCodeの定数を参照。
649
+ * @param {String} message エラーメッセージ
650
+ * @param {Hash} options 補足情報
651
+ */
652
+ container.createError = function( error, code, message, options ) {
653
+ error.errorCode = code;
654
+ error.message = message;
655
+ error.options = options;
656
+ error.name = "container.Exception";
657
+ return error;
658
+ }
659
+
660
+ /**
661
+ * エラーコード
662
+ */
663
+ container.ErrorCode = {
664
+ // 引数が不正
665
+ IllegalArgument: 1,
666
+ // コンポーネント定義が存在しない。
667
+ ComponentNotFound: 100,
668
+ // コンポーネント定義が不正。
669
+ IllegalDefinition: 101,
670
+ // 循環参照
671
+ CircularReference: 102
672
+ }
673
+
674
+ container.Annotation = {
675
+ Container: "@Container",
676
+ Name: "@Name",
677
+ Inject: "@Inject",
678
+ Initialize: "@Initialize",
679
+ Destroy: "@Destroy",
680
+ Intercept: "@Intercept",
681
+ Scope: "@Scope",
682
+ AutoInjection: "@AutoInjection"
683
+ }
684
+ container.Scope = {
685
+ Singleton: "Singleton",
686
+ Prototype: "Prototype",
687
+ EagerSingleton: "EagerSingleton"
688
+ }
689
+
690
+ // ユーティリティ
691
+ /**
692
+ * すべてにマッチするcontainer.Matcherを作成する。
693
+ */
694
+ container.any = function() {
695
+ return new container.Matcher( /.*/ );
696
+ }
697
+ /**
698
+ * コンポーネントを挿入するインジェクション指定を作成する。
699
+ */
700
+ container.component = function( nameOrType ) {
701
+ return new container.inner.Component( nameOrType );
702
+ }
703
+ /**
704
+ * コンポーネントの配列を挿入するインジェクション指定を作成する。
705
+ */
706
+ container.components = function( nameOrType ) {
707
+ return new container.inner.Components( nameOrType );
708
+ }
709
+ /**
710
+ * 関数の実行結果を挿入するインジェクション指定を作成する。
711
+ */
712
+ container.provides = function( func ) {
713
+ return new container.inner.Provider( func );
714
+ }
715
+
716
+ /**
717
+ * 自動インジェクションの指定
718
+ */
719
+ container.Inject = function( nameOrType ) {
720
+ return container.component( nameOrType );
721
+ }
722
+ container.Injects = function( nameOrType ) {
723
+ return container.components( nameOrType );
724
+ }
725
+
726
+ /**
727
+ * タイプ
728
+ */
729
+ container.Type = function() {}
730
+ container.Type.prototype = {
731
+
732
+ /**
733
+ * 同じタイプであるか評価します。
734
+ * @param {container.Type} that タイプ
735
+ * @return 同じであればtrue
736
+ */
737
+ equals: function( that ) {},
738
+
739
+ /**
740
+ * オブジェクトがTypeの条件を満たすか評価します。
741
+ * @param {Object} obj オブジェクト
742
+ * @return 条件を満たす場合true
743
+ */
744
+ isImplementor: function( obj ) {}
745
+ }
746
+
747
+ /**
748
+ * ユーテイリティ
749
+ */
750
+ container.types = {
751
+
752
+ /**
753
+ * 指定されたメソッドをすべて実装することを示すTypeを生成する。
754
+ * @param {String or Regexp or container.Type} methods メソッド名、正規表現またはcontainer.Type
755
+ * @return 指定されたメソッドをすべて実装することを示すcontainer.Type
756
+ */
757
+ has: function() {
758
+ return new container.inner.types.And( container.types._createTypes( arguments ));
759
+ },
760
+ /**
761
+ * 指定されたメソッドのいずれかを実装することを示すTypeを生成する。
762
+ * @param {String or Regexp or container.Type} methods メソッド名、正規表現またはcontainer.Type
763
+ * @return 指定されたメソッドのいずれかを実装することを示すcontainer.Type
764
+ */
765
+ hasAny: function() {
766
+ return new container.inner.types.Or( container.types._createTypes( arguments ));
767
+ },
768
+
769
+ /**
770
+ * 指定された型の条件を満たさないことを示すTypeを生成する。
771
+ * @param {String or Regexp or container.Type} type メソッド名、正規表現またはcontainer.Type
772
+ * @return 指定された型の条件を満たさないことを示すType
773
+ */
774
+ not: function( type ) {
775
+ return new container.inner.types.Not( container.types._createType(type) );
776
+ },
777
+
778
+ _createTypes: function ( list ) {
779
+ var types = [];
780
+ for ( var i=0; i < list.length; i++ ) {
781
+ types.push( container.types._createType( list[i] ));
782
+ }
783
+ return types;
784
+ },
785
+ _createType: function ( item ) {
786
+ if ( item instanceof RegExp ) {
787
+ return new container.inner.types.RegexpMethod(item);
788
+ } else if ( item instanceof container.Type ) {
789
+ return item ;
790
+ } else if ( typeof item == "string" ) {
791
+ return new container.inner.types.Method(item);
792
+ } else {
793
+ throw "illegal argument.";
794
+ }
795
+ }
796
+ }
797
+
798
+ container.inner.types = {}
799
+
800
+ /**
801
+ * 完全一致
802
+ */
803
+ container.inner.types.Method = function( name ) {
804
+ this.name = name;
805
+ }
806
+ container.inner.types.Method.prototype = new container.Type();
807
+ container.inner.types.Method.prototype.equals = function( that ) {
808
+ if ( !that || !( that instanceof container.inner.types.Method ) ){
809
+ return false;
810
+ }
811
+ return this.name == that.name;
812
+ }
813
+ container.inner.types.Method.prototype.isImplementor = function( obj ) {
814
+ return typeof obj[this.name] == "function";
815
+ }
816
+ container.inner.types.Method.prototype.toString = function( ) {
817
+ return "!container.inner.types.Method:" + this.name;
818
+ }
819
+
820
+
821
+ /**
822
+ * 正規表現一致
823
+ */
824
+ container.inner.types.RegexpMethod = function( exp ) {
825
+ this.exp = exp;
826
+ }
827
+ container.inner.types.RegexpMethod.prototype = new container.Type();
828
+ container.inner.types.RegexpMethod.prototype.equals = function( that ) {
829
+ if ( !that || !( that instanceof container.inner.types.RegexpMethod ) ){
830
+ return false;
831
+ }
832
+ return this.exp.ignoreCase == that.exp.ignoreCase
833
+ && this.exp.global == that.exp.global
834
+ && this.exp.source == that.exp.source;
835
+ }
836
+ container.inner.types.RegexpMethod.prototype.isImplementor = function( obj ) {
837
+ for ( var key in obj ) {
838
+ if ( typeof obj[key] == "function" && this.exp.test( key ) ) {
839
+ return true;
840
+ }
841
+ }
842
+ return false;
843
+ }
844
+ container.inner.types.RegexpMethod.prototype.toString = function( ) {
845
+ return "!container.inner.types.RegexpMethod:/" + this.exp.source + "/"
846
+ + this.exp.ignoreCase + "/" + this.exp.global ;
847
+ }
848
+
849
+
850
+ /**
851
+ * And
852
+ */
853
+ container.inner.types.And = function(types) {
854
+ this.types = types;
855
+ }
856
+ container.inner.types.And.prototype = new container.Type();
857
+ container.inner.types.And.prototype.equals = function( that ) {
858
+ if ( !that || !( that instanceof container.inner.types.And ) ){
859
+ return false;
860
+ }
861
+ if ( this.types.length != that.types.length ){
862
+ return false;
863
+ }
864
+ for ( var i=0; i < this.types.length; i++ ) {
865
+ var a = this.types[i];
866
+ var b = that.types[i];
867
+ if ( !a.equals(b) ) { return false; }
868
+ }
869
+ return true;
870
+ }
871
+ container.inner.types.And.prototype.isImplementor = function( obj ) {
872
+ for ( var i=0; i < this.types.length; i++ ) {
873
+ if ( !this.types[i].isImplementor(obj)) {
874
+ return false;
875
+ }
876
+ }
877
+ return true;
878
+ }
879
+ container.inner.types.And.prototype.toString = function( ) {
880
+ var str = "!container.inner.types.And:[";
881
+ for ( var i=0; i < this.types.length; i++ ) {
882
+ str += this.types[i].toString() + ",";
883
+ }
884
+ str += "]";
885
+ return str;
886
+ }
887
+
888
+ /**
889
+ * Or
890
+ */
891
+ container.inner.types.Or = function(types) {
892
+ this.types = types;
893
+ }
894
+ container.inner.types.Or.prototype = new container.Type();
895
+ container.inner.types.Or.prototype.equals = function( that ) {
896
+ if ( !that || !( that instanceof container.inner.types.Or ) ){
897
+ return false;
898
+ }
899
+ if ( this.types.length != that.types.length ){
900
+ return false;
901
+ }
902
+ for ( var i=0; i < this.types.length; i++ ) {
903
+ var a = this.types[i];
904
+ var b = that.types[i];
905
+ if ( !a.equals(b) ) { return false; }
906
+ }
907
+ return true;
908
+ }
909
+ container.inner.types.Or.prototype.isImplementor = function( obj ) {
910
+ for ( var i=0; i < this.types.length; i++ ) {
911
+ if ( this.types[i].isImplementor(obj)) {
912
+ return true;
913
+ }
914
+ }
915
+ return false;
916
+ }
917
+ container.inner.types.Or.prototype.toString = function( ) {
918
+ var str = "!container.inner.types.Or:[";
919
+ for ( var i=0; i < this.types.length; i++ ) {
920
+ str += this.types[i].toString() + ",";
921
+ }
922
+ str += "]";
923
+ return str;
924
+ }
925
+
926
+ /**
927
+ * Not
928
+ */
929
+ container.inner.types.Not = function(type) {
930
+ this.type = type;
931
+ }
932
+ container.inner.types.Not.prototype = new container.Type();
933
+ container.inner.types.Not.prototype.equals = function( that ) {
934
+ if ( !that || !( that instanceof container.inner.types.Not ) ){
935
+ return false;
936
+ }
937
+ return this.type.equals( that.type );
938
+ }
939
+ container.inner.types.Not.prototype.isImplementor = function( obj ) {
940
+ return !this.type.isImplementor(obj);
941
+ }
942
+ container.inner.types.Not.prototype.toString = function( ) {
943
+ return "!container.inner.types.Not:[" + this.type.toString() + "]";
944
+ }