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