/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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$ */ package org.apache.fop.util.text; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.regex.Pattern; import org.apache.xmlgraphics.util.Service; /** * Formats messages based on a template and with a set of named parameters. This is similar to * {@link java.util.MessageFormat} but uses named parameters and supports conditional sub-groups. *
* Example: *
*Missing field "{fieldName}"[ at location: {location}]!
toString()
method unless there is an
* {@link ObjectFormatter} that supports the object. {@link ObjectFormatter}s are registered
* through the service provider mechanism defined by the JAR specification.
* @param obj the object to be formatted
* @param target the target string buffer
*/
public static void formatObject(Object obj, StringBuffer target) {
if (obj instanceof String) {
target.append(obj);
} else {
boolean handled = false;
Iterator iter = OBJECT_FORMATTERS.iterator();
while (iter.hasNext()) {
ObjectFormatter formatter = (ObjectFormatter)iter.next();
if (formatter.supportsObject(obj)) {
formatter.format(target, obj);
handled = true;
break;
}
}
if (!handled) {
target.append(String.valueOf(obj));
}
}
}
private static class FunctionPart implements Part {
private Function function;
public FunctionPart(String functionName) {
this.function = getFunction(functionName);
if (this.function == null) {
throw new IllegalArgumentException("Unknown function: " + functionName);
}
}
public void write(StringBuffer sb, Map params) {
Object obj = this.function.evaluate(params);
formatObject(obj, sb);
}
public boolean isGenerated(Map params) {
Object obj = this.function.evaluate(params);
return obj != null;
}
/** {@inheritDoc} */
public String toString() {
return "{#" + this.function.getName() + "}";
}
}
private static class CompositePart implements Part {
protected List parts = new java.util.ArrayList();
private boolean conditional;
private boolean hasSections = false;
public CompositePart(boolean conditional) {
this.conditional = conditional;
}
private CompositePart(List parts) {
this.parts.addAll(parts);
this.conditional = true;
}
public void addChild(Part part) {
if (part == null) {
throw new NullPointerException("part must not be null");
}
if (hasSections) {
CompositePart composite = (CompositePart)this.parts.get(this.parts.size() - 1);
composite.addChild(part);
} else {
this.parts.add(part);
}
}
public void newSection() {
if (!hasSections) {
List p = this.parts;
//Dropping into a different mode...
this.parts = new java.util.ArrayList();
this.parts.add(new CompositePart(p));
hasSections = true;
}
this.parts.add(new CompositePart(true));
}
public void write(StringBuffer sb, Map params) {
if (hasSections) {
Iterator iter = this.parts.iterator();
while (iter.hasNext()) {
CompositePart part = (CompositePart)iter.next();
if (part.isGenerated(params)) {
part.write(sb, params);
break;
}
}
} else {
if (isGenerated(params)) {
Iterator iter = this.parts.iterator();
while (iter.hasNext()) {
Part part = (Part)iter.next();
part.write(sb, params);
}
}
}
}
public boolean isGenerated(Map params) {
if (hasSections) {
Iterator iter = this.parts.iterator();
while (iter.hasNext()) {
Part part = (Part)iter.next();
if (part.isGenerated(params)) {
return true;
}
}
return false;
} else {
if (conditional) {
Iterator iter = this.parts.iterator();
while (iter.hasNext()) {
Part part = (Part)iter.next();
if (!part.isGenerated(params)) {
return false;
}
}
}
return true;
}
}
/** {@inheritDoc} */
public String toString() {
return this.parts.toString();
}
}
static String unescapeComma(String string) {
return string.replaceAll("\\\\,", ",");
}
}