4 * Copyright 2004-2007 MTBJ, Inc.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
19 package com
.dtrules
.interpreter
;
21 import com
.dtrules
.infrastructure
.RulesException
;
22 import com
.dtrules
.interpreter
.operators
.ROperator
;
23 import com
.dtrules
.session
.DTState
;
24 import com
.dtrules
.session
.RuleSet
;
30 public class RString
extends ARObject
{
34 boolean executable
= false;
36 public double doubleValue() throws RulesException
{
39 d
= Double
.parseDouble(value
);
40 } catch (NumberFormatException e
) {
41 return super.doubleValue();
47 public int intValue() throws RulesException
{
50 i
= Integer
.parseInt(value
);
51 } catch (NumberFormatException e
) {
52 return super.intValue();
58 public long longValue() throws RulesException
{
61 l
= Long
.parseLong(value
);
62 } catch (NumberFormatException e
) {
63 return super.longValue();
69 public RDouble
rDoubleValue() throws RulesException
{
70 return RDouble
.getRDoubleValue(doubleValue());
74 public RInteger
rIntegerValue() throws RulesException
{
75 return RInteger
.getRIntegerValue(longValue());
79 public RName
rNameValue() throws RulesException
{
80 return RName
.getRName(value
);
84 public RString
rStringValue() {
88 private RString(String v
,boolean executable
,RString pair
){
91 this.executable
= executable
;
94 * Return a non Executable string
98 static public RString
newRString(String v
){
99 return newRString(v
,false);
102 * Return an RString of the given executable nature.
107 static public RString
newRString(String v
, boolean executable
){
108 RString s
= new RString(v
,executable
,null);
109 s
.pair
= new RString(v
,!executable
,s
);
114 public IRObject
getExecutable() {
123 public IRObject
getNonExecutable() {
132 * Returns a boolean value if the String can be reasonably
133 * interpreted as a boolean.
137 public boolean booleanValue() throws RulesException
{
138 return RBoolean
.booleanValue(value
);
144 public RBoolean
rBooleanValue() throws RulesException
{
145 return RBoolean
.getRBoolean(booleanValue());
149 * Returns String type.
150 * @see com.dtrules.interpreter.IRObject#type()
157 * Here we look to see if we can do a compile time lookup of
158 * an object. If we can't, we just return the object unchanged.
159 * But if we can, then we return the value we looked up. That
160 * saves many, many runtime lookups.
162 static IRObject
lookup(RuleSet ruleset
, RName name
){
163 IRObject v
= ROperator
.getPrimitives().get(name
); // First check if it is an operator
164 if(v
==null){ // No? Then
165 try { // look for a decision table.
166 v
= ruleset
.getEntityFactory(null).getDecisionTable(name
);
167 } catch (RulesException e
) { } // Any error just means the name isn't
168 } // a decision table. Not a problem.
169 if(v
==null || v
.type()== iArray
) return name
;
174 * Compiles the String and returns the executable Array Object
175 * that results. Unless the compilation fails, at which time
176 * we throw an exception.
179 * @throws RulesException
181 static public IRObject
compile(RuleSet rs
, String v
, boolean executable
) throws RulesException
{
183 if(v
==null)v
=""; // Allow the compiling of null strings (we just don't do anything).
185 SimpleTokenizer tokenizer
= new SimpleTokenizer(v
);
187 IRObject result
= compile(rs
, tokenizer
, v
, executable
, 0);
192 * The compiles of Strings are recursive. When we see a [ or {,
193 * we recurse. Then on a close bracket ] or } we return the
194 * non-executable or executable array. The RString checks to make
195 * sure it is the right type, and throws an error if it isn't.
196 * The recursive depth is checked by compile();
199 * @throws RulesException
201 static private IRObject
compile(RuleSet ruleset
, SimpleTokenizer tokenizer
, String v
, boolean executable
, int depth
) throws RulesException
{
203 RArray result
= new RArray(0,true,executable
);
205 while((token
=tokenizer
.nextToken())!=null){
206 if(token
.getType()== Token
.Type
.STRING
) {
207 IRObject rs
= RString
.newRString(token
.strValue
);
209 }else if(token
.getType()== Token
.Type
.LSQUARE
) {
210 IRObject o
= compile(ruleset
,tokenizer
, v
, false, depth
+1);
212 }else if(token
.getType()== Token
.Type
.RSQUARE
) {
213 if(depth
==0 || executable
){
214 throw new RulesException("Parsing Error",
216 "\nError parsing <<"+v
+">> \nThe token ']' was unexpected.");
220 }else if(token
.getType()== Token
.Type
.LCURLY
) {
221 IRObject o
= compile(ruleset
,tokenizer
,v
,true, depth
+1);
223 }else if(token
.getType()== Token
.Type
.RCURLY
) {
224 if(depth
==0 || !executable
){
225 throw new RulesException("Parsing Error",
227 "\nError parsing <<"+v
+">> \nThe token '}' was unexpected.");
231 }else if(token
.getType()== Token
.Type
.NAME
) {
232 if(token
.nameValue
.isExecutable()){ // All executable names are checked for compile time lookup.
233 IRObject prim
= lookup(ruleset
,token
.nameValue
);
234 if(prim
== null){ // If this name is not a primitive, then
235 result
.add(token
.nameValue
); // then add the name as it is to the array.
237 result
.add(prim
); // Otherwise, compile the reference to the operator.
240 result
.add(token
.nameValue
);
243 }else if (token
.getType() == Token
.Type
.DATE
){
244 result
.add(token
.datevalue
);
246 }else if (token
.getType()== Token
.Type
.INT
) {
247 RInteger i
= RInteger
.getRIntegerValue(token
.longValue
);
249 }else if (token
.getType()== Token
.Type
.REAL
) {
250 RDouble d
= RDouble
.getRDoubleValue(token
.doubleValue
);
255 throw new RulesException("Parsing Error",
257 "\nError parsing << " + v
+ " >>\n missing a " + (executable ?
"}" : "]"));
260 return (IRObject
) result
;
261 } catch (RuntimeException e
) {
262 throw new RulesException("Undefined","String Compile","Error compiling string: '"+v
+"'\n"+e
);
267 * Compiles this String and returns the object.
270 * @throws RulesException
272 public IRObject
compile(RuleSet ruleset
, boolean executable
) throws RulesException
{
273 return compile(ruleset
, value
,executable
);
277 public boolean isExecutable() {
281 public void execute(DTState state
) throws RulesException
{
283 IRObject o
= compile(state
.getSession().getRuleSet(),value
,true);
286 state
.datapush(this);
290 public String
stringValue() {
293 public String
toString(){
294 return "\""+value
+"\"";
299 * returns 0 if both are equal. -1 if this object is less than the argument.
300 * 1 if this object is greater than the argument
302 public int compare(IRObject irObject
) throws RulesException
{
303 int f
= this.value
.compareTo(irObject
.stringValue());
309 public boolean equals(IRObject o
) throws RulesException
{
310 return value
.equals(o
.stringValue());