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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.20