001: package org.wings.macro;
002:
003: import java.io.StringReader;
004: import java.io.Reader;
005:
006: /**
007: * <code>MacroHandler<code>.
008: * <p/>
009: * User: rrd
010: * Date: 08.08.2007
011: * Time: 16:03:34
012: *
013: * @author rrd
014: * @version $Id
015: */
016: public class MacroProcessor {
017:
018: private static MacroProcessor sharedInstance;
019:
020: protected MacroProcessor() {
021:
022: }
023:
024: public static MacroProcessor getInstance() {
025: if (sharedInstance == null) {
026: synchronized (MacroProcessor.class) {
027: if (sharedInstance == null)
028: sharedInstance = new MacroProcessor();
029: }
030: }
031:
032: return sharedInstance;
033: }
034:
035: public MacroContainer buildMacro(String macroTemplate)
036: throws Exception {
037:
038: Macro macro = new MacroContainer();
039:
040: StringReader reader = new StringReader(macroTemplate.trim());
041:
042: return (MacroContainer) createMacro(reader, macro);
043: }
044:
045: private Macro createMacro(Reader reader, Macro parent)
046: throws Exception {
047:
048: StringBuilder characters = new StringBuilder();
049: int c;
050: while ((c = reader.read()) != -1) {
051: // begin macro
052: if ('#' == c) {
053: addStringInstruction(parent, characters.toString());
054: characters = new StringBuilder();
055:
056: Macro macro = getMacro(reader);
057: macro = createMacro(reader, macro);
058: if (macro instanceof Instruction) {
059: parent.addInstruction((Instruction) macro);
060: }
061:
062: continue;
063: }
064: // end macro
065: else if ('}' == c) {
066: addStringInstruction(parent, characters.toString());
067: return parent;
068: }
069: characters.append((char) c);
070: }
071:
072: addStringInstruction(parent, characters.toString());
073: return parent;
074: }
075:
076: private Macro getMacro(Reader reader) throws Exception {
077:
078: StringBuilder type = new StringBuilder();
079: StringBuilder instructions = new StringBuilder();
080:
081: boolean switchInstruction = false;
082: int c;
083: while ((c = reader.read()) != -1) {
084:
085: // delimiter between macro type and macro instruction
086: if (' ' == c || '(' == c) {
087: switchInstruction = true;
088: continue;
089: }
090:
091: if (!switchInstruction) {
092: type.append((char) c);
093: } else {
094: // ignore '{' and ')' brackets
095: if ('{' == c) {
096: break;
097: } else if (')' != c) {
098: instructions.append((char) c);
099: }
100: }
101: }
102:
103: return initializeMacro(type.toString(), instructions.toString());
104: }
105:
106: private Macro initializeMacro(String type, String instructions) {
107:
108: if ("if".equals(type)) {
109:
110: } else if ("else if".equals(type)) {
111:
112: } else if ("else".equals(type)) {
113:
114: } else if ("while".equals(type)) {
115: return new WhileMacro(instructions);
116: } else if ("for".equals(type)) {
117: return new ForMacro(instructions);
118: } else {
119: return new MethodCallMacro(type, instructions);
120: }
121: return null;
122: }
123:
124: /**
125: * Adds a <code>StringInstruction</code> to the macro. If the trimmed characters
126: * string equals "" then this procedure will be skipped by default.
127: * Skip prohibits empty strings. -> SHOULD RAISE PERFORMANCE
128: *
129: * @param macro The macro that gets the string instruction or nothing if the
130: * trimmed string equals "".
131: * @param characters The character string.
132: */
133: private void addStringInstruction(Macro macro, String characters) {
134: characters = removeUnnecessaryLineBreaks(characters);
135:
136: if (!"".equals(characters.trim())) {
137: macro.addInstruction(new StringInstruction(characters));
138: }
139: }
140:
141: /**
142: * Removes unnecessary line breaks at the end of the character string. This will
143: * be performed to reduce the html output and also shows a pretty html format.
144: *
145: * @param characters The characters that may contain unnecessary line breaks.
146: * @return A character string that doesn't contain line breaks at the end. The result
147: * can be the same as the paramter characters.
148: */
149: private String removeUnnecessaryLineBreaks(String characters) {
150: int index = characters.lastIndexOf("\r\n");
151:
152: if (index != -1) {
153: String tmp = characters.substring(index, characters
154: .length());
155: if ("".equals(tmp.trim())) {
156: characters = characters.substring(0, characters
157: .lastIndexOf("\r\n"));
158: }
159: }
160: return characters;
161: }
162: }
|