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     */
017    package org.apache.logging.log4j.core.layout;
018    
019    import org.apache.logging.log4j.core.LogEvent;
020    
021    import java.io.UnsupportedEncodingException;
022    import java.nio.charset.Charset;
023    
024    /**
025     * Base class for Layouts that result in a String.
026     */
027    public abstract class AbstractStringLayout extends LayoutBase<String> {
028    
029        /**
030         * The charset of the formatted message.
031         */
032        private Charset charset;
033    
034        private final StringEncoder encoder;
035    
036        protected AbstractStringLayout(Charset charset) {
037            this.charset = charset;
038            boolean useClass = false;
039            try {
040                Class[] types = new Class[] {Charset.class};
041                if (String.class.getMethod("getBytes", types) != null) {
042                    useClass = true;
043                }
044    
045            } catch (NoSuchMethodException ex) {
046                // Not JDK 6 or greater.
047            }
048            encoder = useClass ? new ClassEncoder() : new NameEncoder();
049        }
050    
051        /**
052         * Format the Log Event.
053         * @param event The Log Event.
054         * @return The formatted event as a byte array.
055         */
056        public byte[] format(LogEvent event) {
057            return encoder.getBytes(formatAs(event));
058        }
059    
060        protected Charset getCharset() {
061            return charset;
062        }
063    
064        /**
065         * Encoder interface to support Java 5 and Java 6+.
066         */
067        private interface StringEncoder {
068    
069            byte[] getBytes(String str);
070        }
071    
072        /**
073         * JDK 6 or greater.
074         */
075        private class ClassEncoder implements StringEncoder {
076            public byte[] getBytes(String str) {
077                return str.getBytes(charset);
078            }
079        }
080    
081        /**
082         * JDK 5.
083         */
084        private class NameEncoder implements StringEncoder {
085            public byte[] getBytes(String str) {
086                try {
087                    return str.getBytes(charset.name());
088                } catch (UnsupportedEncodingException ex) {
089                    // This shouldn't ever happen since an invalid Charset would never have been created.
090                    return str.getBytes();
091                }
092            }
093        }
094    }