// Copyright 2011 Google Inc. All Rights Reserved. // // 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 com.google.api.ads.common.lib.utils.logging; import com.google.common.base.Supplier; import com.google.inject.AbstractModule; import com.google.inject.Provider; import com.google.inject.TypeLiteral; import com.google.inject.name.Names; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.annotation.concurrent.ThreadSafe; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.TransformerFactoryConfigurationError; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathFactory; /** * Module for logging. */ public class LoggingModule extends AbstractModule { private final String loggerPrefix; /** * Constructor. * * @param loggerPrefix the logger prefix. */ public LoggingModule(String loggerPrefix) { this.loggerPrefix = loggerPrefix; } @Override protected void configure() { bind(AdsServiceLoggers.class); // DocumentBuilderFactory is *not* guaranteed to be thread-safe. bind(new TypeLiteral<Supplier<DocumentBuilder>>(){}).to( DocumentBuilderSupplier.class); // Transformer is *not* guaranteed to be thread-safe. bind(new TypeLiteral<Supplier<Transformer>>(){}).to( TransformerSupplier.class); // XPathFactory is *not* guaranteed to be thread-safe. bind(new TypeLiteral<Supplier<XPath>>(){}).to( XPathSupplier.class); bind(PrettyPrinterInterface.class).to(PrettyPrinter.class); bind(Logger.class) .annotatedWith(Names.named("libLogger")).toInstance(AdsServiceLoggers.ADS_API_LIB_LOG); configureLogger(loggerPrefix, "soapXmlLogger"); configureLogger(loggerPrefix, "requestInfoLogger"); } protected void configureLogger(String prefix, String name) { bind(Logger.class).annotatedWith(Names.named(name)).toProvider( new LoggerProvider(prefix, name)).asEagerSingleton(); } /** * Thread-safe supplier for {@link XPath} objects. This is necessary because * {@link XPathFactory} is <em>not</em> thread-safe. */ @ThreadSafe private static final class XPathSupplier implements Supplier<XPath> { @Override public XPath get() { return XPathFactory.newInstance().newXPath(); } } /** * Thread-safe supplier for {@link DocumentBuilder} objects. This is necessary because * {@link DocumentBuilderFactory} is <em>not</em> thread-safe. */ @ThreadSafe private static final class DocumentBuilderSupplier implements Supplier<DocumentBuilder> { @Override public DocumentBuilder get() { try { return DocumentBuilderFactory.newInstance().newDocumentBuilder(); } catch (ParserConfigurationException e) { AdsServiceLoggers.ADS_API_LIB_LOG.warn("Unable to initialize DocumentBuilder. Error: " + e); return null; } } } /** * Thread-safe supplier for {@link Transformer} objects. This is necessary because * {@link TransformerFactory} is <em>not</em> thread-safe. */ @ThreadSafe private static final class TransformerSupplier implements Supplier<Transformer> { @Override public Transformer get() { Transformer transformer; try { transformer = TransformerFactory.newInstance().newTransformer(); } catch (TransformerConfigurationException e) { AdsServiceLoggers.ADS_API_LIB_LOG.warn("Unable to initialize Transformer. Error: " + e); return null; } catch (TransformerFactoryConfigurationError e) { AdsServiceLoggers.ADS_API_LIB_LOG.warn("Unable to initialize Transformer. Error: " + e); return null; } transformer.setOutputProperty(OutputKeys.INDENT, "yes"); transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); return transformer; } } /** * Provider for Loggers. */ private static final class LoggerProvider implements Provider<Logger> { private final String loggerPrefix; private final String logType; /** * Constructor. * * @param loggerPrefix the logger prefix * @param logType the log type (i.e. soap_xml) */ public LoggerProvider(String loggerPrefix, String logType) { this.loggerPrefix = loggerPrefix; this.logType = logType; } @Override public Logger get() { return LoggerFactory.getLogger(loggerPrefix + "." + logType); } } }