View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements. See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache license, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License. You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the license for the specific language governing permissions and
15   * limitations under the license.
16   */
17  package org.apache.logging.log4j.core.appender.db.jpa.converter;
18  
19  import javax.persistence.AttributeConverter;
20  import javax.persistence.Converter;
21  
22  import org.apache.logging.log4j.util.Strings;
23  
24  /**
25   * A JPA 2.1 attribute converter for {@link StackTraceElement}s in {@link org.apache.logging.log4j.core.LogEvent}s. This
26   * converter is capable of converting both to and from {@link String}s.
27   */
28  @Converter(autoApply = false)
29  public class StackTraceElementAttributeConverter implements AttributeConverter<StackTraceElement, String> {
30      private static final int UNKNOWN_SOURCE = -1;
31  
32      private static final int NATIVE_METHOD = -2;
33  
34      @Override
35      public String convertToDatabaseColumn(final StackTraceElement element) {
36          if (element == null) {
37              return null;
38          }
39  
40          return element.toString();
41      }
42  
43      @Override
44      public StackTraceElement convertToEntityAttribute(final String s) {
45          if (Strings.isEmpty(s)) {
46              return null;
47          }
48  
49          return StackTraceElementAttributeConverter.convertString(s);
50      }
51  
52      static StackTraceElement convertString(final String s) {
53          final int open = s.indexOf("(");
54  
55          final String classMethod = s.substring(0, open);
56          final String className = classMethod.substring(0, classMethod.lastIndexOf("."));
57          final String methodName = classMethod.substring(classMethod.lastIndexOf(".") + 1);
58  
59          final String parenthesisContents = s.substring(open + 1, s.indexOf(")"));
60  
61          String fileName = null;
62          int lineNumber = UNKNOWN_SOURCE;
63          if ("Native Method".equals(parenthesisContents)) {
64              lineNumber = NATIVE_METHOD;
65          } else if (!"Unknown Source".equals(parenthesisContents)) {
66              final int colon = parenthesisContents.indexOf(":");
67              if (colon > UNKNOWN_SOURCE) {
68                  fileName = parenthesisContents.substring(0, colon);
69                  try {
70                      lineNumber = Integer.parseInt(parenthesisContents.substring(colon + 1));
71                  } catch (final NumberFormatException ignore) {
72                      // we don't care
73                  }
74              } else {
75                  fileName = parenthesisContents.substring(0);
76              }
77          }
78  
79          return new StackTraceElement(className, methodName, fileName, lineNumber);
80      }
81  }