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.appender.db.jpa;
018    
019    import java.util.Map;
020    
021    import javax.persistence.Basic;
022    import javax.persistence.Convert;
023    import javax.persistence.MappedSuperclass;
024    import javax.persistence.Transient;
025    
026    import org.apache.logging.log4j.Level;
027    import org.apache.logging.log4j.Marker;
028    import org.apache.logging.log4j.ThreadContext;
029    import org.apache.logging.log4j.core.LogEvent;
030    import org.apache.logging.log4j.core.appender.db.jpa.converter.ContextMapAttributeConverter;
031    import org.apache.logging.log4j.core.appender.db.jpa.converter.ContextStackAttributeConverter;
032    import org.apache.logging.log4j.core.appender.db.jpa.converter.LevelAttributeConverter;
033    import org.apache.logging.log4j.core.appender.db.jpa.converter.MarkerAttributeConverter;
034    import org.apache.logging.log4j.core.appender.db.jpa.converter.MessageAttributeConverter;
035    import org.apache.logging.log4j.core.appender.db.jpa.converter.StackTraceElementAttributeConverter;
036    import org.apache.logging.log4j.core.appender.db.jpa.converter.ThrowableAttributeConverter;
037    import org.apache.logging.log4j.core.impl.ThrowableProxy;
038    import org.apache.logging.log4j.message.Message;
039    
040    /**
041     * Users of the JPA appender may want to extend this class instead of {@link AbstractLogEventWrapperEntity}. This class
042     * implements all of the required mutator methods but does not implement a mutable entity ID property. In order to
043     * create an entity based on this class, you need only create two constructors matching this class's
044     * constructors, annotate the class {@link javax.persistence.Entity @Entity} and {@link javax.persistence.Table @Table},
045     * and implement the fully mutable entity ID property annotated with {@link javax.persistence.Id @Id} and
046     * {@link javax.persistence.GeneratedValue @GeneratedValue} to tell the JPA provider how to calculate an ID for new
047     * events.<br>
048     * <br>
049     * The attributes in this entity use the default column names (which, according to the JPA spec, are the property names
050     * minus the "get" and "set" from the accessors/mutators). If you want to use different column names for one or more
051     * columns, override the necessary accessor methods defined in this class with the same annotations plus the
052     * {@link javax.persistence.Column @Column} annotation to specify the column name.<br>
053     * <br>
054     * The {@link #getContextMap()} and {@link #getContextStack()} attributes in this entity use the
055     * {@link ContextMapAttributeConverter} and {@link ContextStackAttributeConverter}, respectively. These convert the
056     * properties to simple strings that cannot be converted back to the properties. If you wish to instead convert these to
057     * a reversible JSON string, override these attributes with the same annotations but use the
058     * {@link org.apache.logging.log4j.core.appender.db.jpa.converter.ContextMapJsonAttributeConverter} and
059     * {@link org.apache.logging.log4j.core.appender.db.jpa.converter.ContextStackJsonAttributeConverter} instead.<br>
060     * <br>
061     * All other attributes in this entity use reversible converters that can be used for both persistence and retrieval. If
062     * there are any attributes you do not want persistent, you should override their accessor methods and annotate with
063     * {@link javax.persistence.Transient @Transient}.
064     *
065     * @see AbstractLogEventWrapperEntity
066     */
067    @MappedSuperclass
068    public abstract class BasicLogEventEntity extends AbstractLogEventWrapperEntity {
069        private static final long serialVersionUID = 1L;
070    
071        /**
072         * Instantiates this base class. All concrete implementations must have a constructor matching this constructor's
073         * signature. The no-argument constructor is required for a standards-compliant JPA provider to accept this as an
074         * entity.
075         */
076        @SuppressWarnings("unused")
077        public BasicLogEventEntity() {
078            super();
079        }
080    
081        /**
082         * Instantiates this base class. All concrete implementations must have a constructor matching this constructor's
083         * signature. This constructor is used for wrapping this entity around a logged event.
084         *
085         * @param wrappedEvent The underlying event from which information is obtained.
086         */
087        public BasicLogEventEntity(final LogEvent wrappedEvent) {
088            super(wrappedEvent);
089        }
090    
091        /**
092         * Gets the level. Annotated with {@code @Basic} and {@code @Enumerated(EnumType.STRING)}.
093         *
094         * @return the level.
095         */
096        @Override
097        @Convert(converter = LevelAttributeConverter.class)
098        public Level getLevel() {
099            return this.getWrappedEvent().getLevel();
100        }
101    
102        /**
103         * Gets the logger name. Annotated with {@code @Basic}.
104         *
105         * @return the logger name.
106         */
107        @Override
108        @Basic
109        public String getLoggerName() {
110            return this.getWrappedEvent().getLoggerName();
111        }
112    
113        /**
114         * Gets the source location information. Annotated with
115         * {@code @Convert(converter = StackTraceElementAttributeConverter.class)}.
116         *
117         * @return the source location information.
118         * @see StackTraceElementAttributeConverter
119         */
120        @Override
121        @Convert(converter = StackTraceElementAttributeConverter.class)
122        public StackTraceElement getSource() {
123            return this.getWrappedEvent().getSource();
124        }
125    
126        /**
127         * Gets the message. Annotated with {@code @Convert(converter = MessageAttributeConverter.class)}.
128         *
129         * @return the message.
130         * @see MessageAttributeConverter
131         */
132        @Override
133        @Convert(converter = MessageAttributeConverter.class)
134        public Message getMessage() {
135            return this.getWrappedEvent().getMessage();
136        }
137    
138        /**
139         * Gets the marker. Annotated with {@code @Convert(converter = MarkerAttributeConverter.class)}.
140         *
141         * @return the marker.
142         * @see MarkerAttributeConverter
143         */
144        @Override
145        @Convert(converter = MarkerAttributeConverter.class)
146        public Marker getMarker() {
147            return this.getWrappedEvent().getMarker();
148        }
149    
150        /**
151         * Gets the thread name. Annotated with {@code @Basic}.
152         *
153         * @return the thread name.
154         */
155        @Override
156        @Basic
157        public String getThreadName() {
158            return this.getWrappedEvent().getThreadName();
159        }
160    
161        /**
162         * Gets the number of milliseconds since JVM launch. Annotated with {@code @Basic}.
163         *
164         * @return the number of milliseconds since JVM launch.
165         */
166        @Override
167        @Basic
168        public long getTimeMillis() {
169            return this.getWrappedEvent().getTimeMillis();
170        }
171    
172        /**
173         * Gets the exception logged. Annotated with {@code @Convert(converter = ThrowableAttributeConverter.class)}.
174         *
175         * @return the exception logged.
176         * @see ThrowableAttributeConverter
177         */
178        @Override
179        @Convert(converter = ThrowableAttributeConverter.class)
180        public Throwable getThrown() {
181            return this.getWrappedEvent().getThrown();
182        }
183    
184        /**
185         * Gets the exception logged. Annotated with {@code @Convert(converter = ThrowableAttributeConverter.class)}.
186         *
187         * @return the exception logged.
188         * @see ThrowableAttributeConverter
189         */
190        @Override
191        @Transient
192        public ThrowableProxy getThrownProxy() {
193            return this.getWrappedEvent().getThrownProxy();
194        }
195    
196        /**
197         * Gets the context map. Annotated with {@code @Convert(converter = ContextMapAttributeConverter.class)}.
198         *
199         * @return the context map.
200         * @see ContextMapAttributeConverter
201         * @see org.apache.logging.log4j.core.appender.db.jpa.converter.ContextMapJsonAttributeConverter
202         */
203        @Override
204        @Convert(converter = ContextMapAttributeConverter.class)
205        public Map<String, String> getContextMap() {
206            return this.getWrappedEvent().getContextMap();
207        }
208    
209        /**
210         * Gets the context stack. Annotated with {@code @Convert(converter = ContextStackAttributeConverter.class)}.
211         *
212         * @return the context stack.
213         * @see ContextStackAttributeConverter
214         * @see org.apache.logging.log4j.core.appender.db.jpa.converter.ContextStackJsonAttributeConverter
215         */
216        @Override
217        @Convert(converter = ContextStackAttributeConverter.class)
218        public ThreadContext.ContextStack getContextStack() {
219            return this.getWrappedEvent().getContextStack();
220        }
221    
222        /**
223         * Gets the fully qualified class name of the caller of the logger API. Annotated with {@code @Basic}.
224         *
225         * @return the fully qualified class name of the caller of the logger API.
226         */
227        @Override
228        @Basic
229        public String getLoggerFqcn() {
230            return this.getWrappedEvent().getLoggerFqcn();
231        }
232    }