View Javadoc
1   /**
2    * Logback: the reliable, generic, fast and flexible logging framework.
3    * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
4    *
5    * This program and the accompanying materials are dual-licensed under
6    * either the terms of the Eclipse Public License v1.0 as published by
7    * the Eclipse Foundation
8    *
9    *   or (per the licensee's choosing)
10   *
11   * under the terms of the GNU Lesser General Public License version 2.1
12   * as published by the Free Software Foundation.
13   */
14  package ch.qos.logback.core.sift;
15  
16  import java.util.Collection;
17  import java.util.Map;
18  
19  import ch.qos.logback.core.Appender;
20  import ch.qos.logback.core.Context;
21  import ch.qos.logback.core.joran.JoranConstants;
22  import ch.qos.logback.core.joran.ParamModelHandler;
23  import ch.qos.logback.core.joran.spi.DefaultNestedComponentRegistry;
24  import ch.qos.logback.core.joran.spi.JoranException;
25  import ch.qos.logback.core.model.AppenderModel;
26  import ch.qos.logback.core.model.ImplicitModel;
27  import ch.qos.logback.core.model.Model;
28  import ch.qos.logback.core.model.ParamModel;
29  import ch.qos.logback.core.model.PropertyModel;
30  import ch.qos.logback.core.model.SiftModel;
31  import ch.qos.logback.core.model.processor.AppenderModelHandler;
32  import ch.qos.logback.core.model.processor.ImplicitModelHandler;
33  import ch.qos.logback.core.model.processor.ModelInterpretationContext;
34  import ch.qos.logback.core.model.processor.PropertyModelHandler;
35  
36  /**
37   * Builds new appenders dynamically by running SiftingJoranConfigurator instance,
38   * a custom configurator tailored for the contents of the sift element.
39   * @param <E>
40   */
41  public class AppenderFactoryUsingSiftModel<E> implements AppenderFactory<E> {
42      
43      Context context;
44      final Model siftModel;
45      protected String discriminatingKey;
46      protected ModelInterpretationContext parentMic;
47      protected DefaultNestedComponentRegistry registry;
48      
49      public AppenderFactoryUsingSiftModel(ModelInterpretationContext parentMic, Model aSiftModel, String discriminatingKey)  {
50          this.siftModel = Model.duplicate(aSiftModel);
51          this.discriminatingKey = discriminatingKey;
52          this.parentMic = parentMic;
53          this.context = parentMic.getContext();
54        
55      }
56  
57  
58      public SiftProcessor<E> getSiftingModelProcessor(String value) {
59          ModelInterpretationContext smic = new ModelInterpretationContext(parentMic) {
60              @Override
61              public boolean hasDependers(String dependeeName) {
62                  return true;
63              } 
64          };
65          SiftProcessor<E> siftProcessor = new SiftProcessor<>(context, smic); 
66          siftProcessor.addHandler(ParamModel.class, ParamModelHandler::makeInstance);
67          siftProcessor.addHandler(PropertyModel.class, PropertyModelHandler::makeInstance);
68          siftProcessor.addHandler(ImplicitModel.class, ImplicitModelHandler::makeInstance);
69          siftProcessor.addHandler(AppenderModel.class, AppenderModelHandler::makeInstance);
70          siftProcessor.addHandler(SiftModel.class, NOPSiftModelHandler::makeInstance);
71          
72          return siftProcessor;
73  
74      }
75  
76      public Appender<E> buildAppender(Context context, String discriminatingValue) throws JoranException {
77          
78          SiftProcessor<E> sp = getSiftingModelProcessor(discriminatingValue);
79          ModelInterpretationContext mic = sp.getModelInterpretationContext();
80          sp.setContext(context);
81          Model duplicate = Model.duplicate(siftModel);
82          mic.addSubstitutionProperty(discriminatingKey, discriminatingValue);
83          sp.process(duplicate);
84          @SuppressWarnings("unchecked")
85          Map<String, Appender<E>> appenderBag = (Map<String, Appender<E>>) mic.getObjectMap()
86                  .get(JoranConstants.APPENDER_BAG);
87          Collection<Appender<E>> values = appenderBag.values();
88          if (values.size() == 0) {
89              return null;
90          }
91          return values.iterator().next();
92      }
93  
94      public Model getSiftModel() {
95          return siftModel;
96      }
97  
98  }