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