View Javadoc
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                     // Tries to found another occurence of the literal
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 }