/[projects]/android/TrainInfoService/src/dk/thoerup/traininfoservice/RequestPlotter.java
ViewVC logotype

Contents of /android/TrainInfoService/src/dk/thoerup/traininfoservice/RequestPlotter.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1427 - (show annotations) (download)
Mon May 2 18:27:05 2011 UTC (13 years ago) by torben
File size: 12261 byte(s)
Also set a content-disposition header for kmz files
1 package dk.thoerup.traininfoservice;
2
3 import java.io.BufferedReader;
4 import java.io.ByteArrayOutputStream;
5 import java.io.File;
6 import java.io.FileInputStream;
7 import java.io.FilenameFilter;
8 import java.io.IOException;
9 import java.io.InputStream;
10 import java.io.InputStreamReader;
11 import java.text.ParseException;
12 import java.text.SimpleDateFormat;
13 import java.util.ArrayList;
14 import java.util.Arrays;
15 import java.util.Date;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.logging.Level;
19 import java.util.logging.Logger;
20 import java.util.zip.ZipEntry;
21 import java.util.zip.ZipOutputStream;
22
23 import javax.servlet.ServletException;
24 import javax.servlet.annotation.WebServlet;
25 import javax.servlet.http.HttpServlet;
26 import javax.servlet.http.HttpServletRequest;
27 import javax.servlet.http.HttpServletResponse;
28
29 import dk.thoerup.genericjavautils.TimeoutMap;
30
31 @WebServlet(urlPatterns={"/RequestPlotter"})
32 public class RequestPlotter extends HttpServlet {
33 private static final long serialVersionUID = 1L;
34
35 static final Logger log = Logger.getLogger(RequestPlotter.class.getName());
36
37 static final String KML = "application/vnd.google-earth.kml";
38 static final String KMZ = "application/vnd.google-earth.kmz";
39
40 Map<String,String> cache = new TimeoutMap<String,String>(30*60*1000);
41
42 class RequestPosition {
43 public String ip;
44 public Date time;
45 public String lat;
46 public String lng;
47 }
48
49 class PositionContainer {
50 List<RequestPosition> blue = new ArrayList<RequestPosition>();
51 List<RequestPosition> green = new ArrayList<RequestPosition>();
52 List<RequestPosition> yellow = new ArrayList<RequestPosition>();
53 List<RequestPosition> red = new ArrayList<RequestPosition>();
54 }
55
56
57 boolean isGz(String fileStr) {
58 return fileStr.substring(fileStr.length() - 3).equals(".gz");
59 }
60
61 protected File[] getFiles(int count) {
62 File accessLogDir = new File("/home/app/domain1/logs/access/");
63 //File accessLogDir = new File("/home/torben/inst/glassfishv3/glassfish/domains/domain1/logs/access/");
64
65 File logFiles[] = accessLogDir.listFiles( new FilenameFilter() {
66 @Override
67 public boolean accept(File dir, String name) {
68 //log.info("name:" + name);
69 return name.startsWith("server_access_log");
70 }
71 });
72
73 Arrays.sort(logFiles);
74
75 if (logFiles == null) {
76 File[] empty = {};
77 log.info("file array was empty");
78 return empty;
79 }
80
81 int from = (count>logFiles.length) ? 0 : logFiles.length - (count);
82 int to = logFiles.length;
83
84 return Arrays.copyOfRange(logFiles, from, to);
85 }
86
87 protected PositionContainer getRequestsFromFileWorker(int count) throws IOException{
88 PositionContainer positions = new PositionContainer();
89
90 try {
91
92 File files[] = getFiles(count);
93
94 SimpleDateFormat df = new SimpleDateFormat("dd/MMM/yyyy:HH:mm:ss");
95
96 Date now = new Date();
97 for (File f : files ) {
98 log.info("Parsing file: " + f.getName() );
99
100 if ( !f.exists() ) {
101 continue;
102 }
103
104
105 InputStream input = new FileInputStream(f);
106
107
108 BufferedReader in = new BufferedReader( new InputStreamReader(input) );
109
110
111 String line;
112 while ( (line=in.readLine()) != null) {
113 if (line.indexOf("LocateStation") == -1 ){
114 continue;
115 }
116
117 if (line.indexOf("latitude=") == -1 ) {
118 continue;
119 }
120
121 if (line.indexOf("longitude=") == -1) {
122 continue;
123 }
124
125 RequestPosition pos = new RequestPosition();
126
127 String toks[] = line.split(" ");
128 pos.ip = toks[0].replaceAll("\"", "");
129
130 pos.time = df.parse( toks[2].replace("\"", "") );
131
132 String argpart = toks[5].split("\\?")[1];
133
134 String args[] = argpart.split("&");
135
136 pos.lat = args[0].split("=")[1];
137 pos.lng = args[1].split("=")[1];
138
139
140 long timediff = now.getTime() - pos.time.getTime();
141 if ( timediff < (3*60*60*1000) ) {
142 positions.red.add(pos); //RED
143 } else if ( timediff < (24*60*60*1000)) {
144 positions.yellow.add(pos); //YELLOW
145 } else if ( timediff < (7*24*60*60*1000)) {
146 positions.green.add(pos); //GREEN
147 } else {
148 positions.blue.add(pos); //BLUE
149 }
150
151 }
152 in.close();
153 input.close();
154
155 }
156 } catch (ParseException pe) {
157 log.log(Level.SEVERE, "parseException", pe);
158 throw new IOException(pe);
159 } catch (IOException e) {
160 log.log(Level.SEVERE, "getKml()", e);
161 throw e;
162 }
163
164 return positions;
165 }
166
167
168 /* old apache code
169 protected PositionContainer getRequestsFromFileWorker(boolean multiple) throws IOException{
170 PositionContainer positions = new PositionContainer();
171
172 try {
173 String files_single[] = {"/var/log/apache2/app_access.log"};
174 String files_multi[] = {"/var/log/apache2/app_access.log.3.gz", "/var/log/apache2/app_access.log.2.gz", "/var/log/apache2/app_access.log.1", "/var/log/apache2/app_access.log"};
175
176 String files[];
177
178 if (multiple == false) {
179 files = files_single;
180 } else {
181 files = files_multi;
182 }
183
184 SimpleDateFormat df = new SimpleDateFormat("dd/MMM/yyyy:HH:mm:ss");
185
186 Date now = new Date();
187 for (String fileStr : files ) {
188 File f = new File(fileStr);
189 if ( !f.exists() ) {
190 continue;
191 }
192
193 FileInputStream fis = new FileInputStream(fileStr);
194
195 InputStream input;
196 if ( isGz(fileStr)) {
197 input = new GZIPInputStream(fis);
198 } else {
199 input = fis;
200 }
201
202 BufferedReader in = new BufferedReader( new InputStreamReader(input) );
203
204
205 String line;
206 while ( (line=in.readLine()) != null) {
207 if (line.indexOf("LocateStation") == -1 ){
208 continue;
209 }
210
211 if (line.indexOf("latitude=") == -1 ) {
212 continue;
213 }
214
215 if (line.indexOf("longitude=") == -1) {
216 continue;
217 }
218
219 RequestPosition pos = new RequestPosition();
220
221 String toks[] = line.split(" ");
222 pos.ip = toks[0];
223
224 pos.time = df.parse( toks[3].replace("[", "") );
225
226 String argpart = toks[6].split("\\?")[1];
227
228 String args[] = argpart.split("&");
229
230 pos.lat = args[0].split("=")[1];
231 pos.lng = args[1].split("=")[1];
232
233
234 long timediff = now.getTime() - pos.time.getTime();
235 if ( timediff < (3*60*60*1000) ) {
236 positions.red.add(pos); //RED
237 } else if ( timediff < (24*60*60*1000)) {
238 positions.yellow.add(pos); //YELLOW
239 } else if ( timediff < (7*24*60*60*1000)) {
240 positions.green.add(pos); //GREEN
241 } else {
242 positions.blue.add(pos); //BLUE
243 }
244
245 }
246 in.close();
247 input.close();
248 fis.close();
249 }
250 } catch (ParseException pe) {
251 log.log(Level.SEVERE, "parseException", pe);
252 throw new IOException(pe);
253 } catch (IOException e) {
254 log.log(Level.SEVERE, "getKml()", e);
255 throw e;
256 }
257
258 return positions;
259 }*/
260
261 protected void formatPositions(StringBuilder sb, String color, List<RequestPosition> list) {
262 sb.append( "<Folder>\n");
263 sb.append( " <name>" ).append(color).append("</name>\n");
264 sb.append( " <open>0</open>\n" );
265
266 int count=0;
267 for(RequestPosition current : list) {
268 String id = color + count++;
269 sb.append( " <Placemark id=\"" + id + "\">\n" );
270 sb.append( " <name>").append(current.time).append("</name>\n" );
271 sb.append( " <styleUrl>#").append(color).append("</styleUrl>\n" );
272 sb.append( " <description><![CDATA[IP=").append(current.ip).append("<br/> ]]></description>\n" );
273 sb.append( " <Point><coordinates>").append(current.lng).append(",").append(current.lat).append(",0</coordinates></Point>\n" );
274 sb.append( " </Placemark>\n" );
275 }
276
277 sb.append("</Folder>\n");
278 }
279
280 protected String formatXml(PositionContainer positions) {
281 StringBuilder sb = new StringBuilder(1024*1024);
282
283 sb.append( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" );
284 sb.append( "<kml xmlns=\"http://www.opengis.net/kml/2.2\">\n" );
285 sb.append( "<Document>\n" );
286 sb.append( " <description><![CDATA[");
287 sb.append( " Red:").append(positions.red.size()).append(" (whithin 3 hours)<br/>\n");
288 sb.append( " Yellow:").append(positions.yellow.size()).append(" (within 24 hours)<br/>\n");
289 sb.append( " Green:").append(positions.green.size()).append(" (within one week)<br/>\n");
290 sb.append( " Blue:").append(positions.blue.size()).append(" (older)<br/>\n");
291 sb.append( " ]]></description>");
292
293
294 sb.append( " <Style id=\"red\">\n" );
295 sb.append( " <IconStyle><Icon><href>http://maps.google.com/mapfiles/kml/paddle/red-circle.png</href></Icon></IconStyle>\n" );
296 sb.append( " </Style>\n");
297
298 sb.append( " <Style id=\"yellow\">\n" );
299 sb.append( " <IconStyle><Icon><href>http://maps.google.com/mapfiles/kml/paddle/ylw-circle.png</href></Icon></IconStyle>\n" );
300 sb.append( " </Style>\n" );
301
302 sb.append( " <Style id=\"green\">\n" );
303 sb.append( " <IconStyle><Icon><href>http://maps.google.com/mapfiles/kml/paddle/grn-circle.png</href></Icon></IconStyle>\n" );
304 sb.append( " </Style>\n\n" );
305
306 sb.append( " <Style id=\"blue\">\n" );
307 sb.append( " <IconStyle><Icon><href>http://maps.google.com/mapfiles/kml/paddle/blu-circle.png</href></Icon></IconStyle>\n" );
308 sb.append( " </Style>\n\n" );
309 /*
310 String overlay =
311 " <ScreenOverlay>" +
312 " <name>Absolute Positioning: Top left</name>" +
313 " <description>Absolute Positioning: Top left</description>" +
314 " <visibility>1</visibility>" +
315 " <Icon>" +
316 " <href>http://code.google.com/apis/kml/documentation/top_left.jpg</href>" +
317 " </Icon>" +
318 " <overlayXY x=\"0\" y=\"1\" xunits=\"fraction\" yunits=\"fraction\"/>" +
319 " <screenXY x=\"0\" y=\"1\" xunits=\"fraction\" yunits=\"fraction\"/>" +
320 " <rotationXY x=\"0\" y=\"0\" xunits=\"fraction\" yunits=\"fraction\"/>" +
321 " <size x=\"0\" y=\"0\" xunits=\"fraction\" yunits=\"fraction\"/>" +
322 " </ScreenOverlay>" ;
323
324 sb.append(overlay);
325 */
326
327
328 formatPositions(sb, "blue", positions.blue);
329 formatPositions(sb, "green", positions.green);
330 formatPositions(sb, "yellow", positions.yellow);
331 formatPositions(sb, "red", positions.red);
332
333
334 sb.append( "</Document>\n" );
335 sb.append( "</kml>\n" );
336
337 return sb.toString();
338 }
339
340 protected String getRequestsFromFile(int count) throws IOException {
341 String kmlData = null;
342 String key;
343
344 key = "kmldata-" + count;
345
346 kmlData = cache.get(key);
347
348 if (kmlData == null) {
349 kmlData = formatXml( getRequestsFromFileWorker(count) );
350 cache.put(key, kmlData);
351 kmlData += "<!-- from source -->";
352 } else {
353 kmlData += "<!-- cached -->";
354 }
355
356 return kmlData;
357 }
358
359 boolean enabled(String param) {
360 if (param == null || param.equals("")) {
361 return false;
362 }
363
364 int p = 0;
365 try {
366 p = Integer.parseInt(param);
367 } catch (Exception e) {}
368
369 return (p != 0);
370 }
371
372 int getCount(String param) {
373 if (param == null || param.equals("")) {
374 return 1;
375 }
376
377 return Integer.parseInt(param);
378 }
379
380
381 @Override
382 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
383
384
385 int count = getCount( req.getParameter("count") );
386
387 if (count > 30) //limit to 30 days
388 count = 30;
389 if (count < 0) //negative count is not allowed
390 count = 0;
391
392 String kmlData = getRequestsFromFile(count);
393
394 if ( enabled(req.getParameter("zip")) ) {
395
396 ByteArrayOutputStream baos = new ByteArrayOutputStream();
397
398 ZipOutputStream zip = new ZipOutputStream(baos);
399 zip.putNextEntry( new ZipEntry("trains.kml") );
400 zip.write( kmlData.getBytes() );
401 zip.closeEntry();
402 zip.close();
403
404 byte bytes[] = baos.toByteArray();
405
406 resp.setContentType(KMZ);
407 resp.setHeader("Content-disposition", "attachment; filename=Traininfo-requestplotter.kmz");
408 resp.setContentLength( bytes.length );
409 resp.getOutputStream().write(bytes);
410
411 } else {
412 resp.setContentType(KML);
413 resp.getWriter().print( kmlData );
414 }
415 }
416 }

  ViewVC Help
Powered by ViewVC 1.1.20