/* * Copyright 2012-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.boot.logging.logback; import java.util.ArrayList; import java.util.List; import ch.qos.logback.core.joran.action.Action; import ch.qos.logback.core.joran.event.InPlayListener; import ch.qos.logback.core.joran.event.SaxEvent; import ch.qos.logback.core.joran.spi.ActionException; import ch.qos.logback.core.joran.spi.InterpretationContext; import ch.qos.logback.core.joran.spi.Interpreter; import ch.qos.logback.core.util.OptionHelper; import org.xml.sax.Attributes; import org.springframework.core.env.Environment; import org.springframework.util.Assert; import org.springframework.util.StringUtils; /** * Logback {@link Action} to support {@code <springProfile>} tags. Allows section of a * logback configuration to only be enabled when a specific profile is active. * * @author Phillip Webb * @author EddĂș MelĂ©ndez */ class SpringProfileAction extends Action implements InPlayListener { private final Environment environment; private int depth = 0; private boolean acceptsProfile; private List<SaxEvent> events; SpringProfileAction(Environment environment) { this.environment = environment; } @Override public void begin(InterpretationContext ic, String name, Attributes attributes) throws ActionException { this.depth++; if (this.depth != 1) { return; } ic.pushObject(this); this.acceptsProfile = acceptsProfiles(ic, attributes); this.events = new ArrayList<>(); ic.addInPlayListener(this); } private boolean acceptsProfiles(InterpretationContext ic, Attributes attributes) { String[] profileNames = StringUtils.trimArrayElements(StringUtils .commaDelimitedListToStringArray(attributes.getValue(NAME_ATTRIBUTE))); if (profileNames.length != 0) { for (String profileName : profileNames) { OptionHelper.substVars(profileName, ic, this.context); } return this.environment != null && this.environment.acceptsProfiles(profileNames); } return false; } @Override public void end(InterpretationContext ic, String name) throws ActionException { this.depth--; if (this.depth != 0) { return; } ic.removeInPlayListener(this); verifyAndPop(ic); if (this.acceptsProfile) { addEventsToPlayer(ic); } } private void verifyAndPop(InterpretationContext ic) { Object o = ic.peekObject(); Assert.state(o != null, "Unexpected null object on stack"); Assert.isInstanceOf(SpringProfileAction.class, o, "logback stack error"); Assert.state(o == this, "ProfileAction different than current one on stack"); ic.popObject(); } private void addEventsToPlayer(InterpretationContext ic) { Interpreter interpreter = ic.getJoranInterpreter(); this.events.remove(0); this.events.remove(this.events.size() - 1); interpreter.getEventPlayer().addEventsDynamically(this.events, 1); } @Override public void inPlay(SaxEvent event) { this.events.add(event); } }