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 021import org.apache.logging.log4j.util.Strings; 022 023/** 024 * The StructuredData identifier. 025 */ 026public class StructuredDataId implements Serializable { 027 028 private static final String AT = "@"; 029 030 /** 031 * RFC 5424 Time Quality. 032 */ 033 public static final StructuredDataId TIME_QUALITY = new StructuredDataId("timeQuality", null, 034 new String[]{"tzKnown", "isSynced", "syncAccuracy"}); 035 036 /** 037 * RFC 5424 Origin. 038 */ 039 public static final StructuredDataId ORIGIN = new StructuredDataId("origin", null, 040 new String[]{"ip", "enterpriseId", "software", "swVersion"}); 041 042 /** 043 * RFC 5424 Meta. 044 */ 045 public static final StructuredDataId META = new StructuredDataId("meta", null, 046 new String[]{"sequenceId", "sysUpTime", "language"}); 047 048 /** 049 * Reserved enterprise number. 050 */ 051 public static final int RESERVED = -1; 052 053 private static final long serialVersionUID = 9031746276396249990L; 054 private static final int MAX_LENGTH = 32; 055 056 private final String name; 057 private final int enterpriseNumber; 058 private final String[] required; 059 private final String[] optional; 060 061 062 protected StructuredDataId(final String name, final String[] required, final String[] optional) { 063 int index = -1; 064 if (name != null) { 065 if (name.length() > MAX_LENGTH) { 066 throw new IllegalArgumentException(String.format("Length of id %s exceeds maximum of %d characters", 067 name, MAX_LENGTH)); 068 } 069 index = name.indexOf(AT); 070 } 071 072 if (index > 0) { 073 this.name = name.substring(0, index); 074 this.enterpriseNumber = Integer.parseInt(name.substring(index + 1)); 075 } else { 076 this.name = name; 077 this.enterpriseNumber = RESERVED; 078 } 079 this.required = required; 080 this.optional = optional; 081 } 082 083 /** 084 * A Constructor that helps conformance to RFC 5424. 085 * 086 * @param name The name portion of the id. 087 * @param enterpriseNumber The enterprise number. 088 * @param required The list of keys that are required for this id. 089 * @param optional The list of keys that are optional for this id. 090 */ 091 public StructuredDataId(final String name, final int enterpriseNumber, final String[] required, 092 final String[] optional) { 093 if (name == null) { 094 throw new IllegalArgumentException("No structured id name was supplied"); 095 } 096 if (name.contains(AT)) { 097 throw new IllegalArgumentException("Structured id name cannot contain an " + Strings.quote(AT)); 098 } 099 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}