View Javadoc

1   /*
2   * The contents of this file are subject to the BT "ZEUS" Open Source 
3   * Licence (L77741), Version 1.0 (the "Licence"); you may not use this file 
4   * except in compliance with the Licence. You may obtain a copy of the Licence
5   * from $ZEUS_INSTALL/licence.html or alternatively from
6   * http://www.labs.bt.com/projects/agents/zeus/licence.htm
7   * 
8   * Except as stated in Clause 7 of the Licence, software distributed under the
9   * Licence is distributed WITHOUT WARRANTY OF ANY KIND, either express or 
10  * implied. See the Licence for the specific language governing rights and 
11  * limitations under the Licence.
12  * 
13  * The Original Code is within the package zeus.*.
14  * The Initial Developer of the Original Code is British Telecommunications
15  * public limited company, whose registered office is at 81 Newgate Street, 
16  * London, EC1A 7AJ, England. Portions created by British Telecommunications 
17  * public limited company are Copyright 1996-9. All Rights Reserved.
18  * 
19  * THIS NOTICE MUST BE INCLUDED ON ANY COPY OF THIS FILE
20  */
21  
22  
23  
24  package zeus.concepts.fn;
25  
26  import java.util.*;
27  import zeus.util.*;
28  import zeus.concepts.*;
29  
30  public class IdFn extends ValueFunction implements PrimitiveFn {
31     protected String arg = null;
32  
33     public IdFn(String arg) {
34        super(ID,10);
35        this.arg = arg;
36     }
37     public ValueFunction mirror() {
38        return new IdFn(arg);
39     }
40     public String toString() {
41        char[] array = arg.toCharArray();
42        for(int i = 0; i < array.length; i++ ) {
43           if ( !Character.isLetterOrDigit(array[i]) &&
44                array[i] != '_' && array[i] != '$' )
45              return "\"" + arg + "\"";
46        }
47        return arg;
48     }
49     Object getArg(int position) {
50         if (position != 0) throw new ArrayIndexOutOfBoundsException(position);
51        return Misc.literalToString(arg);
52     }
53     public boolean isDeterminate() {
54        return true;
55     }
56     public String getValue() {
57        return Misc.literalToString(arg);
58     }
59  
60     public boolean equals(Object any) {
61        if ( !(any instanceof IdFn) ) return false;
62        IdFn fn = (IdFn)any;
63        return arg.equals(fn.getArg());
64     }
65     public boolean less(Object any) {
66        if ( !(any instanceof IdFn) ) return false;
67        IdFn fn = (IdFn)any;
68        return ( arg.compareTo((String)fn.getArg()) < 0);
69     }
70     ValueFunction unify(ValueFunction fn, Bindings b) {
71        return null;
72     }
73     public boolean references(ValueFunction var) {
74        return false;
75     }
76  
77     /* 
78        List of methods associated with this ValueFunction type
79     */
80  
81     static final String[] METHOD_LIST = {
82        /* char    */ "charAt",              "1",   /* (int index) */
83        /* int     */ "compareTo",           "1",   /* (String anotherString) */ 
84        /* int     */ "compareToIgnoreCase", "1",   /* (String str) */ 
85        /* String  */ "concat",              "1",   /* (String str) */ 
86        /* boolean */ "endsWith",            "1",   /* (String suffix) */ 
87        /* boolean */ "equals",              "1",   /* (Object anObject) */ 
88        /* boolean */ "equalsIgnoreCase",    "1",   /* (String anotherString) */ 
89        /* int     */ "indexOf",             "1,2", /* (int str); (int str, int fromIndex);
90        /* int     */ "lastIndexOf",         "1,2", /* (int str); (String str, int fromIndex) */ 
91        /* int     */ "length",              "0",   /* () */ 
92        /* boolean */ "regionMatches",       "4,5", /* (boolean ignoreCase, int toffset, String other, int ooffset, int len) */ 
93                                                    /* (int toffset, String other, int ooffset, int len) */ 
94        /* String  */ "replace",             "2",   /* (char oldChar, char newChar) */ 
95        /* boolean */ "startsWith",          "1,2", /* (String prefix); (String prefix, int toffset) */ 
96        /* String  */ "substring",           "1,2", /* (int beginIndex); (int beginIndex, int endIndex) */ 
97        /* String  */ "toLowerCase",         "0",   /* () */ 
98        /* String  */ "toUpperCase",         "0",   /* () */ 
99        /* String  */ "trim",                "0"    /* () */ 
100    };
101 
102    static final int CHAR_AT 			= 0;
103    static final int COMPARE_TO 			= 2;
104    static final int COMPARE_TO_IGNORE_CASE	= 4;
105    static final int CONCAT 			= 6;
106    static final int ENDS_WITH 			= 8;
107    static final int EQUALS 			= 10;
108    static final int EQUALS_IGNORE_CASE 		= 12;
109    static final int INDEX_OF 			= 14;
110    static final int LAST_INDEX_OF 		= 16;
111    static final int LENGTH 			= 18;
112    static final int REGION_MATCHES 		= 20;
113    static final int REPLACE 			= 22;
114    static final int STARTS_WITH 		= 24;
115    static final int SUBSTRING 			= 26;
116    static final int TO_LOWER_CASE 		= 28;
117    static final int TO_UPPER_CASE 		= 30;
118    static final int TRIM 			= 32;
119 
120    ValueFunction invokeMethod(String method, Vector arguments) {
121       int position = Misc.whichPosition(method,METHOD_LIST);
122 
123       if ( position == -1 )
124          return super.invokeMethod(method,arguments);
125 
126       StringTokenizer st = new StringTokenizer(METHOD_LIST[position+1],",");
127       boolean num_args_ok = false;
128       int arity = -1;
129       while( !num_args_ok && st.hasMoreTokens() ) {
130          arity = Integer.parseInt(st.nextToken());
131          num_args_ok = (arguments.size() == arity);
132       }
133 
134       if ( !num_args_ok )
135          throw new IllegalArgumentException(
136             "Wrong number of arguments in method IdFn.\'" + method + "/" +
137              arity + "\'.");
138 
139        try {
140 
141          IntFn index1, index2, index3;
142          ValueFunction value;
143          IdFn str1, str2;
144          BoolFn state1;
145          String string;
146 
147          switch( position ) {
148             case CHAR_AT:
149                  index1 = (IntFn)arguments.elementAt(0); 
150                  char ch = arg.charAt(index1.intValue());
151                  return new IdFn(String.valueOf(ch));
152 
153             case COMPARE_TO:
154                  value = (ValueFunction)arguments.elementAt(0);
155                  string =  Misc.literalToString(value.toString());
156                  return new IntFn(arg.compareTo(string));
157 
158             case COMPARE_TO_IGNORE_CASE:
159                  value = (ValueFunction)arguments.elementAt(0);
160                  string =  Misc.literalToString(value.toString());
161                  return new IntFn(arg.compareToIgnoreCase(string));
162 
163             case CONCAT:
164                  value = (ValueFunction)arguments.elementAt(0);
165                  string =  Misc.literalToString(value.toString());
166 /*
167                  String xx  = arg.concat(value.toString());
168 System.err.println("XX = " + xx );
169                  return new IdFn( xx );
170 */
171                  return new IdFn(arg.concat(string));
172 
173             case ENDS_WITH:
174                  str1 = (IdFn)arguments.elementAt(0);
175                  return BoolFn.newBoolFn( arg.endsWith(str1.getValue()) );
176 
177             case EQUALS:
178                  str1 = (IdFn)arguments.elementAt(0);
179                  return arg.equals(str1.getValue()) ? BoolFn.trueFn : BoolFn.falseFn;
180 
181             case EQUALS_IGNORE_CASE:
182                  str1 = (IdFn)arguments.elementAt(0);
183                  return arg.equalsIgnoreCase(str1.getValue()) ? BoolFn.trueFn : BoolFn.falseFn;
184 
185             case INDEX_OF:
186                  switch( arity ) {
187                     case 1:
188                        str1 = (IdFn)arguments.elementAt(0);
189                        return new IntFn(arg.indexOf(str1.getValue()));
190 
191                     case 2:
192                        str1 = (IdFn)arguments.elementAt(0);
193                        index1 = (IntFn)arguments.elementAt(1);
194                        return new IntFn(arg.indexOf(str1.getValue(),index1.intValue()));
195                  }
196                  break;
197 
198             case LAST_INDEX_OF:
199                  switch( arity ) {
200                     case 1:
201                        str1 = (IdFn)arguments.elementAt(0);
202                        return new IntFn(arg.lastIndexOf(str1.getValue()));
203 
204                     case 2:
205                        str1 = (IdFn)arguments.elementAt(0);
206                        index1 = (IntFn)arguments.elementAt(1);
207                        return new IntFn(arg.lastIndexOf(str1.getValue(),index1.intValue()));
208                  }
209                  break;
210 
211             case LENGTH:
212                  return new IntFn(arg.length());
213 
214             case REGION_MATCHES:
215                  switch( arity ) {
216                     case 4:
217                        index1 = (IntFn)arguments.elementAt(0);
218                        str1 = (IdFn)arguments.elementAt(1);
219                        index2 = (IntFn)arguments.elementAt(2);
220                        index3 = (IntFn)arguments.elementAt(3);
221                        return BoolFn.newBoolFn( arg.regionMatches(index1.intValue(),
222                                                                   str1.getValue(),
223                                                                   index2.intValue(),
224                                                                   index3.intValue()) 
225                                               );
226 
227                     case 5:
228                        state1 = (BoolFn)arguments.elementAt(0);
229                        index1 = (IntFn)arguments.elementAt(1);
230                        str1 = (IdFn)arguments.elementAt(2);
231                        index2 = (IntFn)arguments.elementAt(3);
232                        index3 = (IntFn)arguments.elementAt(4);
233                        return BoolFn.newBoolFn( arg.regionMatches(state1.getValue(),
234                                                                   index1.intValue(),
235                                                                   str1.getValue(),
236                                                                   index2.intValue(),
237                                                                   index3.intValue()) 
238                                               );
239                  }
240                  break;
241 
242             case REPLACE:
243                  str1 = (IdFn)arguments.elementAt(0);
244                  str2 = (IdFn)arguments.elementAt(1);
245                  return new IdFn(arg.replace((str1.getValue()).charAt(0),(str2.getValue()).charAt(0)));
246 
247             case STARTS_WITH:
248                  switch( arity ) {
249                     case 1:
250                        str1 = (IdFn)arguments.elementAt(0);
251                        return BoolFn.newBoolFn(arg.startsWith(str1.getValue()));
252 
253                     case 2:
254                        str1 = (IdFn)arguments.elementAt(0);
255                        index1 = (IntFn)arguments.elementAt(1);
256                        return BoolFn.newBoolFn(arg.startsWith(str1.getValue(),index1.intValue()));
257                  }
258                  break;
259 
260             case SUBSTRING:
261                  switch( arity ) {
262                     case 1:
263                        index1 = (IntFn)arguments.elementAt(0);
264                        return new IdFn(arg.substring(index1.intValue()));
265 
266                     case 2:
267                        index1 = (IntFn)arguments.elementAt(0);
268                        index2 = (IntFn)arguments.elementAt(1);
269                        return new IdFn(arg.substring(index1.intValue(),index2.intValue()));
270                  }
271                  break;
272 
273             case TO_LOWER_CASE:
274                  return new IdFn(arg.toLowerCase());
275 
276             case TO_UPPER_CASE:
277                  return new IdFn(arg.toUpperCase());
278 
279             case TRIM:
280                  return new IdFn(arg.trim());
281          }
282       }
283       catch(ClassCastException e) {
284          throw new IllegalArgumentException(
285             "Type mismatch in method \'" + this + Fact.A_CHR + method +
286             "(...)\'");
287 
288       }
289       Core.ERROR(null,1,this); // should never get here
290       return null;
291    }
292 
293 }