001/*
002 * Copyright 2002-2019 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.test.web.servlet.result;
018
019import java.io.OutputStream;
020import java.io.PrintWriter;
021import java.io.StringWriter;
022import java.io.Writer;
023
024import org.apache.commons.logging.Log;
025import org.apache.commons.logging.LogFactory;
026
027import org.springframework.lang.Nullable;
028import org.springframework.test.web.servlet.MvcResult;
029import org.springframework.test.web.servlet.ResultHandler;
030import org.springframework.util.CollectionUtils;
031
032/**
033 * Static factory methods for {@link ResultHandler}-based result actions.
034 *
035 * <h3>Eclipse Users</h3>
036 * <p>Consider adding this class as a Java editor favorite. To navigate to
037 * this setting, open the Preferences and type "favorites".
038 *
039 * @author Rossen Stoyanchev
040 * @author Sam Brannen
041 * @since 3.2
042 */
043public abstract class MockMvcResultHandlers {
044
045        private static final Log logger = LogFactory.getLog("org.springframework.test.web.servlet.result");
046
047
048        /**
049         * Log {@link MvcResult} details as a {@code DEBUG} log message via
050         * Apache Commons Logging using the log category
051         * {@code org.springframework.test.web.servlet.result}.
052         * @since 4.2
053         * @see #print()
054         * @see #print(OutputStream)
055         * @see #print(Writer)
056         */
057        public static ResultHandler log() {
058                return new LoggingResultHandler();
059        }
060
061        /**
062         * Print {@link MvcResult} details to the "standard" output stream.
063         * @see System#out
064         * @see #print(OutputStream)
065         * @see #print(Writer)
066         * @see #log()
067         */
068        public static ResultHandler print() {
069                return print(System.out);
070        }
071
072        /**
073         * Print {@link MvcResult} details to the supplied {@link OutputStream}.
074         * @since 4.2
075         * @see #print()
076         * @see #print(Writer)
077         * @see #log()
078         */
079        public static ResultHandler print(OutputStream stream) {
080                return new PrintWriterPrintingResultHandler(new PrintWriter(stream, true));
081        }
082
083        /**
084         * Print {@link MvcResult} details to the supplied {@link Writer}.
085         * @since 4.2
086         * @see #print()
087         * @see #print(OutputStream)
088         * @see #log()
089         */
090        public static ResultHandler print(Writer writer) {
091                return new PrintWriterPrintingResultHandler(new PrintWriter(writer, true));
092        }
093
094
095        /**
096         * A {@link PrintingResultHandler} that writes to a {@link PrintWriter}.
097         */
098        private static class PrintWriterPrintingResultHandler extends PrintingResultHandler {
099
100                public PrintWriterPrintingResultHandler(PrintWriter writer) {
101                        super(new ResultValuePrinter() {
102                                @Override
103                                public void printHeading(String heading) {
104                                        writer.println();
105                                        writer.println(String.format("%s:", heading));
106                                }
107                                @Override
108                                public void printValue(String label, @Nullable Object value) {
109                                        if (value != null && value.getClass().isArray()) {
110                                                value = CollectionUtils.arrayToList(value);
111                                        }
112                                        writer.println(String.format("%17s = %s", label, value));
113                                }
114                        });
115                }
116        }
117
118
119        /**
120         * A {@link ResultHandler} that logs {@link MvcResult} details at
121         * {@code DEBUG} level via Apache Commons Logging.
122         *
123         * <p>Delegates to a {@link PrintWriterPrintingResultHandler} for
124         * building the log message.
125         *
126         * @since 4.2
127         */
128        private static class LoggingResultHandler implements ResultHandler {
129
130                @Override
131                public void handle(MvcResult result) throws Exception {
132                        if (logger.isDebugEnabled()) {
133                                StringWriter stringWriter = new StringWriter();
134                                ResultHandler printingResultHandler =
135                                                new PrintWriterPrintingResultHandler(new PrintWriter(stringWriter));
136                                printingResultHandler.handle(result);
137                                logger.debug("MvcResult details:\n" + stringWriter);
138                        }
139                }
140        }
141
142}