1 User guide for Rule Plugin usage in ConE |
1 User guide for Rule Plugin usage in ConE |
2 ---------------------------------------- |
2 ======================================== |
|
3 |
|
4 .. note:: |
|
5 RuleML v3 is now the officially supported RuleML version. |
|
6 Support for versions 1 and 2 is still present in ConE, but they will not |
|
7 be maintained anymore. If you have e.g. a RuleML v2 file and require some |
|
8 new functionality, the new functionality will be added to RuleML v3 and |
|
9 you will need to update your RuleML file to use version 3. |
|
10 |
|
11 Updating should be easy, since the biggest change is setting reference |
|
12 syntax. Simply add ``${}`` around all setting references in the rules. |
3 |
13 |
4 Introduction |
14 Introduction |
5 ''''''''''''' |
15 ------------ |
6 This page describes how to use ConE Rule plugin. With rule plugin one may set rule configuration |
16 This page describes how to use the ConE Rule plugin. The plug-in provides |
7 for the values in the confml. So for ex. one may have a case where is one confml value is been setted |
17 support for RuleML files, which can be used to execute rules during output |
8 and one may create a rule configuration that if this value is for ex. 'foo' then some other value is |
18 generation. The main use for RuleML is modifying the values of ConfML settings |
9 'bar'. Value may be required or configures. |
19 on run-time based on the values of other settings. |
10 |
20 |
11 |
21 The rule plug-in registers the ImplML namespace for defining rules, and the |
12 Creating a rule configuration file |
22 RuleML-specific file extension: |
13 '''''''''''''''''''''''''''''''''' |
23 |
14 Create a new file a example.ruleml and set it's file encoding to UTF-8. |
24 * Namespace: ``http://www.s60.com/xml/ruleml/3`` |
15 Place the file in the impml folder in configuration project. |
25 * File extension: ``ruleml`` |
16 The file is a XML base file. |
26 |
17 First set the encoding tag |
27 .. note:: |
18 |
28 |
19 .. code-block:: xml |
29 More information about :ref:`file extensions <implml-file-extensions>`. |
20 |
30 |
21 <?xml version="1.0" encoding="UTF-8"?>* |
31 Usage |
22 |
32 ----- |
23 and then create a root tag |
33 |
24 |
34 A RuleML file is simply an XML file that defines a set of rules. For example: |
25 .. code-block:: xml |
35 |
26 |
36 .. code-block:: xml |
27 <ruleml xmlns="http://www.s60.com/xml/ruleml/1">* |
37 |
|
38 <?xml version="1.0" encoding="UTF-8"?> |
|
39 <ruleml xmlns="http://www.s60.com/xml/ruleml/3"> |
|
40 <rule>${SomeFeature.SomeSetting} == 'testing' configures ${SomeFeature.SomeOtherSetting} = 5</rule> |
|
41 <rule>${SomeFeature.SomeSetting} == 'xyz' configures ${SomeFeature.SomeOtherSetting} = 6</rule> |
|
42 </ruleml> |
|
43 |
|
44 The above example sets the value of the setting ``SomeFeature.SomeOtherSetting`` |
|
45 to the integer value ``5`` or ``6`` if the value of ``SomeFeature.SomeSetting`` is |
|
46 one of the strings ``testing`` or ``xyz``. |
|
47 |
|
48 Rules can also contain multiple operations in a single rule, and can span |
|
49 multiple lines to make the rule more readable. For example: |
|
50 |
|
51 .. code-block:: xml |
|
52 |
|
53 <?xml version="1.0" encoding="UTF-8"?> |
|
54 <ruleml xmlns="http://www.s60.com/xml/ruleml/3"> |
|
55 <rule> |
|
56 ${SomeFeature.SomeSetting} == 'testing' configures |
|
57 ${SomeFeature.SomeOtherSetting} = 5 and |
|
58 ${SomeFeature.SomeOtherSetting2} = 6 and |
|
59 ${SomeFeature.SomeOtherSetting3} = 7 |
|
60 </rule> |
|
61 </ruleml> |
|
62 |
|
63 Sometimes the case is that the rule should be executed always, regardless of |
|
64 the values of any other settings. To do this you can simply specify ``True`` |
|
65 as the left-hand side expression: |
|
66 |
|
67 .. code-block:: xml |
|
68 |
|
69 <?xml version="1.0" encoding="UTF-8"?> |
|
70 <ruleml xmlns="http://www.s60.com/xml/ruleml/3"> |
|
71 <rule>True configures ${SomeFeature.SomeOtherSetting} = 'Hello!'</rule> |
|
72 </ruleml> |
|
73 |
|
74 Python expressions in rules |
|
75 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
|
76 |
|
77 RuleML has an extension to the basic rule syntax, which allows any `Python <http://www.python.org/doc/2.5/>`_ |
|
78 expressions to be used. These can be used to create more complex logic into |
|
79 rules than is possible with standard rule expressions. The Python expressions |
|
80 are defined between ``{%`` and ``%}``, and can be used in place of normal |
|
81 value expressions. |
|
82 |
|
83 You can access global ruleml namespace, from which you can find Configuration and Generation Context of the active execution. |
|
84 |
|
85 * ruleml.configuration - links to `Configuration <../../../docbuild/epydoc/cone.public.api.Configuration-class.html>`_ object. |
|
86 * ruleml.context - links to `Generation Context <../../../docbuild/epydoc/cone.public.plugin.GenerationContext-class.html>`_ object. |
28 |
87 |
29 give a set of rules for ex. |
88 |
30 |
89 *Examples of using Python scripts inside ruleml files:* |
31 .. code-block:: xml |
90 |
32 |
91 .. code-block:: xml |
33 <rule>mms.imagesize == 'large' configures pd.ref1 = True and pd.ref2 = True</rule>* |
92 |
34 |
93 <?xml version="1.0" encoding="UTF-8"?> |
35 and close the ruleml tag. |
94 <ruleml xmlns="http://www.s60.com/xml/ruleml/3"> |
36 |
95 <rule> |
37 One may say use several boolean operators for the configuration rule like for ex. |
96 True configures ${SomeFeature.SomeOtherSetting} = {% 2 ** 16 %} |
38 |
97 </rule> |
39 .. code-block:: xml |
98 </ruleml> |
40 |
99 |
41 and, or, ==, !=* |
100 This sets the value of ``SomeFeature.SomeOtherSetting`` to the evaluated value |
42 |
101 of the Python expression ``2 ** 16``, which is 65536. |
43 Like for ex. |
102 |
44 |
103 Obviously, simple expressions like this cannot do much, but an expression can |
45 .. code-block:: xml |
104 also be a function call, and functions can do almost anything. Functions (and |
46 |
105 also any other globals) can be specified using ``<eval_globals>`` elements. |
47 <rule>mms.imagesize == 'large' configures pd.ref1 = True and pd.ref2 = True</rule>* |
106 For example: |
48 |
107 |
49 means that if reference link mms/imagesize in some confml file is set to large then reference |
108 .. code-block:: xml |
50 link pd/ref1 value is true and pd/ref2 value is set to true also. |
109 |
51 |
110 <?xml version="1.0" encoding="UTF-8"?> |
52 **All in all one may create a dependency like project configuration with ruleml files.** |
111 <ruleml xmlns="http://www.s60.com/xml/ruleml/3"> |
53 |
112 <rule> |
54 Ruleml version 2 adds support for calling `Python <http://www.python.org/doc/2.5/>`_ expressions from rules. Python expression are defined between ``{%`` and ``%}``: |
113 True configures ${SomeFeature.SomeOtherSetting} = {% power(2, 16) %} |
55 |
114 </rule> |
56 .. code-block:: xml |
115 <eval_globals> |
57 |
116 def power(x, y): |
58 <rule>feat1.setting2 == True configures feat2.setting2 = {% ${feat3.setting2} %}</rule> |
117 result = 1 |
59 |
118 for i in xrange(y): |
60 Expression return a result, that can be used in rule e.g. to set a value to some setting in configuration. These expression can be used to create more complex logic into rules that is not possible with standard rule expressions. Inside eval expressions features and feature's values can be accessed by following syntax: |
119 result *= x |
61 |
120 return result |
62 Accesses to the value:: |
121 </eval_globals> |
63 |
122 </ruleml> |
64 ${Feature.Setting} |
123 |
65 |
124 This does the same thing as the previous example, except that it uses a custom |
66 Accesses to the feature object:: |
125 function to do it. |
67 |
126 |
68 @{Feature.Setting} |
127 It is also possible to use standard Python libraries or the |
69 |
128 `ConE API <../../epydoc/index.html>`_ from ``<eval_globals>``, and also |
70 Python functions or constants that can be accessed inside expressions can be defined by ``<eval_globals>`` elements: |
129 some RuleML-specific things. Ruleml has all data from |
71 |
130 Configuration and Generation Context classes of the active execution. For example: |
72 .. code-block:: xml |
131 |
73 |
132 .. code-block:: xml |
74 <eval_globals> |
133 |
75 def my_function1(attribute): |
134 <?xml version="1.0" encoding="UTF-8"?> |
76 return attribute + 1 |
135 <ruleml xmlns="http://www.s60.com/xml/ruleml/3"> |
77 </eval_globals> |
136 <rule> |
78 |
137 True configures ${SomeFeature.SomeOtherSetting} = {% power(2, 16) %} |
79 <eval_globals>CONST_1 = "my constant"</eval_globals> |
138 </rule> |
80 |
139 <eval_globals> |
81 <eval_globals file=".scripts/evals_in_file.py"/> |
140 # Import the standard library urllib2 to do operations on URLs |
82 |
141 import urllib2 |
83 Definitions can be inside <eval_globals> elements or definitions can be in separate file referenced with ``file`` attribute. |
142 |
84 The path specified in this attribute is relative to the RuleML implementation file. So, for example, if your implementation |
143 # Import the ConE API |
85 file's location is ``some/layer/implml/my_rules.ruleml``, the actual path specified in the above example would be |
144 from cone.public import api |
86 ``some/layer/implml/.scripts/evals_in_file.py``. It is recommended to place the scripts under a directory beginning |
145 |
87 with a dot, so that the plug-in loader does not attempt to load the .py file as an implementation (files and directories beginning |
146 def get_project_path(): |
88 with a dot are ignored in the implementation loading phase). |
147 # The current configuration is available in ruleml.configuration |
89 |
148 config = ruleml.configuration |
90 Running |
149 |
91 ''''''''''''''''''''' |
150 # Return the path of the storage the current project is in |
92 |
151 project = config.get_project() |
93 :: |
152 return project.storage.get_path() |
94 |
153 </eval_globals> |
95 cone generate -p someproject.cpf -o c:/temp/coneoutput -i rulemlfile.ruleml |
154 </ruleml> |
96 |
155 |
97 Generates files out of configuration file and takes the implementation rulemlfile.ruleml in concern, |
156 |
98 and the output is to been set to -o given folder |
157 In this example configuration is got from ruleml. Generation Context can be |
99 |
158 accessed in the same way, ruleml.context will have all data stored in the |
100 for more example see the cone documentation |
159 Generation Context object. |
101 |
160 |
102 Examples |
161 Generation Context values can be accessed inside the Python expressions using the |
103 ''''''''' |
162 ruleml.context like ruleml.context.output. |
104 |
163 |
105 |
164 This example uses the Generation Context to get defined output folder. |
106 **Ruleml version 1 file example** |
165 See how to access the data from the code example below. |
107 |
166 |
108 .. code-block:: xml |
167 .. code-block:: xml |
109 |
168 |
110 <?xml version="1.0" encoding="UTF-8"?> |
169 <?xml version="1.0" encoding="UTF-8"?> |
111 <ruleml xmlns="http://www.s60.com/xml/ruleml/1"> |
170 <ruleml xmlns="http://www.s60.com/xml/ruleml/3"> |
112 <rule>imaker.imagetarget configures imakerapi.outputLocation = imaker.imagetarget</rule> |
171 <rule> |
113 <rule>mms.imagesize == 'large' configures pd.ref1 = True and pd.ref2 = True</rule> |
172 True configures ${SomeFeature.output} = {% get_output_folder() %} |
114 <rule>mms.imagesize == 'small' configures pd.ref1 = False and pd.ref2 = True</rule> |
173 </rule> |
115 <rule>mms.imagesize == 'extrasmall' configures pd.ref1 = False and pd.ref2 = False</rule> |
174 <eval_globals> |
116 <rule>mms.imagesize == 'extralarge' configures pd.ref1 = True and pd.ref2 = False</rule> |
175 |
117 </ruleml> |
176 def get_output_folder(): |
118 |
177 output = ruleml.context.output |
119 **What do the example ruleml file means** |
178 return output |
120 |
179 </eval_globals> |
121 The example file set the values upon the image size. First it sets the iMaker output |
180 </ruleml> |
122 location target and then it starts to set the mms message image size settings. So if for ex. |
181 |
123 *mms/imagesize* refence link value in confml file is set to *extralarge* then the value of |
182 |
124 *pd/ref1* is set to *true* and the value *pd/ref2* is set to false. |
183 Accessing ConfML values inside Python expressions |
125 |
184 ''''''''''''''''''''''''''''''''''''''''''''''''' |
126 |
185 |
127 **Ruleml version 2 file example** |
186 ConfML setting values can be accessed inside the Python expressions using the |
128 |
187 same notation as elsewhere in the rules, i.e. using ``${`` and ``}``. |
129 .. code-block:: xml |
188 For example: |
130 |
189 |
131 <?xml version="1.0" encoding="UTF-8"?> |
190 .. code-block:: xml |
132 <ruleml xmlns="http://www.s60.com/xml/ruleml/2"> |
191 |
133 <rule>feat1.setting1 == 'somevalue' configures feat2.setting1 = {% len( ${feat3.setting1} ) %}</rule> |
192 <?xml version="1.0" encoding="UTF-8"?> |
134 <rule>feat1.setting2 == True configures feat2.setting2 = {% my_function1( ${feat3.setting2} ) %}</rule> |
193 <ruleml xmlns="http://www.s60.com/xml/ruleml/3"> |
135 <rule>feat1.setting3 == True configures feat2.setting3 = {% CONST_1 %}</rule> |
194 <rule> |
136 <rule>{% my_function2( ${feat1.setting4} ) %} configures feat2.setting4 = False</rule> |
195 ${SomeFeature.SomeSetting} == 'testing' configures ${SomeFeature.SomeOtherSetting} = {% ${SomeFeature.SomeSetting}.upper() %} |
137 <rule>{% @{feat1.setting5}.get_type() %} == 'int' configures feat2.setting5 = 'integer'</rule> |
196 </rule> |
138 <rule>feat1.setting6 == True configures feat2.setting6 = {% '0x%08X' % ${feat2.setting6} %}</rule> |
197 </ruleml> |
139 <eval_globals> |
198 |
140 def my_function1(attribute): |
199 This sets the value of ``SomeFeature.SomeOtherSetting`` to 'TESTING'. |
141 return attribute + 1 |
200 |
142 def my_function2(attribute): |
201 Accessing feature objects inside Python expressions |
143 if attribute == 'abc': |
202 ''''''''''''''''''''''''''''''''''''''''''''''''''' |
144 return True |
203 |
145 else: |
204 Sometimes it is necessary to access the actual feature (or setting) object that |
146 return False |
205 ConE uses internally to perform more complex operations. This can be done |
147 </eval_globals> |
206 similarly to accessing the setting values, the only difference is that the |
148 <eval_globals> |
207 setting reference needs to be surrounded by ``@{}``. For example: |
149 CONST_1 = "my constant" |
208 |
150 </eval_globals> |
209 .. code-block:: xml |
151 <eval_globals file=".scripts/evals_in_file.py"/> |
210 |
152 </ruleml> |
211 <?xml version="1.0" encoding="UTF-8"?> |
153 |
212 <ruleml xmlns="http://www.s60.com/xml/ruleml/3"> |
154 XSD |
213 <rule> |
155 ''''''''' |
214 True configures ${SomeFeature.SomeOtherSetting} = {% get_location(@{SomeFeature.SomeSetting}) %} |
156 |
215 </rule> |
157 Ruleml version 1: :download:`ruleml.xsd </xsd/ruleml.xsd>` |
216 <eval_globals> |
158 |
217 from cone.public import api |
159 Ruleml version 2: :download:`ruleml2.xsd </xsd/ruleml2.xsd>` |
218 |
|
219 def get_location(setting): |
|
220 parent_config = setting._find_parent(type=api.Configuration) |
|
221 return parent_config.get_path() |
|
222 </eval_globals> |
|
223 </ruleml> |
|
224 |
|
225 This example uses the ConE API to find the location (ConfML file) where the |
|
226 given setting is defined. |
|
227 |
|
228 |
|
229 Defining functions in a separate .py file |
|
230 ''''''''''''''''''''''''''''''''''''''''' |
|
231 |
|
232 Defining the Python functions used in the rules in an ``<eval_globals>`` element |
|
233 can quickly become unwieldy for larger functions: |
|
234 |
|
235 - Things like ``<`` need to escaped using the corresponding XML entity references |
|
236 - Syntax highlighting is not available |
|
237 - Writing and running unit tests for the functions is not possible |
|
238 |
|
239 For these reasons, the code of an ``<eval_globals>`` element can also be |
|
240 specified in a separate Python file using the ``file`` attribute. For example: |
|
241 |
|
242 .. code-block:: xml |
|
243 |
|
244 <?xml version="1.0" encoding="UTF-8"?> |
|
245 <ruleml xmlns="http://www.s60.com/xml/ruleml/3"> |
|
246 <rule> |
|
247 True configures ${SomeFeature.SomeOtherSetting} = {% some_very_complex_operation( |
|
248 @{SomeFeature.SomeSetting1}, |
|
249 ${SomeFeature.SomeSetting2}, |
|
250 ${SomeFeature.SomeSetting3}) %} |
|
251 </rule> |
|
252 <eval_globals file="scripts/complex_function.py"/> |
|
253 </ruleml> |
|
254 |
|
255 The path specified in the ``file`` attribute is relative to the implementation |
|
256 file where the rule is specified, so if the RuleML file in this example was |
|
257 located in ``assets/example/implml/some_rule.ruleml``, the referenced Python |
|
258 file would be ``assets/example/implml/scripts/complex_function.py``. |
160 |
259 |
161 FAQ |
260 FAQ |
162 ''''''''' |
261 --- |
163 This will be updated based on the questions. |
262 This will be updated based on any questions. |