package client.net.sf.saxon.ce.trans;
import client.net.sf.saxon.ce.tree.util.FastStringBuffer;
import client.net.sf.saxon.ce.om.Item;
import client.net.sf.saxon.ce.om.NodeInfo;
import client.net.sf.saxon.ce.om.StructuredQName;
import client.net.sf.saxon.ce.type.Type;
import client.net.sf.saxon.ce.value.AtomicValue;
import client.net.sf.saxon.ce.value.StringValue;
import client.net.sf.saxon.ce.value.Whitespace;
/**
* Class containing utility methods for handling error messages
*/
public class Err {
public static final int ELEMENT = 1;
public static final int ATTRIBUTE = 2;
public static final int FUNCTION = 3;
public static final int VALUE = 4;
public static final int VARIABLE = 5;
public static final int GENERAL = 6;
public static final int URI = 7;
/**
* Add delimiters to represent variable information within an error message
* @param cs the variable information to be delimited
* @return the delimited variable information
*/
public static String wrap(CharSequence cs) {
return wrap(cs, GENERAL);
}
/**
* Add delimiters to represent variable information within an error message
* @param cs the variable information to be delimited
* @param valueType the type of value, e.g. element name or attribute name
* @return the delimited variable information
*/
public static String wrap(CharSequence cs, int valueType) {
if (cs == null) {
return "(NULL)";
}
if (cs.length() == 0) {
return "(zero-length-string)";
}
FastStringBuffer sb = new FastStringBuffer(FastStringBuffer.SMALL);
int len = cs.length();
for (int i=0; i<len; i++) {
char c = cs.charAt(i);
switch (c) {
case '\n':
sb.append("\\n");
break;
case '\t':
sb.append("\\t");
break;
case '\r':
sb.append("\\r");
break;
// case '\\':
// sb.append("\\\\");
// break;
default:
if (c < 32 || c > 255) {
sb.append("\\u");
String hex = Integer.toHexString(c);
while (hex.length() < 4) {
hex = "0" + hex;
}
sb.append(hex);
} else {
sb.append(c);
}
}
}
String s;
if (len > 30) {
if (valueType == ELEMENT && sb.charAt(0) == '{') {
StructuredQName qn = StructuredQName.fromClarkName(sb.toString());
String uri = qn.getNamespaceURI();
if (uri.length() > 15) {
uri = "..." + uri.substring(uri.length()-15);
}
s = "{" + uri + "}" + qn.getLocalName();
} else if (valueType == URI) {
s = "..." + sb.toString().substring(len-30);
} else {
s = sb.toString().substring(0, 30) + "...";
}
} else {
s = sb.toString();
}
switch (valueType) {
case ELEMENT:
return "<" + s + ">";
case ATTRIBUTE:
return "@" + s;
case FUNCTION:
return s + "()";
case VARIABLE:
return "$" + s;
case VALUE:
return "\"" + s + "\"";
default:
return "{" + s + "}";
}
}
/**
* Create a string representation of an item for use in an error message
*/
public static CharSequence depict(Item item) {
if (item instanceof AtomicValue) {
CharSequence cs = item.getStringValueCS();
if (item instanceof StringValue) {
return '\"' + truncate30(cs).toString() + '\"';
} else {
return truncate30(cs);
}
} else {
NodeInfo node = (NodeInfo)item;
switch (node.getNodeKind()) {
case Type.DOCUMENT:
return "document-node()";
case Type.ELEMENT:
return "<" + node.getDisplayName() + "/>";
case Type.ATTRIBUTE:
return "@" + node.getDisplayName();
case Type.TEXT:
return "text(\"" + truncate30(node.getStringValue()) + "\")";
case Type.COMMENT:
return "<!--" + truncate30(node.getStringValue()) + "-->";
case Type.PROCESSING_INSTRUCTION:
return "<?" + node.getDisplayName() + "?>";
case Type.NAMESPACE:
String prefix = node.getLocalPart();
return "xmlns" + (prefix.equals("") ? "" : ":" + prefix) + "=\"" + node.getStringValue() + '"';
default:
return "";
}
}
}
private static CharSequence truncate30(CharSequence cs) {
if (cs.length() <= 30) {
return Whitespace.collapseWhitespace(cs);
} else {
return Whitespace.collapseWhitespace(cs.subSequence(0, 30)).toString() + "...";
}
}
}
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
// This Source Code Form is “Incompatible With Secondary Licenses”, as defined by the Mozilla Public License, v. 2.0.