package org.autoplot.servlet; import org.autoplot.RenderType; import org.autoplot.ApplicationModel; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.Image; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.util.logging.Logger; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URI; import java.net.URISyntaxException; import java.nio.file.Files; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.Enumeration; import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Map.Entry; import java.util.TimeZone; import java.util.logging.FileHandler; import java.util.logging.Handler; import java.util.logging.Level; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.io.output.TeeOutputStream; import org.das2.datum.DatumRange; import org.das2.datum.DatumRangeUtil; import org.das2.datum.TimeUtil; import org.das2.datum.Units; import org.das2.datum.UnitsUtil; import org.das2.graph.DasCanvas; import org.das2.graph.Painter; import org.das2.graph.Renderer; import org.das2.system.DasLogger; import org.das2.util.AboutUtil; import org.das2.util.FileUtil; import org.das2.util.TimerConsoleFormatter; import org.das2.util.awt.GraphicsOutput; import org.das2.util.monitor.NullProgressMonitor; import org.autoplot.dom.Application; import org.autoplot.dom.Axis; import org.autoplot.dom.DataSourceFilter; import org.autoplot.dom.Plot; import org.autoplot.dom.PlotElement; import org.autoplot.state.StatePersistence; import org.das2.qds.QDataSet; import org.autoplot.datasource.DataSetSelectorSupport; import org.autoplot.datasource.DataSetURI; import org.autoplot.datasource.DataSource; import org.autoplot.datasource.DataSourceFactory; import org.autoplot.datasource.FileSystemUtil; import org.autoplot.datasource.URISplit; import org.autoplot.datasource.capability.TimeSeriesBrowse; import org.autoplot.datasource.jython.JythonDataSourceFactory; import org.das2.qds.ops.Ops; /** * SimpleServlet produces PNG,PDF, and SVG products for * .vap files and Autoplot URIs. A simple set of controls is provided * to tweak layout when automatic settings are not satisfactory. * * Some known instances:
GET
and POST
methods.
* @param request servlet request
* @param response servlet response
* @throws ServletException
* @throws IOException
*/
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
File cacheFile= null;
File metaCacheFile= null;
FileInputStream fin= null;
String qs= request.getQueryString();
synchronized ( this ) {
if ( ServletInfo.isCaching() && qs!=null ) {
String format = ServletUtil.getStringParameter(request, "format", "image/png");
if ( format.equals("image/png") ) {
String hash= request.getQueryString();
File s= ServletInfo.getCacheDirectory();
hash= String.format( "%04d", Math.abs( hash.hashCode() % 10000 ) );
cacheFile= new File( s, hash + ".png" );
metaCacheFile= new File( s, hash + ".txt" );
if ( cacheFile.exists() ) {
byte[] bb= Files.readAllBytes(metaCacheFile.toPath());
String qs0= new String( bb );
if ( qs0.equals(qs) ) {
cacheFile.setLastModified( new Date().getTime() );
String host= java.net.InetAddress.getLocalHost().getCanonicalHostName();
response.setHeader( "X-Served-By", host );
response.setHeader( "X-Server-Version", ServletInfo.version );
response.setHeader( "X-Autoplot-cache", "yep" );
response.setHeader( "X-Autoplot-cache-filename", cacheFile.getName() );
fin= new FileInputStream( cacheFile );
} else {
logger.finer( "cache slot occupied by another image, overwriting.");
}
}
}
}
}
if ( fin!=null ) {
try ( OutputStream outs= response.getOutputStream() ) {
copyStream( fin, outs );
}
fin.close();
return;
}
//logger.setLevel(Level.FINE);
logger.finer(ServletInfo.version);
logger.fine("=======================");
long t0 = System.currentTimeMillis();
String suniq = request.getParameter("requestId");
long uniq;
if (suniq == null) {
uniq = (long) (Math.random() * 100);
} else {
uniq = Long.parseLong(suniq);
addHandlers(uniq);
}
String debug = request.getParameter("debug");
if ( debug==null ) debug= "false";
//debug= "TRUE";
logit("-- new request " + uniq + " --", t0, uniq, debug);
try {
String suri = request.getParameter("uri");
if ( suri==null ) {
suri = request.getParameter("url");
}
if ( suri!=null && suri.startsWith("vap ") ) { // pluses are interpretted as spaces when they are parameters in URLs. These should have been escaped, but legacy operations require we handle this.
suri= suri.replaceAll(" ","+");
}
String id= request.getParameter("id"); // lookup local URIs in table id.txt
String process = ServletUtil.getStringParameter(request, "process", "");
String vap = request.getParameter("vap");
int width = ServletUtil.getIntParameter(request, "width", -1);
int height = ServletUtil.getIntParameter(request, "height", -1);
String scanvasAspect = ServletUtil.getStringParameter(request, "canvas.aspect", "");
String format = ServletUtil.getStringParameter(request, "format", "image/png");
String font = ServletUtil.getStringParameter(request, "font", "");
String column = ServletUtil.getStringParameter(request, "column", "");
String row = ServletUtil.getStringParameter(request, "row", "");
String srenderType = ServletUtil.getStringParameter(request, "renderType", "");
String ssymbolSize = ServletUtil.getStringParameter(request, "symbolSize", "");
String stimeRange = ServletUtil.getStringParameter(request, "timeRange", "");
if ( stimeRange.length()==0 ) stimeRange= ServletUtil.getStringParameter(request, "timerange", "");
String scolor = ServletUtil.getStringParameter(request, "color", "");
String sfillColor = ServletUtil.getStringParameter(request, "fillColor", "");
String sforegroundColor = ServletUtil.getStringParameter(request, "foregroundColor", "");
String sbackgroundColor = ServletUtil.getStringParameter(request, "backgroundColor", "");
String title = ServletUtil.getStringParameter(request, "plot.title", "");
String xlabel = ServletUtil.getStringParameter(request, "plot.xaxis.label", "");
String xrange = ServletUtil.getStringParameter(request, "plot.xaxis.range", "");
String xlog = ServletUtil.getStringParameter(request, "plot.xaxis.log", "");
String xdrawTickLabels = ServletUtil.getStringParameter(request, "plot.xaxis.drawTickLabels", "");
String ylabel = ServletUtil.getStringParameter(request, "plot.yaxis.label", "");
String yrange = ServletUtil.getStringParameter(request, "plot.yaxis.range", "");
String ylog = ServletUtil.getStringParameter(request, "plot.yaxis.log", "");
String ydrawTickLabels = ServletUtil.getStringParameter(request, "plot.yaxis.drawTickLabels", "");
String zlabel = ServletUtil.getStringParameter(request, "plot.zaxis.label", "");
String zrange = ServletUtil.getStringParameter(request, "plot.zaxis.range", "");
String zlog = ServletUtil.getStringParameter(request, "plot.zaxis.log", "");
String zdrawTickLabels = ServletUtil.getStringParameter(request, "plot.zaxis.drawTickLabels", "");
String grid= ServletUtil.getStringParameter( request, "drawGrid", "" );
String stamp= ServletUtil.getStringParameter( request, "stamp", "false" ); // print a stamp for debugging. If not false, the value is printed in blue along with a timestamp.
for (Enumeration en = request.getParameterNames(); en.hasMoreElements();) {
String n = (String) en.nextElement();
logger.log( Level.FINE, "{0}: {1}", new Object[]{n, Arrays.asList(request.getParameterValues(n))});
}
if (srenderType.equals("fill_to_zero")) {
srenderType = "fillToZero";
}
if ( suri!=null ) logger.log(Level.FINE, "suri={0}", suri);
if ( vap!=null ) logger.log(Level.FINE, "vap={0}", vap);
if ( id!=null ) logger.log(Level.FINE, "id={0}", id);
// allow URI=vapfile
if ( vap==null && suri!=null ) {
if ( suri.contains(".vap") || suri.contains(".vap?") ) {
vap= suri;
suri= null;
}
}
// To support load balancing, insert the actual host that resolved the request
String host= java.net.InetAddress.getLocalHost().getCanonicalHostName();
response.setHeader( "X-Served-By", host );
response.setHeader("X-Server-Version", ServletInfo.version);
if ( suri!=null ) {
response.setHeader( "X-Autoplot-URI", suri );
}
if ( id!=null ) {
response.setHeader( "X-Autoplot-ID", id );
}
// id lookups. The file id.txt is a flat file with hash comments,
// with each record containing a regular expression with groups,
// then a map with group ids.
if ( id!=null ) {
suri= null;
Map