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.
Files changed (136) hide show
  1. data/Apache_Software_License_2.0.txt +202 -0
  2. data/ChangeLog +1 -0
  3. data/ChangeLog.ja +64 -0
  4. data/README +9 -0
  5. data/Rakefile +51 -0
  6. data/example/example01/example.rb +13 -0
  7. data/example/example01/run.rb +20 -0
  8. data/example/example02/example.rb +30 -0
  9. data/example/example02/run.rb +8 -0
  10. data/example/example03/example.rb +8 -0
  11. data/example/example03/run.rb +12 -0
  12. data/example/example04/example.rb +9 -0
  13. data/example/example04/run.rb +15 -0
  14. data/example/example05/example.rb +9 -0
  15. data/example/example05/run.rb +21 -0
  16. data/example/example06/example.rb +9 -0
  17. data/example/example06/run.rb +8 -0
  18. data/example/example07/example.rb +8 -0
  19. data/example/example07/run.rb +15 -0
  20. data/example/example08/example.rb +9 -0
  21. data/example/example08/run.rb +19 -0
  22. data/example/example09/example.rb +7 -0
  23. data/example/example09/run.rb +11 -0
  24. data/example/example10/example.rb +9 -0
  25. data/example/example10/run.rb +10 -0
  26. data/example/example11/example.rb +18 -0
  27. data/example/example11/run.rb +10 -0
  28. data/example/example12/example.rb +9 -0
  29. data/example/example12/run.rb +8 -0
  30. data/example/example13/example.rb +18 -0
  31. data/example/example13/example.sql +4 -0
  32. data/example/example13/run.rb +22 -0
  33. data/example/example13/sample.db +0 -0
  34. data/example/example14/example.db +0 -0
  35. data/example/example14/example.rb +57 -0
  36. data/example/example14/example.sql +50 -0
  37. data/example/example14/run1.rb +23 -0
  38. data/example/example14/run2.rb +28 -0
  39. data/example/example14/run3.rb +25 -0
  40. data/example/example14/run4.rb +23 -0
  41. data/example/example14/run5.rb +35 -0
  42. data/example/example15/example.rb +20 -0
  43. data/example/example15/run.rb +28 -0
  44. data/example/example16/example.rb +15 -0
  45. data/example/example16/run.rb +24 -0
  46. data/example/quickstart/quickstart1/quickstart.rb +10 -0
  47. data/example/quickstart/quickstart2/quickstart.rb +9 -0
  48. data/example/quickstart/quickstart3/quickstart.rb +9 -0
  49. data/example/quickstart/quickstart4/quickstart.rb +14 -0
  50. data/example/quickstart/quickstart5/quickstart.rb +21 -0
  51. data/example/quickstart/quickstart6/quickstart.rb +28 -0
  52. data/example/quickstart/quickstart7/quickstart.rb +18 -0
  53. data/lib/s2container.rb +25 -0
  54. data/lib/seasar/aop/aspect.rb +30 -0
  55. data/lib/seasar/aop/interceptor/trace-interceptor.rb +48 -0
  56. data/lib/seasar/aop/method-invocation.rb +57 -0
  57. data/lib/seasar/aop/pointcut.rb +53 -0
  58. data/lib/seasar/aop/s2aop-factory.rb +125 -0
  59. data/lib/seasar/aop.rb +29 -0
  60. data/lib/seasar/beans/abstract-property-desc.rb +59 -0
  61. data/lib/seasar/beans/attribute-accessor-desc.rb +60 -0
  62. data/lib/seasar/beans/bean-desc-factory.rb +68 -0
  63. data/lib/seasar/beans/bean-desc.rb +232 -0
  64. data/lib/seasar/beans/instance-variable-desc.rb +58 -0
  65. data/lib/seasar/beans.rb +29 -0
  66. data/lib/seasar/container/arg-def.rb +51 -0
  67. data/lib/seasar/container/aspect-def.rb +60 -0
  68. data/lib/seasar/container/aspect-info-def.rb +94 -0
  69. data/lib/seasar/container/assembler/abstract-assembler.rb +68 -0
  70. data/lib/seasar/container/assembler/auto-property-assembler.rb +57 -0
  71. data/lib/seasar/container/assembler/autobinding-auto-def.rb +55 -0
  72. data/lib/seasar/container/assembler/autobinding-def-factory.rb +57 -0
  73. data/lib/seasar/container/assembler/autobinding-none-def.rb +53 -0
  74. data/lib/seasar/container/assembler/manual-constructor-assembler.rb +67 -0
  75. data/lib/seasar/container/assembler/manual-property-assembler.rb +68 -0
  76. data/lib/seasar/container/autobinding-def.rb +36 -0
  77. data/lib/seasar/container/component-def.rb +229 -0
  78. data/lib/seasar/container/component-info-def.rb +117 -0
  79. data/lib/seasar/container/deployer/abstract-component-deployer.rb +47 -0
  80. data/lib/seasar/container/deployer/instance-def-factory.rb +56 -0
  81. data/lib/seasar/container/deployer/instance-outer-def.rb +44 -0
  82. data/lib/seasar/container/deployer/instance-prototype-def.rb +44 -0
  83. data/lib/seasar/container/deployer/instance-singleton-def.rb +42 -0
  84. data/lib/seasar/container/deployer/outer-component-deployer.rb +47 -0
  85. data/lib/seasar/container/deployer/prototype-component-deployer.rb +51 -0
  86. data/lib/seasar/container/deployer/singleton-component-deployer.rb +54 -0
  87. data/lib/seasar/container/exception/component-notfound-runtime-exception.rb +44 -0
  88. data/lib/seasar/container/exception/cyclic-reference-runtime-exception.rb +43 -0
  89. data/lib/seasar/container/exception/illegal-autobinding-def-runtime-exception.rb +43 -0
  90. data/lib/seasar/container/exception/illegal-instance-def-runtime-exception.rb +44 -0
  91. data/lib/seasar/container/exception/toomany-registration-runtime-exception.rb +46 -0
  92. data/lib/seasar/container/instance-def.rb +37 -0
  93. data/lib/seasar/container/outer-component-def.rb +34 -0
  94. data/lib/seasar/container/property-def.rb +43 -0
  95. data/lib/seasar/container/s2application-context.rb +447 -0
  96. data/lib/seasar/container/s2container-component-def.rb +41 -0
  97. data/lib/seasar/container/s2container.rb +308 -0
  98. data/lib/seasar/container/simple-component-def.rb +45 -0
  99. data/lib/seasar/container/toomany-registration-component-def.rb +69 -0
  100. data/lib/seasar/container.rb +143 -0
  101. data/lib/seasar/dbi/dbi-interceptor.rb +97 -0
  102. data/lib/seasar/dbi/paginate.rb +215 -0
  103. data/lib/seasar/dbi.rb +26 -0
  104. data/lib/seasar/exception/notyet-implemented-exception.rb +25 -0
  105. data/lib/seasar/exception/property-notfound-runtime-exception.rb +48 -0
  106. data/lib/seasar/exception/s2runtime-exception.rb +35 -0
  107. data/lib/seasar/exception/unsupported-operation-exception.rb +25 -0
  108. data/lib/seasar/exception.rb +27 -0
  109. data/lib/seasar/log/s2logger.rb +75 -0
  110. data/lib/seasar/log.rb +38 -0
  111. data/lib/seasar/util/class-util.rb +116 -0
  112. data/lib/seasar/util.rb +24 -0
  113. data/setup.rb +1585 -0
  114. data/test/seasar/aop/test_pointcut.rb +25 -0
  115. data/test/seasar/aop/test_s2aop_factory.rb +90 -0
  116. data/test/seasar/beans/test_bean-desc.rb +179 -0
  117. data/test/seasar/container/assembler/test_auto_property_assembler.rb +87 -0
  118. data/test/seasar/container/assembler/test_autobinding_def_factory.rb +22 -0
  119. data/test/seasar/container/assembler/test_manual_property_assembler.rb +59 -0
  120. data/test/seasar/container/assembler/test_manula_constructor_assembler.rb +59 -0
  121. data/test/seasar/container/assembler/test_proc_constructor_assembler.rb +61 -0
  122. data/test/seasar/container/deployer/test_instance_def_factory.rb +24 -0
  123. data/test/seasar/container/deployer/test_prototype-deployer.rb +25 -0
  124. data/test/seasar/container/deployer/test_singleton-component-deployer.rb +24 -0
  125. data/test/seasar/container/s2app_load_sample.rb +6 -0
  126. data/test/seasar/container/test_arg-def.rb +34 -0
  127. data/test/seasar/container/test_aspect-info-def.rb +85 -0
  128. data/test/seasar/container/test_component-def.rb +91 -0
  129. data/test/seasar/container/test_component-info-def.rb +88 -0
  130. data/test/seasar/container/test_s2application-context.rb +290 -0
  131. data/test/seasar/container/test_s2container.rb +268 -0
  132. data/test/seasar/dbi/test_paginate.rb +265 -0
  133. data/test/seasar/test_log.rb +20 -0
  134. data/test/seasar/test_util.rb +46 -0
  135. data/test/test-suite.rb +7 -0
  136. 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
+