package com.esri.geoevent.solutions.adapter.cot; /* * #%L * MessageParser.java - Esri :: AGES :: Solutions :: Adapter :: CoT - Esri - 2013 * org.codehaus.mojo-license-maven-plugin-1.5 * $Id: update-file-header-config.apt.vm 17764 2012-12-12 10:22:04Z tchemit $ * $HeadURL: https://svn.codehaus.org/mojo/tags/license-maven-plugin-1.5/src/site/apt/examples/update-file-header-config.apt.vm $ * %% * Copyright (C) 2013 - 2014 Esri * %% * 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. * #L% */ import java.io.IOException; import java.util.HashMap; import javax.xml.parsers.ParserConfigurationException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import com.esri.ges.core.geoevent.FieldException; import com.esri.ges.messaging.MessagingException; public class MessageParser extends DefaultHandler { private static final String MESSAGES = "messages"; private static final String MESSAGE = "message"; private static final Log LOG = LogFactory.getLog(MessageParser.class); private enum MessageLevel { root, inMessages, inMessage, inAttribute; } private MessageLevel messageLevel = MessageLevel.root; private String attributeName; private String attribute; private String text; private HashMap<String, String> attributes = new HashMap<String, String>(); private CoTAdapterInbound adapter; private String how = null; private String opex = null; private String qos = null; private String type = null; private String uid = null; private String version = null; private String stale = null; private String start = null; private String time = null; private String access = null; private StringBuilder detail = new StringBuilder(); private StringBuilder point = new StringBuilder(); private boolean inDetails = false; private int tabLevel = 0; public MessageParser(CoTAdapterInbound adapter) { super(); this.adapter = adapter; } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { try { if (qName == null) return; if (messageLevel == MessageLevel.root && (qName.equalsIgnoreCase(MESSAGES) || qName .equalsIgnoreCase("geomessages"))) { messageLevel = MessageLevel.inMessages; } else if (messageLevel == MessageLevel.inMessages && (qName.equalsIgnoreCase(MESSAGE) || qName .equalsIgnoreCase("geomessage"))) { messageLevel = MessageLevel.inMessage; } else if (messageLevel == MessageLevel.inMessage) { messageLevel = MessageLevel.inAttribute; attribute = ""; attributeName = qName; } else if (messageLevel == MessageLevel.inAttribute) { throw new SAXException( "Problem parsing message, cannot handle nested attributes. (" + qName + " inside " + attributeName + ")"); } else if (qName.equalsIgnoreCase("event")) { // Event element was found. Store all available CoT attributes. for (int i = 0; attributes.getLength() > i; i++) { String l = attributes.getLocalName(i); String q = attributes.getQName(i); String name = null; if(l.isEmpty()) { name = q; } else { name = l; } if (name.equalsIgnoreCase("how")) { this.how = attributes.getValue(i); } else if (name.equalsIgnoreCase( "opex")) { this.opex = attributes.getValue(i); } else if (name.equalsIgnoreCase( "qos")) { this.qos = attributes.getValue(i); } else if (name.equalsIgnoreCase( "type")) { this.type = attributes.getValue(i); } else if (name.equalsIgnoreCase( "uid")) { this.uid = attributes.getValue(i); } else if (name.equalsIgnoreCase( "stale")) { this.stale = attributes.getValue(i); } else if (name.equalsIgnoreCase( "start")) { this.start = attributes.getValue(i); } else if (name.equalsIgnoreCase( "time")) { this.time = attributes.getValue(i); } else if (name.equalsIgnoreCase( "version")) { this.version = attributes.getValue(i); } else if (name.equalsIgnoreCase( "access")) { this.access = attributes.getValue(i); } } } else if (!inDetails && qName.equalsIgnoreCase("detail")) { // <detail> element started tabLevel++; inDetails = true; detail.append("\n" + makeTabs(tabLevel) + "<eventWrapper><detail"); // (NOTE: detail should NOT have any attributes but search just // in case) for (int i = 0; attributes.getLength() > i; i++) { detail.append("\n" + makeTabs(tabLevel + 1) + attributes.getLocalName(i) + "=" + "\"" + attributes.getValue(i) + "\""); } // close the tag detail.append(">"); } else if (inDetails && !qName.equalsIgnoreCase("detail")) { // some new child element inside the Detail section tabLevel++; detail.append("\n" + makeTabs(tabLevel) + "<" + qName); // search for any attributes for (int i = 0; attributes.getLength() > i; i++) { String l = attributes.getLocalName(i); String q = attributes.getQName(i); String name = null; if(l.isEmpty()) { name = q; } else { name = l; } detail.append("\n" + makeTabs(tabLevel + 1) + name + "=" + "\"" + attributes.getValue(i) + "\""); } // close the tag detail.append(">"); } else if (!inDetails && qName.equalsIgnoreCase("point")) { // <point> element started tabLevel++; point.append("\n" + makeTabs(tabLevel) + "<point"); // search for any attributes for (int i = 0; attributes.getLength() > i; i++) { String l = attributes.getLocalName(i); String q = attributes.getQName(i); String name = null; if(l.isEmpty()) { name = q; } else { name = l; } point.append("\n" + makeTabs(tabLevel + 1) + name + "=" + "\"" + attributes.getValue(i) + "\""); } // close the tag point.append(" />"); tabLevel--; } } catch (Exception e) { LOG.error(e); LOG.error(e.getStackTrace()); } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { try { if (messageLevel == MessageLevel.inMessages && (qName.equalsIgnoreCase(MESSAGES) || qName .equalsIgnoreCase("geomessages"))) { messageLevel = MessageLevel.root; } else if (messageLevel == MessageLevel.inAttribute && qName.equalsIgnoreCase(attributeName)) { messageLevel = MessageLevel.inMessage; attributes.put(attributeName, attribute); attributeName = null; } else if (messageLevel == MessageLevel.root && qName.equalsIgnoreCase("event")) { /* * Event tag was just closed. All available information has been * compiled. Send data via msgFromStream */ try { System.out.println(detail.toString()); adapter.msgFromStream(how, opex, qos, type, uid, version, stale, start, time, access, detail.toString(), point.toString()); } catch (MessagingException e) { LOG.error(e); LOG.error(e.getStackTrace()); } catch (ParserConfigurationException e) { LOG.error(e); LOG.error(e.getStackTrace()); } catch (IOException e) { LOG.error(e); LOG.error(e.getStackTrace()); } catch (FieldException e) { LOG.error(e); LOG.error(e.getStackTrace()); } resetData(); } else if (inDetails && qName.equals("detail")) { detail.append("\n" + makeTabs(tabLevel) + "</detail></eventWrapper>"); inDetails = false; tabLevel--; } else if (inDetails && !qName.equals("detail")) { detail.append("\n" + text + makeTabs(tabLevel) + "</" + qName + ">"); tabLevel--; } else if (!inDetails && !qName.equals("point")) { // apparently this is never true because point is a solo tag // " />" point.append("\n" + makeTabs(tabLevel) + "</point>"); tabLevel--; } } catch (Exception e) { LOG.error(e); LOG.error(e.getStackTrace()); } } private String makeTabs(int desiredNumberOfTabs) throws Exception { try { StringBuilder sb = new StringBuilder(); for (int i = 0; i <= desiredNumberOfTabs; i++) { sb.append(" "); } return sb.toString(); } catch (Exception e) { LOG.error(e); LOG.error(e.getStackTrace()); throw (e); } } private void resetData() { try { this.how = null; this.opex = null; this.qos = null; this.type = null; this.uid = null; this.version = null; this.stale = null; this.start = null; this.time = null; this.access = null; this.detail = new StringBuilder(); this.point = new StringBuilder(); this.inDetails = false; this.tabLevel = 0; } catch (Exception e) { LOG.error(e); LOG.error(e.getStackTrace()); } } @Override public void characters(char ch[], int start, int length) throws SAXException { try { String str = new String(ch, start, length); if (messageLevel == MessageLevel.inAttribute) { attribute = str; } else { text = str; } } catch (Exception e) { LOG.error(e); LOG.error(e.getStackTrace()); } } public void setAdapter(CoTAdapterInbound adapter) { this.adapter = adapter; } }