phenomenal 0.9.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/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
|