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.
- data/ChangeLog +24 -1
- data/README +0 -0
- data/base/shared_lib/moving_average.rb +34 -33
- data/base/shared_lib/system/cross.rb +76 -0
- data/base/shared_lib/system/position_manager.rb +160 -0
- data/base/shared_lib/system/signal.rb +347 -0
- data/html/css/datatable.css +4 -4
- data/html/css/default.css +57 -5
- data/html/css/treeview.css +205 -0
- data/html/img/bin_closed.png +0 -0
- data/html/img/bin_empty.png +0 -0
- data/html/img/button_add_small.gif +0 -0
- data/html/img/button_add_small_gray.gif +0 -0
- data/html/img/button_add_small_over.gif +0 -0
- data/html/img/button_mkcol.gif +0 -0
- data/html/img/button_mkcol_gray.gif +0 -0
- data/html/img/button_mkcol_over.gif +0 -0
- data/html/img/button_remove_small.gif +0 -0
- data/html/img/button_remove_small_gray.gif +0 -0
- data/html/img/button_remove_small_over.gif +0 -0
- data/html/img/button_rename.gif +0 -0
- data/html/img/button_rename_gray.gif +0 -0
- data/html/img/button_rename_over.gif +0 -0
- data/html/img/control_play.png +0 -0
- data/html/img/control_play_blue.png +0 -0
- data/html/img/folder.png +0 -0
- data/html/img/folder_brick.png +0 -0
- data/html/img/folder_user.png +0 -0
- data/html/{js/codepress/images → img}/line-numbers.png +0 -0
- data/html/img/page_white_ruby.png +0 -0
- data/html/img/sidebar_agent_edit.png +0 -0
- data/html/img/sidebar_agent_edit_over.png +0 -0
- data/html/img/sidebar_agent_edit_s.png +0 -0
- data/html/img/yui/treeview-sprite.gif +0 -0
- data/html/index.html +34 -18
- data/html/js/agent-editor/agent-editor-page.js +324 -0
- data/html/js/agent-editor/agent-editor.js +363 -0
- data/html/js/agent-editor/agent-list-tree.js +251 -0
- data/html/js/agent-selector.js +23 -28
- data/html/js/app.js +63 -91
- data/html/js/bt-create-page.js +25 -19
- data/html/js/container-min.js +1 -1
- data/html/js/container.js +944 -0
- data/html/js/edit_area/autocompletion.js +11 -13
- data/html/js/edit_area/edit_area.css +79 -40
- data/html/js/edit_area/edit_area.js +255 -226
- data/html/js/edit_area/edit_area_compressor.php +4 -4
- data/html/js/edit_area/edit_area_full.gz +0 -0
- data/html/js/edit_area/edit_area_full.js +31 -31
- data/html/js/edit_area/edit_area_full_with_plugins.gz +0 -0
- data/html/js/edit_area/edit_area_full_with_plugins.js +31 -31
- data/html/js/edit_area/edit_area_functions.js +448 -341
- data/html/js/edit_area/edit_area_loader.js +409 -397
- data/html/js/edit_area/elements_functions.js +120 -123
- data/html/js/edit_area/highlight.js +305 -197
- data/html/js/edit_area/images/goto.png +0 -0
- data/html/js/edit_area/images/help.png +0 -0
- data/html/js/edit_area/images/redo.png +0 -0
- data/html/js/edit_area/images/save.png +0 -0
- data/html/js/edit_area/images/search.png +0 -0
- data/html/js/edit_area/images/undo.png +0 -0
- data/html/js/edit_area/images/word_wrap.gif +0 -0
- data/html/js/edit_area/keyboard.js +5 -5
- data/html/js/edit_area/langs/bg.js +73 -0
- data/html/js/edit_area/langs/cs.js +2 -0
- data/html/js/edit_area/langs/de.js +2 -0
- data/html/js/edit_area/langs/dk.js +2 -0
- data/html/js/edit_area/langs/en.js +2 -0
- data/html/js/edit_area/langs/eo.js +2 -0
- data/html/js/edit_area/langs/es.js +2 -0
- data/html/js/edit_area/langs/fi.js +67 -0
- data/html/js/edit_area/langs/fr.js +2 -0
- data/html/js/edit_area/langs/hr.js +2 -0
- data/html/js/edit_area/langs/it.js +2 -0
- data/html/js/edit_area/langs/ja.js +2 -0
- data/html/js/edit_area/langs/mk.js +2 -0
- data/html/js/edit_area/langs/nl.js +2 -0
- data/html/js/edit_area/langs/pl.js +2 -0
- data/html/js/edit_area/langs/pt.js +2 -0
- data/html/js/edit_area/langs/ru.js +2 -0
- data/html/js/edit_area/langs/sk.js +2 -0
- data/html/js/edit_area/langs/zh.js +67 -0
- data/html/js/edit_area/manage_area.js +362 -205
- data/html/js/edit_area/plugins/charmap/langs/bg.js +12 -0
- data/html/js/edit_area/plugins/charmap/langs/zh.js +6 -0
- data/html/js/edit_area/plugins/test/langs/bg.js +10 -0
- data/html/js/edit_area/plugins/test/langs/zh.js +4 -0
- data/html/js/edit_area/reg_syntax/java.js +56 -0
- data/html/js/edit_area/reg_syntax/ruby.js +9 -9
- data/html/js/edit_area/reg_syntax.js +15 -13
- data/html/js/edit_area/regexp.js +36 -32
- data/html/js/edit_area/resize_area.js +43 -47
- data/html/js/edit_area/search_replace.js +29 -29
- data/html/js/edit_area/template.html +6 -4
- data/html/js/json-broker-client.js +23 -17
- data/html/js/result-page.js +107 -57
- data/html/js/rt-setting-page.js +38 -15
- data/html/js/sidebar.js +41 -27
- data/html/js/templates.js +167 -32
- data/html/js/utils.js +143 -7
- data/html/js/yui/treeview.js +3671 -0
- data/html/swf/chart.swf +0 -0
- data/html/test/agent_editor_spec.js +815 -0
- data/html/test/index.html +40 -0
- data/html/test/jsspec/JSSpec.css +224 -0
- data/html/test/jsspec/JSSpec.js +1549 -0
- data/html/test/jsspec/diff_match_patch.js +1 -0
- data/html/test/utils_spec.js +111 -0
- data/lib/jiji/agent/agent.rb +69 -12
- data/lib/jiji/agent/agent_manager.rb +18 -12
- data/lib/jiji/agent/agent_registry.rb +35 -121
- data/lib/jiji/collector.rb +16 -6
- data/lib/jiji/command.rb +46 -5
- data/lib/jiji/dao/file_system_dao.rb +158 -0
- data/lib/jiji/dao/timed_data_dao.rb +2 -0
- data/lib/jiji/dao/trade_result_dao.rb +1 -1
- data/lib/jiji/error.rb +24 -8
- data/lib/jiji/migration/migrator1_2_0.rb +67 -0
- data/lib/jiji/models.rb +82 -24
- data/lib/jiji/operator.rb +55 -51
- data/lib/jiji/output.rb +85 -29
- data/lib/jiji/output_manager.rb +84 -0
- data/lib/jiji/plugin/embedded/single_click_client.rb +2 -2
- data/lib/jiji/plugin/securities_plugin.rb +0 -1
- data/lib/jiji/process.rb +229 -208
- data/lib/jiji/process_manager.rb +190 -96
- data/lib/jiji/registry.rb +87 -19
- data/lib/jiji/server.rb +1 -0
- data/lib/jiji/service/agent_service.rb +147 -48
- data/lib/jiji/service/output_service.rb +37 -17
- data/lib/jiji/service/process_service.rb +3 -5
- data/lib/jiji/service/trade_result_service.rb +4 -5
- data/lib/jiji/util/file_lock.rb +4 -4
- data/lib/jiji/util/include_proxy.rb +17 -0
- data/lib/jiji/util/json_broker.rb +6 -4
- data/lib/jiji/util/util.rb +1 -1
- data/swf/chart/fx/chart/Chart.as +7 -0
- data/swf/chart/fx/chart/ui/graph/GraphManager.as +15 -2
- data/test/ProcessTest/agents/foo.rb +10 -0
- data/test/ProcessTest/conf/configuration.yaml +3 -0
- data/test/agent/agent_tests.rb +10 -0
- data/test/agent/test_AgentManager.rb +28 -12
- data/test/agent/test_AgentRegistry.rb +194 -99
- data/test/agent/test_PeriodicallyAgent.rb +1 -2
- data/test/agent/test_Permitter.rb +1 -2
- data/test/all_tests.rb +7 -19
- data/test/dao/dao_tests.rb +9 -0
- data/test/dao/test_FileSystemDao.rb +431 -0
- data/test/dao/test_RateDao.rb +5 -7
- data/test/dao/test_TradeResultDao.rb +1 -2
- data/test/migration/migration_tests.rb +10 -0
- data/test/migration/migrator1_2_0test_data/basic/out/M2NlOTA2ODEtZDdlNi00NWU1LWIwNDQtMjBmODY2ZGNkNzBj/56e75YuV5bmz5Z2H57ea/meta.yaml +8 -0
- data/test/migration/migrator1_2_0test_data/basic/out/MDVhYzcxMjYtMGFlMS00Mzk0LWEyNmUtYjVjZjgwNDA0ZmE2/56e75YuV5bmz5Z2H57ea/meta.yaml +8 -0
- data/test/migration/migrator1_2_0test_data/basic/out/MzA1YTk0NDgtNzhjNi00NDk3LTk2NTktYzE1ZjBhNzdiYjNj/56e75YuV5bmz5Z2H57ea/meta.yaml +8 -0
- data/test/migration/migrator1_2_0test_data/basic/out/YjRkOTI1MzEtZTM4MS00YjQwLTg1ZTQtMWFmZDRlNDUwMzBm/56e75YuV5bmz5Z2H57ea/meta.yaml +9 -0
- data/test/migration/migrator1_2_0test_data/basic/props.yaml +85 -0
- data/test/migration/migrator1_2_0test_data/illegal_props/out/M2NlOTA2ODEtZDdlNi00NWU1LWIwNDQtMjBmODY2ZGNkNzBj/56e75YuV5bmz5Z2H57ea/meta.yaml +8 -0
- data/test/migration/migrator1_2_0test_data/illegal_props/out/MDVhYzcxMjYtMGFlMS00Mzk0LWEyNmUtYjVjZjgwNDA0ZmE2/56e75YuV5bmz5Z2H57ea/meta.yaml +8 -0
- data/test/migration/migrator1_2_0test_data/illegal_props/out/MzA1YTk0NDgtNzhjNi00NDk3LTk2NTktYzE1ZjBhNzdiYjNj/56e75YuV5bmz5Z2H57ea/meta.yaml +8 -0
- data/test/migration/migrator1_2_0test_data/illegal_props/out/YjRkOTI1MzEtZTM4MS00YjQwLTg1ZTQtMWFmZDRlNDUwMzBm/56e75YuV5bmz5Z2H57ea/meta.yaml +9 -0
- data/test/migration/migrator1_2_0test_data/illegal_props/props.yaml +1 -0
- data/test/migration/migrator1_2_0test_data/no_outs/props.yaml +85 -0
- data/test/migration/migrator1_2_0test_data/no_props/out/M2NlOTA2ODEtZDdlNi00NWU1LWIwNDQtMjBmODY2ZGNkNzBj/56e75YuV5bmz5Z2H57ea/meta.yaml +8 -0
- data/test/migration/migrator1_2_0test_data/no_props/out/MDVhYzcxMjYtMGFlMS00Mzk0LWEyNmUtYjVjZjgwNDA0ZmE2/56e75YuV5bmz5Z2H57ea/meta.yaml +8 -0
- data/test/migration/migrator1_2_0test_data/no_props/out/MzA1YTk0NDgtNzhjNi00NDk3LTk2NTktYzE1ZjBhNzdiYjNj/56e75YuV5bmz5Z2H57ea/meta.yaml +8 -0
- data/test/migration/migrator1_2_0test_data/no_props/out/YjRkOTI1MzEtZTM4MS00YjQwLTg1ZTQtMWFmZDRlNDUwMzBm/56e75YuV5bmz5Z2H57ea/meta.yaml +9 -0
- data/test/migration/test_Migrator.rb +1 -1
- data/test/migration/test_Migrator1_0_3.rb +1 -1
- data/test/migration/test_Migrator1_1_0.rb +1 -1
- data/test/migration/test_Migrator1_2_0.rb +94 -0
- data/test/plugin/embedded/test_SingleClickClient.rb +1 -2
- data/test/plugin/plugin_tests.rb +8 -0
- data/test/plugin/test_Loader.rb +1 -1
- data/test/shared/rate.csv +144 -0
- data/test/shared/shared_tests.rb +9 -0
- data/test/shared/test_Cross.rb +144 -0
- data/test/shared/test_PositionManager.rb +285 -0
- data/test/shared/test_Signal.rb +65 -0
- data/test/test_Output.rb +28 -21
- data/test/test_OutputManager.rb +162 -0
- data/test/test_Output_registry.rb +6 -17
- data/test/test_Process.rb +434 -222
- data/test/test_ProcessManager.rb +458 -101
- data/test/test_utils.rb +71 -8
- data/test/util/test_BlockToSession.rb +1 -2
- data/test/util/test_CSV.rb +1 -2
- data/test/util/test_SynchronizeInterceptor.rb +1 -2
- data/test/util/util_tests.rb +9 -0
- metadata +127 -47
- data/html/js/agent-editor-page.js +0 -440
- data/html/js/codepress/codepress.css +0 -21
- data/html/js/codepress/codepress.html +0 -35
- data/html/js/codepress/codepress.js +0 -138
- data/html/js/codepress/engines/gecko.js +0 -293
- data/html/js/codepress/engines/khtml.js +0 -0
- data/html/js/codepress/engines/msie.js +0 -304
- data/html/js/codepress/engines/older.js +0 -0
- data/html/js/codepress/engines/opera.js +0 -260
- data/html/js/codepress/images/line-numbers.gif +0 -0
- data/html/js/codepress/index.html +0 -443
- data/html/js/codepress/languages/asp.css +0 -71
- data/html/js/codepress/languages/asp.js +0 -117
- data/html/js/codepress/languages/autoit.css +0 -13
- data/html/js/codepress/languages/autoit.js +0 -32
- data/html/js/codepress/languages/csharp.css +0 -9
- data/html/js/codepress/languages/csharp.js +0 -25
- data/html/js/codepress/languages/css.css +0 -10
- data/html/js/codepress/languages/css.js +0 -23
- data/html/js/codepress/languages/generic.css +0 -9
- data/html/js/codepress/languages/generic.js +0 -25
- data/html/js/codepress/languages/html.css +0 -13
- data/html/js/codepress/languages/html.js +0 -59
- data/html/js/codepress/languages/java.css +0 -7
- data/html/js/codepress/languages/java.js +0 -24
- data/html/js/codepress/languages/javascript.css +0 -8
- data/html/js/codepress/languages/javascript.js +0 -30
- data/html/js/codepress/languages/perl.css +0 -11
- data/html/js/codepress/languages/perl.js +0 -27
- data/html/js/codepress/languages/php.css +0 -12
- data/html/js/codepress/languages/php.js +0 -61
- data/html/js/codepress/languages/ruby.css +0 -10
- data/html/js/codepress/languages/ruby.js +0 -26
- data/html/js/codepress/languages/sql.css +0 -10
- data/html/js/codepress/languages/sql.js +0 -30
- data/html/js/codepress/languages/text.css +0 -5
- data/html/js/codepress/languages/text.js +0 -9
- data/html/js/codepress/languages/vbscript.css +0 -71
- data/html/js/codepress/languages/vbscript.js +0 -117
- data/html/js/codepress/languages/xsl.css +0 -15
- data/html/js/codepress/languages/xsl.js +0 -103
- data/html/js/codepress/license.txt +0 -458
- data/html/js/edit_area/images/Thumbs.db +0 -0
- 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
|
+
}
|