phenomenal 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +27 -0
- data/README +3 -0
- data/Rakefile +11 -0
- data/lib/phenomenal.rb +24 -0
- data/lib/phenomenal/adaptation.rb +79 -0
- data/lib/phenomenal/conflict_policies.rb +20 -0
- data/lib/phenomenal/context.rb +269 -0
- data/lib/phenomenal/dsl.rb +119 -0
- data/lib/phenomenal/feature.rb +8 -0
- data/lib/phenomenal/logger.rb +34 -0
- data/lib/phenomenal/manager.rb +317 -0
- data/lib/phenomenal/proc.rb +34 -0
- data/lib/phenomenal/relationships/context_relationships.rb +22 -0
- data/lib/phenomenal/relationships/dsl.rb +18 -0
- data/lib/phenomenal/relationships/feature_relationships.rb +42 -0
- data/lib/phenomenal/relationships/implication.rb +35 -0
- data/lib/phenomenal/relationships/relationship.rb +42 -0
- data/lib/phenomenal/relationships/relationships_manager.rb +63 -0
- data/lib/phenomenal/relationships/relationships_store.rb +73 -0
- data/lib/phenomenal/relationships/requirement.rb +26 -0
- data/lib/phenomenal/relationships/suggestion.rb +41 -0
- data/lib/phenomenal/version.rb +3 -0
- data/spec/adaptation_spec.rb +64 -0
- data/spec/behavior/adaptation_spec.rb +5 -0
- data/spec/behavior/combined_contexts_spec.rb +5 -0
- data/spec/behavior/composition_spec.rb +5 -0
- data/spec/behavior/conflict_policy_spec.rb +5 -0
- data/spec/behavior/open_context.rb +5 -0
- data/spec/behavior/relationships_spec.rb +249 -0
- data/spec/context_spec.rb +268 -0
- data/spec/dsl_spec.rb +181 -0
- data/spec/feature_spec.rb +5 -0
- data/spec/manager_spec.rb +84 -0
- data/spec/proc_spec.rb +20 -0
- data/spec/relationships/context_relationships_spec.rb +13 -0
- data/spec/relationships/dsl_spec.rb +13 -0
- data/spec/relationships/feature_relationships_spec.rb +13 -0
- data/spec/relationships/relationship_spec.rb +31 -0
- data/spec/relationships/relationships_manager_spec.rb +15 -0
- data/spec/relationships/relationships_store_spec.rb +19 -0
- data/spec/spec_helper.rb +18 -0
- data/spec/test_classes.rb +111 -0
- metadata +124 -0
data/LICENSE
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
Copyright (C) 2011 Thibault Poncelet <thibault.poncelet@student.uclouvain.be>
|
2
|
+
Copyright (C) 2011 Loic Vigneron <loic.vigneron@student.uclouvain.be>
|
3
|
+
|
4
|
+
This program is free software; you can redistribute it and/or modify
|
5
|
+
it under the terms of the GNU General Public License as published by
|
6
|
+
the Free Software Foundation; either version 2 of the License, or
|
7
|
+
(at your option) any later version.
|
8
|
+
|
9
|
+
This program is distributed in the hope that it will be useful,
|
10
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
GNU General Public License for more details.
|
13
|
+
|
14
|
+
You should have received a copy of the GNU General Public License
|
15
|
+
along with this program; if not, write to the Free Software
|
16
|
+
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
17
|
+
|
18
|
+
========================
|
19
|
+
|
20
|
+
Master thesis : The phenomenal gem
|
21
|
+
Prof : Kim Mens
|
22
|
+
Year : 2011-2012
|
23
|
+
Students names,sections :
|
24
|
+
- Poncelet Thibault (SINF22MS)
|
25
|
+
- Vigneron Loic (SINF22MS)
|
26
|
+
Start date : May 1, 2011
|
27
|
+
|
data/README
ADDED
data/Rakefile
ADDED
data/lib/phenomenal.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# Load the gem files in the system
|
2
|
+
module Phenomenal end
|
3
|
+
#Relationships
|
4
|
+
require_relative "./phenomenal/relationships/context_relationships.rb"
|
5
|
+
require_relative "./phenomenal/relationships/feature_relationships.rb"
|
6
|
+
require_relative "./phenomenal/relationships/relationships_store.rb"
|
7
|
+
require_relative "./phenomenal/relationships/relationships_manager.rb"
|
8
|
+
require_relative "./phenomenal/relationships/relationship.rb"
|
9
|
+
require_relative "./phenomenal/relationships/requirement.rb"
|
10
|
+
require_relative "./phenomenal/relationships/implication.rb"
|
11
|
+
require_relative "./phenomenal/relationships/suggestion.rb"
|
12
|
+
|
13
|
+
# Core
|
14
|
+
require_relative "./phenomenal/adaptation.rb"
|
15
|
+
require_relative "./phenomenal/conflict_policies.rb"
|
16
|
+
require_relative "./phenomenal/context.rb"
|
17
|
+
require_relative "./phenomenal/feature.rb"
|
18
|
+
require_relative "./phenomenal/logger.rb"
|
19
|
+
require_relative "./phenomenal/manager.rb"
|
20
|
+
require_relative "./phenomenal/proc.rb"
|
21
|
+
|
22
|
+
# DSL
|
23
|
+
require_relative "./phenomenal/relationships/dsl.rb"
|
24
|
+
require_relative "./phenomenal/dsl.rb"
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# Represent a method adaptation for a particular context
|
2
|
+
class Phenomenal::Adaptation
|
3
|
+
attr_accessor :context, :klass, :method_name, :implementation, :src_file,
|
4
|
+
:src_line,:instance_adaptation
|
5
|
+
|
6
|
+
def initialize(context,klass, method_name,instance_adapatation,implementation)
|
7
|
+
@context = context
|
8
|
+
@klass = klass
|
9
|
+
@method_name = method_name
|
10
|
+
@implementation = implementation
|
11
|
+
@instance_adaptation=instance_adapatation
|
12
|
+
|
13
|
+
check_validity
|
14
|
+
# Save the source location if any, this is used to find again the adaptation
|
15
|
+
# in a ctxt_proceed call. It always exists except for method directly
|
16
|
+
# implemented in C -> Not a problem because these one never use ctxt_proceed
|
17
|
+
source_location = implementation.source_location
|
18
|
+
if source_location
|
19
|
+
@src_file = implementation.source_location[0]
|
20
|
+
@src_line = implementation.source_location[1]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Deploy actually the adaptation in the target class by overriding the current
|
25
|
+
# implementation
|
26
|
+
def deploy
|
27
|
+
method_name = self.method_name
|
28
|
+
implementation = self.implementation
|
29
|
+
if instance_adaptation?
|
30
|
+
klass.class_eval { define_method(method_name, implementation) }
|
31
|
+
else
|
32
|
+
klass.define_singleton_method(method_name,implementation)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# IMPROVE check for better implementation
|
37
|
+
# Bind the implementation corresponding to this adaptation to 'instance' when
|
38
|
+
# instance_method or to implementation klass when class method
|
39
|
+
def bind(instance,*args,&block)
|
40
|
+
if instance_adaptation?
|
41
|
+
if implementation.class==Proc
|
42
|
+
implementation.phenomenal_bind(instance).call(*args,&block)
|
43
|
+
else
|
44
|
+
implementation.bind(instance).call(*args,&block)
|
45
|
+
end
|
46
|
+
else
|
47
|
+
if implementation.class==Proc
|
48
|
+
implementation.phenomenal_class_bind(klass).call(*args,&block)
|
49
|
+
else
|
50
|
+
implementation.call(*args,&block)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
#True if the adaptation concern the class n_klass and method n_method
|
56
|
+
def concern?(klass,method_name,instance_adaptation)
|
57
|
+
self.klass==klass &&
|
58
|
+
self.method_name==method_name &&
|
59
|
+
self.instance_adaptation==instance_adaptation
|
60
|
+
end
|
61
|
+
|
62
|
+
alias_method :instance_adaptation?, :instance_adaptation
|
63
|
+
|
64
|
+
# String representation
|
65
|
+
def to_s
|
66
|
+
":#{context.name} => #{klass.name}.#{method_name} :: #{src_file}:#{src_line}"
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
def check_validity
|
71
|
+
if klass.instance_methods.include?(method_name) && !instance_adaptation? ||
|
72
|
+
!klass.instance_methods.include?(method_name) && instance_adaptation?
|
73
|
+
Phenomenal::Logger.instance.error(
|
74
|
+
"Illegal adaptation for context: #{context}" +
|
75
|
+
" for #{klass.name}.#{method_name}, type mismatch"
|
76
|
+
)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# Context conflict resolution policies
|
2
|
+
module Phenomenal::ConflictPolicies
|
3
|
+
# Prefer not default adaptation, error if two not default ones
|
4
|
+
def no_resolution_conflict_policy(adaptation1,adaptation2)
|
5
|
+
if adaptation1.context==default_context()
|
6
|
+
1
|
7
|
+
elsif adaptation2.context.name==default_context()
|
8
|
+
-1
|
9
|
+
else #Fail if two non default adaptations
|
10
|
+
Phenomenal::Logger.instance.error(
|
11
|
+
"Error: Illegal duplicate adapation of #{adaptation1.to_s}"
|
12
|
+
)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# Age based conflict resolution
|
17
|
+
def age_conflict_policy(adaptation1, adaptation2)
|
18
|
+
adaptation1.context.age <=> adaptation2.context.age
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,269 @@
|
|
1
|
+
# Represent a first class context
|
2
|
+
class Phenomenal::Context
|
3
|
+
include Phenomenal::ContextRelationships
|
4
|
+
@@total_activations = 0
|
5
|
+
def self.create(context,*contexts,nested,closest_feature,&block)
|
6
|
+
manager = Phenomenal::Manager.instance
|
7
|
+
contexts.insert(0,context)
|
8
|
+
if contexts.length==1
|
9
|
+
if !manager.context_defined?(context)
|
10
|
+
context = self.new(context)
|
11
|
+
else
|
12
|
+
context = manager.find_context(context)
|
13
|
+
if !context.instance_of?(self)
|
14
|
+
Phenomenal::Logger.instance.error(
|
15
|
+
"Only #{self.name} can be used with this keyword"
|
16
|
+
)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
else #Combined contexts
|
20
|
+
if !manager.context_defined?(*contexts) # New combined context
|
21
|
+
context = self.new
|
22
|
+
context.parent=closest_feature # Set parent
|
23
|
+
instances = Array.new
|
24
|
+
first = contexts.first
|
25
|
+
contexts.each do |c|
|
26
|
+
# Use the object instance if already available
|
27
|
+
# otherwise create it
|
28
|
+
if manager.context_defined?(c)
|
29
|
+
c = manager.find_context(c)
|
30
|
+
if !nested && c!=first && !c.instance_of?(self)
|
31
|
+
Phenomenal::Logger.instance.error(
|
32
|
+
"Only #{self.name} can be used with this keyword"
|
33
|
+
)
|
34
|
+
end
|
35
|
+
else
|
36
|
+
c = self.new(c)
|
37
|
+
end
|
38
|
+
instances.push(c)
|
39
|
+
manager.shared_contexts[c]= Array.new if !manager.shared_contexts[c]
|
40
|
+
manager.shared_contexts[c].push(context)
|
41
|
+
end
|
42
|
+
manager.combined_contexts[context] = instances
|
43
|
+
else
|
44
|
+
context = manager.find_context(*contexts)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
context.add_adaptations(&block)
|
48
|
+
context
|
49
|
+
end
|
50
|
+
|
51
|
+
attr_accessor :activation_age, :activation_frequency, :adaptations,
|
52
|
+
:activation_count, :parent,:forgotten
|
53
|
+
attr_reader :manager,:name
|
54
|
+
|
55
|
+
def initialize(name=nil, manager=nil)
|
56
|
+
@manager = manager || Phenomenal::Manager.instance
|
57
|
+
@name = name
|
58
|
+
@activation_age = 0
|
59
|
+
@activation_count = 0
|
60
|
+
@adaptations = Array.new
|
61
|
+
@manager.register_context(self)
|
62
|
+
@parent=nil
|
63
|
+
@forgotten=false
|
64
|
+
end
|
65
|
+
|
66
|
+
# Unregister the context from the context manager,
|
67
|
+
# This context shoudn't be used after.
|
68
|
+
# The context has to be inactive before being forgetted
|
69
|
+
# TODO handle relationships references
|
70
|
+
def forget
|
71
|
+
if active?
|
72
|
+
Phenomenal::Logger.instance.error(
|
73
|
+
"Active context cannot be forgotten"
|
74
|
+
)
|
75
|
+
else
|
76
|
+
manager.unregister_context(self)
|
77
|
+
forgotten=true
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# Add a new method adaptation to the context
|
82
|
+
# Return the adaptation just created
|
83
|
+
def add_adaptation(klass, method_name,instance,umeth=nil, &implementation)
|
84
|
+
if umeth
|
85
|
+
implementation = umeth
|
86
|
+
instance = klass.instance_methods.include?(method_name)
|
87
|
+
end
|
88
|
+
if adaptations.find{ |i| i.concern?(klass,method_name,instance) }
|
89
|
+
Phenomenal::Logger.instance.error(
|
90
|
+
"Error: Illegal duplicated adaptation in context: #{self} for " +
|
91
|
+
"#{klass.name}:#{method_name}"
|
92
|
+
)
|
93
|
+
else
|
94
|
+
if klass.instance_methods.include?(method_name) && instance
|
95
|
+
method = klass.instance_method(method_name)
|
96
|
+
elsif klass.methods.include?(method_name) && !instance
|
97
|
+
method = klass.method(method_name)
|
98
|
+
else
|
99
|
+
Phenomenal::Logger.instance.error(
|
100
|
+
"Error: Illegal adaptation for context #{self},a method with "+
|
101
|
+
"name: #{method_name} should exist in class #{klass.name} to "+
|
102
|
+
"be adapted"
|
103
|
+
)
|
104
|
+
end
|
105
|
+
if method.arity != implementation.arity
|
106
|
+
Phenomenal::Logger.instance.error(
|
107
|
+
"Error: Illegal adaptation for context #{self},the adaptation "+
|
108
|
+
"have to keep the original method arity for method: " +
|
109
|
+
"#{klass.name}.#{method_name}: (#{method.arity} instead of " +
|
110
|
+
"#{implementation.arity})"
|
111
|
+
)
|
112
|
+
end
|
113
|
+
|
114
|
+
adaptation = Phenomenal::Adaptation.new(
|
115
|
+
self, klass, method_name,instance, implementation
|
116
|
+
)
|
117
|
+
adaptations.push(adaptation)
|
118
|
+
manager.register_adaptation(adaptation)
|
119
|
+
adaptation
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# Catch nested context calls and transform them in nested contexts creation
|
124
|
+
def context(context,*contexts,&block)
|
125
|
+
check_validity
|
126
|
+
Phenomenal::Context.create(self,context,*contexts,true,self,&block)
|
127
|
+
end
|
128
|
+
alias_method :phen_context,:context
|
129
|
+
|
130
|
+
# Catch nested feature calls and transform them in nested contexts creation
|
131
|
+
def feature(feature,*features, &block)
|
132
|
+
check_validity
|
133
|
+
Phenomenal::Feature.create(self,feature,*features,true,self,&block)
|
134
|
+
end
|
135
|
+
alias_method :phen_feature,:feature
|
136
|
+
|
137
|
+
# Add multiple adaptations at definition time
|
138
|
+
def add_adaptations(&block)
|
139
|
+
instance_eval(&block) if block
|
140
|
+
end
|
141
|
+
|
142
|
+
# Set the current adapted class for the next adapt calls
|
143
|
+
def adaptations_for(klass)
|
144
|
+
@current_adapted_class = klass
|
145
|
+
end
|
146
|
+
|
147
|
+
# Adapt a method for @current_adapted_class
|
148
|
+
def adapt(method,&block)
|
149
|
+
add_adaptation(@current_adapted_class,method,true,&block)
|
150
|
+
end
|
151
|
+
|
152
|
+
# Adapt a method for @current_adapted_class
|
153
|
+
def adapt_klass(method,&block)
|
154
|
+
add_adaptation(@current_adapted_class,method,false,&block)
|
155
|
+
end
|
156
|
+
|
157
|
+
# Remove a method adaptation from the context
|
158
|
+
def remove_adaptation(klass,method_name,instance)
|
159
|
+
adaptation_index =
|
160
|
+
adaptations.find_index{ |i| i.concern?(klass, method_name,instance) }
|
161
|
+
if !adaptation_index
|
162
|
+
Phenomenal::Logger.instance.error(
|
163
|
+
"Error: Illegal deleting of an inexistent adaptation in context: " +
|
164
|
+
"#{self} for #{klass.name}.#{method_name})"
|
165
|
+
)
|
166
|
+
end
|
167
|
+
|
168
|
+
adaptation = adaptations.delete_at(adaptation_index)
|
169
|
+
manager.unregister_adaptation(adaptation)
|
170
|
+
end
|
171
|
+
|
172
|
+
# Activate the context
|
173
|
+
def activate
|
174
|
+
check_validity
|
175
|
+
@@total_activations +=1
|
176
|
+
self.activation_age =@@total_activations
|
177
|
+
self.activation_count = self.activation_count+1
|
178
|
+
manager.activate_context(self)
|
179
|
+
self
|
180
|
+
end
|
181
|
+
|
182
|
+
# Deactivate the context
|
183
|
+
def deactivate(caller_context=nil)
|
184
|
+
check_validity
|
185
|
+
was_active = active?
|
186
|
+
if self.activation_count>0
|
187
|
+
#Deactivation
|
188
|
+
self.activation_count = self.activation_count-1
|
189
|
+
end
|
190
|
+
if was_active && !active?
|
191
|
+
manager.deactivate_context(self)
|
192
|
+
end
|
193
|
+
self
|
194
|
+
end
|
195
|
+
|
196
|
+
# True if the context is active
|
197
|
+
def active?
|
198
|
+
activation_count>0
|
199
|
+
end
|
200
|
+
|
201
|
+
# True if the context has just became active
|
202
|
+
def just_activated?
|
203
|
+
activation_count==1
|
204
|
+
end
|
205
|
+
|
206
|
+
# True if the context is anonymous
|
207
|
+
def anonymous?
|
208
|
+
name.nil?
|
209
|
+
end
|
210
|
+
|
211
|
+
# Return the activation age of the context:
|
212
|
+
# The age counter minus the age counter when the context was activated
|
213
|
+
# for the last time
|
214
|
+
def age
|
215
|
+
@@total_activations-activation_age
|
216
|
+
end
|
217
|
+
|
218
|
+
# Return context informations:
|
219
|
+
# - Name
|
220
|
+
# - List of the adaptations
|
221
|
+
# - Active state
|
222
|
+
# - Activation age
|
223
|
+
# - Activation count
|
224
|
+
def information
|
225
|
+
{
|
226
|
+
:name=>name,
|
227
|
+
:adaptations=>adaptations,
|
228
|
+
:active=>active?,
|
229
|
+
:age=>age,
|
230
|
+
:activation_count=>activation_count,
|
231
|
+
:type=>self.class.name
|
232
|
+
}
|
233
|
+
end
|
234
|
+
|
235
|
+
# Return the closest parent feature of the context
|
236
|
+
def parent_feature
|
237
|
+
p = parent
|
238
|
+
while p!=nil && !p.is_a?(Phenomenal::Feature) do
|
239
|
+
p=p.parent
|
240
|
+
end
|
241
|
+
if p.nil?
|
242
|
+
manager.default_context
|
243
|
+
else
|
244
|
+
p
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
# String representation of the context
|
249
|
+
def to_s
|
250
|
+
if name
|
251
|
+
name.to_s
|
252
|
+
elsif self==manager.default_context
|
253
|
+
"'Default context'"
|
254
|
+
elsif manager.combined_contexts[self]
|
255
|
+
"'Combined context : #{manager.combined_contexts[self].flatten}'"
|
256
|
+
else
|
257
|
+
"'Anonymous context'"
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
private
|
262
|
+
def check_validity
|
263
|
+
if forgotten
|
264
|
+
Phenomenal::Logger.instance.error(
|
265
|
+
"Action not allowed anymore when context has been forgotten"
|
266
|
+
)
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
# Define the DSL methods
|
2
|
+
module Phenomenal::DSL
|
3
|
+
#Override included hook method
|
4
|
+
def self.included(klass)
|
5
|
+
klass.class_eval do
|
6
|
+
#Define Context
|
7
|
+
def phen_define_context(name=nil,priority=nil)
|
8
|
+
Phenomenal::Context.new(name,priority)
|
9
|
+
end
|
10
|
+
# Define context with adaptations
|
11
|
+
def phen_context(context,*contexts,&block)
|
12
|
+
Phenomenal::Context.create(context,*contexts,false,nil,&block)
|
13
|
+
end
|
14
|
+
Phenomenal::DSL.phen_alias(:context,klass)
|
15
|
+
|
16
|
+
# Define context with adaptations
|
17
|
+
def phen_feature(context,*contexts,&block)
|
18
|
+
Phenomenal::Feature.create(context,*contexts,false,nil,&block)
|
19
|
+
end
|
20
|
+
Phenomenal::DSL.phen_alias(:feature,klass)
|
21
|
+
|
22
|
+
|
23
|
+
# Forget Context
|
24
|
+
def phen_forget_context(context)
|
25
|
+
Phenomenal::Manager.instance.find_context(context).forget
|
26
|
+
end
|
27
|
+
|
28
|
+
# Add adaptation
|
29
|
+
def phen_add_adaptation(context,klass, method_name, &implementation)
|
30
|
+
Phenomenal::Manager.instance.find_context(context).add_adaptation(
|
31
|
+
klass, method_name,true, &implementation
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
35
|
+
def phen_add_class_adaptation(context,klass, method_name, &implementation)
|
36
|
+
Phenomenal::Manager.instance.find_context(context).add_adaptation(
|
37
|
+
klass, method_name,false, &implementation
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Remove Adaptation
|
42
|
+
def phen_remove_adaptation(context,klass,method_name)
|
43
|
+
Phenomenal::Manager.instance.find_context(context).remove_adaptation(
|
44
|
+
klass,method_name,true
|
45
|
+
)
|
46
|
+
end
|
47
|
+
|
48
|
+
def phen_remove_class_adaptation(context,klass,method_name)
|
49
|
+
Phenomenal::Manager.instance.find_context(context).remove_adaptation(
|
50
|
+
klass,method_name,false
|
51
|
+
)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Activate Context
|
55
|
+
def phen_activate_context(context)
|
56
|
+
Phenomenal::Manager.instance.find_context(context).activate
|
57
|
+
end
|
58
|
+
Phenomenal::DSL.phen_alias(:activate_context,klass)
|
59
|
+
|
60
|
+
# Deactivate Context
|
61
|
+
def phen_deactivate_context(context)
|
62
|
+
Phenomenal::Manager.instance.find_context(context).deactivate
|
63
|
+
end
|
64
|
+
Phenomenal::DSL.phen_alias(:deactivate_context,klass)
|
65
|
+
|
66
|
+
# Context is active?
|
67
|
+
def phen_context_active?(context)
|
68
|
+
Phenomenal::Manager.instance.find_context(context).active?
|
69
|
+
end
|
70
|
+
|
71
|
+
# Context informations
|
72
|
+
def phen_context_information(context)
|
73
|
+
Phenomenal::Manager.instance.find_context(context).information
|
74
|
+
end
|
75
|
+
|
76
|
+
# Default Context
|
77
|
+
def phen_default_context
|
78
|
+
Phenomenal::Manager.instance.default_context
|
79
|
+
end
|
80
|
+
|
81
|
+
# Defined context registered in the manager
|
82
|
+
def phen_defined_contexts
|
83
|
+
Phenomenal::Manager.instance.contexts.values
|
84
|
+
end
|
85
|
+
|
86
|
+
# Proceed
|
87
|
+
def phen_proceed(*args,&block)
|
88
|
+
Phenomenal::Manager.instance.proceed(caller,self,*args,&block)
|
89
|
+
end
|
90
|
+
Phenomenal::DSL.phen_alias(:proceed,klass)
|
91
|
+
|
92
|
+
# Change conflict resolution policy (for the proceed call)
|
93
|
+
def phen_change_conflict_policy(&block)
|
94
|
+
Phenomenal::Manager.instance.change_conflict_policy(&block)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
# Add relationships specific DSL
|
98
|
+
define_relationships(klass)
|
99
|
+
end
|
100
|
+
|
101
|
+
private
|
102
|
+
def self.phen_alias(method,klass)
|
103
|
+
if Kernel.respond_to? method
|
104
|
+
Phenomenal::Logger.instance.warn(
|
105
|
+
"The Phenomenal DSL keyword #{method} wasn't defined, use"+
|
106
|
+
" phen_#{method} instead"
|
107
|
+
)
|
108
|
+
else
|
109
|
+
klass.class_eval do
|
110
|
+
alias_method method, "phen_#{method}"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
#Load the phenomenal primitives as top level methods
|
117
|
+
module Kernel
|
118
|
+
include Phenomenal::DSL
|
119
|
+
end
|