001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache license, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the license for the specific language governing permissions and
015 * limitations under the license.
016 */
017package org.apache.logging.log4j.message;
018
019import java.io.Serializable;
020
021/**
022 * Default factory for flow messages.
023 *
024 * @since 2.6
025 */
026public class DefaultFlowMessageFactory implements FlowMessageFactory, Serializable {
027
028    private static final String EXIT_DEFAULT_PREFIX = "Exit";
029    private static final String ENTRY_DEFAULT_PREFIX = "Enter";
030    private static final long serialVersionUID = 8578655591131397576L;
031
032    private final String entryText;
033    private final String exitText;
034
035    /**
036     * Constructs a message factory with {@code "Enter"} and {@code "Exit"} as the default flow strings.
037     */
038    public DefaultFlowMessageFactory() {
039        this(ENTRY_DEFAULT_PREFIX, EXIT_DEFAULT_PREFIX);
040    }
041
042    /**
043     * Constructs a message factory with the given entry and exit strings.
044     * @param entryText the text to use for trace entry, like {@code "Enter"}.
045     * @param exitText the text to use for trace exit, like {@code "Exit"}.
046     */
047    public DefaultFlowMessageFactory(final String entryText, final String exitText) {
048        super();
049        this.entryText = entryText;
050        this.exitText = exitText;
051    }
052
053    private static class AbstractFlowMessage implements FlowMessage {
054
055        private static final long serialVersionUID = 1L;
056        private final Message message;
057        private final String text;
058
059        AbstractFlowMessage(final String text, final Message message) {
060            this.message = message;
061            this.text = text;
062        }
063
064        @Override
065        public String getFormattedMessage() {
066            if (message != null) {
067                return text + " " + message.getFormattedMessage();
068            }
069            return text;
070        }
071
072        @Override
073        public String getFormat() {
074            if (message != null) {
075                return text + ": " + message.getFormat();
076            }
077            return text;
078        }
079
080        @Override
081        public Object[] getParameters() {
082            if (message != null) {
083                return message.getParameters();
084            }
085            return null;
086        }
087
088        @Override
089        public Throwable getThrowable() {
090            if (message != null) {
091                return message.getThrowable();
092            }
093            return null;
094        }
095
096        @Override
097        public Message getMessage() {
098            return message;
099        }
100
101        @Override
102        public String getText() {
103            return text;
104        }
105    }
106
107    private static final class SimpleEntryMessage extends AbstractFlowMessage implements EntryMessage {
108
109        private static final long serialVersionUID = 1L;
110
111        SimpleEntryMessage(final String entryText, final Message message) {
112            super(entryText, message);
113        }
114
115    }
116
117    private static final class SimpleExitMessage extends AbstractFlowMessage implements ExitMessage {
118
119        private static final long serialVersionUID = 1L;
120
121        private final Object result;
122        private final boolean isVoid;
123
124        SimpleExitMessage(final String exitText, final EntryMessage message) {
125            super(exitText, message.getMessage());
126            this.result = null;
127            isVoid = true;
128        }
129
130        SimpleExitMessage(final String exitText, final Object result, final EntryMessage message) {
131            super(exitText, message.getMessage());
132            this.result = result;
133            isVoid = false;
134        }
135
136        SimpleExitMessage(final String exitText, final Object result, final Message message) {
137            super(exitText, message);
138            this.result = result;
139            isVoid = false;
140        }
141
142        @Override
143        public String getFormattedMessage() {
144            final String formattedMessage = super.getFormattedMessage();
145            if (isVoid) {
146                return formattedMessage;
147            }
148            return formattedMessage + ": " + result;
149        }
150    }
151
152    /**
153     * Gets the entry text.
154     * @return the entry text.
155     */
156    public String getEntryText() {
157        return entryText;
158    }
159
160    /**
161     * Gets the exit text.
162     * @return the exit text.
163     */
164    public String getExitText() {
165        return exitText;
166    }
167
168    /*
169     * (non-Javadoc)
170     *
171     * @see org.apache.logging.log4j.message.MessageFactory#newEntryMessage(org.apache.logging.log4j.message.Message)
172     */
173    @Override
174    public EntryMessage newEntryMessage(final Message message) {
175        return new SimpleEntryMessage(entryText, makeImmutable(message));
176    }
177
178    private Message makeImmutable(final Message message) {
179        if (!(message instanceof ReusableMessage)) {
180            return message;
181        }
182        return new SimpleMessage(message.getFormattedMessage());
183    }
184
185    /*
186     * (non-Javadoc)
187     *
188     * @see org.apache.logging.log4j.message.FlowMessageFactory#newExitMessage(org.apache.logging.log4j.message.EntryMessage)
189     */
190    @Override
191    public ExitMessage newExitMessage(final EntryMessage message) {
192        return new SimpleExitMessage(exitText, message);
193    }
194
195    /*
196     * (non-Javadoc)
197     *
198     * @see org.apache.logging.log4j.message.FlowMessageFactory#newExitMessage(java.lang.Object, org.apache.logging.log4j.message.EntryMessage)
199     */
200    @Override
201    public ExitMessage newExitMessage(final Object result, final EntryMessage message) {
202        return new SimpleExitMessage(exitText, result, message);
203    }
204
205    /*
206     * (non-Javadoc)
207     *
208     * @see org.apache.logging.log4j.message.FlowMessageFactory#newExitMessage(java.lang.Object, org.apache.logging.log4j.message.Message)
209     */
210    @Override
211    public ExitMessage newExitMessage(final Object result, final Message message) {
212        return new SimpleExitMessage(exitText, result, message);
213    }
214}