001/**
002 * Logback: the reliable, generic, fast and flexible logging framework.
003 * Copyright (C) 1999-2002, 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.sift;
015
016import java.util.stream.Stream;
017
018import ch.qos.logback.core.Context;
019import ch.qos.logback.core.CoreConstants;
020import ch.qos.logback.core.model.AppenderModel;
021import ch.qos.logback.core.model.Model;
022import ch.qos.logback.core.model.SiftModel;
023import ch.qos.logback.core.model.processor.ModelHandlerBase;
024import ch.qos.logback.core.model.processor.ModelHandlerException;
025import ch.qos.logback.core.model.processor.ModelInterpretationContext;
026
027public class SiftModelHandler extends ModelHandlerBase {
028    final static String ONE_AND_ONLY_ONE_URL = CoreConstants.CODES_URL + "#1andOnly1";
029    
030    public SiftModelHandler(Context context) {
031        super(context);
032    }
033
034    static public SiftModelHandler makeInstance(Context context, ModelInterpretationContext ic) {
035        return new SiftModelHandler(context);
036    }
037
038    @Override
039    protected Class<SiftModel> getSupportedModelClass() {
040        return SiftModel.class;
041    }
042    
043    @SuppressWarnings("unchecked")
044    @Override
045    public void handle(ModelInterpretationContext mic, Model model) throws ModelHandlerException {
046        
047        SiftModel siftModel = (SiftModel) model;
048        // don't let the processor handle sub-models
049        siftModel.markAsSkipped();
050        
051        long appenderModelCount = computeAppenderModelCount(siftModel);
052        
053        if(appenderModelCount == 0) {
054            String errMsg = "No nested appenders found within the <sift> element in SiftingAppender.";    
055            addError(errMsg);
056            return;
057        }
058        if(appenderModelCount > 1) {
059            String errMsg = "Only and only one appender can be nested the <sift> element in SiftingAppender. See also " + ONE_AND_ONLY_ONE_URL;
060            addError(errMsg);
061            return;
062        }
063        
064        
065        Object o = mic.peekObject();
066        if (o instanceof SiftingAppenderBase) {
067            @SuppressWarnings("rawtypes")
068            SiftingAppenderBase sa = (SiftingAppenderBase) o;
069
070            String key = sa.getDiscriminatorKey();
071            @SuppressWarnings("rawtypes")
072            AppenderFactoryUsingSiftModel afusm = new AppenderFactoryUsingSiftModel(mic, siftModel, key);
073         
074            sa.setAppenderFactory(afusm);
075            
076        } else {
077            addError("Unexpected object "+ o);
078        }
079    }
080
081    private long computeAppenderModelCount(SiftModel siftModel) {
082        Stream<Model> stream = siftModel.getSubModels().stream();
083        long count = stream.filter((Model m) -> m instanceof AppenderModel).count();
084        return count;
085    }
086
087}