s2container 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Apache_Software_License_2.0.txt +202 -0
- data/ChangeLog +1 -0
- data/ChangeLog.ja +64 -0
- data/README +9 -0
- data/Rakefile +51 -0
- data/example/example01/example.rb +13 -0
- data/example/example01/run.rb +20 -0
- data/example/example02/example.rb +30 -0
- data/example/example02/run.rb +8 -0
- data/example/example03/example.rb +8 -0
- data/example/example03/run.rb +12 -0
- data/example/example04/example.rb +9 -0
- data/example/example04/run.rb +15 -0
- data/example/example05/example.rb +9 -0
- data/example/example05/run.rb +21 -0
- data/example/example06/example.rb +9 -0
- data/example/example06/run.rb +8 -0
- data/example/example07/example.rb +8 -0
- data/example/example07/run.rb +15 -0
- data/example/example08/example.rb +9 -0
- data/example/example08/run.rb +19 -0
- data/example/example09/example.rb +7 -0
- data/example/example09/run.rb +11 -0
- data/example/example10/example.rb +9 -0
- data/example/example10/run.rb +10 -0
- data/example/example11/example.rb +18 -0
- data/example/example11/run.rb +10 -0
- data/example/example12/example.rb +9 -0
- data/example/example12/run.rb +8 -0
- data/example/example13/example.rb +18 -0
- data/example/example13/example.sql +4 -0
- data/example/example13/run.rb +22 -0
- data/example/example13/sample.db +0 -0
- data/example/example14/example.db +0 -0
- data/example/example14/example.rb +57 -0
- data/example/example14/example.sql +50 -0
- data/example/example14/run1.rb +23 -0
- data/example/example14/run2.rb +28 -0
- data/example/example14/run3.rb +25 -0
- data/example/example14/run4.rb +23 -0
- data/example/example14/run5.rb +35 -0
- data/example/example15/example.rb +20 -0
- data/example/example15/run.rb +28 -0
- data/example/example16/example.rb +15 -0
- data/example/example16/run.rb +24 -0
- data/example/quickstart/quickstart1/quickstart.rb +10 -0
- data/example/quickstart/quickstart2/quickstart.rb +9 -0
- data/example/quickstart/quickstart3/quickstart.rb +9 -0
- data/example/quickstart/quickstart4/quickstart.rb +14 -0
- data/example/quickstart/quickstart5/quickstart.rb +21 -0
- data/example/quickstart/quickstart6/quickstart.rb +28 -0
- data/example/quickstart/quickstart7/quickstart.rb +18 -0
- data/lib/s2container.rb +25 -0
- data/lib/seasar/aop/aspect.rb +30 -0
- data/lib/seasar/aop/interceptor/trace-interceptor.rb +48 -0
- data/lib/seasar/aop/method-invocation.rb +57 -0
- data/lib/seasar/aop/pointcut.rb +53 -0
- data/lib/seasar/aop/s2aop-factory.rb +125 -0
- data/lib/seasar/aop.rb +29 -0
- data/lib/seasar/beans/abstract-property-desc.rb +59 -0
- data/lib/seasar/beans/attribute-accessor-desc.rb +60 -0
- data/lib/seasar/beans/bean-desc-factory.rb +68 -0
- data/lib/seasar/beans/bean-desc.rb +232 -0
- data/lib/seasar/beans/instance-variable-desc.rb +58 -0
- data/lib/seasar/beans.rb +29 -0
- data/lib/seasar/container/arg-def.rb +51 -0
- data/lib/seasar/container/aspect-def.rb +60 -0
- data/lib/seasar/container/aspect-info-def.rb +94 -0
- data/lib/seasar/container/assembler/abstract-assembler.rb +68 -0
- data/lib/seasar/container/assembler/auto-property-assembler.rb +57 -0
- data/lib/seasar/container/assembler/autobinding-auto-def.rb +55 -0
- data/lib/seasar/container/assembler/autobinding-def-factory.rb +57 -0
- data/lib/seasar/container/assembler/autobinding-none-def.rb +53 -0
- data/lib/seasar/container/assembler/manual-constructor-assembler.rb +67 -0
- data/lib/seasar/container/assembler/manual-property-assembler.rb +68 -0
- data/lib/seasar/container/autobinding-def.rb +36 -0
- data/lib/seasar/container/component-def.rb +229 -0
- data/lib/seasar/container/component-info-def.rb +117 -0
- data/lib/seasar/container/deployer/abstract-component-deployer.rb +47 -0
- data/lib/seasar/container/deployer/instance-def-factory.rb +56 -0
- data/lib/seasar/container/deployer/instance-outer-def.rb +44 -0
- data/lib/seasar/container/deployer/instance-prototype-def.rb +44 -0
- data/lib/seasar/container/deployer/instance-singleton-def.rb +42 -0
- data/lib/seasar/container/deployer/outer-component-deployer.rb +47 -0
- data/lib/seasar/container/deployer/prototype-component-deployer.rb +51 -0
- data/lib/seasar/container/deployer/singleton-component-deployer.rb +54 -0
- data/lib/seasar/container/exception/component-notfound-runtime-exception.rb +44 -0
- data/lib/seasar/container/exception/cyclic-reference-runtime-exception.rb +43 -0
- data/lib/seasar/container/exception/illegal-autobinding-def-runtime-exception.rb +43 -0
- data/lib/seasar/container/exception/illegal-instance-def-runtime-exception.rb +44 -0
- data/lib/seasar/container/exception/toomany-registration-runtime-exception.rb +46 -0
- data/lib/seasar/container/instance-def.rb +37 -0
- data/lib/seasar/container/outer-component-def.rb +34 -0
- data/lib/seasar/container/property-def.rb +43 -0
- data/lib/seasar/container/s2application-context.rb +447 -0
- data/lib/seasar/container/s2container-component-def.rb +41 -0
- data/lib/seasar/container/s2container.rb +308 -0
- data/lib/seasar/container/simple-component-def.rb +45 -0
- data/lib/seasar/container/toomany-registration-component-def.rb +69 -0
- data/lib/seasar/container.rb +143 -0
- data/lib/seasar/dbi/dbi-interceptor.rb +97 -0
- data/lib/seasar/dbi/paginate.rb +215 -0
- data/lib/seasar/dbi.rb +26 -0
- data/lib/seasar/exception/notyet-implemented-exception.rb +25 -0
- data/lib/seasar/exception/property-notfound-runtime-exception.rb +48 -0
- data/lib/seasar/exception/s2runtime-exception.rb +35 -0
- data/lib/seasar/exception/unsupported-operation-exception.rb +25 -0
- data/lib/seasar/exception.rb +27 -0
- data/lib/seasar/log/s2logger.rb +75 -0
- data/lib/seasar/log.rb +38 -0
- data/lib/seasar/util/class-util.rb +116 -0
- data/lib/seasar/util.rb +24 -0
- data/setup.rb +1585 -0
- data/test/seasar/aop/test_pointcut.rb +25 -0
- data/test/seasar/aop/test_s2aop_factory.rb +90 -0
- data/test/seasar/beans/test_bean-desc.rb +179 -0
- data/test/seasar/container/assembler/test_auto_property_assembler.rb +87 -0
- data/test/seasar/container/assembler/test_autobinding_def_factory.rb +22 -0
- data/test/seasar/container/assembler/test_manual_property_assembler.rb +59 -0
- data/test/seasar/container/assembler/test_manula_constructor_assembler.rb +59 -0
- data/test/seasar/container/assembler/test_proc_constructor_assembler.rb +61 -0
- data/test/seasar/container/deployer/test_instance_def_factory.rb +24 -0
- data/test/seasar/container/deployer/test_prototype-deployer.rb +25 -0
- data/test/seasar/container/deployer/test_singleton-component-deployer.rb +24 -0
- data/test/seasar/container/s2app_load_sample.rb +6 -0
- data/test/seasar/container/test_arg-def.rb +34 -0
- data/test/seasar/container/test_aspect-info-def.rb +85 -0
- data/test/seasar/container/test_component-def.rb +91 -0
- data/test/seasar/container/test_component-info-def.rb +88 -0
- data/test/seasar/container/test_s2application-context.rb +290 -0
- data/test/seasar/container/test_s2container.rb +268 -0
- data/test/seasar/dbi/test_paginate.rb +265 -0
- data/test/seasar/test_log.rb +20 -0
- data/test/seasar/test_util.rb +46 -0
- data/test/test-suite.rb +7 -0
- metadata +211 -0
@@ -0,0 +1,57 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#--
|
3
|
+
# +----------------------------------------------------------------------+
|
4
|
+
# | Copyright 2005-2008 the Seasar Foundation and the Others. |
|
5
|
+
# +----------------------------------------------------------------------+
|
6
|
+
# | Licensed under the Apache License, Version 2.0 (the "License"); |
|
7
|
+
# | you may not use this file except in compliance with the License. |
|
8
|
+
# | You may obtain a copy of the License at |
|
9
|
+
# | |
|
10
|
+
# | http://www.apache.org/licenses/LICENSE-2.0 |
|
11
|
+
# | |
|
12
|
+
# | Unless required by applicable law or agreed to in writing, software |
|
13
|
+
# | distributed under the License is distributed on an "AS IS" BASIS, |
|
14
|
+
# | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, |
|
15
|
+
# | either express or implied. See the License for the specific language |
|
16
|
+
# | governing permissions and limitations under the License. |
|
17
|
+
# +----------------------------------------------------------------------+
|
18
|
+
#++
|
19
|
+
|
20
|
+
module Seasar
|
21
|
+
module Aop
|
22
|
+
# アスペクトされたインターセプターを管理・実行するクラスです。
|
23
|
+
# アスペクトされたメソッドが実行される度にインスタンス化されます。
|
24
|
+
class MethodInvocation
|
25
|
+
# MethodInvocationを構築します。
|
26
|
+
# - args
|
27
|
+
# - none
|
28
|
+
def initialize
|
29
|
+
@index = 0
|
30
|
+
@method = nil
|
31
|
+
@interceptors = nil
|
32
|
+
@enhanced_class = nil
|
33
|
+
@component_class = nil
|
34
|
+
@args = nil
|
35
|
+
@this = nil
|
36
|
+
end
|
37
|
+
attr_accessor :method, :interceptors, :enhanced_class, :component_class, :args, :procedure, :this
|
38
|
+
|
39
|
+
# MethodInvocation自身および、保持しているインターセプタから呼び出されます。
|
40
|
+
# すべてのインターセプタが実行されたのちにターゲットメソッドが実行されます。
|
41
|
+
#
|
42
|
+
# - args
|
43
|
+
# - none
|
44
|
+
# - return
|
45
|
+
# - mixed
|
46
|
+
#
|
47
|
+
def proceed
|
48
|
+
if @index < @interceptors.length
|
49
|
+
@index += 1
|
50
|
+
return @interceptors[@index - 1].call(self)
|
51
|
+
else
|
52
|
+
return @method.call(*@args, &@procedure)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#--
|
3
|
+
# +----------------------------------------------------------------------+
|
4
|
+
# | Copyright 2005-2008 the Seasar Foundation and the Others. |
|
5
|
+
# +----------------------------------------------------------------------+
|
6
|
+
# | Licensed under the Apache License, Version 2.0 (the "License"); |
|
7
|
+
# | you may not use this file except in compliance with the License. |
|
8
|
+
# | You may obtain a copy of the License at |
|
9
|
+
# | |
|
10
|
+
# | http://www.apache.org/licenses/LICENSE-2.0 |
|
11
|
+
# | |
|
12
|
+
# | Unless required by applicable law or agreed to in writing, software |
|
13
|
+
# | distributed under the License is distributed on an "AS IS" BASIS, |
|
14
|
+
# | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, |
|
15
|
+
# | either express or implied. See the License for the specific language |
|
16
|
+
# | governing permissions and limitations under the License. |
|
17
|
+
# +----------------------------------------------------------------------+
|
18
|
+
#++
|
19
|
+
|
20
|
+
module Seasar
|
21
|
+
module Aop
|
22
|
+
class Pointcut
|
23
|
+
|
24
|
+
#
|
25
|
+
# - args
|
26
|
+
# 1. Regexp|Symbol|String <em>point</em>
|
27
|
+
#
|
28
|
+
def initialize(point)
|
29
|
+
@point = point
|
30
|
+
if @point.is_a?(Regexp)
|
31
|
+
@matcher = lambda {|method_name| @point.match(method_name.to_s)}
|
32
|
+
elsif @point.is_a?(Symbol)
|
33
|
+
@matcher = lambda {|method_name| @point.to_s == method_name.to_s}
|
34
|
+
elsif @point.is_a?(String)
|
35
|
+
@matcher = lambda {|method_name| @point == method_name.to_s}
|
36
|
+
else
|
37
|
+
raise ArgumentError.new("unsupported point class #{@point}")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
attr_accessor :point
|
41
|
+
|
42
|
+
#
|
43
|
+
# - args
|
44
|
+
# 1. String <em>method_name</em>
|
45
|
+
# - return
|
46
|
+
# - Boolean
|
47
|
+
#
|
48
|
+
def applicable?(method_name)
|
49
|
+
return @matcher.call(method_name)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#--
|
3
|
+
# +----------------------------------------------------------------------+
|
4
|
+
# | Copyright 2005-2008 the Seasar Foundation and the Others. |
|
5
|
+
# +----------------------------------------------------------------------+
|
6
|
+
# | Licensed under the Apache License, Version 2.0 (the "License"); |
|
7
|
+
# | you may not use this file except in compliance with the License. |
|
8
|
+
# | You may obtain a copy of the License at |
|
9
|
+
# | |
|
10
|
+
# | http://www.apache.org/licenses/LICENSE-2.0 |
|
11
|
+
# | |
|
12
|
+
# | Unless required by applicable law or agreed to in writing, software |
|
13
|
+
# | distributed under the License is distributed on an "AS IS" BASIS, |
|
14
|
+
# | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, |
|
15
|
+
# | either express or implied. See the License for the specific language |
|
16
|
+
# | governing permissions and limitations under the License. |
|
17
|
+
# +----------------------------------------------------------------------+
|
18
|
+
#++
|
19
|
+
require "thread"
|
20
|
+
module Seasar
|
21
|
+
module Aop
|
22
|
+
|
23
|
+
# アスペクトを適用したクラスを生成するファクトリクラスです。
|
24
|
+
class S2AopFactory
|
25
|
+
@@index = 0
|
26
|
+
@@mutex = ::Mutex.new
|
27
|
+
|
28
|
+
class << self
|
29
|
+
|
30
|
+
#クラスにアスペクトを適用します。
|
31
|
+
#
|
32
|
+
# - args
|
33
|
+
# 1. Class <em>component_class</em>
|
34
|
+
# 2. Array <em>aspects</em>
|
35
|
+
# - return
|
36
|
+
# - Class
|
37
|
+
#
|
38
|
+
def create(component_class, aspects)
|
39
|
+
enhanced_class = S2AopFactory.generate_enhanced_class(component_class)
|
40
|
+
method_interceptors_map = S2AopFactory.creat_method_interceptors_map(component_class, aspects)
|
41
|
+
method_interceptors_map.each {|method_name, interceptors|
|
42
|
+
S2AopFactory.weave_aspect(component_class, enhanced_class, method_name, interceptors)
|
43
|
+
}
|
44
|
+
return enhanced_class
|
45
|
+
end
|
46
|
+
|
47
|
+
# 元のクラスを継承した新規クラスを返します。
|
48
|
+
# 新規クラスの名前には、「_EnhancedByS2Aop_###」が付加されます。
|
49
|
+
#
|
50
|
+
# - args
|
51
|
+
# 1. Class <em>component_class</em>
|
52
|
+
# - return
|
53
|
+
# - Class
|
54
|
+
#
|
55
|
+
def generate_enhanced_class(component_class)
|
56
|
+
#return Class.new(component_class)
|
57
|
+
consts = component_class.name.split(/::/)
|
58
|
+
enhanced_class_name = nil
|
59
|
+
@@mutex.synchronize {
|
60
|
+
enhanced_class_name = consts.pop + '_EnhancedByS2Aop_' + @@index.to_s
|
61
|
+
@@index += 1
|
62
|
+
}
|
63
|
+
if consts.size == 0
|
64
|
+
namespace = Object
|
65
|
+
else
|
66
|
+
namespace = eval(consts.join('::'))
|
67
|
+
end
|
68
|
+
clazz = Class.new(component_class)
|
69
|
+
# TODO: should throw exception? if contant has already defined in the namespace(module)
|
70
|
+
namespace.const_set(enhanced_class_name, clazz) unless namespace.const_defined?(enhanced_class_name)
|
71
|
+
return clazz
|
72
|
+
end
|
73
|
+
|
74
|
+
# クラスの各メソッドに適用するアスペクトを分類します。
|
75
|
+
#
|
76
|
+
# - args
|
77
|
+
# 1. Class <em>component_class</em>
|
78
|
+
# 2. Array <em>aspects</em>
|
79
|
+
# - return
|
80
|
+
# - Hash
|
81
|
+
#
|
82
|
+
def creat_method_interceptors_map(component_class, aspects)
|
83
|
+
methods = Seasar::Util::ClassUtil.get_aspectable_methods(component_class)
|
84
|
+
method_interceptors_map = {}
|
85
|
+
methods.each {|method_name|
|
86
|
+
interceptors = []
|
87
|
+
aspects.each {|aspect|
|
88
|
+
if aspect.pointcut.applicable?(method_name)
|
89
|
+
interceptors << aspect.interceptor
|
90
|
+
end
|
91
|
+
}
|
92
|
+
if 0 < interceptors.length
|
93
|
+
method_interceptors_map[method_name] = interceptors
|
94
|
+
end
|
95
|
+
}
|
96
|
+
return method_interceptors_map
|
97
|
+
end
|
98
|
+
|
99
|
+
# メソッドにアスペクトを織り込みます。(メソッドをinvokeクロージャで置き換えます)
|
100
|
+
#
|
101
|
+
# - args
|
102
|
+
# 1. Class <em>component_class</em>
|
103
|
+
# 2. Class <em>enhanced_class</em>
|
104
|
+
# 3. String|Symbol <em>method_name</em>
|
105
|
+
# 4. Array <em>interceptors</em>
|
106
|
+
# - return
|
107
|
+
# - none
|
108
|
+
#
|
109
|
+
def weave_aspect(component_class, enhanced_class, method_name, interceptors)
|
110
|
+
enhanced_class.__send__(:define_method, method_name) {|*args, &procedure|
|
111
|
+
invoker = MethodInvocation.new
|
112
|
+
invoker.method = component_class.instance_method(method_name).bind(self)
|
113
|
+
invoker.interceptors = interceptors
|
114
|
+
invoker.enhanced_class = enhanced_class
|
115
|
+
invoker.component_class = component_class
|
116
|
+
invoker.args = args
|
117
|
+
invoker.procedure = procedure
|
118
|
+
invoker.this = self
|
119
|
+
return invoker.proceed
|
120
|
+
}
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
data/lib/seasar/aop.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#--
|
3
|
+
# +----------------------------------------------------------------------+
|
4
|
+
# | Copyright 2005-2008 the Seasar Foundation and the Others. |
|
5
|
+
# +----------------------------------------------------------------------+
|
6
|
+
# | Licensed under the Apache License, Version 2.0 (the "License"); |
|
7
|
+
# | you may not use this file except in compliance with the License. |
|
8
|
+
# | You may obtain a copy of the License at |
|
9
|
+
# | |
|
10
|
+
# | http://www.apache.org/licenses/LICENSE-2.0 |
|
11
|
+
# | |
|
12
|
+
# | Unless required by applicable law or agreed to in writing, software |
|
13
|
+
# | distributed under the License is distributed on an "AS IS" BASIS, |
|
14
|
+
# | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, |
|
15
|
+
# | either express or implied. See the License for the specific language |
|
16
|
+
# | governing permissions and limitations under the License. |
|
17
|
+
# +----------------------------------------------------------------------+
|
18
|
+
#++
|
19
|
+
|
20
|
+
require 'seasar/aop/interceptor/trace-interceptor'
|
21
|
+
module Seasar
|
22
|
+
module Aop
|
23
|
+
autoload :Aspect, 'seasar/aop/aspect'
|
24
|
+
autoload :MethodInvocation, 'seasar/aop/method-invocation'
|
25
|
+
autoload :Pointcut, 'seasar/aop/pointcut'
|
26
|
+
autoload :S2AopFactory, 'seasar/aop/s2aop-factory'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#--
|
3
|
+
# +----------------------------------------------------------------------+
|
4
|
+
# | Copyright 2005-2008 the Seasar Foundation and the Others. |
|
5
|
+
# +----------------------------------------------------------------------+
|
6
|
+
# | Licensed under the Apache License, Version 2.0 (the "License"); |
|
7
|
+
# | you may not use this file except in compliance with the License. |
|
8
|
+
# | You may obtain a copy of the License at |
|
9
|
+
# | |
|
10
|
+
# | http://www.apache.org/licenses/LICENSE-2.0 |
|
11
|
+
# | |
|
12
|
+
# | Unless required by applicable law or agreed to in writing, software |
|
13
|
+
# | distributed under the License is distributed on an "AS IS" BASIS, |
|
14
|
+
# | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, |
|
15
|
+
# | either express or implied. See the License for the specific language |
|
16
|
+
# | governing permissions and limitations under the License. |
|
17
|
+
# +----------------------------------------------------------------------+
|
18
|
+
#++
|
19
|
+
|
20
|
+
module Seasar
|
21
|
+
module Beans
|
22
|
+
|
23
|
+
# プロパティの定義を行う抽象クラスです。
|
24
|
+
class AbstractPropertyDesc
|
25
|
+
|
26
|
+
# プロパティ値をセットするメソッド定義です。
|
27
|
+
#
|
28
|
+
# - args
|
29
|
+
# 1. Object <em>instance</em>
|
30
|
+
# 2. mixed <em>value</em>
|
31
|
+
# - return
|
32
|
+
# - nil
|
33
|
+
#
|
34
|
+
def set_value(instance, value)
|
35
|
+
end
|
36
|
+
|
37
|
+
# プロパティ値を返します。
|
38
|
+
#
|
39
|
+
# - args
|
40
|
+
# 1. Object <em>instance</em>
|
41
|
+
# - return
|
42
|
+
# - mixed
|
43
|
+
#
|
44
|
+
def get_value(instance)
|
45
|
+
end
|
46
|
+
|
47
|
+
# PropertyDescを構築します。
|
48
|
+
#
|
49
|
+
# - args
|
50
|
+
# 1. Symbol <em>prop_name</em>
|
51
|
+
def initialize(prop_name)
|
52
|
+
@property_name = prop_name
|
53
|
+
@typehint = nil
|
54
|
+
@array_acceptable = false
|
55
|
+
end
|
56
|
+
attr_accessor :property_name, :typehint, :array_acceptable
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#--
|
3
|
+
# +----------------------------------------------------------------------+
|
4
|
+
# | Copyright 2005-2008 the Seasar Foundation and the Others. |
|
5
|
+
# +----------------------------------------------------------------------+
|
6
|
+
# | Licensed under the Apache License, Version 2.0 (the "License"); |
|
7
|
+
# | you may not use this file except in compliance with the License. |
|
8
|
+
# | You may obtain a copy of the License at |
|
9
|
+
# | |
|
10
|
+
# | http://www.apache.org/licenses/LICENSE-2.0 |
|
11
|
+
# | |
|
12
|
+
# | Unless required by applicable law or agreed to in writing, software |
|
13
|
+
# | distributed under the License is distributed on an "AS IS" BASIS, |
|
14
|
+
# | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, |
|
15
|
+
# | either express or implied. See the License for the specific language |
|
16
|
+
# | governing permissions and limitations under the License. |
|
17
|
+
# +----------------------------------------------------------------------+
|
18
|
+
#++
|
19
|
+
|
20
|
+
module Seasar
|
21
|
+
module Beans
|
22
|
+
class AttributeAccessorDesc < AbstractPropertyDesc
|
23
|
+
|
24
|
+
# AttributeAccessorDescを構築します。
|
25
|
+
#
|
26
|
+
# - args
|
27
|
+
# 1. Symbol <em>prop_name</em>
|
28
|
+
#
|
29
|
+
def initialize(prop_name)
|
30
|
+
super
|
31
|
+
name = prop_name.to_s
|
32
|
+
@getter_name = name[1..name.length]
|
33
|
+
@setter_name = @getter_name + '='
|
34
|
+
end
|
35
|
+
|
36
|
+
# プロパティ値をセットするメソッドです。
|
37
|
+
#
|
38
|
+
# - args
|
39
|
+
# 1. Object <em>instance</em>
|
40
|
+
# 2. mixed <em>value</em>
|
41
|
+
# - return
|
42
|
+
# - nil
|
43
|
+
#
|
44
|
+
def set_value(instance, value)
|
45
|
+
instance.method(@setter_name).call(value)
|
46
|
+
end
|
47
|
+
|
48
|
+
# プロパティ値を返します。
|
49
|
+
#
|
50
|
+
# - args
|
51
|
+
# 1. Object <em>instance</em>
|
52
|
+
# - return
|
53
|
+
# - mixed
|
54
|
+
#
|
55
|
+
def get_value(instance)
|
56
|
+
return instance.method(@getter_name).call
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#--
|
3
|
+
# +----------------------------------------------------------------------+
|
4
|
+
# | Copyright 2005-2008 the Seasar Foundation and the Others. |
|
5
|
+
# +----------------------------------------------------------------------+
|
6
|
+
# | Licensed under the Apache License, Version 2.0 (the "License"); |
|
7
|
+
# | you may not use this file except in compliance with the License. |
|
8
|
+
# | You may obtain a copy of the License at |
|
9
|
+
# | |
|
10
|
+
# | http://www.apache.org/licenses/LICENSE-2.0 |
|
11
|
+
# | |
|
12
|
+
# | Unless required by applicable law or agreed to in writing, software |
|
13
|
+
# | distributed under the License is distributed on an "AS IS" BASIS, |
|
14
|
+
# | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, |
|
15
|
+
# | either express or implied. See the License for the specific language |
|
16
|
+
# | governing permissions and limitations under the License. |
|
17
|
+
# +----------------------------------------------------------------------+
|
18
|
+
#++
|
19
|
+
|
20
|
+
module Seasar
|
21
|
+
module Beans
|
22
|
+
|
23
|
+
# BeanDescを生成するファクトリクラスです。
|
24
|
+
# @attribute @@spool private
|
25
|
+
class BeanDescFactory
|
26
|
+
|
27
|
+
@@spool = {}
|
28
|
+
|
29
|
+
# シングルトンのBeanDescを返します。
|
30
|
+
#
|
31
|
+
# - args
|
32
|
+
# 1. Object <em>component</em>
|
33
|
+
# - return
|
34
|
+
# - Seasar::Beans::BeanDesc
|
35
|
+
#
|
36
|
+
def BeanDescFactory.get_bean_desc(component)
|
37
|
+
if not @@spool.key?(component.class)
|
38
|
+
@@spool[component.class] = BeanDesc.new(component)
|
39
|
+
end
|
40
|
+
return @@spool[component.class]
|
41
|
+
end
|
42
|
+
|
43
|
+
# シングルトンのBeanDescを削除します。Outer Injection時に使用されます。
|
44
|
+
#
|
45
|
+
# - args
|
46
|
+
# 1. Object <em>component</em>
|
47
|
+
# - return
|
48
|
+
# - none
|
49
|
+
#
|
50
|
+
def BeanDescFactory.remove_bean_desc(component)
|
51
|
+
if @@spool.key?(component.class)
|
52
|
+
@@spool.delete(component.class)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
#
|
57
|
+
# - args
|
58
|
+
# - none
|
59
|
+
# - return
|
60
|
+
# - none
|
61
|
+
#
|
62
|
+
def BeanDescFactory.init
|
63
|
+
@@spool = {}
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
@@ -0,0 +1,232 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
#--
|
3
|
+
# +----------------------------------------------------------------------+
|
4
|
+
# | Copyright 2005-2008 the Seasar Foundation and the Others. |
|
5
|
+
# +----------------------------------------------------------------------+
|
6
|
+
# | Licensed under the Apache License, Version 2.0 (the "License"); |
|
7
|
+
# | you may not use this file except in compliance with the License. |
|
8
|
+
# | You may obtain a copy of the License at |
|
9
|
+
# | |
|
10
|
+
# | http://www.apache.org/licenses/LICENSE-2.0 |
|
11
|
+
# | |
|
12
|
+
# | Unless required by applicable law or agreed to in writing, software |
|
13
|
+
# | distributed under the License is distributed on an "AS IS" BASIS, |
|
14
|
+
# | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, |
|
15
|
+
# | either express or implied. See the License for the specific language |
|
16
|
+
# | governing permissions and limitations under the License. |
|
17
|
+
# +----------------------------------------------------------------------+
|
18
|
+
#++
|
19
|
+
|
20
|
+
module Seasar
|
21
|
+
module Beans
|
22
|
+
# Bean定義を表すクラスです。
|
23
|
+
# publicな属性を管理します。
|
24
|
+
# publicでタイプヒントされた属性を管理します。
|
25
|
+
# セッターメソッドを管理します。
|
26
|
+
# タイプヒントされたセッターメソッドを管理します。
|
27
|
+
class BeanDesc
|
28
|
+
|
29
|
+
DI_SYMBOL = [:di, :DI, :Di, :dI]
|
30
|
+
DI_REGEXP = /^di (.*)$/i
|
31
|
+
|
32
|
+
# BeanDescを構築します。
|
33
|
+
#
|
34
|
+
# - args
|
35
|
+
# 1. Object <em>component</em>
|
36
|
+
#
|
37
|
+
def initialize(component)
|
38
|
+
@bean_class = component.class
|
39
|
+
@property_descs = {}
|
40
|
+
@typehint_property_descs = {}
|
41
|
+
self.setup_instance_variable_descs(component)
|
42
|
+
self.setup_attribute_accessor_descs(component)
|
43
|
+
end
|
44
|
+
attr_accessor :property_descs, :typehint_property_descs
|
45
|
+
|
46
|
+
# 渡された属性名の属性が存在するかどうかを返します。
|
47
|
+
#
|
48
|
+
# - args
|
49
|
+
# 1. Symbol <em>name</em>
|
50
|
+
# - return
|
51
|
+
# - Boolean
|
52
|
+
#
|
53
|
+
def has_property_desc(name)
|
54
|
+
return @property_descs.key?(name)
|
55
|
+
end
|
56
|
+
|
57
|
+
# 渡された属性名の属性定義を返します。
|
58
|
+
#
|
59
|
+
# - args
|
60
|
+
# 1. Symbol <em>name</em>
|
61
|
+
# - return
|
62
|
+
# - Seasar::Beans::AbstractPropertyDesc
|
63
|
+
#
|
64
|
+
def get_property_desc(name)
|
65
|
+
if self.has_property_desc(name)
|
66
|
+
return @property_descs[name]
|
67
|
+
end
|
68
|
+
raise Seasar::Exception::PropertyNotFoundRuntimeException.new(@bean_class, name)
|
69
|
+
end
|
70
|
+
|
71
|
+
# 渡された属性名のタイプヒント付き属性定義が存在するかどうかを返します。
|
72
|
+
#
|
73
|
+
# - args
|
74
|
+
# 1. Symbol <em>name</em>
|
75
|
+
# - return
|
76
|
+
# - Boolean
|
77
|
+
#
|
78
|
+
def has_typehint_property_desc(name)
|
79
|
+
return @typehint_property_descs.key?(name)
|
80
|
+
end
|
81
|
+
|
82
|
+
# 渡された属性名のタイプヒント付き属性定義を返します。
|
83
|
+
#
|
84
|
+
# - args
|
85
|
+
# 1. Symbol <em>name</em>
|
86
|
+
# - return
|
87
|
+
# - Seasar::Beans::AbstractPropertyDesc
|
88
|
+
#
|
89
|
+
def get_typehint_property_desc(name)
|
90
|
+
if self.has_typehint_property_desc(name)
|
91
|
+
return @typehint_property_descs[name]
|
92
|
+
end
|
93
|
+
raise Seasar::Exception::PropertyNotFoundRuntimeException.new(@bean_class, name)
|
94
|
+
end
|
95
|
+
|
96
|
+
#
|
97
|
+
# - args
|
98
|
+
# 1. Object <em>component</em>
|
99
|
+
# - return
|
100
|
+
# - nil
|
101
|
+
#
|
102
|
+
def setup_attribute_accessor_descs(component)
|
103
|
+
Seasar::Util::ClassUtil.get_accessor_attributes(component).each {|name|
|
104
|
+
next if has_property_desc(name)
|
105
|
+
property_desc = Seasar::Beans::AttributeAccessorDesc.new(name)
|
106
|
+
no_at_name = name.to_s
|
107
|
+
no_at_name = no_at_name[1..no_at_name.length].to_sym
|
108
|
+
@property_descs[name] = property_desc
|
109
|
+
setup_property_desc_nil(property_desc, name, no_at_name)
|
110
|
+
}
|
111
|
+
end
|
112
|
+
|
113
|
+
# 属性定義を生成します
|
114
|
+
# 属性名が「_」ではじまる場合は無視されます。
|
115
|
+
# 属性値が文字列で「DI:」ではじまる場合に属性定義が作成されます。
|
116
|
+
# 属性値が文字列で「DI:」の後ろの文字列がコンポーネントキーになります。空文字列の場合は、
|
117
|
+
# 属性名がコンポーネントキーとして扱われます。
|
118
|
+
# 属性値が文字列で「[]」で終わる場合は、複数のコンポーネントを配列で受けることができます。
|
119
|
+
#
|
120
|
+
# - args
|
121
|
+
# 1. Object <em>component</em>
|
122
|
+
# - return
|
123
|
+
# - nil
|
124
|
+
#
|
125
|
+
def setup_instance_variable_descs(component)
|
126
|
+
attributes = Seasar::Util::ClassUtil.get_instance_attributes(component)
|
127
|
+
attributes.each {|name, value|
|
128
|
+
no_at_name = name.to_s
|
129
|
+
no_at_name = no_at_name[1..no_at_name.length].to_sym
|
130
|
+
property_desc = Seasar::Beans::InstanceVariableDesc.new(name)
|
131
|
+
@property_descs[name] = property_desc
|
132
|
+
if value.nil?
|
133
|
+
setup_property_desc_nil(property_desc, name, no_at_name)
|
134
|
+
elsif value.is_a?(Class)
|
135
|
+
setup_property_desc_class(property_desc, name, value)
|
136
|
+
elsif value.is_a?(Symbol)
|
137
|
+
setup_property_desc_symbol(property_desc, name, value)
|
138
|
+
elsif value.is_a?(String) and DI_REGEXP.match(value)
|
139
|
+
setup_property_desc_string(property_desc, name, no_at_name, $1)
|
140
|
+
elsif value.is_a?(Array) and value.size == 2
|
141
|
+
setup_property_desc_array(property_desc, name, no_at_name, value[0], value[1])
|
142
|
+
elsif value.is_a?(Hash) and value.size == 1
|
143
|
+
key = value.keys[0]
|
144
|
+
setup_property_desc_hash(property_desc, name, no_at_name, key, value[key])
|
145
|
+
end
|
146
|
+
}
|
147
|
+
end
|
148
|
+
|
149
|
+
#
|
150
|
+
# - args
|
151
|
+
# 1. Seasar::Beans::AbstractPropertyDesc <em>property_desc</em>
|
152
|
+
# 2. Symbol <em>name</em>
|
153
|
+
# 3. Symbol <em>value</em>
|
154
|
+
# - return
|
155
|
+
# - nil
|
156
|
+
#
|
157
|
+
def setup_property_desc_symbol(property_desc, name, value)
|
158
|
+
@typehint_property_descs[name] = property_desc
|
159
|
+
property_desc.typehint = value
|
160
|
+
property_desc.array_acceptable = false
|
161
|
+
end
|
162
|
+
alias setup_property_desc_class setup_property_desc_symbol
|
163
|
+
|
164
|
+
#
|
165
|
+
# - args
|
166
|
+
# 1. Seasar::Beans::AbstractPropertyDesc <em>property_desc</em>
|
167
|
+
# 2. Symbol <em>name</em>
|
168
|
+
# 3. Symbol <em>no_at_name</em>
|
169
|
+
# - return
|
170
|
+
# - nil
|
171
|
+
#
|
172
|
+
def setup_property_desc_nil(property_desc, name, no_at_name)
|
173
|
+
@typehint_property_descs[name] = property_desc
|
174
|
+
property_desc.typehint = no_at_name
|
175
|
+
property_desc.array_acceptable = false
|
176
|
+
end
|
177
|
+
|
178
|
+
#
|
179
|
+
# - args
|
180
|
+
# 1. Seasar::Beans::AbstractPropertyDesc <em>property_desc</em>
|
181
|
+
# 2. Symbol <em>name</em>
|
182
|
+
# 3. Symbol <em>no_at_name</em>
|
183
|
+
# 4. String <em>value</em>
|
184
|
+
# - return
|
185
|
+
# - nil
|
186
|
+
#
|
187
|
+
def setup_property_desc_string(property_desc, name, no_at_name, value)
|
188
|
+
@typehint_property_descs[name] = property_desc
|
189
|
+
typehint = value.strip
|
190
|
+
typehint = no_at_name if typehint == ''
|
191
|
+
if /^(.*?)\[\]$/i =~ typehint
|
192
|
+
property_desc.array_acceptable = true
|
193
|
+
typehint = $1.strip
|
194
|
+
typehint = no_at_name if typehint == ''
|
195
|
+
else
|
196
|
+
property_desc.array_acceptable = false
|
197
|
+
end
|
198
|
+
property_desc.typehint = typehint
|
199
|
+
end
|
200
|
+
|
201
|
+
#
|
202
|
+
# - args
|
203
|
+
# 1. Seasar::Beans::AbstractPropertyDesc <em>property_desc</em>
|
204
|
+
# 2. Symbol <em>name</em>
|
205
|
+
# 3. Symbol <em>no_at_name</em>
|
206
|
+
# 4. String <em>key</em>
|
207
|
+
# 5. miced <em>value</em>
|
208
|
+
# - return
|
209
|
+
# - nil
|
210
|
+
#
|
211
|
+
def setup_property_desc_array(property_desc, name, no_at_name, key, value)
|
212
|
+
if DI_SYMBOL.member?(key) or key.downcase == "di"
|
213
|
+
@typehint_property_descs[name] = property_desc
|
214
|
+
if value.nil?
|
215
|
+
setup_property_desc_nil(property_desc, name, no_at_name, value)
|
216
|
+
elsif value.is_a?(Class)
|
217
|
+
setup_property_desc_class(property_desc, name, value)
|
218
|
+
elsif value.is_a?(Symbol)
|
219
|
+
setup_property_desc_symbol(property_desc, name, value)
|
220
|
+
elsif value.is_a?(String)
|
221
|
+
setup_property_desc_string(property_desc, name, no_at_name, value)
|
222
|
+
else
|
223
|
+
raise ArgumentError.new("invalid value #{value.inspect} for :DI. property [#{name}] of class [#{@bean_class.name}].")
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
alias setup_property_desc_hash setup_property_desc_array
|
228
|
+
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|