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     * Abstract base class for Layouts that result in a String.
026     */
027    public abstract class AbstractStringLayout extends AbstractLayout<String> {
028    
029        /**
030         * The charset of the formatted message.
031         */
032        private final 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                if (String.class.getMethod("getBytes", new Class[] {Charset.class}) != null) {
041                    useClass = true;
042                }
043            } catch (NoSuchMethodException ex) {
044                // Not JDK 6 or greater.
045            }
046            encoder = useClass ? new ClassEncoder() : new NameEncoder();
047        }
048    
049        /**
050         * Formats the Log Event as a byte array.
051         *
052         * @param event The Log Event.
053         * @return The formatted event as a byte array.
054         */
055        public byte[] toByteArray(LogEvent event) {
056            return encoder.getBytes(toSerializable(event));
057        }
058    
059        protected Charset getCharset() {
060            return charset;
061        }
062    
063        /**
064         * Encoder interface to support Java 5 and Java 6+.
065         */
066        private interface StringEncoder {
067    
068            byte[] getBytes(String str);
069        }
070    
071        /**
072         * JDK 6 or greater.
073         */
074        private class ClassEncoder implements StringEncoder {
075            public byte[] getBytes(String str) {
076                return str.getBytes(charset);
077            }
078        }
079    
080        /**
081         * JDK 5.
082         */
083        private class NameEncoder implements StringEncoder {
084            public byte[] getBytes(String str) {
085                try {
086                    return str.getBytes(charset.name());
087                } catch (UnsupportedEncodingException ex) {
088                    // This shouldn't ever happen since an invalid Charset would never have been created.
089                    return str.getBytes();
090                }
091            }
092        }
093    }