/**
* Copyright (C) 2008 - 2014 52°North Initiative for Geospatial Open Source
* Software GmbH
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* If the program is linked with libraries which are licensed under one of
* the following licenses, the combination of the program with the linked
* library is not considered a "derivative work" of the program:
*
* - Apache License, version 2.0
* - Apache Software License, version 1.0
* - GNU Lesser General Public License, version 3
* - Mozilla Public License, versions 1.0, 1.1 and 2.0
* - Common Development and Distribution License (CDDL), version 1.0
*
* Therefore the distribution of the program linked with libraries licensed
* under the aforementioned licenses, is permitted by the copyright holders
* if the distribution is compliant with both the GNU General Public
* icense version 2 and the aforementioned licenses.
*
* 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 General
* Public License for more details.
*/
package org.n52.ses.io.parser;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.xml.namespace.QName;
import net.opengis.gml.x32.BoundedByDocument;
import net.opengis.gml.x32.EnvelopeDocument;
import net.opengis.gml.x32.LineStringDocument;
import net.opengis.gml.x32.PointDocument;
import net.opengis.gml.x32.PolygonDocument;
import org.apache.muse.ws.notification.NotificationMessage;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.joda.time.DateTime;
import org.n52.oxf.xmlbeans.parser.XMLBeansParser;
import org.n52.oxf.xmlbeans.tools.XmlUtil;
import org.n52.ses.api.AbstractParser;
import org.n52.ses.api.event.MapEvent;
import org.n52.ses.api.exception.GMLParseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Element;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.io.ParseException;
/**
*
* Class for parsing WXXM data.
*
* @author Matthes Rieke <m.rieke@uni-muenster.de>
*
*/
public class WXXMParser extends AbstractParser {
private static final Logger logger = LoggerFactory
.getLogger(WXXMParser.class);
/**
* namespace used for WXXM data
*/
public static final String WXXM_NAMESPACE = "http://www.eurocontrol.int/wx/1.1";
/**
* namespace used for AVWX data
*/
public static final String AVWX_NAMESPACE = "http://www.eurocontrol.int/avwx/1.1";
/*
* WX and AVWX qnames
*/
private static final QName AERODROME_FC_NAME = new QName(AVWX_NAMESPACE, "aerodromeWxForecast");
private static final QName AIRSPACE_AREA_FC_NAME = new QName(AVWX_NAMESPACE, "airspaceAreaForecast");
private static final QName AERODROME_OBS_NAME = new QName(AVWX_NAMESPACE, "aerodromeWxObservation");
private static final QName AIRSPACE_OBS_NAME = new QName(AVWX_NAMESPACE, "airspaceWxObservation");
private static final QName FORECAST_NAME = new QName(WXXM_NAMESPACE, "Forecast");
private static final QName APPLIES_TO_NAME = new QName(AVWX_NAMESPACE, "appliesTo");
private static final QName ISSUED_FOR_NAME = new QName(AVWX_NAMESPACE, "issuedFor");
private static final QName AERODROME_NAME = new QName(AVWX_NAMESPACE, "Aerodrome");
private static final QName AIRSPACE_NAME = new QName(AVWX_NAMESPACE, "Airspace");
private static final QName VALID_TIME_NAME = new QName(WXXM_NAMESPACE, "validTime");
private static final QName ISSUE_TIME_NAME = new QName(AVWX_NAMESPACE, "issueTime");
private static final QName FORECAST_ANALYSIS_TIME_NAME = new QName(WXXM_NAMESPACE,
"forecastAnalysisTime");
private static final QName FEATURE_COLLECTION_NAME = new QName(WXXM_NAMESPACE, "FeatureCollection");
private static final QName FEATURE_MEMBER_NAME = new QName(WXXM_NAMESPACE, "featureMember");
private static final QName WX_OBSERVATION_NAME = new QName(WXXM_NAMESPACE, "Observation");
/*
* OM qnames
*/
private static final QName OM_FOI_NAME = new QName(OMParser.OM_GML32_NAMESPACE, "featureOfInterest");
/*
* GML qnames
*/
private static final QName LOCATION_NAME = new QName(GML32Parser.GML32_NAMESPACE, "location");
private static final QName BOUNDED_BY_NAME = new QName(GML32Parser.GML32_NAMESPACE, "boundedBy");
private static final QName IDENTIFIER_NAME = new QName(GML32Parser.GML32_NAMESPACE, "identifier");
/*
* XPath expressions
*/
private static final String SELECT_TAF_XPATH = "declare namespace avwx='" +
AVWX_NAMESPACE + "'; .//avwx:TAF";
private static final String SELECT_SIGMET_XPATH = "declare namespace avwx='" +
AVWX_NAMESPACE + "'; .//avwx:SIGMET";
private static final String SELECT_METAR_XPATH = "declare namespace avwx='" +
AVWX_NAMESPACE + "'; .//avwx:METAR";
private static final String SELECT_PIREP_XPATH = "declare namespace avwx='" +
AVWX_NAMESPACE + "'; .//avwx:PIREP";
private static final String SELECT_EXTENT_OF_XPATH = "declare namespace wx='" +
WXXM_NAMESPACE + "'; .//wx:extentOf";
private static final String SELECT_ICAO_CODE_XPATH = "declare namespace avwx='" +
AVWX_NAMESPACE + "'; .//avwx:icaoCode";
private static final String SELECT_SYSTEMS_XPATH = "declare namespace avwx='" +
AVWX_NAMESPACE + "'; " + "declare namespace wx='" +
WXXM_NAMESPACE + "'; " + "declare namespace gml='" +
GML32Parser.GML32_NAMESPACE + "'; .//avwx:process//wx:System/gml:name";
private static final String AVWX_TYPE_KEY = "avwxType";
/**
* default constructor
*/
public WXXMParser() {
//nothing to do
}
/**
* @param collection the collection of WXXM data
* @return List of data elements
*/
public List<MapEvent> parseWXXM(XmlObject collection) {
ArrayList<MapEvent> results = new ArrayList<MapEvent>();
/*
* parse TAFs
*/
parseTAFs(results, collection);
/*
* parse SIGMETs
*/
parseSIGMETs(results, collection);
/*
* parse METARs
*/
parseMETARs(results, collection);
/*
* parse PIREPs
*/
parsePIREPs(results, collection);
/*
* check if we do not have any results.
* then try to parse other stuff (e.g., severe weather model)
*/
if (results.size() == 0) {
parseOther(results, collection);
}
return results;
}
private void parseTAFs(ArrayList<MapEvent> results, XmlObject collection) {
XmlObject[] tafs = XmlUtil.selectPath(SELECT_TAF_XPATH, collection);
if (tafs != null && tafs.length > 0) {
for (XmlObject taf : tafs) {
Geometry tafGeometry = null;
DateTime tafTime = null;
String tafAeroFeature = null;
/*
*
* get the TAF-wide geometry from the appliesTo element.
*
*/
XmlObject[] appTo = taf.selectChildren(APPLIES_TO_NAME);
if (appTo.length > 0) {
XmlObject[] aero = appTo[0].selectChildren(AERODROME_NAME);
if (aero.length > 0) {
try {
tafGeometry = getGeometryFromLocationOrBoundedBy(aero[0]);
}
catch (Exception e) {
logger.warn(e.getMessage(), e);
}
tafAeroFeature = XmlUtil.stripText(aero[0].selectChildren(IDENTIFIER_NAME));
}
}
/*
* could also be child of TAF-element
*/
if (tafGeometry == null) {
try {
tafGeometry = getGeometryFromLocationOrBoundedBy(taf);
}
catch (Exception e) {
logger.warn(e.getMessage(), e);
}
}
/*
* get the issue time, used if time from forecast could
* not be parsed.
*/
XmlObject[] issue = taf.selectChildren(ISSUE_TIME_NAME);
if (issue.length > 0) {
tafTime = new DateTime(issue[0].newCursor().getTextValue());
}
/*
*
* get the Forecast objects
*
*/
XmlObject[] aeroFCs = taf.selectChildren(AERODROME_FC_NAME);
/*
* multiple forecasts possible.
* generate one MapEvent for each
*/
for (XmlObject aefc : aeroFCs) {
DateTime[] dateTimes = null;
Geometry geometry = null;
String aeroFeature = tafAeroFeature;
/*
* select the Forecast
*/
XmlObject[] fc = aefc.selectChildren(FORECAST_NAME);
if (fc.length > 0) {
/*
* select time
*/
dateTimes = getTimeFromForecast(fc[0]);
/*
* select the geometry
*/
geometry = getGeometryFromForecast(fc[0]);
}
if (dateTimes == null || dateTimes.length == 0) {
// time could not be parsed, try taf-wide
// issueTime
if (tafTime != null) {
dateTimes = new DateTime[] {tafTime};
}
else {
logger.warn("Time for current TAF could not be parsed. skipping");
continue;
}
}
/*
* generate the new MapEvent
*/
if (geometry == null && tafGeometry != null) {
geometry = tafGeometry;
}
MapEvent newEvent = createMapEvent(dateTimes, geometry);
if (newEvent == null) continue;
if (aeroFeature != null) {
newEvent.put(AIXMParser.AERO_FEATURE_KEY, aeroFeature);
}
newEvent.put(AVWX_TYPE_KEY, "TAF");
results.add(newEvent);
}
}
}
}
private void parseSIGMETs(ArrayList<MapEvent> results, XmlObject collection) {
XmlObject[] sigmets = XmlUtil.selectPath(SELECT_SIGMET_XPATH, collection);
if (sigmets != null && sigmets.length > 0) {
for (XmlObject sigmet : sigmets) {
Geometry sigmetGeometry = null;
DateTime sigmetTime = null;
/*
* get SIGMET-wide geometry
* issuedFor
*/
XmlObject[] issuedFor = sigmet.selectChildren(ISSUED_FOR_NAME);
if (issuedFor.length > 0) {
/*
* Airspace
*/
XmlObject[] airspace = issuedFor[0].selectChildren(AIRSPACE_NAME);
if (airspace.length > 0) {
try {
sigmetGeometry = getGeometryFromLocationOrBoundedBy(airspace[0]);
} catch (Exception e) {
logger.warn(e.getMessage(), e);
}
}
}
//try the child of sigmet
if (sigmetGeometry == null) {
try {
sigmetGeometry = getGeometryFromLocationOrBoundedBy(sigmet);
} catch (Exception e) {
logger.warn(e.getMessage(), e);
}
}
/*
* get the issue time, used if time from forecast could
* not be parsed.
*/
XmlObject[] issue = sigmet.selectChildren(ISSUE_TIME_NAME);
if (issue.length > 0) {
sigmetTime = new DateTime(issue[0].newCursor().getTextValue());
}
XmlObject[] aaFCs = sigmet.selectChildren(AIRSPACE_AREA_FC_NAME);
/*
* multiple AIRSPACE_AREA_Forecast possible
*/
for (XmlObject aafc : aaFCs) {
Geometry geometry = null;
DateTime[] dateTimes = null;
String aeroFeature = null;
XmlObject[] fc = aafc.selectChildren(FORECAST_NAME);
if (fc.length > 0) {
/*
* parse the geometry
*/
geometry = getGeometryFromForecast(fc[0]);
/*
* parse the time
*/
dateTimes = getTimeFromForecast(fc[0]);
XmlObject[] foi = fc[0].selectChildren(OM_FOI_NAME);
if (foi.length > 0) {
aeroFeature = XmlUtil.stripText(XmlUtil.selectPath(SELECT_ICAO_CODE_XPATH, foi[0]));
}
}
if (dateTimes == null || dateTimes.length == 0) {
// time could not be parsed, try TAF-wide
// issueTime
// if (sigmet != null) {
dateTimes = new DateTime[] {sigmetTime};
// }
}
// if (dateTimes != null) {
/*
* generate the new MapEvent
*/
if (geometry == null && sigmetGeometry != null) {
geometry = sigmetGeometry;
}
MapEvent newEvent = createMapEvent(dateTimes, geometry);
if (newEvent == null) continue;
if (aeroFeature != null) {
newEvent.put(AIXMParser.AERO_FEATURE_KEY, aeroFeature);
}
newEvent.put(AVWX_TYPE_KEY, "SIGMET");
results.add(newEvent);
// }
// else {
// log.warning("Time for current SIGMET could not be parsed. skipping");
// }
}
}
}
}
private void parseMETARs(ArrayList<MapEvent> results, XmlObject collection) {
XmlObject[] metars = XmlUtil.selectPath(SELECT_METAR_XPATH, collection);
if (metars != null && metars.length > 0) {
for (XmlObject metar : metars) {
Geometry metarGeometry = null;
DateTime metarTime = null;
String metarAeroFeature = null;
/*
*
* get the TAF-wide geometry from the appliesTo element.
*
*/
XmlObject[] appTo = metar.selectChildren(APPLIES_TO_NAME);
if (appTo.length > 0) {
XmlObject[] aero = appTo[0].selectChildren(AERODROME_NAME);
if (aero.length > 0) {
try {
metarGeometry = getGeometryFromLocationOrBoundedBy(aero[0]);
}
catch (Exception e) {
logger.warn(e.getMessage(), e);
}
metarAeroFeature = XmlUtil.stripText(aero[0].selectChildren(IDENTIFIER_NAME));
}
}
/*
* could also be child of TAF-element
*/
if (metarGeometry == null) {
try {
metarGeometry = getGeometryFromLocationOrBoundedBy(metar);
}
catch (Exception e) {
logger.warn(e.getMessage(), e);
}
}
/*
* get the issue time, used if time from forecast could
* not be parsed.
*/
XmlObject[] issue = metar.selectChildren(ISSUE_TIME_NAME);
if (issue.length > 0) {
metarTime = new DateTime(issue[0].newCursor().getTextValue());
}
/*
*
* get the Observation objects
*
*/
XmlObject[] aeroOBs = metar.selectChildren(AERODROME_OBS_NAME);
/*
* multiple Observations possible.
* generate one MapEvent for each
*/
for (XmlObject aeob : aeroOBs) {
DateTime[] dateTimes = null;
Geometry geometry = null;
String aeroFeature = metarAeroFeature;
/*
* try forecast
*/
XmlObject[] fc = aeob.selectChildren(FORECAST_NAME);
if (fc.length > 0) {
dateTimes = getTimeFromForecast(fc[0]);
geometry = getGeometryFromForecast(fc[0]);
}
else {
/*
* try observation
*/
XmlObject[] obs = aeob.selectChildren(WX_OBSERVATION_NAME);
if (obs.length > 0) {
dateTimes = getTimeFromObservation(obs[0]);
geometry = getGeometryFromObservation(obs[0]);
}
}
if ((dateTimes == null || dateTimes.length == 0) && metarTime != null) {
dateTimes = new DateTime[] {metarTime};
}
if (geometry == null && metarGeometry != null) {
geometry = metarGeometry;
}
/*
* create mapevent
*/
MapEvent newEvent = createMapEvent(dateTimes, geometry);
if (newEvent == null) {
continue;
}
if (aeroFeature != null) {
newEvent.put(AIXMParser.AERO_FEATURE_KEY, aeroFeature);
}
newEvent.put(AVWX_TYPE_KEY, "METAR");
results.add(newEvent);
}
}
}
}
private void parsePIREPs(ArrayList<MapEvent> results, XmlObject collection) {
XmlObject[] pireps = XmlUtil.selectPath(SELECT_PIREP_XPATH, collection);
if (pireps != null && pireps.length > 0) {
for (XmlObject pirep : pireps) {
Geometry pirepGeometry = null;
String pirepAeroFeature = null;
/*
* could also be child of PIREP-element
*/
try {
pirepGeometry = getGeometryFromLocationOrBoundedBy(pirep);
}
catch (Exception e) {
logger.warn(e.getMessage(), e);
}
/*
* get the Systems
*/
XmlObject[] systems = XmlUtil.selectPath(SELECT_SYSTEMS_XPATH, pirep);
String[] systemNames = new String[systems.length];
for (int i = 0; i < systems.length; i++) {
systemNames[i] = XmlUtil.stripText(systems[i]);
}
/*
*
* get the Observation objects
*
*/
XmlObject[] aeroOBs = pirep.selectChildren(AIRSPACE_OBS_NAME);
/*
* multiple Observations possible.
* generate one MapEvent for each
*/
for (XmlObject aeob : aeroOBs) {
DateTime[] dateTimes = null;
Geometry geometry = null;
String aeroFeature = pirepAeroFeature;
/*
* try observation
*/
XmlObject[] obs = aeob.selectChildren(WX_OBSERVATION_NAME);
if (obs.length > 0) {
dateTimes = getTimeFromObservation(obs[0]);
geometry = getGeometryFromObservation(obs[0]);
}
if ((dateTimes == null || dateTimes.length == 0)) {
logger.info("Could not parse time of current PIREP. skipping.");
continue;
}
if (geometry == null && pirepGeometry != null) {
geometry = pirepGeometry;
}
/*
* create mapevent
*/
MapEvent newEvent = createMapEvent(dateTimes, geometry);
if (newEvent == null) {
continue;
}
if (aeroFeature != null) {
newEvent.put(AIXMParser.AERO_FEATURE_KEY, aeroFeature);
}
newEvent.put(AVWX_TYPE_KEY, "PIREP");
/*
* make a duplicate for each affected system
*/
for (String sys : systemNames) {
MapEvent dupl = new MapEvent(newEvent);
dupl.put(AIXMParser.AERO_FEATURE_KEY, sys);
results.add(dupl);
}
}
}
}
}
private void parseOther(ArrayList<MapEvent> results, XmlObject collection) {
XmlObject[] coll = collection.selectChildren(FEATURE_COLLECTION_NAME);
XmlObject[] members = null;
if (coll.length > 0) {
members = coll[0].selectChildren(FEATURE_MEMBER_NAME);
}
else {
return;
}
/*
* go through all featureMembers
*/
for (XmlObject member : members) {
DateTime[] dateTimes = null;
Geometry geometry = null;
XmlObject[] obs = member.selectChildren(WX_OBSERVATION_NAME);
/*
* parse time
*/
if (obs.length > 0) {
dateTimes = getTimeFromObservation(obs[0]);
/*
* parse geometry
*/
geometry = getGeometryFromObservation(obs[0]);
}
if (dateTimes != null) {
MapEvent newEvent = createMapEvent(dateTimes, geometry);
if (newEvent == null) continue;
newEvent.put(AVWX_TYPE_KEY, "WXXM");
results.add(newEvent);
}
else {
logger.warn("Time for current WXXM element could not be parsed. skipping");
continue;
}
}
}
private MapEvent createMapEvent(DateTime[] dateTimes, Geometry geometry) {
MapEvent newEvent = null;
if (dateTimes.length == 1) {
newEvent = new MapEvent(dateTimes[0].getMillis(), dateTimes[0].getMillis());
}
else if (dateTimes.length == 2) {
newEvent = new MapEvent(dateTimes[0].getMillis(), dateTimes[1].getMillis());
}
else {
logger.warn("Time for current WXXM element could not be parsed. skipping");
return null;
}
if (geometry != null) {
newEvent.put(MapEvent.GEOMETRY_KEY, geometry);
}
else {
String time = "";
for (DateTime dateTime : dateTimes) {
time += dateTime +", ";
}
logger.warn("Current WXXM element has no (parseable) geometry: "+ time);
}
return newEvent;
}
private Geometry getGeometryFromObservation(XmlObject obs) {
XmlObject[] foi = obs.selectChildren(OM_FOI_NAME);
if (foi.length > 0) {
XmlCursor cursor = foi[0].newCursor();
cursor.toFirstChild();
return getGeometryFromLocationOrBoundedBy(cursor.getObject());
}
return null;
}
private DateTime[] getTimeFromObservation(XmlObject obs) {
XmlObject[] times = obs.selectChildren(new QName(OMParser.OM_GML32_NAMESPACE,
"samplingTime"));
if (times.length == 0) {
/*
* probably O&M/GML32 NS used
*/
times = obs.selectChildren(new QName(OMParser.OM_NAMESPACE,
"samplingTime"));
}
if (times.length > 0) {
return extractTime(times);
}
return null;
}
private Geometry getGeometryFromLocationOrBoundedBy(XmlObject xobj) {
XmlObject geomObc = null;
XmlObject[] geomXML = xobj.selectChildren(LOCATION_NAME);
/*
* try location
*/
if (geomXML.length > 0) {
try {
geomObc = PointDocument.Factory.parse(geomXML[0].toString());
} catch (XmlException e) {
/*
* nothing
*/
}
if (geomObc == null) {
try {
geomObc = LineStringDocument.Factory.parse(geomXML[0].toString());
} catch (XmlException e) {
/*
*
*/
}
}
}
/*
* try boundedBy
*/
else {
geomXML = xobj.selectChildren(BOUNDED_BY_NAME);
if (geomXML.length > 0) {
try {
geomObc = BoundedByDocument.Factory.parse(
geomXML[0].toString()).getBoundedBy().getEnvelope();
} catch (Exception e) {
/*
* nothing
*/
}
}
}
if (geomObc != null) {
try {
return GML32Parser.parseGeometry(geomObc);
} catch (ParseException e) {
logger.warn(e.getMessage(), e);
} catch (GMLParseException e) {
logger.warn(e.getMessage(), e);
}
}
return null;
}
private Geometry getGeometryFromForecast(XmlObject forecast) {
/*
* get the om:result
*/
XmlObject[] omResult = forecast.selectChildren(new QName(OMParser.OM_GML32_NAMESPACE,
"result"));
/*
* om1.0/gml31 is used
*/
if (omResult.length == 0) {
omResult = forecast.selectChildren(new QName(OMParser.OM_NAMESPACE,
"result"));
}
if (omResult.length > 0) {
XmlObject[] extents = XmlUtil.selectPath(SELECT_EXTENT_OF_XPATH, omResult[0]);
if (extents.length > 0) {
XmlObject geomElem = null;
try {
//Polygon
geomElem = PolygonDocument.Factory.parse(extents[0].toString());
//Envelope
if (geomElem == null) {
EnvelopeDocument.Factory.parse(extents[0].toString());
}
//try parsing
if (geomElem != null) {
return GML32Parser.parseGeometry(geomElem);
}
} catch (XmlException e) {
logger.warn(e.getMessage(), e);
} catch (ParseException e) {
logger.warn(e.getMessage(), e);
} catch (GMLParseException e) {
logger.warn(e.getMessage(), e);
}
}
/*
* TODO other elements in om:result where geometry could be set
*/
}
/*
* TODO parse om:featureOfInterest? many possibilities
*/
/*
* try location or boundedBy
*/
return getGeometryFromLocationOrBoundedBy(forecast);
}
private DateTime[] getTimeFromForecast(XmlObject forecast) {
DateTime[] result = null;
/*
* first try the wx:validTime
* it should be more precise
*/
XmlObject[] times = forecast.selectChildren(VALID_TIME_NAME);
// om:samplingTime is mandatory, hence always there
if (times.length == 0) {
times = forecast.selectChildren(new QName(OMParser.OM_GML32_NAMESPACE,
"samplingTime"));
}
if (times.length == 0) {
/*
* probably O&M/GML31 NS used
*/
times = forecast.selectChildren(new QName(OMParser.OM_NAMESPACE,
"samplingTime"));
}
/*
* try FORECAST_ANALYSIS_TIME_NAME
*/
if (times.length == 0) {
times = forecast.selectChildren(FORECAST_ANALYSIS_TIME_NAME);
}
result = extractTime(times);
return result;
}
private DateTime[] extractTime(XmlObject[] times) {
if (times.length > 0) {
try {
//create doc
XmlObject time = XmlObject.Factory.parse(
times[0].toString());
//try parsing
if (time != null) {
return GML32Parser.parseTime(time);
}
} catch (XmlException e) {
logger.warn(e.getMessage(), e);
}
}
return null;
}
/**
* @param args not used
*/
public static void main(String[] args) {
File f = new File("D:/pirep1.xml");
try {
logger.info("parse METAR");
List<MapEvent> evs = new WXXMParser().parseWXXM(XmlObject.Factory.parse(f));
for (MapEvent mapEvent : evs) {
System.err.println(mapEvent);
}
logger.info("parse tafs");
f = new File("D:/metar1.xml");
evs = new WXXMParser().parseWXXM(XmlObject.Factory.parse(f));
for (MapEvent mapEvent : evs) {
System.err.println(mapEvent);
}
//
// log.info("parse sigmet");
// f = new File("D:/sigmet1.xml");
// evs = new WXXMParser(XmlObject.Factory.parse(f)).parseWXXM();
// for (MapEvent mapEvent : evs) {
// System.err.println(mapEvent);
// }
} catch (XmlException e) {
logger.warn(e.getMessage(), e);
} catch (IOException e) {
logger.warn(e.getMessage(), e);
}
}
@Override
public boolean accept(NotificationMessage message) {
@SuppressWarnings("unchecked")
Collection<QName> cnames = message.getMessageContentNames();
for (QName qn : cnames) {
if (hasWXXMContent(qn, message)) return true;
}
return false;
}
private boolean hasWXXMContent(QName qn, NotificationMessage message) {
/*
* check if root is one of the types
*/
if (qn.equals(new QName(WXXMParser.AVWX_NAMESPACE, "TAF"))) {
return true;
}
else if (qn.equals(new QName(WXXMParser.AVWX_NAMESPACE, "SIGMET"))) {
return true;
}
else if (qn.equals(new QName(WXXMParser.AVWX_NAMESPACE, "METAR"))) {
return true;
}
else if (qn.equals(new QName(WXXMParser.AVWX_NAMESPACE, "PIREP"))) {
return true;
}
Element content = message.getMessageContent(qn);
/*
* else check for subnodes
*/
if (content.getElementsByTagNameNS(WXXMParser.AVWX_NAMESPACE, "TAF").getLength() > 0) {
return true;
}
else if (content.getElementsByTagNameNS(WXXMParser.AVWX_NAMESPACE, "SIGMET").getLength() > 0) {
return true;
}
else if (content.getElementsByTagNameNS(WXXMParser.AVWX_NAMESPACE, "METAR").getLength() > 0) {
return true;
}
else if (content.getElementsByTagNameNS(WXXMParser.AVWX_NAMESPACE, "PIREP").getLength() > 0) {
return true;
}
else if (content.getElementsByTagNameNS(WXXMParser.WXXM_NAMESPACE, "featureMember").getLength() > 0) {
return true;
}
return false;
}
@Override
public List<MapEvent> parse(NotificationMessage message) throws Exception {
@SuppressWarnings("unchecked")
Collection<QName> cnames = message.getMessageContentNames();
for (QName qn : cnames) {
if (hasWXXMContent(qn, message)) {
return parseWXXM(XMLBeansParser.parse(message.getMessageContent(qn), false));
}
}
return null;
}
@Override
protected String getName() {
return "WXXMParser [for TAF, SIGMET, METAR, PIREP]";
}
}