/** * Copyright (c) 1998 - 2003, Jinfonet Software, Inc. * All Rights Reserved. */ import java.util.*; public class MappingNameFinder { private static final int NORMAL = 0, LEADER = NORMAL + 1, LEADER_NORMAL = LEADER + 1, LEADER_IN_DQ = LEADER_NORMAL + 1, IN_DQ = LEADER_IN_DQ + 1, IN_SQ = IN_DQ + 1, IN_APSQ = IN_SQ + 1; public static final char LEADER_0 = '@', LEADER_1 = ':', DOUBLE_QUOTA = '\"', SINGLE_QUOTA = '\'', APOSTROPHE_QUOTA = '`', SPACE = ' '; /** * This method finds all mapping names who have a leader char in * front of it, and returns a vector of Position, indicating where * these sub strings are located. * @param s the string to find mapping names. * @return Vector of Position info. If no such mapping name * found, return a zero length Vector. */ public static Vector find(String s) { Vector v = new Vector(); if (s == null || s.trim().length() == 0) { return v; } char c; int st = NORMAL; Position p = new Position(); StringBuffer sbuf = new StringBuffer(); StringBuffer mapn = new StringBuffer(); int iLength = s.length(); for (int i = 0; i < iLength; i++) { c = s.charAt(i); switch (st) { case NORMAL: { switch (c) { case LEADER_0: case LEADER_1: st = LEADER; mapn.setLength(0); p = new Position(); p.leader = c; p.begin = i; v.addElement(p); break; case DOUBLE_QUOTA: st = IN_DQ; break; case SINGLE_QUOTA: st = IN_SQ; break; case APOSTROPHE_QUOTA: st = IN_APSQ; break; } break; } case LEADER: { if (c == DOUBLE_QUOTA) { st = LEADER_IN_DQ; } else if (c != SPACE) { st = LEADER_NORMAL; mapn.append(c); } break; } case LEADER_NORMAL: { if (c == SPACE || c == ')' || c == ',') { st = NORMAL; p.end = i; p.name = mapn.toString(); } else { mapn.append(c); } break; } case LEADER_IN_DQ: { if (c == DOUBLE_QUOTA) { st = NORMAL; p.end = i + 1; p.name = mapn.toString(); } else { mapn.append(c); } break; } case IN_DQ: { if (c == DOUBLE_QUOTA && (i == iLength - 1 || s.charAt(i + 1) != DOUBLE_QUOTA)) { st = NORMAL; } break; } case IN_SQ: { if (c == SINGLE_QUOTA && (i == iLength - 1 || s.charAt(i + 1) != SINGLE_QUOTA)) { st = NORMAL; } break; } case IN_APSQ: { if (c == APOSTROPHE_QUOTA) { st = NORMAL; } break; } } } if (st != NORMAL) { p.end = s.length(); p.name = mapn.toString(); } return v; } public static void main(String[] args) { String sql = "Select Customer.ID " + "From Customers " + "Where Customer.\"cus ID\" <> @\"cus id\" " + "and Cutomer.city in (:cities) " + "and Customer.ID in @ SubQuery " + "or Customer.mail = \'someone@jinfonet.com\'"; System.out.println( "SQL = " + sql); System.out.println(find(sql)); System.out.println(sql.substring(0, 61)); System.out.println(sql.substring(70, 92)); System.out.println(sql.substring(99, 120)); System.out.println(sql.substring(130)); System.out.println(); } public static class Position { /** * begin and end indicate that the name (including leader char * and quotation marks) begins at the leader char begin and extends * to the character at index end - 1. *

* For example: * a Position stands for where @ "customer id" would have * begin = 5 and end = 21. *

*/ public int begin = -1; // leader char position public int end = -1; // end position (including double quotation mark if has) /** * The prefix char before a mapping name. It is defined as * LEADER_0 and/or LEADER_1. */ public char leader; /** * The mapping name, not including leader char and quotation marks. */ public String name; public Position() { } public String toString() { return "[" + leader + ", " + name + ", " + begin + " - " + end + "] "; } } }