
net.sf.saxon.ma.json.JsonHandler Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of Saxon-HE Show documentation
Show all versions of Saxon-HE Show documentation
The XSLT and XQuery Processor
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2015 Saxonica Limited.
// 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.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
package net.sf.saxon.ma.json;
import net.sf.saxon.expr.XPathContext;
import net.sf.saxon.ma.map.MapItem;
import net.sf.saxon.om.Function;
import net.sf.saxon.om.Item;
import net.sf.saxon.om.Sequence;
import net.sf.saxon.serialize.charcode.UTF16CharacterSet;
import net.sf.saxon.trans.XPathException;
import net.sf.saxon.tree.util.FastStringBuffer;
import net.sf.saxon.type.SpecificFunctionType;
import net.sf.saxon.value.SequenceType;
import net.sf.saxon.value.StringValue;
import net.sf.saxon.z.IntPredicate;
/**
* Default handler class for accepting the result from parsing JSON strings
*/
public class JsonHandler {
public boolean escape;
protected IntPredicate charChecker;
private XPathContext context;
private Function fallbackFunction = null;
private static final String REPLACEMENT = "\ufffd";
public void setContext(XPathContext context) {
this.context = context;
}
public XPathContext getContext() {
return context;
}
public Sequence getResult() throws XPathException {
return null;
};
/**
* Set the key to be written for the next entry in an object/map
*
* @param unEscaped the key for the entry (null implies no key) in unescaped form (backslashes,
* if present, do not signal an escape sequence)
* @param reEscaped the key for the entry (null implies no key) in reescaped form. In this form
* special characters are represented as backslash-escaped sequences if the escape
* option is yes; if escape=no, the reEscaped form is the same as the unEscaped form.
* @return true if the key is already present in the map, false if it is not
*/
public boolean setKey(String unEscaped, String reEscaped) {
return false;
};
/**
* Open a new array
*
* @throws XPathException if any error occurs
*/
public void startArray() throws XPathException {};
/**
* Close the current array
*
* @throws XPathException if any error occurs
*/
public void endArray() throws XPathException {};
/**
* Start a new object/map
*
* @throws XPathException if any error occurs
*/
public void startMap() throws XPathException {};
/**
* Close the current object/map
*
* @throws XPathException if any error occurs
*/
public void endMap() throws XPathException {};
/**
* Write a numeric value
*
* @param asString the string representation of the value
* @param asDouble the double representation of the value
* @throws XPathException if any error occurs
*/
public void writeNumeric(String asString, double asDouble) throws XPathException {};
/**
* Write a string value
*
* @param val The string to be written (which may or may not contain JSON escape sequences, according to the
* options that were set)
* @throws XPathException if any error occurs
*/
public void writeString(String val) throws XPathException {};
public String reEscape(String val, boolean isKey) throws XPathException {
CharSequence escaped;
if (escape) {
escaped = JsonReceiver.escape(val, true, new IntPredicate() {
public boolean matches(int value) {
return (value >= 0 && value <= 0x1F) ||
(value >= 0x7F && value <= 0x9F) ||
!charChecker.matches(value) ||
(value == 0x5C);
}
});
//markAsEscaped(escaped, isKey);
} else {
FastStringBuffer buffer = new FastStringBuffer(val);
handleInvalidCharacters(buffer);
escaped = buffer;
}
return escaped.toString();
}
/**
* Write a boolean value
* @param value the boolean value to be written
* @throws XPathException if any error occurs
*/
public void writeBoolean(boolean value) throws XPathException {};
/**
* Write a null value
*
* @throws XPathException if any error occurs
*/
public void writeNull() throws XPathException {};
/**
* Deal with invalid characters in the JSON string
* @param buffer the JSON string
* @throws XPathException if any error occurs
*/
protected void handleInvalidCharacters(FastStringBuffer buffer) throws XPathException {
//if (checkSurrogates && !liberal) {
IntPredicate charChecker = context.getConfiguration().getValidCharacterChecker();
for (int i = 0; i < buffer.length(); i++) {
char ch = buffer.charAt(i);
if (UTF16CharacterSet.isHighSurrogate(ch)) {
if (i + 1 >= buffer.length() || !UTF16CharacterSet.isLowSurrogate(buffer.charAt(i + 1))) {
substitute(buffer, i, 1, context);
}
} else if (UTF16CharacterSet.isLowSurrogate(ch)) {
if (i == 0 || !UTF16CharacterSet.isHighSurrogate(buffer.charAt(i - 1))) {
substitute(buffer, i, 1, context);
} else {
int pair = UTF16CharacterSet.combinePair(buffer.charAt(i - 1), ch);
if (!charChecker.matches(pair)) {
substitute(buffer, i - 1, 2, context);
}
}
} else {
if (!charChecker.matches(ch)) {
substitute(buffer, i, 1, context);
}
}
}
//}
}
protected void markAsEscaped(CharSequence escaped, boolean isKey) throws XPathException {
// do nothing in this class
}
/**
* Replace an character or two characters within a string buffer, either by executing the replacement function,
* or using the default Unicode replacement character
*
* @param buffer the string buffer, which is modified by this call
* @param offset the position of the characters to be replaced
* @param count the number of characters to be replaced
* @param context the XPath context
* @throws XPathException if the callback function throws an exception
*/
private void substitute(FastStringBuffer buffer, int offset, int count, XPathContext context) throws XPathException {
FastStringBuffer escaped = new FastStringBuffer(count*6);
for (int j=0; j
© 2015 - 2025 Weber Informatics LLC | Privacy Policy