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.message;
18  
19  import java.io.Serializable;
20  
21  import org.apache.logging.log4j.util.Strings;
22  
23  /**
24   * The StructuredData identifier.
25   */
26  public class StructuredDataId implements Serializable {
27  
28      private static final String AT = "@";
29  
30      /**
31       * RFC 5424 Time Quality.
32       */
33      public static final StructuredDataId TIME_QUALITY = new StructuredDataId("timeQuality", null,
34          new String[]{"tzKnown", "isSynced", "syncAccuracy"});
35  
36      /**
37       * RFC 5424 Origin.
38       */
39      public static final StructuredDataId ORIGIN = new StructuredDataId("origin", null,
40          new String[]{"ip", "enterpriseId", "software", "swVersion"});
41  
42      /**
43       * RFC 5424 Meta.
44       */
45      public static final StructuredDataId META = new StructuredDataId("meta", null,
46          new String[]{"sequenceId", "sysUpTime", "language"});
47  
48      /**
49       * Reserved enterprise number.
50       */
51      public static final int RESERVED = -1;
52  
53      private static final long serialVersionUID = 9031746276396249990L;
54      private static final int MAX_LENGTH = 32;
55  
56      private final String name;
57      private final int enterpriseNumber;
58      private final String[] required;
59      private final String[] optional;
60  
61  
62      protected StructuredDataId(final String name, final String[] required, final String[] optional) {
63          int index = -1;
64          if (name != null) {
65              if (name.length() > MAX_LENGTH) {
66                  throw new IllegalArgumentException(String.format("Length of id %s exceeds maximum of %d characters",
67                          name, MAX_LENGTH));
68              }
69              index = name.indexOf(AT);
70          }
71  
72          if (index > 0) {
73              this.name = name.substring(0, index);
74              this.enterpriseNumber = Integer.parseInt(name.substring(index + 1));
75          } else {
76              this.name = name;
77              this.enterpriseNumber = RESERVED;
78          }
79          this.required = required;
80          this.optional = optional;
81      }
82  
83      /**
84       * A Constructor that helps conformance to RFC 5424.
85       *
86       * @param name             The name portion of the id.
87       * @param enterpriseNumber The enterprise number.
88       * @param required         The list of keys that are required for this id.
89       * @param optional         The list of keys that are optional for this id.
90       */
91      public StructuredDataId(final String name, final int enterpriseNumber, final String[] required,
92                              final String[] optional) {
93          if (name == null) {
94              throw new IllegalArgumentException("No structured id name was supplied");
95          }
96          if (name.contains(AT)) {
97              throw new IllegalArgumentException("Structured id name cannot contain an " + Strings.quote(AT));
98          }
99          if (enterpriseNumber <= 0) {
100             throw new IllegalArgumentException("No enterprise number was supplied");
101         }
102         this.name = name;
103         this.enterpriseNumber = enterpriseNumber;
104         final String id = enterpriseNumber < 0 ? name : name + AT + enterpriseNumber;
105         if (id.length() > MAX_LENGTH) {
106             throw new IllegalArgumentException("Length of id exceeds maximum of 32 characters: " + id);
107         }
108         this.required = required;
109         this.optional = optional;
110     }
111 
112     /**
113      * Creates an id using another id to supply default values.
114      * @param id The original StructuredDataId.
115      * @return the new StructuredDataId.
116      */
117     public StructuredDataId makeId(final StructuredDataId id) {
118         if (id == null) {
119             return this;
120         }
121         return makeId(id.getName(), id.getEnterpriseNumber());
122     }
123 
124     /**
125      * Creates an id based on the current id.
126      * @param defaultId The default id to use if this StructuredDataId doesn't have a name.
127      * @param enterpriseNumber The enterprise number.
128      * @return a StructuredDataId.
129      */
130     public StructuredDataId makeId(final String defaultId, final int enterpriseNumber) {
131         String id;
132         String[] req;
133         String[] opt;
134         if (enterpriseNumber <= 0) {
135             return this;
136         }
137         if (this.name != null) {
138             id = this.name;
139             req = this.required;
140             opt = this.optional;
141         } else {
142             id = defaultId;
143             req = null;
144             opt = null;
145         }
146 
147         return new StructuredDataId(id, enterpriseNumber, req, opt);
148     }
149 
150     /**
151      * Returns a list of required keys.
152      * @return a List of required keys or null if none have been provided.
153      */
154     public String[] getRequired() {
155         return required;
156     }
157 
158     /**
159      * Returns a list of optional keys.
160      * @return a List of optional keys or null if none have been provided.
161      */
162     public String[] getOptional() {
163         return optional;
164     }
165 
166     /**
167      * Returns the StructuredDataId name.
168      * @return the StructuredDataId name.
169      */
170     public String getName() {
171         return name;
172     }
173 
174     /**
175      * Returns the enterprise number.
176      * @return the enterprise number.
177      */
178     public int getEnterpriseNumber() {
179         return enterpriseNumber;
180     }
181 
182     /**
183      * Indicates if the id is reserved.
184      * @return true if the id uses the reserved enterprise number, false otherwise.
185      */
186     public boolean isReserved() {
187         return enterpriseNumber <= 0;
188     }
189 
190     @Override
191     public String toString() {
192         return isReserved() ? name : name + AT + enterpriseNumber;
193     }
194 }