/**
* Copyright (c) 2005-2010, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. 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.
*/
package org.apache.synapse.commons.json;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.util.StreamReaderDelegate;
/**
* Detaches the special prefix applied by the JsonReaderDelegate.<br/>
* Hence this returns the original key value that was read in.
*/
final class XmlReaderDelegate extends StreamReaderDelegate {
private static final Log logger = LogFactory.getLog(XmlReaderDelegate.class.getName());
private boolean processNCNames;
public XmlReaderDelegate(XMLStreamReader reader, boolean processNCNames) {
super(reader);
/** Possible reader implementations include;
com.ctc.wstx.sr.ValidatingStreamReader
de.odysseus.staxon.json.JsonXMLStreamReader
com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl
*/
if (logger.isDebugEnabled()) {
logger.debug("#XmlReaderDelegate. Setting XMLStreamReader: " + reader.getClass().getName());
}
this.processNCNames = processNCNames;
}
public String getLocalName() {
String localName = super.getLocalName();
String newName = localName;
if (localName == null || "".equals(localName)) {
return localName;
}
boolean checked = false;
String subStr;
if (localName.charAt(0) == Constants.C_USOCRE) {
if (localName.startsWith(Constants.PRECEDING_DIGIT)) {
subStr = localName.substring(Constants.PRECEDING_DIGIT.length(),
localName.length());
if (processNCNames) {
newName = toOrigJsonKey(subStr);
checked = true;
} else {
newName = subStr;
}
} else if (localName.startsWith(Constants.PRECEDING_DOLLOR)) {
subStr = localName.substring(Constants.PRECEDING_DOLLOR.length(),
localName.length());
if (processNCNames) {
newName = (char) Constants.C_DOLLOR + toOrigJsonKey(subStr);
checked = true;
} else {
newName = (char) Constants.C_DOLLOR + subStr;
}
}
}
if (!checked && processNCNames) {
newName = toOrigJsonKey(newName);
}
if (logger.isDebugEnabled()) {
logger.debug("#getLocalName. old=" + localName + ", new=" + newName);
}
return newName;
}
public QName getName() {
QName qName = super.getName();
String localName = qName.getLocalPart();
QName newName = qName;
if (localName == null || "".equals(localName)) {
return qName;
}
boolean checked = false;
String subStr;
if (localName.charAt(0) == Constants.C_USOCRE) {
if (localName.startsWith(Constants.PRECEDING_DIGIT)) {
subStr = localName.substring(Constants.PRECEDING_DIGIT.length(),
localName.length());
if (processNCNames) {
localName = toOrigJsonKey(subStr);
checked = true;
} else {
localName = subStr;
}
newName = new QName(qName.getNamespaceURI(), localName, qName.getPrefix());
} else if (localName.startsWith(Constants.PRECEDING_DOLLOR)) {
subStr = localName.substring(Constants.PRECEDING_DOLLOR.length(),
localName.length());
if (processNCNames) {
localName = (char) Constants.C_DOLLOR + toOrigJsonKey(subStr);
checked = true;
} else {
localName = (char) Constants.C_DOLLOR + subStr;
}
newName = new QName(qName.getNamespaceURI(), localName, qName.getPrefix());
}
}
if (!checked && processNCNames) {
String newNameP = toOrigJsonKey(localName);
if (!localName.equals(newNameP)) {
newName = new QName(qName.getNamespaceURI(), newNameP, qName.getPrefix());
}
}
if (logger.isDebugEnabled()) {
logger.debug("#getName. old=" + localName + ", new=" + newName.getLocalPart());
}
return newName;
}
private String toOrigJsonKey(String src) {
int indexO, indexN;
indexO = indexN = 0;
int length = Constants.ID_KEY.length();
StringBuilder newStr = new StringBuilder(src.length());
int[] index = new int[1];
while (indexN < src.length()) {
indexN = src.indexOf(Constants.ID_KEY, indexO);
if (indexN == -1) {
if (indexO == 0) {
return src;
}
copyChars(src, indexO, src.length(), newStr);
break;
}
copyChars(src, indexO, indexN, newStr);
indexO = indexN + length;
index[0] = indexO;
int character = readInt(src, index);
if (character != -1) {
newStr.append((char) character);
indexO = index[0] + 1;
} else {
copyChars(src, indexO - length, indexO, newStr);
}
}
return newStr.toString();
}
private static void copyChars(String src, int low, int high, StringBuilder newStr) {
for (int i = low; i < high; ++i) {
newStr.append(src.charAt(i));
}
}
private static int readInt(String s, int[] index) {
int value = 0;
int l = s.length();
while (index[0] < l && index[0] != -1 && s.charAt(index[0]) != '_') {
int n = s.charAt(index[0]++) - '0';
n = (n >= 0 && n <= 9) ? n : -1;
if (n == -1) {
return -1;
}
value = value * 10 + n;
}
if (value <= 0) {
return -1;
}
return value;
}
}