KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > versant > core > jdo > ParamDeclarationParser


1
2 /*
3  * Copyright (c) 1998 - 2005 Versant Corporation
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  * Versant Corporation - initial API and implementation
11  */

12 package com.versant.core.jdo;
13
14 import com.versant.core.util.CharBuf;
15
16 import com.versant.core.common.BindingSupportImpl;
17
18 /**
19  * This parses a comma separated list of query parameters into types and names.
20  * TODO Make this parse array types e.g. String[]
21  */

22 public class ParamDeclarationParser {
23
24     /**
25      * Callback interface for parsing results.
26      */

27     public static interface Handler {
28
29         /**
30          * The parser has sucessfully parsed a parameter type and name at
31          * position index in the parameter list (first param is 0).
32          */

33         public void parameterParsed(int index, String JavaDoc type, String JavaDoc name);
34     }
35
36     private static final int STATE_START = 0;
37     private static final int STATE_LOOK_FOR_TYPE = 1;
38     private static final int STATE_IN_TYPE = 2;
39     private static final int STATE_LOOK_FOR_NAME = 3;
40     private static final int STATE_IN_NAME = 4;
41     private static final int STATE_LOOK_FOR_COMMA = 5;
42
43     /**
44      * Parse params into types and names and return the number of parameters
45      * parsed.
46      */

47     public static int parse(String JavaDoc params, Handler handler) {
48         if (params == null) return 0;
49         int len = params.length();
50         if (len == 0) return 0;
51         int state = STATE_START;
52         String JavaDoc type = null;
53         int count = 0;
54         CharBuf buf = new CharBuf();
55         for (int pos = 0; ; pos++) {
56             if (pos < len) {
57                 char c = params.charAt(pos);
58                 switch (state) {
59                     case STATE_START:
60                     case STATE_LOOK_FOR_TYPE:
61                         if (isIdStart(c)) {
62                             buf.append(c);
63                             state = STATE_IN_TYPE;
64                         } else if (!isWs(c)) {
65                             error(pos, "parameter type", c);
66                         }
67                         break;
68                     case STATE_IN_TYPE:
69                         if (isId(c) || c == '.') {
70                             buf.append(c);
71                         } else if (isWs(c)) {
72                             type = buf.toString();
73                             buf.clear();
74                             state = STATE_LOOK_FOR_NAME;
75                         } else {
76                             error(pos, "parameter type", c);
77                         }
78                         break;
79                     case STATE_LOOK_FOR_NAME:
80                         if (isIdStart(c)) {
81                             buf.append(c);
82                             state = STATE_IN_NAME;
83                         } else if (!isWs(c)) {
84                             error(pos, "parameter name", c);
85                         }
86                         break;
87                     case STATE_IN_NAME:
88                         if (isId(c)) {
89                             buf.append(c);
90                         } else if (c == ',' || isWs(c)) {
91                             handler.parameterParsed(count++, type, buf.toString());
92                             buf.clear();
93                             type = null;
94                             if (c == ',') state = STATE_LOOK_FOR_TYPE;
95                             else state = STATE_LOOK_FOR_COMMA;
96                         } else {
97                             error(pos, "parameter name", c);
98                         }
99                         break;
100                     case STATE_LOOK_FOR_COMMA:
101                         if (c == ',') {
102                             state = STATE_LOOK_FOR_TYPE;
103                         } else if (!isWs(c)) {
104                             error(pos, "comma", c);
105                         }
106                         break;
107                 }
108             } else {
109                 switch (state) {
110                     case STATE_LOOK_FOR_TYPE:
111                         error(pos, "parameter type", (char)-1);
112                     case STATE_IN_TYPE:
113                     case STATE_LOOK_FOR_NAME:
114                         error(pos, "parameter name", (char)-1);
115                     case STATE_IN_NAME:
116                         handler.parameterParsed(count++, type, buf.toString());
117                 }
118                 break;
119             }
120         }
121         return count;
122     }
123
124     private static boolean isWs(char c) {
125         return c == ' ' || c == '\n' || c == '\t';
126     }
127
128     private static boolean isIdStart(char c) {
129         return c == '_'
130             || (c >= 'A' && c <= 'Z')
131             || (c >= 'a' && c <= 'z');
132     }
133
134     private static boolean isId(char c) {
135         return c == '_'
136             || (c >= 'A' && c <= 'Z')
137             || (c >= 'a' && c <= 'z')
138             || (c >= '0' && c <= '9');
139     }
140
141     private static void error(int pos, String JavaDoc msg, char c) {
142         throw BindingSupportImpl.getInstance().runtime("Invalid parameter declaration: Expected " +
143             msg + ", got '" + c + "' at position " + pos);
144     }
145
146 }
147
148
Popular Tags