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 18 package org.apache.log4j.helpers; 19 20 21 /** 22 * Formats messages according to very simple rules. 23 * See {@link #format(String, Object)} and 24 * {@link #format(String, Object, Object)} for more details. 25 * 26 * @author Ceki Gülcü 27 */ 28 public final class MessageFormatter { 29 /** 30 * Private formatter since all methods and members are static. 31 */ 32 private MessageFormatter() { 33 super(); 34 } 35 36 /** 37 * Start of replacement block. 38 */ 39 private static final char DELIM_START = '{'; 40 /** 41 * End of replacement block. 42 */ 43 private static final char DELIM_STOP = '}'; 44 45 /** 46 * Performs single argument substitution for the 'messagePattern' passed as 47 * parameter. 48 * <p> 49 * <p>For example, <code>MessageFormatter.format("Hi {}.", "there");</code> 50 * will return the string "Hi there.". 51 * </p> 52 * The {} pair is called the formatting element. It serves to designate the 53 * location where the argument needs to be inserted within the pattern. 54 * 55 * @param messagePattern The message pattern which will be parsed and formatted 56 * @param argument The argument to be inserted instead of the formatting element 57 * @return The formatted message 58 */ 59 public static String format(final String messagePattern, 60 final Object argument) { 61 int j = messagePattern.indexOf(DELIM_START); 62 int len = messagePattern.length(); 63 char escape = 'x'; 64 65 // if there are no { characters or { is the last character 66 // then we just return messagePattern 67 if (j == -1 || (j + 1 == len)) { 68 return messagePattern; 69 } else { 70 char delimStop = messagePattern.charAt(j + 1); 71 if (j > 0) { 72 escape = messagePattern.charAt(j - 1); 73 } 74 if ((delimStop != DELIM_STOP) || (escape == '\\')) { 75 // invalid DELIM_START/DELIM_STOP pair or espace character is 76 // present 77 return messagePattern; 78 } else { 79 String sbuf = messagePattern.substring(0, j) + 80 argument + 81 messagePattern.substring(j + 2); 82 return sbuf; 83 } 84 } 85 } 86 87 /** 88 * /** 89 * Performs a two argument substitution for the 'messagePattern' passed as 90 * parameter. 91 * <p> 92 * <p>For example, <code>MessageFormatter.format("Hi {}. My name is {}.", 93 * "there", "David");</code> will return the string 94 * "Hi there. My name is David.". 95 * </p> 96 * The '{}' pair is called a formatting element. It serves to designate the 97 * location where the arguments need to be inserted within 98 * the message pattern. 99 * 100 * @param messagePattern The message pattern which will be parsed and formatted 101 * @param arg1 The first argument to replace the first formatting element 102 * @param arg2 The second argument to replace the second formatting element 103 * @return The formatted message 104 */ 105 public static String format(final String messagePattern, 106 final Object arg1, 107 final Object arg2) { 108 int i = 0; 109 int len = messagePattern.length(); 110 111 StringBuilder sbuf = new StringBuilder(messagePattern.length() + 50); 112 113 for (int l = 0; l < 2; l++) { 114 int j = messagePattern.indexOf(DELIM_START, i); 115 116 if (j == -1 || (j + 1 == len)) { 117 // no more variables 118 if (i == 0) { // this is a simple string 119 return messagePattern; 120 } else { 121 // add the tail string which contains no variables 122 // and return the result. 123 sbuf.append(messagePattern.substring(i, 124 messagePattern.length())); 125 return sbuf.toString(); 126 } 127 } else { 128 char delimStop = messagePattern.charAt(j + 1); 129 if ((delimStop != DELIM_STOP)) { 130 // invalid DELIM_START/DELIM_STOP pair 131 sbuf.append(messagePattern.substring(i, 132 messagePattern.length())); 133 return sbuf.toString(); 134 } 135 sbuf.append(messagePattern.substring(i, j)); 136 if (l == 0) { 137 sbuf.append(arg1); 138 } else { 139 sbuf.append(arg2); 140 } 141 i = j + 2; 142 } 143 } 144 // append the characters following the second {} pair. 145 sbuf.append(messagePattern.substring(i, messagePattern.length())); 146 return sbuf.toString(); 147 } 148 }