/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.autoplot.servlet; import java.io.IOException; import java.io.PrintWriter; import java.lang.reflect.Array; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; 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.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Document; import org.w3c.dom.Element; /** * Servlet takes a set of URIs and returns a vap v1.08 that will display them. * @author jbf */ public class CdawebVapServlet extends HttpServlet { private String getUriParam( HttpServletRequest request, String p ) { String uri= request.getParameter( p ); if ( uri==null ) return null; if ( uri.startsWith("vap " ) ) { // vap+inline URI encoding throw new IllegalArgumentException("Escape the pluses with %2B: "+uri); } return uri; } /** * Given a list of URIs, return a vap. * GET and * POST methods. * * @param request servlet request, containing list of URI-encoded, ampersand delimited, URIs. data0=, data1=, etc. and timeRange=iso8601 * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/x-autoplot-vap+xml;charset=UTF-8"); String tt= new SimpleDateFormat("yyyyMMdd_HHmmss").format( new Date() ); response.setHeader("Content-Disposition","inline; filename=\"default_"+tt+".vap\"" ); response.setHeader("Access-Control-Allow-Origin","*"); response.setHeader("Access-Control-Allow-Methods","GET"); PrintWriter out = response.getWriter(); Map params= new HashMap(request.getParameterMap()); // verify that data0 is not in there twice. String qs= request.getQueryString(); int idata0= qs.indexOf("data0="); if ( idata0==-1 ) { throw new IllegalArgumentException("at least data0= must be specified"); } idata0= qs.indexOf("data0=",idata0+6); if ( idata0!=-1 ) { throw new IllegalArgumentException("data0 appears to be specified twice"); } LinkedHashMap uris= new LinkedHashMap(); int first= 0; String uri= getUriParam( request,"data"+first ); if ( uri!=null ) params.remove("data"+first); if ( uri==null ) { // allow data1 to be the first one. first= 1; uri= getUriParam( request,"data"+first ); if ( uri!=null ) params.remove("data"+first); } while ( uri!=null ) { uris.put( "data_"+first, uri ); first++; uri= getUriParam( request,"data"+first ); if ( uri!=null ) params.remove("data"+first); } //uris.put("data_1","vap+inline:timegen('2014-01-17','60s',1440),ripples(1440)"); //uris.put("data_2","vap+inline:timegen('2014-01-17','60s',1440),rand(1440)+ripples(1440)*100"); //String timeRange= "2014-01-16 23:00 to 2014-01-18 01:00"; String timeRange= request.getParameter("timeRange"); if ( timeRange!=null ) params.remove("timeRange"); if ( timeRange==null ) { timeRange= request.getParameter("timerange"); if ( timeRange!=null ) params.remove("timerange"); } if ( timeRange==null ) { throw new IllegalArgumentException("timeRange must be specified"); } if ( !params.isEmpty() ) { StringBuilder b= new StringBuilder(); Set es= params.entrySet(); int count=0; for ( Iterator it = es.iterator(); it.hasNext(); ) { Entry e = (Entry) it.next(); b.append(" "); Object v= e.getValue(); if ( v.getClass().isArray() ) { for ( int jj= 0; jj1 ) { throw new IllegalArgumentException("unrecognized parameters ("+count+"): "+b.substring(1) + note); } else { throw new IllegalArgumentException("unrecognized parameter: "+b.substring(1)+ note); } } try { DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder = docFactory.newDocumentBuilder(); Document doc= docBuilder.newDocument(); Element vap= doc.createElement("vap"); doc.appendChild(vap); vap.setAttribute("appVersionTag",""); vap.setAttribute("domVersion","1.08"); Element app= doc.createElement("Application"); app.setAttribute("id","app_1"); vap.appendChild(app); Element bindings= createArray( doc, "BindingModel", uris.size(), "bindings" ); for ( int i=0; i plotDescriptors= new LinkedHashMap(); for ( int i=0; i> plotss= new LinkedHashMap>(); Map aplot; int i=0; for ( Entry uriEntry: uris.entrySet() ) { aplot= new HashMap(); aplot.put("dataSourceFilterId", uriEntry.getKey() ); aplot.put("plotId","plot_"+(i+1)); plotss.put( "plotElement_"+(i+1), aplot ); i++; } Element plotElements= createPlotElements(doc,plotss); app.appendChild(plotElements); // add the timeRange to the file. Element trp= doc.createElement( "property" ); trp.setAttribute("name", "timeRange"); trp.setAttribute("type", "datumRange"); Element tr= doc.createElement("datumRange"); tr.setAttribute("units","us2000"); tr.setAttribute("value",timeRange ); trp.appendChild(tr); app.appendChild(trp); //write the content into xml file TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); DOMSource source = new DOMSource(doc); StreamResult result = new StreamResult( out ); transformer.transform(source, result); } catch (ParserConfigurationException ex) { Logger.getLogger(CdawebVapServlet.class.getName()).log(Level.SEVERE, null, ex); } catch (TransformerConfigurationException ex) { Logger.getLogger(CdawebVapServlet.class.getName()).log(Level.SEVERE, null, ex); } catch (TransformerException ex) { Logger.getLogger(CdawebVapServlet.class.getName()).log(Level.SEVERE, null, ex); } finally { out.close(); } } private Element createArray( Document doc, String clasname, int len, String name ) { Element array= doc.createElement( "property" ); array.setAttribute("class", clasname ); array.setAttribute("length",String.valueOf(len) ); array.setAttribute("name",name); return array; } private Element createPlotElements( Document doc, Map> pplotss ) { Element plots; plots= createArray(doc, "PlotElement", pplotss.size(), "plotElements" ); for ( Entry> aplotss: pplotss.entrySet() ) { plots.appendChild( createPlotElement( doc, aplotss.getKey(), aplotss.getValue() ) ); } return plots; } private Element createPlotElement( Document doc, String id, Map pe ) { Element plotElement= doc.createElement("PlotElement"); addProperty( doc, plotElement, "autoComponent", "Boolean", "true" ); addProperty( doc, plotElement, "autoLabel", "Boolean", "true" ); addProperty( doc, plotElement, "autoRenderType", "Boolean", "true" ); addProperty( doc, plotElement, "plotId", "String", pe.get("plotId") ); addProperty( doc, plotElement, "dataSourceFilterId", "String", pe.get("dataSourceFilterId") ); plotElement.setAttribute("id", id ); return plotElement; } public static class PlotDescriptor { String xmin, xmax; String ymin, ymax; String zmin, zmax; boolean xlog,ylog,zlog; String xlabel, ylabel, zlabel; } /** * * @param doc * @param plotDescriptors map of plot_INT to properties. * @return */ private Element createPlots( Document doc, Map plotDescriptors ) { Element plots; plots= createArray(doc, "Plot", plotDescriptors.size(), "plots" ); // TODO: assumes one plot element for each plot. for ( Entry plot: plotDescriptors.entrySet() ) { int i= plot.getKey().indexOf("_"); int iid= Integer.valueOf(plot.getKey().substring(i+1)); Element plotE= createPlot( doc, plot.getKey(), iid, plot.getValue() ); plots.appendChild( plotE ); } return plots; } private Element createPlot( Document doc, String id, int iid, PlotDescriptor pd ) { Element plot= doc.createElement("Plot"); addProperty( doc, plot, "autoLabel", "Boolean", "true" ); addProperty( doc, plot, "xaxis", "DomNode", createAxis( doc, "xaxis_"+iid, iid, pd.xmin, pd.xmax, pd.xlog, pd.xlabel ) ); //TODO: Why not Axis instead of DomNode addProperty( doc, plot, "yaxis", "DomNode", createAxis( doc, "yaxis_"+iid, iid, pd.ymin, pd.ymax, pd.ylog, pd.ylabel ) ); addProperty( doc, plot, "zaxis", "DomNode", createAxis( doc, "zaxis_"+iid, iid, pd.zmin, pd.zmax, pd.zlog, pd.zlabel ) ); plot.setAttribute("id", id ); return plot; } private Element createAxis( Document doc, String id, int iid, String min, String max, boolean log, String label ) { Element axis= doc.createElement("Axis"); if ( min==null ) { addProperty( doc, axis, "autoRange", "Boolean", "true" ); addProperty( doc, axis, "autoLabel", "Boolean", "true" ); } else { addProperty( doc, axis, "log", "Boolean", String.valueOf(log) ); if ( min.contains("T") ) { addProperty( doc, axis, "range", "datumRange", min+"/"+max ); } else { addProperty( doc, axis, "range", "datumRange", min+" to "+max ); } addProperty( doc, axis, "log", "Boolean", String.valueOf(log) ); addProperty( doc, axis, "label", "String", label ); } axis.setAttribute( "id", id ); return axis; } private Element createDataSourceFilters( Document doc, Map uris ) { Element dss; dss= createArray(doc, "DataSourceFilter", uris.size(), "dataSourceFilters" ); for ( Entry uri: uris.entrySet() ) { dss.appendChild( createDsf( doc, uri.getKey(), uri.getValue() ) ); } return dss; } private Element createDsf( Document doc, String id, String uri ) { Element dsf= doc.createElement("DataSourceFilter"); dsf.setAttribute("id", id ); addProperty( doc, dsf, "uri", "String", uri ); return dsf; } private Element createCanvasAndLayout( Document doc ) { Element canvases; canvases= createArray(doc, "Canvas", 1, "canvases" ); Element canvas= doc.createElement("Canvas"); canvas.setAttribute("id","canvas_0"); canvases.appendChild(canvas); Element columns= createArray( doc, "Column", 0, "columns" ); canvas.appendChild( columns ); addProperty( doc, canvas, "height", "Integer", "604" ); addProperty( doc, canvas, "width", "Integer", "722" ); Element column= addColumn( doc, "marginColumn_0", "", "+7.0em", "100.00%-7.0em" ); addProperty( doc, canvas, "marginColumn", "DomNode", column ); Element row= addRow( doc, "marginRow_0", "", "2.0em", "100%-1.0em" ); addProperty( doc, canvas, "marginRow", "DomNode", row ); Element prop; prop= doc.createElement("property"); prop.setAttribute("class", "Row"); prop.setAttribute("length", "2"); prop.setAttribute("name","rows"); Element row1= addRow( doc, "row1", "marginRow_0", "+2.0em", "50%-2.0em" ); prop.appendChild(row1); Element row2= addRow( doc, "row2", "marginRow_0", "50%+2.0em", "100%-2.0em" ); prop.appendChild(row2); canvas.appendChild(prop); return canvases; } private void addProperty( Document doc, Element canvas, String name, String type, String value ) { Element cprop= doc.createElement("property"); cprop.setAttribute("name",name); cprop.setAttribute("type",type); cprop.setAttribute("value",value); canvas.appendChild(cprop); } private void addProperty( Document doc, Element canvas, String name, String type, Element p ) { Element cprop= doc.createElement("property"); cprop.setAttribute("name",name); cprop.setAttribute("type",type); canvas.appendChild(cprop); cprop.appendChild(p); } private Element addColumn( Document doc, String name, String parent, String left, String right ) { Element column= doc.createElement("Column"); column.setAttribute("id",name); Element cprop= doc.createElement("property"); cprop.setAttribute("default", "2em" ); cprop.setAttribute("type", "String" ); cprop.setAttribute("name","left"); cprop.setAttribute("value",left); column.appendChild(cprop); cprop= doc.createElement("property"); cprop.setAttribute("type", "String" ); cprop.setAttribute("name","parent"); cprop.setAttribute("value",parent); column.appendChild(cprop); cprop= doc.createElement("property"); cprop.setAttribute("default", "100%-3em" ); cprop.setAttribute("type", "String" ); cprop.setAttribute("name","right"); cprop.setAttribute("value",right); column.appendChild(cprop); return column; } private Element addRow( Document doc, String name, String parent, String top, String bottom ) { Element row= doc.createElement("Row"); row.setAttribute("id",name); Element cprop; cprop= doc.createElement("property"); cprop.setAttribute("type", "String" ); cprop.setAttribute("name","parent"); cprop.setAttribute("value",parent); row.appendChild(cprop); cprop= doc.createElement("property"); cprop.setAttribute("default", "+2em" ); cprop.setAttribute("type", "String" ); cprop.setAttribute("name","top"); cprop.setAttribute("value",top); row.appendChild(cprop); cprop= doc.createElement("property"); cprop.setAttribute("default", "100%-2.0em" ); cprop.setAttribute("type", "String" ); cprop.setAttribute("name","bottom"); cprop.setAttribute("value",bottom); row.appendChild(cprop); return row; } // /** * Handles the HTTP * GET method. * * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** * Handles the HTTP * POST method. * * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** * Returns a short description of the servlet. * * @return a String containing servlet description */ @Override public String getServletInfo() { return "Short description"; }// }