001: /*
002: * Copyright 2002 (C) TJDO.
003: * All rights reserved.
004: *
005: * This software is distributed under the terms of the TJDO License version 1.0.
006: * See the terms of the TJDO License in the documentation provided with this software.
007: *
008: * $Id: MacroString.java,v 1.2 2002/10/17 21:01:00 pierreg0 Exp $
009: */
010:
011: package com.triactive.jdo.util;
012:
013: import javax.jdo.JDOUserException;
014:
015: public class MacroString {
016: private final Class this Class;
017: private final Imports imports;
018: private final String macroString;
019:
020: public MacroString(Class this Class, String importsString,
021: String macroString) {
022: this .this Class = this Class;
023: this .macroString = macroString;
024:
025: imports = new Imports();
026: imports.importPackage(this Class);
027:
028: if (importsString != null)
029: imports.parseImports(importsString);
030: }
031:
032: public String substituteMacros(MacroHandler mh) {
033: StringBuffer outBuf = new StringBuffer();
034: int left, right;
035:
036: /* Pass 1: Substitute SQL identifier macros "{...}". */
037: for (int curr = 0; curr < macroString.length(); curr = right + 1) {
038: if ((left = macroString.indexOf('{', curr)) < 0) {
039: outBuf.append(macroString.substring(curr));
040: break;
041: }
042:
043: outBuf.append(macroString.substring(curr, left));
044:
045: if ((right = macroString.indexOf('}', left + 1)) < 0)
046: throw new JDOUserException(
047: "Unmatched braces for identifier macro: "
048: + macroString);
049:
050: IdentifierMacro im = parseIdentifierMacro(macroString
051: .substring(left + 1, right));
052: mh.onIdentifierMacro(im);
053:
054: outBuf.append(im.value);
055: }
056:
057: String tmpString = outBuf.toString();
058: outBuf = new StringBuffer();
059:
060: /* Pass 2: Substitute parameter macros "?...?". */
061: for (int curr = 0; curr < tmpString.length(); curr = right + 1) {
062: if ((left = tmpString.indexOf('?', curr)) < 0) {
063: outBuf.append(tmpString.substring(curr));
064: break;
065: }
066:
067: outBuf.append(tmpString.substring(curr, left));
068:
069: if ((right = tmpString.indexOf('?', left + 1)) < 0)
070: throw new JDOUserException(
071: "Unmatched question marks for parameter macro: "
072: + tmpString);
073:
074: ParameterMacro pm = new ParameterMacro(tmpString.substring(
075: left + 1, right));
076: mh.onParameterMacro(pm);
077:
078: outBuf.append('?');
079: }
080:
081: return outBuf.toString();
082: }
083:
084: private Class resolveClassDeclaration(String className) {
085: try {
086: return className.equals("this") ? this Class : imports
087: .resolveClassDeclaration(className);
088: } catch (ClassNotFoundException e) {
089: return null;
090: }
091: }
092:
093: private IdentifierMacro parseIdentifierMacro(String unparsed) {
094: String className = null;
095: String fieldName = null;
096: String subfieldName = null;
097:
098: Class c = resolveClassDeclaration(unparsed);
099:
100: if (c == null) {
101: /* The last '.' in the string. */
102: int lastDot = unparsed.lastIndexOf('.');
103:
104: if (lastDot < 0)
105: throw new JDOUserException(
106: "Cannot parse identifier macro: " + unparsed);
107:
108: fieldName = unparsed.substring(lastDot + 1);
109: className = unparsed.substring(0, lastDot);
110: c = resolveClassDeclaration(className);
111:
112: if (c == null) {
113: /* The second to the last dot in the string. */
114: int lastDot2 = unparsed.lastIndexOf('.', lastDot - 1);
115:
116: if (lastDot2 < 0)
117: throw new JDOUserException(
118: "Cannot parse identifier macro: "
119: + unparsed);
120:
121: subfieldName = fieldName;
122: fieldName = unparsed.substring(lastDot2 + 1, lastDot);
123: className = unparsed.substring(0, lastDot2);
124: c = resolveClassDeclaration(className);
125:
126: if (c == null)
127: throw new JDOUserException(
128: "Cannot parse identifier macro: "
129: + unparsed);
130: }
131: }
132:
133: return new IdentifierMacro(unparsed, c, fieldName, subfieldName);
134: }
135:
136: public static class IdentifierMacro {
137: public final String unparsed;
138: public final Class clazz;
139: public final String fieldName;
140: public final String subfieldName;
141: public String value;
142:
143: IdentifierMacro(String unparsed, Class clazz, String fieldName,
144: String subfieldName) {
145: this .unparsed = unparsed;
146: this .clazz = clazz;
147: this .fieldName = fieldName;
148: this .subfieldName = subfieldName;
149: this .value = null;
150: }
151:
152: public String toString() {
153: return "{" + unparsed + "}";
154: }
155: }
156:
157: public static class ParameterMacro {
158: public final String parameterName;
159:
160: ParameterMacro(String parameterName) {
161: this .parameterName = parameterName;
162: }
163:
164: public String toString() {
165: return "?" + parameterName + "?";
166: }
167: }
168:
169: public static interface MacroHandler {
170: void onIdentifierMacro(IdentifierMacro im);
171:
172: void onParameterMacro(ParameterMacro pm);
173: }
174: }
|