1 package net.logAnalyzer.converters;
2
3 import net.logAnalyzer.handlers.LALogHandler;
4 import net.logAnalyzer.handlers.ParsingException;
5
6 /***
7 * This class implements a Log4J pattern converter. It is used to parse or
8 * convert a log messageLabel part.
9 *
10 * @author Karim REFEYTON
11 * @version 0.1
12 */
13 public abstract class LAConverter {
14
15 /***
16 * Definition of the converter.
17 */
18 private ConverterDefinition definition;
19
20 /***
21 * Literal value identifying the converter in the Log4J pattern.
22 */
23 private String literal;
24
25 /***
26 * Option string.
27 */
28 private String option;
29
30 /***
31 * Next converter or <tt>null</tt>.
32 */
33 private LAConverter next = null;
34
35 /***
36 * Constructs a new converter from a converter definition.
37 *
38 * @param definition
39 * Definition of the converter.
40 * @param literal
41 * Literal value identifying the converter.
42 */
43 public LAConverter(ConverterDefinition definition, String literal) {
44 this.definition = definition;
45 this.literal = literal;
46 }
47
48 /***
49 * Returns the converter label.
50 *
51 * @return LAConverter label.
52 */
53 public String getLabel() {
54 return this.definition.getLabel();
55 }
56
57 /***
58 * Returns <tt>true</tt> if the converter is a literal.
59 *
60 * @return <tt>true</tt> if the converter is a literal.
61 */
62 public boolean isLiteral() {
63 return LiteralConverter.class.isAssignableFrom(this.getClass());
64 }
65
66 /***
67 * Returns the literal value identifying the literal in the Log4J pattern.
68 * <ul>
69 * <li>for a literal converter, it is the literal ;</li>
70 * <li>otherwise, it is the character identifying the converter.</li>
71 * </ul>
72 *
73 * @return Literal value.
74 */
75 public String getLiteral() {
76 return this.literal;
77 }
78
79 /***
80 * Returns <tt>true</tt> if the converter is a messageLabel converter.
81 * <p>
82 * A messageLabel is a special field which could be extended during parsing
83 * process.
84 * <p>
85 * For example, if you log a Java exception, the exception may be written on
86 * more than one line, so the parsing process has to concat several lines to
87 * get the complete messageLabel.
88 *
89 * @return <tt>true</tt> if the converter is used to parse a messageLabel;
90 * <tt>false</tt> otherwise.
91 */
92 public boolean isMessage() {
93 return definition.isMessage();
94 }
95
96 /***
97 * Returns the option string of the converter.
98 *
99 * @return Option string.
100 */
101 public String getOption() {
102 return this.option;
103 }
104
105 /***
106 * Sets the option string of the converter. LAConverter may parse this
107 * string.
108 *
109 * @param option
110 * LAConverter option
111 */
112 public void setOption(String option) {
113 this.option = option;
114 }
115
116 /***
117 * Returns the next converter.
118 *
119 * @return Next converter or <tt>null</tt>.
120 */
121 public LAConverter getNext() {
122 return this.next;
123 }
124
125 /***
126 * Sets the next converter. Warning : no control is made on loops !
127 *
128 * @param next
129 * Next converter.
130 */
131 public void setNext(LAConverter next) {
132 this.next = next;
133 }
134
135 /***
136 * Returns the class of the values affected to the column (for example
137 * <tt>java.lang.String</tt> or <tt>java.lang.Double</tt>).
138 *
139 * @return Value class.
140 */
141 public abstract Class getValueClass();
142
143 /***
144 * Parses the message string to extract a value. Message is truncated by the
145 * previous converters.
146 *
147 * @param message
148 * String to parse.
149 * @param handler
150 * Log handler parsing.
151 * @return Parsed value
152 * @throws ParsingException
153 * If can't parse messageLabel.
154 */
155 public Object parse(StringBuffer message, LALogHandler handler)
156 throws ParsingException {
157 String value = null;
158 if (this.isLiteral()) {
159 int literalPosition = message.indexOf(this.getLiteral());
160 if (literalPosition != 0) {
161 throw new ParsingException("Can't parse for converter ["
162 + this.getLiteral() + "]");
163 }
164 value = this.getLiteral();
165 message.delete(0, value.length());
166 return parse(value);
167 } else if (getNext() == null) {
168 value = message.toString();
169 message.setLength(0);
170 return parse(value);
171 } else if (getNext().isLiteral()) {
172 value = "";
173 Object parsedValue = null;
174 do {
175 int literalPosition = message.indexOf(getNext().getLiteral());
176 if (literalPosition < 0) {
177 throw new ParsingException("Can't parse for converter ["
178 + this.getLiteral() + "]");
179 }
180 value += message.substring(0, literalPosition);
181 message.delete(0, literalPosition);
182 try {
183 parsedValue = parse(value);
184 } catch (ParsingException pe) {
185
186 value += message.substring(0, 1);
187 message.delete(0, 1);
188 }
189 } while (parsedValue == null);
190 return parsedValue;
191 } else {
192 throw new ParsingException("Can't parse for converter ["
193 + this.getLiteral() + "]");
194 }
195 }
196
197 /***
198 * Parse a string value to the value class as returned by
199 * {@link #getValueClass()}.
200 *
201 * @param value
202 * String value to parse.
203 * @return Parsed value.
204 * @throws ParsingException
205 * If value can't be parsed.
206 */
207 public abstract Object parse(String value) throws ParsingException;
208
209 /***
210 * Returns a string representation of the value calling <tt>toString()</tt>.
211 *
212 * @param value
213 * Value to convert as String.
214 * @return String representation of the value.
215 */
216 public abstract String toString(Object value);
217
218 /***
219 * Returns the converter label.
220 *
221 * @return LAConverter label.
222 */
223 public String toString() {
224 return getLabel();
225 }
226 }