/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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.apache.cxf.interceptor; import java.io.FilterWriter; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import java.io.StringWriter; import java.io.Writer; import java.util.logging.Level; import java.util.logging.Logger; import org.apache.cxf.common.injection.NoJSR250Annotations; import org.apache.cxf.common.logging.LogUtils; import org.apache.cxf.io.CacheAndWriteOutputStream; import org.apache.cxf.io.CachedOutputStream; import org.apache.cxf.io.CachedOutputStreamCallback; import org.apache.cxf.message.Message; import org.apache.cxf.phase.Phase; /** * @deprecated use the logging module rt/features/logging instead */ @NoJSR250Annotations @Deprecated public class LoggingOutInterceptor extends AbstractLoggingInterceptor { private static final Logger LOG = LogUtils.getLogger(LoggingOutInterceptor.class); private static final String LOG_SETUP = LoggingOutInterceptor.class.getName() + ".log-setup"; public LoggingOutInterceptor(String phase) { super(phase); addBefore(StaxOutInterceptor.class.getName()); } public LoggingOutInterceptor() { this(Phase.PRE_STREAM); } public LoggingOutInterceptor(int lim) { this(); limit = lim; } public LoggingOutInterceptor(PrintWriter w) { this(); this.writer = w; } public void handleMessage(Message message) throws Fault { final OutputStream os = message.getContent(OutputStream.class); final Writer iowriter = message.getContent(Writer.class); if (os == null && iowriter == null) { return; } Logger logger = getMessageLogger(message); if (logger != null && (logger.isLoggable(Level.INFO) || writer != null)) { // Write the output while caching it for the log message boolean hasLogged = message.containsKey(LOG_SETUP); if (!hasLogged) { message.put(LOG_SETUP, Boolean.TRUE); if (os != null) { final CacheAndWriteOutputStream newOut = new CacheAndWriteOutputStream(os); if (threshold > 0) { newOut.setThreshold(threshold); } if (limit > 0) { newOut.setCacheLimit(limit); } message.setContent(OutputStream.class, newOut); newOut.registerCallback(new LoggingCallback(logger, message, os)); } else { message.setContent(Writer.class, new LogWriter(logger, message, iowriter)); } } } } private LoggingMessage setupBuffer(Message message) { String id = (String)message.getExchange().get(LoggingMessage.ID_KEY); if (id == null) { id = LoggingMessage.nextId(); message.getExchange().put(LoggingMessage.ID_KEY, id); } final LoggingMessage buffer = new LoggingMessage("Outbound Message\n---------------------------", id); Integer responseCode = (Integer)message.get(Message.RESPONSE_CODE); if (responseCode != null) { buffer.getResponseCode().append(responseCode); } String encoding = (String)message.get(Message.ENCODING); if (encoding != null) { buffer.getEncoding().append(encoding); } String httpMethod = (String)message.get(Message.HTTP_REQUEST_METHOD); if (httpMethod != null) { buffer.getHttpMethod().append(httpMethod); } String address = (String)message.get(Message.ENDPOINT_ADDRESS); if (address != null) { buffer.getAddress().append(address); String uri = (String)message.get(Message.REQUEST_URI); if (uri != null && !address.startsWith(uri)) { if (!address.endsWith("/") && !uri.startsWith("/")) { buffer.getAddress().append("/"); } buffer.getAddress().append(uri); } } String ct = (String)message.get(Message.CONTENT_TYPE); if (ct != null) { buffer.getContentType().append(ct); } Object headers = message.get(Message.PROTOCOL_HEADERS); if (headers != null) { buffer.getHeader().append(headers); } return buffer; } private class LogWriter extends FilterWriter { StringWriter out2; int count; Logger logger; //NOPMD Message message; final int lim; LogWriter(Logger logger, Message message, Writer writer) { super(writer); this.logger = logger; this.message = message; if (!(writer instanceof StringWriter)) { out2 = new StringWriter(); } lim = limit == -1 ? Integer.MAX_VALUE : limit; } public void write(int c) throws IOException { super.write(c); if (out2 != null && count < lim) { out2.write(c); } count++; } public void write(char[] cbuf, int off, int len) throws IOException { super.write(cbuf, off, len); if (out2 != null && count < lim) { out2.write(cbuf, off, len); } count += len; } public void write(String str, int off, int len) throws IOException { super.write(str, off, len); if (out2 != null && count < lim) { out2.write(str, off, len); } count += len; } public void close() throws IOException { LoggingMessage buffer = setupBuffer(message); if (count >= lim) { buffer.getMessage().append("(message truncated to " + lim + " bytes)\n"); } StringWriter w2 = out2; if (w2 == null) { w2 = (StringWriter)out; } String ct = (String)message.get(Message.CONTENT_TYPE); try { writePayload(buffer.getPayload(), w2, ct); } catch (Exception ex) { //ignore } log(logger, formatLoggingMessage(buffer)); message.setContent(Writer.class, out); super.close(); } } protected String formatLoggingMessage(LoggingMessage buffer) { return buffer.toString(); } class LoggingCallback implements CachedOutputStreamCallback { private final Message message; private final OutputStream origStream; private final Logger logger; //NOPMD private final int lim; LoggingCallback(final Logger logger, final Message msg, final OutputStream os) { this.logger = logger; this.message = msg; this.origStream = os; this.lim = limit == -1 ? Integer.MAX_VALUE : limit; } public void onFlush(CachedOutputStream cos) { } public void onClose(CachedOutputStream cos) { LoggingMessage buffer = setupBuffer(message); String ct = (String)message.get(Message.CONTENT_TYPE); if (!isShowBinaryContent() && isBinaryContent(ct)) { buffer.getMessage().append(BINARY_CONTENT_MESSAGE).append('\n'); log(logger, formatLoggingMessage(buffer)); return; } if (!isShowMultipartContent() && isMultipartContent(ct)) { buffer.getMessage().append(MULTIPART_CONTENT_MESSAGE).append('\n'); log(logger, formatLoggingMessage(buffer)); return; } if (cos.getTempFile() == null) { //buffer.append("Outbound Message:\n"); if (cos.size() >= lim) { buffer.getMessage().append("(message truncated to " + lim + " bytes)\n"); } } else { buffer.getMessage().append("Outbound Message (saved to tmp file):\n"); buffer.getMessage().append("Filename: " + cos.getTempFile().getAbsolutePath() + "\n"); if (cos.size() >= lim) { buffer.getMessage().append("(message truncated to " + lim + " bytes)\n"); } } try { String encoding = (String)message.get(Message.ENCODING); writePayload(buffer.getPayload(), cos, encoding, ct); } catch (Exception ex) { //ignore } log(logger, formatLoggingMessage(buffer)); try { //empty out the cache cos.lockOutputStream(); cos.resetOut(null, false); } catch (Exception ex) { //ignore } message.setContent(OutputStream.class, origStream); } } @Override protected Logger getLogger() { return LOG; } }