001/**
002 * Logback: the reliable, generic, fast and flexible logging framework.
003 * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
004 *
005 * This program and the accompanying materials are dual-licensed under
006 * either the terms of the Eclipse Public License v1.0 as published by
007 * the Eclipse Foundation
008 *
009 *   or (per the licensee's choosing)
010 *
011 * under the terms of the GNU Lesser General Public License version 2.1
012 * as published by the Free Software Foundation.
013 */
014package ch.qos.logback.core.joran.action;
015
016import ch.qos.logback.core.CoreConstants;
017import ch.qos.logback.core.joran.JoranConstants;
018import ch.qos.logback.core.joran.spi.SaxEventInterpretationContext;
019import ch.qos.logback.core.model.ConversionRuleModel;
020import ch.qos.logback.core.model.Model;
021import ch.qos.logback.core.util.OptionHelper;
022import org.xml.sax.Attributes;
023
024import java.util.HashMap;
025import java.util.Map;
026
027import static ch.qos.logback.core.joran.JoranConstants.CONVERSION_WORD_ATTRIBUTE;
028
029public class ConversionRuleAction extends BaseModelAction {
030
031    static public String CONVERTER_CLASS_ATTRIBUTE = "converterClass";
032
033
034    @Override
035    protected boolean validPreconditions(SaxEventInterpretationContext seic, String name, Attributes attributes) {
036        PreconditionValidator pv = new PreconditionValidator(this, seic, name, attributes);
037
038        boolean invalidConverterClassAttribute = pv.isInvalidAttribute(CONVERTER_CLASS_ATTRIBUTE);
039        boolean invalidClassAttribute = pv.isInvalidAttribute(CLASS_ATTRIBUTE);
040
041        if(!invalidConverterClassAttribute) {
042            pv.addWarn("["+CONVERTER_CLASS_ATTRIBUTE +"] attribute is deprecated and replaced by ["+CLASS_ATTRIBUTE+
043                    "]. "+pv.getLocationSuffix());
044        }
045        boolean missingClass = invalidClassAttribute && invalidConverterClassAttribute;
046        if(missingClass) {
047            pv.addMissingAttributeError(CLASS_ATTRIBUTE);
048            return false;
049        }
050
051        boolean multipleClassAttributes = (!invalidClassAttribute) && (!invalidConverterClassAttribute);
052        if(multipleClassAttributes) {
053            pv.addWarn("Both ["+CONVERTER_CLASS_ATTRIBUTE+"] attribute and ["+CLASS_ATTRIBUTE+"] attribute specified. ");
054            pv.addWarn( "["+CLASS_ATTRIBUTE+"] attribute will override. ");
055        }
056        pv.validateGivenAttribute(CONVERSION_WORD_ATTRIBUTE);
057        return pv.isValid();
058    }
059
060
061
062    @Override
063    protected Model buildCurrentModel(SaxEventInterpretationContext interpretationContext, String name,
064            Attributes attributes) {
065        ConversionRuleModel conversionRuleModel = new ConversionRuleModel();
066        conversionRuleModel.setConversionWord(attributes.getValue(CONVERSION_WORD_ATTRIBUTE));
067
068        String converterClassStr = attributes.getValue(CONVERTER_CLASS_ATTRIBUTE);
069        if(!OptionHelper.isNullOrEmpty(converterClassStr)) {
070            conversionRuleModel.setClassName(converterClassStr);
071        }
072        // if both converterClass and class are specified the latter overrides.
073        String classStr = attributes.getValue(CLASS_ATTRIBUTE);
074        if(!OptionHelper.isNullOrEmpty(classStr)) {
075            conversionRuleModel.setClassName(classStr);
076        }
077        return conversionRuleModel;
078    }
079
080//    /**
081//     * Instantiates a layout of the given class and sets its name.
082//     *
083//     */
084//    @SuppressWarnings("unchecked")
085//    public void begin(SaxEventInterpretationContext ec, String localName, Attributes attributes) {
086//        // Let us forget about previous errors (in this object)
087//        inError = false;
088//
089//        String errorMsg;
090//        String conversionWord = attributes.getValue(CONVERSION_WORD_ATTRIBUTE);
091//        String converterClass = attributes.getValue(JoranConstants.CONVERTER_CLASS_ATTRIBUTE);
092//
093//        if (OptionHelper.isNullOrEmptyOrAllSpaces(conversionWord)) {
094//            inError = true;
095//            errorMsg = "No 'conversionWord' attribute in <conversionRule>";
096//            addError(errorMsg);
097//
098//            return;
099//        }
100//
101//        if (OptionHelper.isNullOrEmptyOrAllSpaces(converterClass)) {
102//            inError = true;
103//            errorMsg = "No 'converterClass' attribute in <conversionRule>";
104//            ec.addError(errorMsg);
105//
106//            return;
107//        }
108//
109//        try {
110//            Map<String, String> ruleRegistry = (Map<String, String>) context
111//                    .getObject(CoreConstants.PATTERN_RULE_REGISTRY);
112//            if (ruleRegistry == null) {
113//                ruleRegistry = new HashMap<String, String>();
114//                context.putObject(CoreConstants.PATTERN_RULE_REGISTRY, ruleRegistry);
115//            }
116//            // put the new rule into the rule registry
117//            addInfo("registering conversion word " + conversionWord + " with class [" + converterClass + "]");
118//            ruleRegistry.put(conversionWord, converterClass);
119//        } catch (Exception oops) {
120//            inError = true;
121//            errorMsg = "Could not add conversion rule to PatternLayout.";
122//            addError(errorMsg);
123//        }
124//    }
125//
126//
127//    /**
128//     * Once the children elements are also parsed, now is the time to activate the
129//     * appender options.
130//     */
131//    public void end(SaxEventInterpretationContext ec, String n) {
132//    }
133//
134//    public void finish(SaxEventInterpretationContext ec) {
135//    }
136}