/*******************************************************************************
* This file is part of OpenNMS(R).
*
* Copyright (C) 2006-2011 The OpenNMS Group, Inc.
* OpenNMS(R) is Copyright (C) 1999-2011 The OpenNMS Group, Inc.
*
* OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc.
*
* OpenNMS(R) is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* OpenNMS(R) 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenNMS(R). If not, see:
* http://www.gnu.org/licenses/
*
* For more information contact:
* OpenNMS(R) Licensing <license@opennms.org>
* http://www.opennms.org/
* http://www.opennms.com/
*******************************************************************************/
package org.opennms.netmgt.eventd.adaptors.udp;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;
import org.exolab.castor.xml.MarshalException;
import org.exolab.castor.xml.ValidationException;
import org.opennms.core.xml.JaxbUtils;
import org.opennms.netmgt.xml.event.Event;
import org.opennms.netmgt.xml.event.Log;
import org.xml.sax.InputSource;
/**
*
* @author <a href="mailto:weave@oculan.com">Brian Weaver </a>
* @author <a href="http://www.oculan.com">Oculan Corporation </a>
*
*/
final class UdpReceivedEvent {
/**
* The received XML event, decoded using the US-ASCII encoding.
*/
private String m_eventXML;
/**
* The decoded event document. The classes are defined in an XSD and
* generated by castor.
*/
private Log m_log;
/**
* The internet addrress of the sending agent.
*/
private InetAddress m_sender;
/**
* The port of the agent on the remote system.
*/
private int m_port;
/**
* The list of event that have been acknowledged.
*/
private List<Event> m_ackEvents;
/**
* Private constructor to prevent the used of <em>new</em> except by the
* <code>make</code> method.
*/
private UdpReceivedEvent() {
// constructor not supported except through make method!
}
/**
* Constructs a new event encapsulation instance based upon the information
* passed to the method. The passed datagram data is decoded into a string
* using the <tt>US-ASCII</tt> character encoding.
*
* @param packet
* The datagram received from the remote agent.
*
* @throws java.io.UnsupportedEncodingException
* Thrown if the data buffer cannot be decoded using the
* US-ASCII encoding.
*/
static UdpReceivedEvent make(DatagramPacket packet) throws UnsupportedEncodingException {
return make(packet.getAddress(), packet.getPort(), packet.getData(), packet.getLength());
}
/**
* Constructs a new event encapsulation instance based upon the information
* passed to the method. The passed byte array is decoded into a string
* using the <tt>US-ASCII</tt> character encoding.
*
* @param addr
* The remote agent's address.
* @param port
* The remote agent's port
* @param data
* The XML data in US-ASCII encoding.
* @param len
* The length of the XML data in the buffer.
*
* @throws java.io.UnsupportedEncodingException
* Thrown if the data buffer cannot be decoded using the
* US-ASCII encoding.
*/
static UdpReceivedEvent make(InetAddress addr, int port, byte[] data, int len) throws UnsupportedEncodingException {
UdpReceivedEvent e = new UdpReceivedEvent();
e.m_sender = addr;
e.m_port = port;
e.m_eventXML = new String(data, 0, len, "US-ASCII");
e.m_ackEvents = new ArrayList<Event>(16);
e.m_log = null;
return e;
}
/**
* Decodes the XML package from the remote agent. If an error occurs or the
* datagram had malformed XML then an exception is generated.
*
* @return The toplevel <code>Log</code> element of the XML document.
*
* @throws org.exolab.castor.xml.ValidationException
* Throws if the documents data does not match the defined XML
* Schema Definition.
* @throws org.exolab.castor.xml.MarshalException
* Thrown if the XML is malformed and cannot be converted.
*/
Log unmarshal() throws ValidationException, MarshalException {
if (m_log == null) {
final InputStream is = new ByteArrayInputStream(m_eventXML.getBytes());
m_log = JaxbUtils.unmarshal(Log.class, new InputSource(is));
}
return m_log;
}
/**
* Adds the event to the list of events acknowledged in this event XML
* document.
*
* @param e
* The event to acknowledge.
*/
void ackEvent(Event e) {
if (!m_ackEvents.contains(e)) {
m_ackEvents.add(e);
}
}
/**
* Returns the raw XML data as a string.
*/
String getXmlData() {
return m_eventXML;
}
/**
* Returns the sender's address.
*/
InetAddress getSender() {
return m_sender;
}
/**
* Returns the sender's port
*/
int getPort() {
return m_port;
}
/**
* Get the acknowledged events
*
* @return a {@link java.util.List} object.
*/
public List<Event> getAckedEvents() {
return m_ackEvents;
}
/**
* {@inheritDoc}
*
* Returns true if the instance matches the object based upon the remote
* agent's address & port. If the passed instance is from the same agent
* then it is considered equal.
*/
public boolean equals(Object o) {
if (o != null && o instanceof UdpReceivedEvent) {
UdpReceivedEvent e = (UdpReceivedEvent) o;
return (this == e || (m_port == e.m_port && m_sender.equals(e.m_sender)));
}
return false;
}
/**
* Returns the hash code of the instance. The hash code is computed by
* taking the bitwise XOR of the port and the agent's internet address hash
* code.
*
* @return The 32-bit has code for the instance.
*/
public int hashCode() {
return (m_port ^ m_sender.hashCode());
}
}