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