So I'm trying to populate two arrays from a file reader. Which I believe requires nested loops. I think I'm on the right track but I've been a little stuck since yesterday. The purpose of this program is to initiate the program through a jsp and to read in the values dynamically. Any help would really be appreciated. I think I'm on the right track but I can't seem to finish it on my own. The first line of fxRates.csv should be populated into the currencyCodes Array and the rest of the lines should be populated into the 2d array fxExchangeRates. I got the code to not have any errors but now all I get is this when I try to run the program:
Here is the error log:
Info: visiting unvisited references
Info: visiting unvisited references
Info: visiting unvisited references
Warning: Ignore WEB-INF/sun-web.xml in archive /G:/School/Java II/Labs/MidtermAD/build/web/, as WLS counterpart runtime xml WEB-INF/glassfish-web.xml is present in the same archive.
Info: Loading application [MidtermAD] at [/MidtermAD]
Info: MidtermAD was successfully deployed in 464 milliseconds.
Warning: StandardWrapperValve[jsp]: Servlet.service() for servlet jsp threw exception
java.lang.NullPointerException
at java.lang.String.split(String.java:2337)
at java.lang.String.split(String.java:2422)
at data.FxDataModel.<init>(FxDataModel.java:38)
at org.apache.jsp.fxCalc_jsp.jspInit(fxCalc_jsp.java:45)
at org.apache.jasper.runtime.HttpJspBase.init(HttpJspBase.java:92)
at org.apache.jasper.servlet.JspServletWrapper.getServlet(JspServletWrapper.java:210)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:388)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:473)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:377)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:415)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:282)
at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:201)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:175)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:561)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545)
at java.lang.Thread.run(Thread.java:745)
fxInit.jsp:
<%@page import="java.io.*"%>
<%@page import="java.util.*"%>
<%@ page import="data.FxDataModel"%>
<%!
private FxDataModel fxDataModel;
public void jspInit(){
Properties fxProps = new Properties();
ServletContext context = getServletContext();
fxProps.getProperty(FxDataModel.FX_PRP_FILE_NAME_KEY);
context.getRealPath(context.getInitParameter(FxDataModel.FX_PRP_FILE_NAME_KEY));
try{
FileInputStream input = new FileInputStream(FxDataModel.FX_PRP_FILE_NAME_KEY);
fxProps.load(input);
input.close();
}catch(IOException e){
FileInputStream input = null;
}
context.getRealPath(fxProps.getProperty(FxDataModel.FX_RATE_FILE_NAME_KEY));
try{
FileInputStream input = new FileInputStream(FxDataModel.FX_RATE_FILE_NAME_KEY);
fxProps.load(input);
input.close();
}catch(IOException e){
FileInputStream input = null;
}
fxDataModel = new FxDataModel(fxProps);
}
%>
FxDataModel.Java:
package data;
import java.util.*;
public class FxDataModel {
public static final String FX_PRP_FILE_NAME_KEY = "fx.prp.file.name";
public static final String FX_RATE_FILE_NAME_KEY = "fx.rates.file.name";
public static final String FX_RATES_FILE_DLMTR_KEY = "fx.rates.file.dlmtr";
public static final String SRC_AMT_KEY = "src.amt";
public static final String SRC_CUCY_KEY = "src.cucy";
public static final String DST_AMT_KEY = "dst.amt";
public static final String DST_CUCY_KEY = "dst.cucy";
private Properties fxProps = new Properties();
private double [][] fxExchangeRates;
private String[] fxCurrencies;
public FxDataModel(Properties fxProps)
{
this.fxProps = fxProps;
String[] rateStrings;
String record;
fxProps .setProperty(FX_RATES_FILE_DLMTR_KEY,"fx.rates.file.dlmtr");
String delimiter = fxProps.getProperty(FX_RATES_FILE_DLMTR_KEY);
Scanner reader = new Scanner(FX_RATE_FILE_NAME_KEY);
fxCurrencies = reader.nextLine().split(delimiter);
for( int i = 0 ; i < fxCurrencies.length ; i++ ){
record= reader.nextLine();
rateStrings = record.split(delimiter);
fxExchangeRates[i] = new double[fxCurrencies.length];
for( int j = 0 ; j < rateStrings.length ; j++ ){
fxExchangeRates[i][j]= Double.parseDouble(rateStrings[j]);
}
reader.close();
}
}
public Properties getFxProps()
{
return fxProps;
}
public String[] getFxCurrencies(){
return fxCurrencies;
}
public double getFxRate(final String inNumber, final String outNumber){
int Currency1;
int Currency2;
double rate;
for(Currency1 = 0; Currency1 <getFxCurrencies().length; Currency1++){
if(inNumber.equals(fxCurrencies[Currency1])){
break;
}
}
for(Currency2 = 0; Currency2 <getFxCurrencies().length; Currency2++){
if(outNumber.equals(fxCurrencies[Currency2])){
break;
}
}
rate = fxExchangeRates[Currency1][Currency2];
return rate;
}
}
fxCalc.jsp
<%@include file="fxInit.jsp"%>
<%
Properties fxProps = fxDataModel.getFxProps();
String srcAmtName = fxProps.getProperty(FxDataModel.SRC_AMT_KEY );
String dstAmtName = fxProps.getProperty(FxDataModel.DST_AMT_KEY );
String srcCucyName = fxProps.getProperty(FxDataModel.SRC_CUCY_KEY );
String dstCucyName = fxProps.getProperty(FxDataModel.DST_CUCY_KEY );
String Curr1 = request.getParameter(srcAmtName);
String Curr2 = request.getParameter(dstAmtName);
String formInput;
String formOutput;
String[] currencies = fxDataModel.getFxCurrencies();
try {
formInput = request.getParameter(srcAmtName);
Double formDouble = Double.parseDouble(formInput);
Double Conversion = fxDataModel.getFxRate(Curr1,Curr2)*formDouble;
formOutput = String.valueOf(Conversion);
} catch (NumberFormatException ex) {
Curr1= Curr2 = currencies[0];
formInput = ("");
formOutput = ("");
} catch (NullPointerException npe){
Curr1= Curr2 = currencies[0];
formInput = ("");
formOutput = ("");
}
%>
<html>
<head>
<title>F/X Calculator</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<style>
h1{
color: white;
font-family: verdana;
font-size: 200%;
font-style: italic;
text-align: center;
}
hr{
color:white;
}
select{
margin-top: 30px;
margin-right:10px;
}
input{
margin-top: 30px;
margin-right:10px;
}
</style>
<body bgcolor = "blue">
<h1>
Money Banks F/X Calculator<br>
</h1>
<hr>
<div align="center">
<form name ="fxCalc" action="fxCalc.jsp" method="POST">
<select name="<%=srcCucyName%>">
<% for (String currency : currencies) { %>
<option value="<%=currency%>" <%=currency.equals(Curr1)?"selected":""%>><%=currency%></option>
<%}%>
</select>
<input name="<%=srcAmtName%>" type="text" value = <%=formInput%> >
<select name="<%=dstCucyName%>">
<% for (String currency : currencies) { %>
<option value="<%=currency%>" <%=currency.equals(Curr2)?"selected":""%>><%=currency%></option>
<%}%>
</select>
<input name="<%=dstAmtName%>" type="text" disabled="disabled" value = <%=formOutput%>>
<br>
<input name="submitbutton" type="submit" value="Convert" name="Convert"/>
<input name="resetbutton" type="reset" value="Reset"/>
<form/>
<div/>
</body>
</html>
One thing I'm really not understanding is that I'm not supposed to "hard code" the form controls in the html so that is why these "SRC_AMT_KEY" keys were provided. I'm just not sure exactly how to implement them. I tried my best but I don't understand this part entirely. Are the keys supposed to replace variables like "Curr1" and "Curr2"? This is how the application worked before but we are updating it now so that nothing is hard coded. I would really appreciate any help in understanding this project. I've been stuck on it for a couple days now and I will continue to update the code if I make any progress. Thank you!
Here are also the contents of the fxCalc.prp file:
dst.amt=dstAmt
dst.cucy=dstCucy
fx.rates.file.dlmtr=,
fx.rates.file.name=/WEB-INF/fxRates.csv
src.amt=srcAmt
src.cucy=srcCucy
The fxRates.csv file also contains these codes:
CAD,EUR,GBP,USD
1.0,0.624514066,0.588714763,0.810307
1.601244959,1.0,0.942676548,1.2975
1.698615463,1.060809248,1.0,1.3764
1.234100162,0.772200772,.726532984,1.0