/**
* Copyright (C) 2010 Orbeon, Inc.
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU Lesser General Public License as published by the Free Software Foundation; either version
* 2.1 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* The full text of the license is available at http://www.gnu.org/copyleft/lesser.html
*/
package org.orbeon.oxf.processor.sql.interpreters;
import org.orbeon.dom.Namespace$;
import org.orbeon.dom.QName;
import org.orbeon.oxf.common.ValidationException;
import org.orbeon.oxf.processor.sql.SQLProcessor;
import org.orbeon.oxf.processor.sql.SQLProcessorInterpreterContext;
import org.orbeon.oxf.util.StringUtils;
import org.orbeon.oxf.xml.DeferredXMLReceiver;
import org.orbeon.oxf.xml.DeferredXMLReceiverImpl;
import org.orbeon.oxf.xml.XMLReceiverAdapter;
import org.orbeon.oxf.xml.dom4j.LocationData;
import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import java.util.Map;
/**
* Add an attribute to the last element output.
*/
public class AttributeInterpreter extends SQLProcessor.InterpreterContentHandler {
private DeferredXMLReceiver savedOutput;
private String attributeName;
private StringBuilder content;
public AttributeInterpreter(SQLProcessorInterpreterContext interpreterContext) {
super(interpreterContext, false);
setForward(true);
}
public void start(String uri, String localname, String qName, Attributes attributes) throws SAXException {
// Attribute name
this.attributeName = attributes.getValue("name");
// Remember output
savedOutput = getInterpreterContext().getOutput();
// New output just gather character data
getInterpreterContext().setOutput(new DeferredXMLReceiverImpl(new XMLReceiverAdapter() {
public void characters(char ch[], int start, int length) {
if (content == null)
content = new StringBuilder();
content.append(ch, start, length);
}
}));
addAllDefaultElementHandlers();
}
public void end(String uri, String localname, String qName) throws SAXException {
// Restore output
getInterpreterContext().setOutput(savedOutput);
// Normalize
final String contentString;
if (content == null)
contentString = "";
else
contentString = StringUtils.trimAllToEmpty(content.toString());
// Output attribute
final QName attributeQName = getQName(getDocumentLocator(), attributeName, getInterpreterContext().getPrefixesMap());
getInterpreterContext().getOutput().startPrefixMapping(attributeQName.getName(), attributeQName.getNamespaceURI());// NOTE: we may have to check that the mapping does not exist yet
getInterpreterContext().getOutput().addAttribute(attributeQName.getNamespaceURI(), attributeQName.getName(), attributeName, contentString);
// Clear state
savedOutput = null;
attributeName = null;
content = null;
}
private static QName getQName(Locator locator, String qNameString, Map prefixesMap) {
final int colonIndex = qNameString.indexOf(':');
if (colonIndex == -1)
return QName.get(qNameString);
if (colonIndex == 0)
throw new ValidationException("Invalid QName:" + qNameString, new LocationData(locator));
final String prefix = qNameString.substring(0, colonIndex);
final String localName = qNameString.substring(colonIndex + 1);
if (prefixesMap.get(prefix) == null) {
throw new ValidationException("Undeclared prefix for QName:" + qNameString, new LocationData(locator));
} else {
return QName.get(localName, Namespace$.MODULE$.apply(prefix, (String) prefixesMap.get(prefix)));
}
}
}