Java tutorial
/******************************************************************************* * Copyright (c) 2010, 2011 LogSaw project and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * LogSaw project committers - initial API and implementation *******************************************************************************/ package net.sf.logsaw.dialect.log4j.pattern; import java.text.DateFormat; import java.text.DateFormatSymbols; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.TimeZone; import java.util.regex.Matcher; import java.util.regex.Pattern; import net.sf.logsaw.core.dialect.ILogLevelProvider; import net.sf.logsaw.core.field.ALogEntryField; import net.sf.logsaw.core.field.Level; import net.sf.logsaw.core.field.LogEntry; import net.sf.logsaw.dialect.log4j.Log4JDialectPlugin; import net.sf.logsaw.dialect.log4j.Log4JFieldProvider; import net.sf.logsaw.dialect.log4j.internal.Messages; import net.sf.logsaw.dialect.pattern.APatternDialect; import net.sf.logsaw.dialect.pattern.ConversionRule; import net.sf.logsaw.dialect.pattern.IConversionPatternTranslator; import net.sf.logsaw.dialect.pattern.RegexUtils; import org.apache.commons.io.IOUtils; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.osgi.util.NLS; /** * This class can extract conversion rules out of a Log4J pattern. * * @author Philipp Nanz */ public final class Log4JConversionPatternTranslator implements IConversionPatternTranslator { private static final Pattern EXTRACTION_PATTERN = Pattern .compile("%(-?(\\d+))?(\\.(\\d+))?([a-zA-Z])(\\{([^\\}]+)\\})?"); //$NON-NLS-1$ private static final Pattern NEWLINE_PATTERN = Pattern.compile("%n"); //$NON-NLS-1$ private static final String PROP_DATEFORMAT = "dateFormat"; //$NON-NLS-1$ private int minLinesPerEntry; /* (non-Javadoc) * @see net.sf.logsaw.dialect.pattern.IConversionPatternTranslator#prepare(java.lang.String) */ @Override public String prepare(String externalPattern) throws CoreException { if (!externalPattern.endsWith("%n")) { //$NON-NLS-1$ throw new CoreException(new Status(IStatus.ERROR, Log4JDialectPlugin.PLUGIN_ID, Messages.Log4JConversionRuleExtractor_error_mustEndWithNewLine)); } // Pattern without %n externalPattern = externalPattern.substring(0, externalPattern.length() - 2); Matcher m = NEWLINE_PATTERN.matcher(externalPattern); minLinesPerEntry = 1; while (m.find()) { minLinesPerEntry++; } return externalPattern; } /* (non-Javadoc) * @see net.sf.logsaw.dialect.pattern.IConversionPatternTranslator#getMinLinesPerEntry() */ @Override public int getMinLinesPerEntry() { return minLinesPerEntry; } /* (non-Javadoc) * @see net.sf.logsaw.dialect.pattern.IConversionPatternTranslator#applyLocale(java.util.Locale, java.util.List) */ @Override public void applyLocale(Locale loc, List<ConversionRule> rules) { for (ConversionRule rule : rules) { if (rule.getPlaceholderName().equals("d")) { //$NON-NLS-1$ SimpleDateFormat df = rule.getProperty(PROP_DATEFORMAT, SimpleDateFormat.class); Assert.isNotNull(df, "dateFormat"); //$NON-NLS-1$ df.setDateFormatSymbols(DateFormatSymbols.getInstance(loc)); return; } } } /* (non-Javadoc) * @see net.sf.logsaw.dialect.pattern.IConversionPatternTranslator#applyTimeZone(java.util.TimeZone, java.util.List) */ @Override public void applyTimeZone(TimeZone tz, List<ConversionRule> rules) { for (ConversionRule rule : rules) { if (rule.getPlaceholderName().equals("d")) { //$NON-NLS-1$ SimpleDateFormat df = rule.getProperty(PROP_DATEFORMAT, SimpleDateFormat.class); Assert.isNotNull(df, "dateFormat"); //$NON-NLS-1$ df.setTimeZone(tz); return; } } } /* (non-Javadoc) * @see net.sf.logsaw.dialect.log4j.pattern.IConversionRuleExtractor#extractRules(java.lang.String) */ @Override public List<ConversionRule> extractRules(String externalPattern) throws CoreException { // Find supported conversion characters Matcher m = EXTRACTION_PATTERN.matcher(externalPattern); List<ConversionRule> ret = new ArrayList<ConversionRule>(); while (m.find()) { String minWidthModifier = m.group(2); String maxWidthModifier = m.group(4); String conversionName = m.group(5); String conversionModifier = m.group(7); int minWidth = -1; // not specified if ((minWidthModifier != null) && (minWidthModifier.length() > 0)) { minWidth = Integer.parseInt(minWidthModifier); } int maxWidth = -1; // not specified if ((maxWidthModifier != null) && (maxWidthModifier.length() > 0)) { maxWidth = Integer.parseInt(maxWidthModifier); } ConversionRule rule = new ConversionRule(); rule.setBeginIndex(m.start()); rule.setLength(m.end() - m.start()); rule.setMaxWidth(maxWidth); rule.setMinWidth(minWidth); rule.setPlaceholderName(conversionName); rule.setModifier(conversionModifier); if (conversionName.equals("n")) { rule.setLineBreak(true); } ret.add(rule); } return ret; } /* (non-Javadoc) * @see net.sf.logsaw.dialect.pattern.IConversionPatternTranslator#applyDefaults(net.sf.logsaw.dialect.pattern.ConversionRule, net.sf.logsaw.dialect.pattern.APatternDialect) */ @Override public void applyDefaults(ConversionRule rule, APatternDialect dialect) throws CoreException { if (rule.getPlaceholderName().equals("d") && (rule.getModifier() == null)) { //$NON-NLS-1$ // ISO8601 is the default rule.setModifier("ISO8601"); //$NON-NLS-1$ } } /* (non-Javadoc) * @see net.sf.logsaw.dialect.pattern.IConversionPatternTranslator#rewrite(net.sf.logsaw.dialect.pattern.ConversionRule, net.sf.logsaw.dialect.pattern.APatternDialect) */ @Override public void rewrite(ConversionRule rule, APatternDialect dialect) throws CoreException { if (rule.getPlaceholderName().equals("d")) { //$NON-NLS-1$ if (rule.getModifier().equals("ABSOLUTE")) { //$NON-NLS-1$ rule.setModifier("HH:mm:ss,SSS"); //$NON-NLS-1$ } else if (rule.getModifier().equals("DATE")) { //$NON-NLS-1$ rule.setModifier("dd MMM yyyy HH:mm:ss,SSS"); //$NON-NLS-1$ } else if (rule.getModifier().equals("ISO8601")) { //$NON-NLS-1$ rule.setModifier("yyyy-MM-dd HH:mm:ss,SSS"); //$NON-NLS-1$ } try { // Cache date format rule.putProperty(PROP_DATEFORMAT, new SimpleDateFormat(rule.getModifier())); dialect.configure(APatternDialect.OPTION_TIMESTAMP_PATTERN, rule.getModifier()); } catch (IllegalArgumentException e) { throw new CoreException(new Status(IStatus.ERROR, Log4JDialectPlugin.PLUGIN_ID, NLS.bind( Messages.Log4JConversionRuleTranslator_error_dataFormatNotSupported, rule.getModifier()))); } } } /* (non-Javadoc) * @see net.sf.logsaw.dialect.log4j.pattern.IConversionRuleTranslator#convertToRegexPattern(net.sf.logsaw.dialect.log4j.pattern.ConversionRule) */ @Override public String getRegexPatternForRule(ConversionRule rule) throws CoreException { if (rule.getPlaceholderName().equals("d")) { //$NON-NLS-1$ // Pattern is dynamic return "(" + RegexUtils.getRegexForSimpleDateFormat(rule.getModifier()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$ } else if (rule.getPlaceholderName().equals("p")) { //$NON-NLS-1$ String lnHint = RegexUtils.getLengthHint(rule); if (lnHint.length() > 0) { return "([ A-Z]" + lnHint + ")"; //$NON-NLS-1$ //$NON-NLS-2$ } // Default: Length is limited by the levels available return "([A-Z]{4,5})"; //$NON-NLS-1$ } else if (rule.getPlaceholderName().equals("c")) { //$NON-NLS-1$ return "(.*" + RegexUtils.getLengthHint(rule) + RegexUtils.getLazySuffix(rule) + ")"; //$NON-NLS-1$ //$NON-NLS-2$ } else if (rule.getPlaceholderName().equals("t")) { //$NON-NLS-1$ return "(.*" + RegexUtils.getLengthHint(rule) + RegexUtils.getLazySuffix(rule) + ")"; //$NON-NLS-1$ //$NON-NLS-2$ } else if (rule.getPlaceholderName().equals("m")) { //$NON-NLS-1$ return "(.*" + RegexUtils.getLengthHint(rule) + RegexUtils.getLazySuffix(rule) + ")"; //$NON-NLS-1$ //$NON-NLS-2$ } else if (rule.getPlaceholderName().equals("n")) { //$NON-NLS-1$ return "(" + IOUtils.LINE_SEPARATOR + ")"; //$NON-NLS-1$ //$NON-NLS-2$ } else if (rule.getPlaceholderName().equals("F")) { //$NON-NLS-1$ return "(.*" + RegexUtils.getLengthHint(rule) + RegexUtils.getLazySuffix(rule) + ")"; //$NON-NLS-1$ //$NON-NLS-2$ } else if (rule.getPlaceholderName().equals("C")) { //$NON-NLS-1$ return "(.*" + RegexUtils.getLengthHint(rule) + RegexUtils.getLazySuffix(rule) + ")"; //$NON-NLS-1$ //$NON-NLS-2$ } else if (rule.getPlaceholderName().equals("M")) { //$NON-NLS-1$ return "([a-zA-Z0-9]*" + RegexUtils.getLengthHint(rule) + RegexUtils.getLazySuffix(rule) + ")"; //$NON-NLS-1$ //$NON-NLS-2$ } else if (rule.getPlaceholderName().equals("L")) { //$NON-NLS-1$ return "([0-9]*" + RegexUtils.getLengthHint(rule) + ")"; //$NON-NLS-1$ //$NON-NLS-2$ } else if (rule.getPlaceholderName().equals("x")) { //$NON-NLS-1$ return "(.*" + RegexUtils.getLengthHint(rule) + RegexUtils.getLazySuffix(rule) + ")"; //$NON-NLS-1$ //$NON-NLS-2$ } throw new CoreException(new Status(IStatus.ERROR, Log4JDialectPlugin.PLUGIN_ID, NLS.bind(Messages.Log4JConversionRuleTranslator_error_unsupportedConversionCharacter, rule.getPlaceholderName()))); } /* (non-Javadoc) * @see net.sf.logsaw.dialect.log4j.pattern.IConversionRuleTranslator#getFieldForRule(net.sf.logsaw.dialect.log4j.pattern.ConversionRule) */ @Override public ALogEntryField<?, ?> getFieldForRule(ConversionRule rule) throws CoreException { if (rule.getPlaceholderName().equals("d")) { //$NON-NLS-1$ return Log4JFieldProvider.FIELD_TIMESTAMP; } else if (rule.getPlaceholderName().equals("p")) { //$NON-NLS-1$ return Log4JFieldProvider.FIELD_LEVEL; } else if (rule.getPlaceholderName().equals("c")) { //$NON-NLS-1$ return Log4JFieldProvider.FIELD_LOGGER; } else if (rule.getPlaceholderName().equals("t")) { //$NON-NLS-1$ return Log4JFieldProvider.FIELD_THREAD; } else if (rule.getPlaceholderName().equals("m")) { //$NON-NLS-1$ return Log4JFieldProvider.FIELD_MESSAGE; } else if (rule.getPlaceholderName().equals("n")) { //$NON-NLS-1$ return null; } else if (rule.getPlaceholderName().equals("F")) { //$NON-NLS-1$ return Log4JFieldProvider.FIELD_LOC_FILENAME; } else if (rule.getPlaceholderName().equals("C")) { //$NON-NLS-1$ return Log4JFieldProvider.FIELD_LOC_CLASS; } else if (rule.getPlaceholderName().equals("M")) { //$NON-NLS-1$ return Log4JFieldProvider.FIELD_LOC_METHOD; } else if (rule.getPlaceholderName().equals("L")) { //$NON-NLS-1$ return Log4JFieldProvider.FIELD_LOC_LINE; } else if (rule.getPlaceholderName().equals("x")) { //$NON-NLS-1$ return Log4JFieldProvider.FIELD_NDC; } throw new CoreException(new Status(IStatus.ERROR, Log4JDialectPlugin.PLUGIN_ID, NLS.bind(Messages.Log4JConversionRuleTranslator_error_unsupportedConversionCharacter, rule.getPlaceholderName()))); } /* (non-Javadoc) * @see net.sf.logsaw.dialect.log4j.pattern.IConversionRuleTranslator#extractField(net.sf.logsaw.core.model.LogEntry, net.sf.logsaw.dialect.log4j.pattern.ConversionRule, net.sf.logsaw.core.model.ALogEntryField, java.lang.String) */ @Override public void extractField(LogEntry entry, ConversionRule rule, String val) throws CoreException { if (rule.getPlaceholderName().equals("d")) { //$NON-NLS-1$ DateFormat df = rule.getProperty(PROP_DATEFORMAT, DateFormat.class); Assert.isNotNull(df, "dateFormat"); //$NON-NLS-1$ try { entry.put(Log4JFieldProvider.FIELD_TIMESTAMP, df.parse(val.trim())); } catch (ParseException e) { throw new CoreException(new Status(IStatus.ERROR, Log4JDialectPlugin.PLUGIN_ID, NLS.bind(Messages.Log4JConversionRuleTranslator_error_failedToParseTimestamp, val.trim()))); } } else if (rule.getPlaceholderName().equals("p")) { //$NON-NLS-1$ Level lvl = Log4JFieldProvider.FIELD_LEVEL.getLevelProvider().findLevel(val.trim()); if (ILogLevelProvider.ID_LEVEL_UNKNOWN == lvl.getValue()) { throw new CoreException(new Status(IStatus.WARNING, Log4JDialectPlugin.PLUGIN_ID, NLS.bind(Messages.Log4JConversionRuleTranslator_warning_unknownPriority, val.trim()))); } entry.put(Log4JFieldProvider.FIELD_LEVEL, lvl); } else if (rule.getPlaceholderName().equals("c")) { //$NON-NLS-1$ entry.put(Log4JFieldProvider.FIELD_LOGGER, val.trim()); } else if (rule.getPlaceholderName().equals("t")) { //$NON-NLS-1$ entry.put(Log4JFieldProvider.FIELD_THREAD, val.trim()); } else if (rule.getPlaceholderName().equals("m")) { //$NON-NLS-1$ entry.put(Log4JFieldProvider.FIELD_MESSAGE, val.trim()); } else if (rule.getPlaceholderName().equals("n")) { //$NON-NLS-1$ // nadda } else if (rule.getPlaceholderName().equals("F")) { //$NON-NLS-1$ entry.put(Log4JFieldProvider.FIELD_LOC_FILENAME, val.trim()); } else if (rule.getPlaceholderName().equals("C")) { //$NON-NLS-1$ entry.put(Log4JFieldProvider.FIELD_LOC_CLASS, val.trim()); } else if (rule.getPlaceholderName().equals("M")) { //$NON-NLS-1$ entry.put(Log4JFieldProvider.FIELD_LOC_METHOD, val.trim()); } else if (rule.getPlaceholderName().equals("L")) { //$NON-NLS-1$ entry.put(Log4JFieldProvider.FIELD_LOC_LINE, val.trim()); } else if (rule.getPlaceholderName().equals("x")) { //$NON-NLS-1$ entry.put(Log4JFieldProvider.FIELD_NDC, val.trim()); } else { throw new CoreException(new Status(IStatus.ERROR, Log4JDialectPlugin.PLUGIN_ID, NLS.bind(Messages.Log4JConversionRuleTranslator_error_unsupportedConversionCharacter, rule.getPlaceholderName()))); } } }