package ch.qos.logback.core.joran;
import ch.qos.logback.core.Context;
import ch.qos.logback.core.joran.event.SaxEvent;
import ch.qos.logback.core.joran.event.SaxEventRecorder;
import ch.qos.logback.core.joran.spi.*;
import ch.qos.logback.core.joran.util.ConfigurationWatchListUtil;
import ch.qos.logback.core.joran.util.beans.BeanDescriptionCache;
import ch.qos.logback.core.spi.ContextAwareBase;
import ch.qos.logback.core.status.StatusUtil;
import org.xml.sax.InputSource;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import static ch.qos.logback.core.CoreConstants.SAFE_JORAN_CONFIGURATION;
public abstract class GenericConfigurator extends ContextAwareBase {
private BeanDescriptionCache beanDescriptionCache;
protected Interpreter interpreter;
public final void doConfigure(URL url) throws JoranException {
InputStream in = null;
try {
informContextOfURLUsedForConfiguration(getContext(), url);
URLConnection urlConnection = url.openConnection();
urlConnection.setUseCaches(false);
in = urlConnection.getInputStream();
doConfigure(in, url.toExternalForm());
} catch (IOException ioe) {
String errMsg = "Could not open URL [" + url + "].";
addError(errMsg, ioe);
throw new JoranException(errMsg, ioe);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException ioe) {
String errMsg = "Could not close input stream";
addError(errMsg, ioe);
throw new JoranException(errMsg, ioe);
}
}
}
}
public final void doConfigure(String filename) throws JoranException {
doConfigure(new File(filename));
}
public final void doConfigure(File file) throws JoranException {
FileInputStream fis = null;
try {
URL url = file.toURI().toURL();
informContextOfURLUsedForConfiguration(getContext(), url);
fis = new FileInputStream(file);
doConfigure(fis, url.toExternalForm());
} catch (IOException ioe) {
String errMsg = "Could not open [" + file.getPath() + "].";
addError(errMsg, ioe);
throw new JoranException(errMsg, ioe);
} finally {
if (fis != null) {
try {
fis.close();
} catch (java.io.IOException ioe) {
String errMsg = "Could not close [" + file.getName() + "].";
addError(errMsg, ioe);
throw new JoranException(errMsg, ioe);
}
}
}
}
public static void informContextOfURLUsedForConfiguration(Context context, URL url) {
ConfigurationWatchListUtil.setMainWatchURL(context, url);
}
public final void doConfigure(InputStream inputStream) throws JoranException {
doConfigure(new InputSource(inputStream));
}
public final void doConfigure(InputStream inputStream, String systemId) throws JoranException {
InputSource inputSource = new InputSource(inputStream);
inputSource.setSystemId(systemId);
doConfigure(inputSource);
}
protected BeanDescriptionCache getBeanDescriptionCache() {
if (beanDescriptionCache == null) {
beanDescriptionCache = new BeanDescriptionCache(getContext());
}
return beanDescriptionCache;
}
protected abstract void addInstanceRules(RuleStore rs);
protected abstract void addImplicitRules(Interpreter interpreter);
protected void addDefaultNestedComponentRegistryRules(DefaultNestedComponentRegistry registry) {
}
protected ElementPath initialElementPath() {
return new ElementPath();
}
protected void buildInterpreter() {
RuleStore rs = new SimpleRuleStore(context);
addInstanceRules(rs);
this.interpreter = new Interpreter(context, rs, initialElementPath());
InterpretationContext interpretationContext = interpreter.getInterpretationContext();
interpretationContext.setContext(context);
addImplicitRules(interpreter);
addDefaultNestedComponentRegistryRules(interpretationContext.getDefaultNestedComponentRegistry());
}
public final void doConfigure(final InputSource inputSource) throws JoranException {
long threshold = System.currentTimeMillis();
SaxEventRecorder recorder = new SaxEventRecorder(context);
recorder.recordEvents(inputSource);
doConfigure(recorder.saxEventList);
StatusUtil statusUtil = new StatusUtil(context);
if (statusUtil.noXMLParsingErrorsOccurred(threshold)) {
addInfo("Registering current configuration as safe fallback point");
registerSafeConfiguration(recorder.saxEventList);
}
}
public void doConfigure(final List<SaxEvent> eventList) throws JoranException {
buildInterpreter();
synchronized (context.getConfigurationLock()) {
interpreter.getEventPlayer().play(eventList);
}
}
public void registerSafeConfiguration(List<SaxEvent> eventList) {
context.putObject(SAFE_JORAN_CONFIGURATION, eventList);
}
@SuppressWarnings("unchecked")
public List<SaxEvent> recallSafeConfiguration() {
return (List<SaxEvent>) context.getObject(SAFE_JORAN_CONFIGURATION);
}
}