/* Copyright 1996-2008 Ariba, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. $Id: //ariba/platform/util/core/ariba/util/io/TaggedStringProcessor.java#7 $ */ package ariba.util.io; import ariba.util.core.ListUtil; import ariba.util.core.FastStringBuffer; import java.util.List; /** A TaggedStringProcessor processes a string that contains "tags", i.e. substrings delimited by a special sequence of characters. For each tag it finds in the string, it calls its TagHandler with the tag string and replaces the tag string (including the delimeters) with the result. @see TagHandler @aribaapi private */ public class TaggedStringProcessor { /*----------------------------------------------------------------------- Public Constants -----------------------------------------------------------------------*/ // the tag prefix/suffix; all tags should be enclosed in this string public static final String TagDelimiter = "@@"; // the prefix/suffix for an arguments list public static final String BeginArgsChar = "("; public static final String EndArgsChar = ")"; // the arguments list separator public static final String ArgsSeparator = ","; /*----------------------------------------------------------------------- Constructors -----------------------------------------------------------------------*/ public TaggedStringProcessor (TagHandler handler) { this.handler = handler; } /*----------------------------------------------------------------------- Public Methods -----------------------------------------------------------------------*/ /** Given a line of text string, process all the tags that it find in this line. It returns the processed string. There are two flavors of processString(), one which accepts an existing FastStringBuffer and arguments List created by the caller and one which creates one on the fly as needed. These aren't currently cached to avoid synchronization overhead. The second interface is provided for users making heavy use of this routine for batch processing to avoid object creation overhead. */ public String processString (String string) { return processString(string, null, null); } public String processString (String string, FastStringBuffer userBuf, List args) { // short-circuit: just return if there are no tags if (string.indexOf(TagDelimiter) == -1) { return string; } // Use userBuf if given; else create one FastStringBuffer buf; if (userBuf == null) { buf = new FastStringBuffer(); } else { buf = userBuf; } int pos = 0; int idx = -1; int end; String tag, result; // search for tags, i.e. words between our tag delimiter string while ((idx = string.indexOf(TagDelimiter, pos)) != -1) { // copy the text from our current position up to the tag buf.append(string.substring(pos, idx)); // find the ending tag delimiter idx += TagDelimiter.length(); end = string.indexOf(TagDelimiter, idx); if (end == -1) { break; } // get the tag string tag = string.substring(idx, end); // move our current position to just after the tag pos = end + TagDelimiter.length(); // see if the tag is in the form of a method name // and a list of arguments, e.g. "foo(hello, bye)" String method = method(tag); List arguments = arguments(tag, args); // append the string returned by the tag handler result = handler.stringForTag(method, arguments); // just append the tag itself if the handler returns null buf.append((result == null) ? tag : result); } // copy the rest of the string to the buffer buf.append(string.substring(pos, string.length())); return buf.toString(); } /** Given a tag string that in the form of a method with arguments, returns the portion of the tag that's the method name. */ public String method (String tag) { // Look for the beginning parameter string int index; if ((index = tag.indexOf(BeginArgsChar)) != -1) { // Yes, we found the parameter // Return only the method part of it return(tag.substring(0, index).trim()); } else { return(tag); } } /** Given a tag string that in the form of a method with arguments, returns an array containing the argument strings. */ public static List arguments (String tag, List args) { // look for the arguments list character int beginIndex = tag.indexOf(BeginArgsChar); // short circuit: return null if there isn't an arguments list if (beginIndex < 0) { return null; } // move past the arguments list character beginIndex++; // reset arguments vector if we have one if (args != null) { args.clear(); } // look for all the arguments int endIndex = beginIndex; while (endIndex >= 0) { // arguments are separated by commas or the end of the list if (((endIndex = tag.indexOf(ArgsSeparator, beginIndex)) != -1) || ((endIndex = tag.indexOf(EndArgsChar, beginIndex)) != -1)) { // create the arguments vector if null if (args == null) { args = ListUtil.list(); } // Copy the argument into the list args.add(tag.substring(beginIndex, endIndex).trim()); // reset the begin index position beginIndex = endIndex + 1; } } return args; } /*----------------------------------------------------------------------- Protected Fields -----------------------------------------------------------------------*/ // the tag handler, i.e. the code that will give us the string to // insert in place of a given tag from the string to process protected TagHandler handler; }