1     package sutut1;
2     
3     import javax.servlet.*;
4     import javax.servlet.http.*;
5     import java.io.*;
6     import java.util.*;
7     
8     import us.oh.state.common.utility.*;
9     
10    public class app2 extends HttpServlet {
11    
12    // actions
13    private static final String LOGIN = "Proceed";
14    private static final String MORE_DATA = "Enter More";
15    private static final String DONE_DATA = "No More Data";
16    private static final String CHART = "Chart";
17    private static final String LOGOUT = "Cancel";
18    
19    // keys
20    private static final String ACTION = "action";
21    private static final String USERNAME = "username";
22    private static final String START_YEAR = "starting_year";
23    private static final String MORE_YEAR = "more_year";
24    private static final String SALARY_COUNT = "salary_count";
25    
26    private Properties configOptions = null;
27    
28    public void init(ServletConfig cfg) throws ServletException {
29      String confFileName = cfg.getInitParameter("configFile");
30      if ((confFileName == null) || (confFileName.length() == 0))
31        throw new ServletException("No configuration information found!");
32      configOptions = new Properties();
33      try {
34        FileInputStream propFile = new FileInputStream(confFileName);
35        configOptions.load(propFile);
36        propFile.close();
37      }
38      catch (IOException e) {
39        throw new ServletException("Can't read configuration from " + confFileName);
40      }
41      String dataFileName = configOptions.getProperty("cpidata");
42      if ((dataFileName == null) || (dataFileName.length() == 0))
43        throw new ServletException("No cpidata file name specified");
44      try {
45        CPIData = parseCPIData(dataFileName);
46      }
47      catch (IOException e) {
48        throw new ServletException("Can't read data from " + dataFileName);
49      }
50    }
51    
52    private class CPI {
53      int year;
54      double indexPercentage;
55      CPI(int year, double indexPercentage) {
56        this.year = year;
57        this.indexPercentage = indexPercentage;
58      }
59    }
60    
61    private static CPI [] CPIData = null;
62    
63    private CPI []  parseCPIData(String fileName) throws IOException {
64      LineNumberReader reader = new LineNumberReader(new FileReader(fileName));
65      Vector tmpCache = new Vector();
66      int year = 0;
67      double index = 0.0;
68      while (true) {
69        String line = reader.readLine();
70        if (line == null) break;
71        StringTokenizer column = new StringTokenizer(line, ",");
72        if ((column == null) || !column.hasMoreTokens()) continue;
73        String s = column.nextToken();
74        try {
75          year = Integer.parseInt(s);
76        }
77        catch (NumberFormatException e) {
78          continue; // not a data line, perhaps the header
79        }
80        while (column.hasMoreTokens()) {
81          s = column.nextToken();
82        }
83        // the last column is the annual index
84        try {
85          index = Double.parseDouble(s);
86        }
87        catch (NumberFormatException e) {
88          System.err.println("Bad data found at line " + reader.getLineNumber());
89        }
90        tmpCache.addElement(new CPI(year, index));
91      }
92      reader.close();
93      Enumeration enum = tmpCache.elements();
94      CPI [] data = new CPI[tmpCache.size()];
95      int i = 0;
96      while (enum.hasMoreElements()) data[i++] = (CPI)enum.nextElement();
97      return data;
98    }
99    
100   public void doGet(HttpServletRequest request, HttpServletResponse response)
101       throws ServletException, IOException {
102     HttpSession ses = request.getSession(true);
103     if (ses == null) {
104       HtmlPage page = new HtmlPage(response);
105       String s = "Sorry...";
106       page.title(s);
107       page.body();
108       page.center(true);
109       page.heading(1, s);
110       page.heading(2, "There are too many users to let you sign in");
111       page.out.println("Come back later");
112       page.close();
113       return;
114     }
115     String username = (String)ses.getValue(USERNAME);
116     if (ses.isNew() || (username == null)) signIn(request, response);
117     else acceptValues(request, response, ses);
118   }
119   
120   public void doPost(HttpServletRequest request, HttpServletResponse response)
121       throws ServletException, IOException {
122     String action = request.getParameter(ACTION);
123     HttpSession ses = request.getSession(true);
124     String username = (String)ses.getValue(USERNAME);
125     if (LOGIN.equals(action)) {
126       ses.putValue(USERNAME, request.getParameter(USERNAME));
127       try {
128         Integer year = new Integer(request.getParameter(START_YEAR));
129         ses.putValue(START_YEAR, year);
130         ses.putValue(MORE_YEAR, year);
131       }
132       catch (NumberFormatException e) {
133         ses.putValue(START_YEAR, new Integer(1985));
134         ses.putValue(MORE_YEAR, new Integer(1985));
135       }
136       acceptValues(request, response, ses);
137       return;
138     }
139     if (ses.isNew() || (username == null)) signIn(request, response);
140     else if (MORE_DATA.equals(action)) {
141       appendData(request, response, ses);
142       acceptValues(request, response, ses);
143     }
144     else if (DONE_DATA.equals(action)) {
145       appendData(request, response, ses);
146       dataReady(request, response, ses);
147     }
148     else if (CHART.equals(action)) {
149       makeChart(request, response, ses);
150     }
151     else {
152       ses.invalidate();
153       signIn(request, response);
154     }
155   }
156   
157   // Send the user here if there isn't any session data or it has become invalid
158   private void signIn(HttpServletRequest request, HttpServletResponse response)
159       throws ServletException, IOException {
160     HtmlPage page = new HtmlPage(response);
161     String s = "Compare salary to cost of living";
162     page.title(s);
163     page.body();
164     page.center(true);
165     page.heading(1, s);
166     page.heading(2, "Please sign in");
167     page.form(request.getServletPath());
168     page.table(0);
169     page.tField("Name:", USERNAME, "to print on report", 20, 40);
170     page.tField("Starting year:", START_YEAR, "1985", 20, 40);
171     page.row();
172       page.col();
173       page.col();
174       page.submit(ACTION, LOGIN);
175     page.table();
176     page.form();
177     page.close();
178   }
179   
180   private void acceptValues(HttpServletRequest request, HttpServletResponse response,
181       HttpSession ses) throws ServletException, IOException {
182     HtmlPage page = new HtmlPage(response);
183     String s = "Data entry - " + (String)ses.getValue(USERNAME);
184     page.title(s);
185     page.body();
186     page.center(true);
187     page.heading(1, s);
188     int count = 0;
189     int start = 0;
190     try {
191       start = ((Integer)ses.getValue(START_YEAR)).intValue();
192       count = ((Integer)ses.getValue(SALARY_COUNT)).intValue();
193     }
194     catch (Exception e) {
195     }
196     page.heading(3, count + " values entered so far, starting with " + start);
197     String servlet = request.getServletPath();
198     page.form(servlet);
199     page.table(0);
200     page.row();
201       page.col();
202       page.out.println("Year");
203       page.col();
204       page.out.println("Salary (USD)");
205     Integer moreYear = (Integer)ses.getValue(MORE_YEAR);
206     int year = 1985;
207     if (moreYear != null) year = moreYear.intValue();
208     int n = year + 5;
209     while (year < n) {
210       page.row();
211         page.col();
212         page.out.println(year);
213         page.col();
214         page.field("sal" + year, "0", 10, 10);
215       ++year;
216     }
217     ses.putValue(MORE_YEAR, new Integer(year));
218     page.table();
219     page.submit(ACTION, MORE_DATA);
220     page.submit(ACTION, DONE_DATA);
221     page.submit(ACTION, LOGOUT);
222     page.form();
223     page.close();
224   }
225   
226   private void dataReady(HttpServletRequest request, HttpServletResponse response,
227       HttpSession ses) throws ServletException, IOException {
228     HtmlPage page = new HtmlPage(response);
229     String s = "Data ready - " + (String)ses.getValue(USERNAME);
230     page.title(s);
231     page.body();
232     page.center(true);
233     page.heading(1, s);
234     int count = 0;
235     int start = 0;
236     try {
237       start = ((Integer)ses.getValue(START_YEAR)).intValue();
238       count = ((Integer)ses.getValue(SALARY_COUNT)).intValue();
239     }
240     catch (Exception e) {
241     }
242     int end = start + count;
243     page.heading(3, count + " values entered " + start + " through " + end);
244     String servlet = request.getServletPath();
245     page.form(servlet, CHART, "target=_blank");
246     page.submit(ACTION, CHART);
247     page.form();
248     page.form(servlet, LOGOUT);
249     page.submit(ACTION, LOGOUT);
250     page.form();
251   }
252   
253   private void appendData(HttpServletRequest request, HttpServletResponse response,
254       HttpSession ses) throws ServletException, IOException {
255     Enumeration parameterList = request.getParameterNames();
256     int count = 0;
257     try {
258       count = ((Integer)ses.getValue(SALARY_COUNT)).intValue();
259     }
260     catch (Exception e) {
261     }
262     while (parameterList.hasMoreElements()) {
263       String parm = (String)parameterList.nextElement();
264       Integer val = null;
265       try {
266         val = new Integer(request.getParameter(parm));
267       }
268       catch (NumberFormatException e) {
269         val = new Integer(0);
270       }
271       if (parm.startsWith("sal")) {
272         ++count;
273         ses.putValue(parm, val);
274         }
275     }
276     ses.putValue(SALARY_COUNT, new Integer(count));
277   }
278   
279   private void makeChart(HttpServletRequest request, HttpServletResponse response,
280       HttpSession ses) throws ServletException, IOException {
281     appendData(request, response, ses);
282     response.setContentType("application/pdf");
283     PdfChart chart = new PdfChart(response.getOutputStream(),
284       (int)(11.0 * PdfChart.POINTS_PER_INCH), (int)(8.5 * PdfChart.POINTS_PER_INCH));
285     chart.setTextColor(0x0);
286     chart.setFont(chart.BOLD, 18);
287     chart.println((String)ses.getValue(USERNAME));
288   
289     // Get the cost of living base
290     double costOfLivingBase = 1000.0;
291     try {
292       costOfLivingBase = Double.parseDouble(configOptions.getProperty("costbase"));
293     }
294     catch (Exception e) {
295     }
296     chart.setFont(chart.NORMAL, 12);
297     chart.println("Cost of living 1968 base: $" + (int)costOfLivingBase);
298     chart.println(new Date().toString());
299   
300     // Set up the salary value set
301     int startYear = ((Integer)ses.getValue(START_YEAR)).intValue();
302     Vector salaries = new Vector();
303     double maxSal = 0.0;
304     int j = 0;
305     while (true) {
306       int yr = startYear + j;
307       ++j;
308       Integer val = (Integer)ses.getValue("sal" + yr);
309       if (val == null) break;
310       salaries.addElement(val);
311       if (val.intValue() > maxSal) maxSal = val.intValue();
312     }
313     if (maxSal < 1.0) {
314       chart.println("No salary data found");
315       chart.close();
316       return;
317     }
318     maxSal = ((int)(1.1 * maxSal / 10000.0) + 1) * 10000.0; // round up to $10K
319     double [] salData = new double [salaries.size()];
320     Enumeration enum = salaries.elements();
321     j = 0;
322     while (enum.hasMoreElements()) {
323       Integer val = (Integer)enum.nextElement();
324       salData[j++] = (double)val.intValue();
325     }
326     BurstGlyphValueSet salLine = new BurstGlyphValueSet("Income", 1.0,
327       0xff0000, salData, startYear, startYear + salData.length, 0xffff00,
328       10, new double [] { 0.08, 0.03 });
329     salLine.setConnected(true);
330   
331     // Set up the cost-of-living value set
332     j = 0;
333     while (j < CPIData.length) {
334       if (CPIData[j].year == startYear) break;
335       ++j;
336     }
337     if (j < CPIData.length) {
338       double [] cpi = new double [salData.length];
339       for (int i = 0; i < cpi.length; ++i) {
340         cpi[i] = CPIData[j + i].indexPercentage;
341       }
342       AreaValueSet cpiArea = new AreaValueSet("Cost of Living", 1.0, 0x0000ff,
343         cpi, startYear, startYear + cpi.length, 0xaaaaff, true);
344       chart.appendValues(cpiArea);
345       cpiArea.setRange(0.0, (maxSal / costOfLivingBase) * 100.0, 0.0);
346     }
347   
348     // Draw the chart
349     salLine.setRange(0.0, maxSal, 0.0);
350     chart.appendValues(salLine);
351     chart.appendGridX(0.5, 1, 0xffffff);
352     chart.appendGridY(0.5, 1, 0xffffff);
353     chart.drawMain(1.0, 2.0, 9.0, 5.0,
354       salData.length - 1, (int)(maxSal / 10000.0),
355       0xdddddd, 1.5, 0x0);
356     chart.drawLegend(6.0, 0.5, 2.0, 1.0, 0.15, 0.09, 0xdddddd, 2.0, 0x0);
357     String [] years = new String [salData.length];
358     for (int i = 0; i < years.length; ++i) years[i] = Integer.toString(startYear + i);
359     chart.drawBottomLabels(-0.15, 0.25, 0.0, years, 0.06);
360     String [] k = new String [(int)(maxSal / 10000.0) + 1];
361     k[0] = null;
362     for (int i = 1; i < k.length; ++i) k[i] = "$" + i + "0K";
363     chart.drawLeftLabels(0.15, -0.16, 90.0, k, 0.06);
364     chart.close();
365   }
366   
367   }