Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.marklogic.client.alerting.RuleDefinition Maven / Gradle / Ivy
/*
* Copyright 2013-2016 MarkLogic Corporation
*
* Licensed 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 com.marklogic.client.alerting;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.xml.XMLConstants;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventFactory;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import com.marklogic.client.MarkLogicBindingException;
import com.marklogic.client.MarkLogicIOException;
import com.marklogic.client.RequestConstants;
import com.marklogic.client.impl.ClientPropertiesImpl;
import com.marklogic.client.impl.DOMWriter;
import com.marklogic.client.impl.HandleAccessor;
import com.marklogic.client.impl.Utilities;
import com.marklogic.client.impl.ValueConverter;
import com.marklogic.client.io.BaseHandle;
import com.marklogic.client.io.BytesHandle;
import com.marklogic.client.io.DOMHandle;
import com.marklogic.client.io.Format;
import com.marklogic.client.io.OutputStreamSender;
import com.marklogic.client.io.marker.RuleReadHandle;
import com.marklogic.client.io.marker.RuleWriteHandle;
import com.marklogic.client.io.marker.XMLReadHandle;
import com.marklogic.client.io.marker.XMLWriteHandle;
import com.marklogic.client.util.NameMap;
/**
* A RuleDefinition represents a set of criteria that describe a named condition.
*/
public class RuleDefinition extends BaseHandle
implements OutputStreamSender, RuleReadHandle, RuleWriteHandle {
private static final Logger logger = (Logger) LoggerFactory
.getLogger(RuleDefinition.class);
private static XMLOutputFactory factory = XMLOutputFactory.newFactory();
/**
* A RuleMetadata represents optional client-supplied metadata that is stored alongside a RuleDefinition.
*/
public interface RuleMetadata extends NameMap {
}
@SuppressWarnings("serial")
private static class RuleMetadataImpl extends ClientPropertiesImpl implements
RuleMetadata {
private RuleMetadataImpl() {
super();
}
}
private ValueSerializer valueSerializer;
private String name;
private String description;
private List queryPayload;
private RuleMetadata metadata;
/**
* Make a new rule definition
*
* @param name
* The name of the rule. Should be unique among rule names on the
* REST server.
* @param description
* Text description of the rule.
*/
public RuleDefinition(String name, String description) {
this();
this.setName(name);
this.setDescription(description);
}
/**
* Make a new rule definition, no argument constructor.
*/
public RuleDefinition() {
factory.setProperty("javax.xml.stream.isRepairingNamespaces", true);
this.metadata = new RuleMetadataImpl();
}
/**
* Sets the name of the rule.
*
* @param name
* The rule's name.
*/
public void setName(String name) {
this.name = name;
}
/**
* Gets the name of the rule.
*
* @return The rule's name.
*/
public String getName() {
return this.name;
}
/**
* Sets the description of the rule.
*
* @param description
* The rule's description.
*/
public void setDescription(String description) {
this.description = description;
}
/**
* Returns the rule's definition.
*
* @return The definition.
*/
public String getDescription() {
return this.description;
}
/**
* Imports an XML combined search definition that defines the matching
* criteria for this rule.
*
* @param queryDef
* A combined raw query definition serialized as XML.
*/
public void importQueryDefinition(XMLWriteHandle queryDef) {
List importedList = Utilities.importFromHandle(queryDef);
// modify XMLEvent list if the imported XML was a structured query.
XMLEvent firstEvent = importedList.get(0);
if (firstEvent.getEventType() == XMLStreamConstants.START_ELEMENT) {
StartElement startElement = firstEvent.asStartElement();
if (startElement.getName().getNamespaceURI() == RequestConstants.SEARCH_NS &&
startElement.getName().getLocalPart().equals("query")) {
//wrap in search.
List wrappedList = new ArrayList();
XMLEventFactory eventFactory = XMLEventFactory.newInstance();
XMLEvent startSearchElement = eventFactory.createStartElement("search", RequestConstants.SEARCH_NS, "search");
XMLEvent endSearchElement = eventFactory.createEndElement("search", RequestConstants.SEARCH_NS, "search");
wrappedList.add(startSearchElement);
wrappedList.addAll(importedList);
wrappedList.add(endSearchElement);
this.queryPayload = wrappedList;
}
else {
this.queryPayload = importedList;
}
}
else {
logger.warn("Expected imported XML to be an element, but it's not.");
this.queryPayload = importedList;
}
}
/**
* Exports the embedded query definitions and options to a handle
*
* @param handle
* The handle to use for export.
* @param the type of XMLReadHandle to return
* @return The handle, with a combined query and options included as XML.
*/
public T exportQueryDefinition(T handle) {
return Utilities.exportToHandle(this.queryPayload, handle);
}
/**
* Gets the metadata object associated with this rule
*
* @return The metadata.
*/
public RuleMetadata getMetadata() {
return metadata;
}
/**
* Sets the metadata object for this rule.
*
* @param metadata
* The metadata
*/
public void setMetadata(RuleMetadata metadata) {
this.metadata = metadata;
}
/**
* Writes a serialized RuleDefinition to an OutputStream as XML.
*/
@Override
public void write(OutputStream out) throws IOException {
try {
valueSerializer = null;
XMLStreamWriter serializer = factory.createXMLStreamWriter(out,
"UTF-8");
serializer.setPrefix(RequestConstants.RESTAPI_PREFIX,
RequestConstants.RESTAPI_NS);
serializer.setPrefix(RequestConstants.SEARCH_PREFIX,
RequestConstants.SEARCH_NS);
serializer.setPrefix("xsi",
XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
serializer.setPrefix("xs", XMLConstants.W3C_XML_SCHEMA_NS_URI);
serializer.writeStartDocument("utf-8", "1.0");
serializer.writeStartElement(RequestConstants.RESTAPI_PREFIX,
"rule", RequestConstants.RESTAPI_NS);
serializer.writeStartElement(RequestConstants.RESTAPI_PREFIX,
"name", RequestConstants.RESTAPI_NS);
serializer.writeCharacters(getName());
serializer.writeEndElement();
serializer.writeStartElement(RequestConstants.RESTAPI_PREFIX,
"description", RequestConstants.RESTAPI_NS);
String description = getDescription();
if ( description != null ) serializer.writeCharacters(description);
serializer.writeEndElement();
serializer.flush();
// logger.debug("Send: " + new String(queryPayload));
XMLEventWriter eventWriter = factory.createXMLEventWriter(out);
for (XMLEvent event : this.queryPayload) {
eventWriter.add(event);
}
eventWriter.flush();
out.flush();
writeMetadataElement(serializer);
serializer.writeEndElement();
serializer.writeEndDocument();
} catch (XMLStreamException e) {
throw new MarkLogicIOException("Failed to serialize rule", e);
} catch (TransformerFactoryConfigurationError e) {
throw new MarkLogicIOException("Failed to serialize rule", e);
} catch (TransformerException e) {
throw new MarkLogicIOException("Failed to serialize rule", e);
} finally {
valueSerializer = null;
}
}
private Element getChildByName(Element element, String ns, String localName) {
NodeList nl = element.getElementsByTagNameNS(ns, localName);
if (nl.getLength() == 1) {
return (Element) nl.item(0);
} else {
throw new MarkLogicBindingException(
"Invalid rule - must have one element only named "
+ localName);
}
}
protected void receiveContent(InputStream content) {
DOMHandle handle = new DOMHandle();
HandleAccessor.receiveContent(handle, content);
Element ruleElement = handle.get().getDocumentElement();
receiveElement(ruleElement);
}
void receiveElement(Element ruleElement) {
Element nameElement = getChildByName(ruleElement,
RequestConstants.RESTAPI_NS, "name");
this.setName(nameElement.getTextContent());
Element descElement = getChildByName(ruleElement,
RequestConstants.RESTAPI_NS, "description");
this.setDescription(descElement.getTextContent());
Element searchElement = getChildByName(ruleElement,
RequestConstants.SEARCH_NS, "search");
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
TransformerFactory transfac = TransformerFactory.newInstance();
Transformer trans = transfac.newTransformer();
trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
trans.setOutputProperty(OutputKeys.VERSION, "1.0");
trans.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
trans.setOutputProperty(OutputKeys.INDENT, "no");
trans.transform(new DOMSource(searchElement),
new StreamResult(baos));
importQueryDefinition(new BytesHandle(baos.toByteArray())
.withFormat(Format.XML));
} catch (TransformerConfigurationException e) {
throw new MarkLogicIOException(
"Could not get query from rule payload");
} catch (TransformerException e) {
throw new MarkLogicIOException(
"Could not get query from rule payload");
}
receiveRuleMetadataImpl(ruleElement);
}
private void receiveRuleMetadataImpl(Element ruleElement) {
RuleMetadata ruleMetadata = getMetadata();
ruleMetadata.clear();
Node metadataContainer = ruleElement.getElementsByTagNameNS(
RequestConstants.RESTAPI_NS, "rule-metadata").item(0);
if (metadataContainer == null)
return;
NodeList metadataIn = metadataContainer.getChildNodes();
for (int i = 0; i < metadataIn.getLength(); i++) {
Node node = metadataIn.item(i);
if (node.getNodeType() != Node.ELEMENT_NODE)
continue;
Element metadataElement = (Element) node;
QName metadataPropertyName = null;
String namespaceURI = metadataElement.getNamespaceURI();
if (namespaceURI != null) {
String prefix = metadataElement.getPrefix();
if (prefix != null) {
metadataPropertyName = new QName(namespaceURI,
metadataElement.getLocalName(), prefix);
} else {
metadataPropertyName = new QName(namespaceURI,
metadataElement.getTagName());
}
} else {
metadataPropertyName = new QName(metadataElement.getTagName());
}
if (!metadataElement.hasChildNodes()) {
metadata.put(metadataPropertyName, (String) null);
continue;
}
NodeList children = metadataElement.getChildNodes();
boolean hasChildElements = false;
int childCount = children.getLength();
for (int j = 0; j < childCount; j++) {
Node child = children.item(j);
if (child.getNodeType() == Node.ELEMENT_NODE) {
hasChildElements = true;
break;
}
}
if (hasChildElements) {
metadata.put(metadataPropertyName, children);
continue;
}
String value = metadataElement.getTextContent();
if (metadataElement.hasAttributeNS(
XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "type")) {
String type = metadataElement.getAttributeNS(
XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "type");
metadata.put(metadataPropertyName,
ValueConverter.convertToJava(type, value));
continue;
} else {
metadata.put(metadataPropertyName, value);
}
metadata.put(metadataPropertyName, value);
}
}
private void writeMetadataElement(final XMLStreamWriter serializer)
throws XMLStreamException, TransformerFactoryConfigurationError,
TransformerException {
serializer.writeStartElement("rapi", "rule-metadata",
RequestConstants.RESTAPI_NS);
serializer.writeNamespace("xs", XMLConstants.W3C_XML_SCHEMA_NS_URI);
for (Map.Entry metadataProperty : getMetadata()
.entrySet()) {
QName propertyName = metadataProperty.getKey();
Object value = metadataProperty.getValue();
boolean hasNodeValue = value instanceof NodeList;
String namespaceURI = propertyName.getNamespaceURI();
String prefix = null;
String localPart = propertyName.getLocalPart();
if (namespaceURI != null && namespaceURI.length() > 0) {
if (RequestConstants.RESTAPI_NS.equals(namespaceURI))
continue;
prefix = propertyName.getPrefix();
serializer.writeStartElement(prefix, localPart, namespaceURI);
} else {
serializer.writeStartElement(localPart);
}
if (!hasNodeValue) {
if (valueSerializer == null)
valueSerializer = new ValueSerializer(serializer);
ValueConverter.convertFromJava(value, valueSerializer);
} else {
new DOMWriter(serializer).serializeNodeList((NodeList) value);
}
serializer.writeEndElement();
}
serializer.writeEndElement();
}
static private class ValueSerializer implements
ValueConverter.ValueProcessor {
private XMLStreamWriter serializer;
public ValueSerializer(XMLStreamWriter serializer) {
super();
this.serializer = serializer;
}
@Override
public void process(Object original, String type, String value) {
if (original == null)
return;
try {
serializer.writeAttribute("xsi",
XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "type",
type);
serializer.writeCharacters(value);
} catch (XMLStreamException e) {
throw new MarkLogicIOException(e);
}
}
}
protected Class receiveAs() {
return InputStream.class;
}
protected OutputStreamSender sendContent() {
return this;
}
}