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        this.entryText = entryText;
049        this.exitText = exitText;
050    }
051
052    private static class AbstractFlowMessage implements FlowMessage {
053
054        private static final long serialVersionUID = 1L;
055        private final Message message;
056        private final String text;
057
058        AbstractFlowMessage(final String text, final Message message) {
059            this.message = message;
060            this.text = text;
061        }
062
063        @Override
064        public String getFormattedMessage() {
065            if (message != null) {
066                return text + " " + message.getFormattedMessage();
067            }
068            return text;
069        }
070
071        @Override
072        public String getFormat() {
073            if (message != null) {
074                return text + ": " + message.getFormat();
075            }
076            return text;
077        }
078
079        @Override
080        public Object[] getParameters() {
081            if (message != null) {
082                return message.getParameters();
083            }
084            return null;
085        }
086
087        @Override
088        public Throwable getThrowable() {
089            if (message != null) {
090                return message.getThrowable();
091            }
092            return null;
093        }
094
095        @Override
096        public Message getMessage() {
097            return message;
098        }
099
100        @Override
101        public String getText() {
102            return text;
103        }
104    }
105
106    private static final class SimpleEntryMessage extends AbstractFlowMessage implements EntryMessage {
107
108        private static final long serialVersionUID = 1L;
109
110        SimpleEntryMessage(final String entryText, final Message message) {
111            super(entryText, message);
112        }
113
114    }
115
116    private static final class SimpleExitMessage extends AbstractFlowMessage implements ExitMessage {
117
118        private static final long serialVersionUID = 1L;
119
120        private final Object result;
121        private final boolean isVoid;
122
123        SimpleExitMessage(final String exitText, final EntryMessage message) {
124            super(exitText, message.getMessage());
125            this.result = null;
126            isVoid = true;
127        }
128
129        SimpleExitMessage(final String exitText, final Object result, final EntryMessage message) {
130            super(exitText, message.getMessage());
131            this.result = result;
132            isVoid = false;
133        }
134
135        SimpleExitMessage(final String exitText, final Object result, final Message message) {
136            super(exitText, message);
137            this.result = result;
138            isVoid = false;
139        }
140
141        @Override
142        public String getFormattedMessage() {
143            final String formattedMessage = super.getFormattedMessage();
144            if (isVoid) {
145                return formattedMessage;
146            }
147            return formattedMessage + ": " + result;
148        }
149    }
150
151    /**
152     * Gets the entry text.
153     * @return the entry text.
154     */
155    public String getEntryText() {
156        return entryText;
157    }
158
159    /**
160     * Gets the exit text.
161     * @return the exit text.
162     */
163    public String getExitText() {
164        return exitText;
165    }
166
167    /*
168     * (non-Javadoc)
169     *
170     * @see org.apache.logging.log4j.message.MessageFactory#newEntryMessage(org.apache.logging.log4j.message.Message)
171     */
172    @Override
173    public EntryMessage newEntryMessage(final Message message) {
174        return new SimpleEntryMessage(entryText, makeImmutable(message));
175    }
176
177    private Message makeImmutable(final Message message) {
178        if (!(message instanceof ReusableMessage)) {
179            return message;
180        }
181        return new SimpleMessage(message.getFormattedMessage());
182    }
183
184    /*
185     * (non-Javadoc)
186     *
187     * @see org.apache.logging.log4j.message.FlowMessageFactory#newExitMessage(org.apache.logging.log4j.message.EntryMessage)
188     */
189    @Override
190    public ExitMessage newExitMessage(final EntryMessage message) {
191        return new SimpleExitMessage(exitText, message);
192    }
193
194    /*
195     * (non-Javadoc)
196     *
197     * @see org.apache.logging.log4j.message.FlowMessageFactory#newExitMessage(java.lang.Object, org.apache.logging.log4j.message.EntryMessage)
198     */
199    @Override
200    public ExitMessage newExitMessage(final Object result, final EntryMessage message) {
201        return new SimpleExitMessage(exitText, result, message);
202    }
203
204    /*
205     * (non-Javadoc)
206     *
207     * @see org.apache.logging.log4j.message.FlowMessageFactory#newExitMessage(java.lang.Object, org.apache.logging.log4j.message.Message)
208     */
209    @Override
210    public ExitMessage newExitMessage(final Object result, final Message message) {
211        return new SimpleExitMessage(exitText, result, message);
212    }
213}