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 }