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(final 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 (final 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(final LogEvent event) {
056            return encoder.getBytes(toSerializable(event));
057        }
058    
059        /**
060         * @return The default content type for Strings.
061         */
062        public String getContentType() {
063            return "text/plain";
064        }
065    
066        protected Charset getCharset() {
067            return charset;
068        }
069    
070        /**
071         * Encoder interface to support Java 5 and Java 6+.
072         */
073        private interface StringEncoder {
074    
075            byte[] getBytes(String str);
076        }
077    
078        /**
079         * JDK 6 or greater.
080         */
081        private class ClassEncoder implements StringEncoder {
082            public byte[] getBytes(final String str) {
083                return str.getBytes(charset);
084            }
085        }
086    
087        /**
088         * JDK 5.
089         */
090        private class NameEncoder implements StringEncoder {
091            public byte[] getBytes(final String str) {
092                try {
093                    return str.getBytes(charset.name());
094                } catch (final UnsupportedEncodingException ex) {
095                    // This shouldn't ever happen since an invalid Charset would never have been created.
096                    return str.getBytes();
097                }
098            }
099        }
100    }