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.message;
018
019 import java.io.Serializable;
020
021 /**
022 * The StructuredData identifier.
023 */
024 public class StructuredDataId implements Serializable {
025
026 /**
027 * RFC 5424 Time Quality.
028 */
029 public static final StructuredDataId TIME_QUALITY = new StructuredDataId("timeQuality", null,
030 new String[]{"tzKnown", "isSynced", "syncAccuracy"});
031 /**
032 * RFC 5424 Origin.
033 */
034 public static final StructuredDataId ORIGIN = new StructuredDataId("origin", null,
035 new String[]{"ip", "enterpriseId", "software", "swVersion"});
036 /**
037 * RFC 5424 Meta.
038 */
039 public static final StructuredDataId META = new StructuredDataId("meta", null,
040 new String[]{"sequenceId", "sysUpTime", "language"});
041
042 /**
043 * Reserved enterprise number.
044 */
045 public static final int RESERVED = -1;
046
047 private static final long serialVersionUID = 9031746276396249990L;
048 private static final int MAX_LENGTH = 32;
049
050 private final String name;
051 private final int enterpriseNumber;
052 private final String[] required;
053 private final String[] optional;
054
055
056 protected StructuredDataId(final String name, final String[] required, final String[] optional) {
057 int index = -1;
058 if (name != null) {
059 if (name.length() > MAX_LENGTH) {
060 throw new IllegalArgumentException(String.format("Length of id %s exceeds maximum of %d characters",
061 name, MAX_LENGTH));
062 }
063 index = name.indexOf("@");
064 }
065
066 if (index > 0) {
067 this.name = name.substring(0, index);
068 this.enterpriseNumber = Integer.parseInt(name.substring(index + 1));
069 } else {
070 this.name = name;
071 this.enterpriseNumber = RESERVED;
072 }
073 this.required = required;
074 this.optional = optional;
075 }
076
077 /**
078 * A Constructor that helps conformance to RFC 5424.
079 *
080 * @param name The name portion of the id.
081 * @param enterpriseNumber The enterprise number.
082 * @param required The list of keys that are required for this id.
083 * @param optional The list of keys that are optional for this id.
084 */
085 public StructuredDataId(final String name, final int enterpriseNumber, final String[] required,
086 final String[] optional) {
087 if (name == null) {
088 throw new IllegalArgumentException("No structured id name was supplied");
089 }
090 if (name.contains("@")) {
091 throw new IllegalArgumentException("Structured id name cannot contain an '@");
092 }
093 if (enterpriseNumber <= 0) {
094 throw new IllegalArgumentException("No enterprise number was supplied");
095 }
096 this.name = name;
097 this.enterpriseNumber = enterpriseNumber;
098 final String id = enterpriseNumber < 0 ? name : name + "@" + enterpriseNumber;
099 if (id.length() > MAX_LENGTH) {
100 throw new IllegalArgumentException("Length of id exceeds maximum of 32 characters: " + id);
101 }
102 this.required = required;
103 this.optional = optional;
104 }
105
106 /**
107 * Creates an id using another id to supply default values.
108 * @param id The original StructuredDataId.
109 * @return the new StructuredDataId.
110 */
111 public StructuredDataId makeId(final StructuredDataId id) {
112 if (id == null) {
113 return this;
114 }
115 return makeId(id.getName(), id.getEnterpriseNumber());
116 }
117
118 /**
119 * Creates an id based on the current id.
120 * @param defaultId The default id to use if this StructuredDataId doesn't have a name.
121 * @param enterpriseNumber The enterprise number.
122 * @return a StructuredDataId.
123 */
124 public StructuredDataId makeId(final String defaultId, final int enterpriseNumber) {
125 String id;
126 String[] req;
127 String[] opt;
128 if (enterpriseNumber <= 0) {
129 return this;
130 }
131 if (this.name != null) {
132 id = this.name;
133 req = this.required;
134 opt = this.optional;
135 } else {
136 id = defaultId;
137 req = null;
138 opt = null;
139 }
140
141 return new StructuredDataId(id, enterpriseNumber, req, opt);
142 }
143
144 /**
145 * Returns a list of required keys.
146 * @return a List of required keys or null if none have been provided.
147 */
148 public String[] getRequired() {
149 return required;
150 }
151
152 /**
153 * Returns a list of optional keys.
154 * @return a List of optional keys or null if none have been provided.
155 */
156 public String[] getOptional() {
157 return optional;
158 }
159
160 /**
161 * Returns the StructuredDataId name.
162 * @return the StructuredDataId name.
163 */
164 public String getName() {
165 return name;
166 }
167
168 /**
169 * Returns the enterprise number.
170 * @return the enterprise number.
171 */
172 public int getEnterpriseNumber() {
173 return enterpriseNumber;
174 }
175
176 /**
177 * Indicates if the id is reserved.
178 * @return true if the id uses the reserved enterprise number, false otherwise.
179 */
180 public boolean isReserved() {
181 return enterpriseNumber <= 0;
182 }
183
184 @Override
185 public String toString() {
186 return isReserved() ? name : name + "@" + enterpriseNumber;
187 }
188 }