use of org.exist.dom.memtree.DocumentImpl in project exist by eXist-db.
the class FunSerialize method normalize.
/**
* Sequence normalization as described in
* http://www.w3.org/TR/xslt-xquery-serialization-30/#serdm
*
* @param input non-normalized sequence
* @param context current context
* @param callingExpr the expression from which the function is called.
* needed for error reporting
* @return normalized sequence
* @throws XPathException in case of dynamic error
*/
public static Sequence normalize(final Expression callingExpr, final XQueryContext context, final Sequence input) throws XPathException {
if (input.isEmpty()) // "If the sequence that is input to serialization is empty, create a sequence S1 that consists of a zero-length string."
{
return StringValue.EMPTY_STRING;
}
final ValueSequence temp = new ValueSequence(input.getItemCount());
for (final SequenceIterator i = input.iterate(); i.hasNext(); ) {
final Item next = i.nextItem();
if (Type.subTypeOf(next.getType(), Type.NODE)) {
if (next.getType() == Type.ATTRIBUTE || next.getType() == Type.NAMESPACE || next.getType() == Type.FUNCTION_REFERENCE) {
throw new XPathException(callingExpr, FnModule.SENR0001, "It is an error if an item in the sequence to serialize is an attribute node or a namespace node.");
}
temp.add(next);
} else {
// atomic value
Item last = null;
if (!temp.isEmpty()) {
last = temp.itemAt(temp.getItemCount() - 1);
}
if (last != null && last.getType() == Type.STRING) // "For each subsequence of adjacent strings in S2, copy a single string to the new sequence
// equal to the values of the strings in the subsequence concatenated in order, each separated
// by a single space."
{
((StringValue) last).append(" " + next.getStringValue());
} else // "For each item in S1, if the item is atomic, obtain the lexical representation of the item by
// casting it to an xs:string and copy the string representation to the new sequence;"
{
temp.add(new StringValue(next.getStringValue()));
}
}
}
context.pushDocumentContext();
try {
final MemTreeBuilder builder = context.getDocumentBuilder();
final DocumentBuilderReceiver receiver = new DocumentBuilderReceiver(builder, true);
for (final SequenceIterator i = temp.iterate(); i.hasNext(); ) {
final Item next = i.nextItem();
if (Type.subTypeOf(next.getType(), Type.NODE)) {
next.copyTo(context.getBroker(), receiver);
} else {
receiver.characters(next.getStringValue());
}
}
return (DocumentImpl) receiver.getDocument();
} catch (final SAXException e) {
throw new XPathException(callingExpr, FnModule.SENR0001, e.getMessage());
} finally {
context.popDocumentContext();
}
}
use of org.exist.dom.memtree.DocumentImpl in project exist by eXist-db.
the class IdFunctionTest method differingRealAndEffectiveUsers.
/**
* Test of eval method, of class IdFunction.
* when real and effective users are different
*/
@Test
public void differingRealAndEffectiveUsers() throws XPathException, XpathException {
final XQueryContext mckContext = createMockBuilder(XQueryContext.class).addMockedMethod("pushDocumentContext").addMockedMethod("getDocumentBuilder", new Class[0]).addMockedMethod("popDocumentContext").addMockedMethod("getRealUser").addMockedMethod("getEffectiveUser").createMock();
final Subject mckRealUser = EasyMock.createMock(Subject.class);
final String realUsername = "real";
mckContext.pushDocumentContext();
expectLastCall().once();
expect(mckContext.getDocumentBuilder()).andReturn(new MemTreeBuilder());
mckContext.popDocumentContext();
expectLastCall().once();
expect(mckContext.getRealUser()).andReturn(mckRealUser).times(2);
expect(mckRealUser.getName()).andReturn(realUsername);
expect(mckRealUser.getGroups()).andReturn(new String[] { "realGroup1", "realGroup2" });
expect(mckRealUser.getId()).andReturn(1);
final Subject mckEffectiveUser = EasyMock.createMock(Subject.class);
final String effectiveUsername = "effective";
expect(mckContext.getEffectiveUser()).andReturn(mckEffectiveUser).times(2);
expect(mckEffectiveUser.getId()).andReturn(2);
expect(mckEffectiveUser.getName()).andReturn(effectiveUsername);
expect(mckEffectiveUser.getGroups()).andReturn(new String[] { "effectiveGroup1", "effectiveGroup2" });
replay(mckEffectiveUser, mckRealUser, mckContext);
final IdFunction idFunctions = new IdFunction(mckContext, IdFunction.FNS_ID);
final Sequence result = idFunctions.eval(new Sequence[] { Sequence.EMPTY_SEQUENCE }, null);
assertEquals(1, result.getItemCount());
final XpathEngine xpathEngine = XMLUnit.newXpathEngine();
final Map<String, String> namespaces = new HashMap<>();
namespaces.put("sm", "http://exist-db.org/xquery/securitymanager");
xpathEngine.setNamespaceContext(new SimpleNamespaceContext(namespaces));
final DocumentImpl resultDoc = (DocumentImpl) result.itemAt(0);
final String actualRealUsername = xpathEngine.evaluate("/sm:id/sm:real/sm:username", resultDoc);
assertEquals(realUsername, actualRealUsername);
final String actualEffectiveUsername = xpathEngine.evaluate("/sm:id/sm:effective/sm:username", resultDoc);
assertEquals(effectiveUsername, actualEffectiveUsername);
verify(mckEffectiveUser, mckRealUser, mckContext);
}
use of org.exist.dom.memtree.DocumentImpl in project exist by eXist-db.
the class DescribeFunction method eval.
@Override
public Sequence eval(Sequence contextSequence, Item contextItem) throws XPathException {
final String fname = getArgument(0).eval(contextSequence, contextItem).getStringValue();
final QName qname;
try {
qname = QName.parse(context, fname, context.getDefaultFunctionNamespace());
} catch (final QName.IllegalQNameException e) {
throw new XPathException(this, ErrorCodes.XPST0081, "No namespace defined for prefix " + fname);
}
final String uri = qname.getNamespaceURI();
context.pushDocumentContext();
try {
final MemTreeBuilder builder = context.getDocumentBuilder();
final AttributesImpl attribs = new AttributesImpl();
attribs.addAttribute("", "name", "name", "CDATA", qname.getStringValue());
attribs.addAttribute("", "module", "module", "CDATA", uri);
final int nodeNr = builder.startElement("", "function", "function", attribs);
FunctionSignature signature;
final Module[] modules = context.getModules(uri);
if (isNotEmpty(modules)) {
for (final Module module : modules) {
final Iterator<FunctionSignature> i = module.getSignaturesForFunction(qname);
while (i.hasNext()) {
signature = i.next();
writeSignature(signature, builder);
}
}
} else {
final Iterator<FunctionSignature> i = context.getSignaturesForFunction(qname);
while (i.hasNext()) {
signature = i.next();
writeSignature(signature, builder);
}
}
builder.endElement();
return ((DocumentImpl) builder.getDocument()).getNode(nodeNr);
} finally {
context.popDocumentContext();
}
}
use of org.exist.dom.memtree.DocumentImpl in project exist by eXist-db.
the class GetIndexStatistics method eval.
public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {
final IndexStatistics index = (IndexStatistics) context.getBroker().getBrokerPool().getIndexManager().getIndexById(IndexStatistics.ID);
if (index == null) {
// module may not be enabled
return Sequence.EMPTY_SEQUENCE;
}
final SAXAdapter adapter = new SAXAdapter(context);
try {
adapter.startDocument();
index.toSAX(adapter);
adapter.endDocument();
} catch (final SAXException e) {
throw new XPathException(this, "Error caught while retrieving statistics: " + e.getMessage(), e);
}
final DocumentImpl doc = (DocumentImpl) adapter.getDocument();
return (NodeImpl) doc.getFirstChild();
}
use of org.exist.dom.memtree.DocumentImpl in project exist by eXist-db.
the class ModuleUtils method htmlToXHtml.
/**
* Takes a HTML InputSource and creates an XML representation of the HTML by
* tidying it
*
* @param context
* The Context of the calling XQuery
* @param srcHtml
* The InputSource for the HTML
* @param parserFeatures
* The features to set on the Parser
* @param parserProperties
* The properties to set on the Parser
*
* @throws SAXException in case of a SAX error
* @throws IOException in case of error reading input source
* @return An in-memory Document representing the XML'ised HTML
*/
public static DocumentImpl htmlToXHtml(final XQueryContext context, final InputSource srcHtml, final Map<String, Boolean> parserFeatures, final Map<String, String> parserProperties) throws IOException, SAXException {
// use the configures HTML parser to parse the HTML content to XML
final Optional<Either<Throwable, XMLReader>> maybeReaderInst = HtmlToXmlParser.getHtmlToXmlParser(context.getBroker().getConfiguration());
if (maybeReaderInst.isPresent()) {
final Either<Throwable, XMLReader> readerInst = maybeReaderInst.get();
if (readerInst.isLeft()) {
final String msg = "Unable to parse HTML to XML please ensure the parser is configured in conf.xml and is present on the classpath";
final Throwable t = readerInst.left().get();
LOG.error(msg, t);
throw new IOException(msg, t);
} else {
final XMLReader reader = readerInst.right().get();
if (parserFeatures != null) {
for (final Map.Entry<String, Boolean> parserFeature : parserFeatures.entrySet()) {
reader.setFeature(parserFeature.getKey(), parserFeature.getValue());
}
}
if (parserProperties != null) {
for (final Map.Entry<String, String> parserProperty : parserProperties.entrySet()) {
reader.setProperty(parserProperty.getKey(), parserProperty.getValue());
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("Converting HTML to XML using: {}", reader.getClass().getName());
}
final SAXAdapter adapter = new SAXAdapter();
// allow multiple attributes of the same name attached to the same element
// to enhance resilience against bad HTML. The last attribute value wins.
adapter.setReplaceAttributeFlag(true);
reader.setContentHandler(adapter);
reader.setProperty(Namespaces.SAX_LEXICAL_HANDLER, adapter);
reader.parse(srcHtml);
final Document doc = adapter.getDocument();
// we use eXist's in-memory DOM implementation
final DocumentImpl memtreeDoc = (DocumentImpl) doc;
memtreeDoc.setContext(context);
return memtreeDoc;
}
} else {
throw new SAXException("There is no HTML to XML parser configured in conf.xml");
}
}
Aggregations