001 /** 002 * 003 */ 004 package org.wdssii.core; 005 006 import java.io.File; 007 import java.io.IOException; 008 import java.util.Date; 009 import java.util.Map; 010 011 import javax.xml.parsers.DocumentBuilder; 012 import javax.xml.parsers.DocumentBuilderFactory; 013 import javax.xml.parsers.ParserConfigurationException; 014 015 import org.apache.commons.logging.Log; 016 import org.apache.commons.logging.LogFactory; 017 import org.w3c.dom.Document; 018 import org.w3c.dom.Element; 019 020 /** 021 * @author lakshman 022 * 023 */ 024 public class XmlDataEncoder extends DataEncoder { 025 private static Log log = LogFactory.getLog(XmlDataEncoder.class); 026 027 @Override 028 protected String[] getParams(String relativeFileName) { 029 String reader = isCompressionEnabled() ? "GzippedFile" : "FlatFile"; 030 return new String[] { "W2ALGS", reader, "{indexlocation}", "xmldata", 031 relativeFileName }; 032 } 033 034 @Override 035 protected void writeAndNotify(PolarGrid dt, String outputDir, 036 String[] subtypes) { 037 throw new UnsupportedOperationException("Only datatable"); 038 } 039 040 @Override 041 protected void writeAndNotify(LatLonGrid dt, String outputDir, 042 String[] subtypes) { 043 throw new UnsupportedOperationException("Only datatable"); 044 } 045 046 @Override 047 protected void writeAndNotify(DataTable dt, String outputDir, 048 String[] subtypes) { 049 try { 050 // create XML document 051 Document doc = createXMLDocument(dt); 052 053 // where to write 054 String formattedDate = getFormattedDate(dt); 055 String relativeFileName = getRelativeFileName(dt, outputDir, 056 formattedDate, subtypes); 057 String fileName = outputDir + '/' + relativeFileName; 058 059 // write XML document 060 XMLUtil.writeXmlFile(doc, fileName, isCompressionEnabled()); 061 062 // notify 063 notifyRecord(dt, outputDir, subtypes, formattedDate, 064 relativeFileName); 065 } catch (Exception e) { 066 log.error("Writing failed: ", e); 067 } finally { 068 069 } 070 } 071 072 private static Document createXMLDocument(DataTable dt) throws ParserConfigurationException { 073 DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); 074 Document doc = builder.newDocument(); 075 076 Element root = doc.createElement("datatable"); 077 doc.appendChild(root); 078 079 root.appendChild( createDataTypeElement(doc, dt) ); 080 081 Element data = doc.createElement("data"); 082 root.appendChild(data); 083 084 for (DataTable.Column column : dt.getColumns()){ 085 Element col = doc.createElement("datacolumn"); 086 data.appendChild(col); 087 col.setAttribute("name", column.getName()); 088 col.setAttribute("units", column.getUnit()); 089 for (String value : column.getValues()){ 090 Element item = doc.createElement("item"); 091 item.setAttribute("value", value); 092 col.appendChild(item); 093 } 094 } 095 096 return doc; 097 } 098 099 private static Element createDataTypeElement(Document doc, DataTable dt) { 100 Element datatype = doc.createElement("datatype"); 101 datatype.setAttribute("name", dt.getTypeName()); 102 datatype.appendChild( createStrefElement(doc, dt.getLocation(), dt.getTime())); 103 // append attributes 104 for (Map.Entry<String, String> entry : dt.getAttributes().entrySet()){ 105 Element attr = doc.createElement("attr"); 106 attr.setAttribute("name", entry.getKey()); 107 Element dc = doc.createElement("datacolumn"); 108 dc.setAttribute("name", entry.getKey()); 109 dc.setAttribute("units", "dimensionless"); 110 Element value = doc.createElement("item"); 111 value.setAttribute("value", entry.getValue()); 112 dc.appendChild(value); 113 attr.appendChild(dc); 114 datatype.appendChild(attr); 115 } 116 return datatype; 117 } 118 119 private static Element createStrefElement(Document doc, Location location, Date time) { 120 Element stref = doc.createElement("stref"); 121 Element loc = doc.createElement("location"); 122 stref.appendChild(loc); 123 124 Element lat = doc.createElement("lat"); 125 loc.appendChild(lat); 126 Element angle = doc.createElement("angle"); 127 lat.appendChild(angle); 128 angle.setAttribute("units", "Degrees"); 129 angle.setAttribute("value", Double.toString(location.getLatitude())); 130 Element lon = doc.createElement("lon"); 131 loc.appendChild(lon); 132 angle = doc.createElement("angle"); 133 lon.appendChild(angle); 134 angle.setAttribute("units", "Degrees"); 135 angle.setAttribute("value", Double.toString(location.getLongitude())); 136 Element ht = doc.createElement("ht"); 137 Element htval = doc.createElement("length"); 138 ht.appendChild(htval); 139 htval.setAttribute("units", "Meters"); 140 htval.setAttribute("value", Double.toString(location.getHeightKms()*1000)); 141 loc.appendChild(ht); 142 143 Element t = doc.createElement("time"); 144 stref.appendChild(t); 145 t.setAttribute("units", "secondsSinceEpoch"); 146 t.setAttribute("value", Long.toString(time.getTime())); 147 return stref; 148 } 149 150 private String getRelativeFileName(DataType dt, String outputDir, 151 String formattedDate, String[] subtypes) throws IOException { 152 String subtype = (subtypes.length > 0) ? subtypes[0] : ""; 153 154 StringBuilder dirName = new StringBuilder(); 155 dirName.append(dt.getTypeName()).append("/"); 156 dirName.append(subtype).append("/"); 157 158 new File(outputDir + '/' + dirName.toString()).mkdirs(); 159 160 String extension = isCompressionEnabled()? ".xml.gz" : ".xml"; 161 162 String fileName = dirName.append(formattedDate).append(extension).toString(); 163 return fileName; 164 } 165 }