1 | package PIANOS.datastructures; |
2 | |
3 | import PIANOS.exceptions.*; |
4 | import java.util.*; |
5 | import java.io.File; |
6 | import java.io.FileNotFoundException; |
7 | import java.util.StringTokenizer; |
8 | |
9 | |
10 | public class DistributionFactory{ |
11 | |
12 | private HashMap<String, DistributionSkeleton> userDistributions; |
13 | |
14 | |
15 | |
16 | public DistributionFactory (String name) throws MissingFunctionException, SyntaxException{ |
17 | |
18 | userDistributions = new HashMap<String, DistributionSkeleton>(); |
19 | |
20 | Scanner reader = null; |
21 | try{ |
22 | reader = new Scanner (new File (name)); |
23 | }catch (FileNotFoundException e){ |
24 | throw new MissingFunctionException ("The user defined function file could not be found!"); |
25 | // The file was not found |
26 | } |
27 | |
28 | StringTokenizer tokenizer; |
29 | String temp; |
30 | int count, index, line = 0, userParameters = 0; |
31 | |
32 | String nameOfFunction; |
33 | boolean[] type; |
34 | boolean hasGen; |
35 | |
36 | DistributionSkeleton skeleton; |
37 | |
38 | // Do as long as the first character in the line is '!' |
39 | while (reader.hasNextLine()){ |
40 | temp = reader.nextLine(); |
41 | |
42 | if (temp.length() > 0 && temp.charAt(0) != '!') |
43 | break; |
44 | |
45 | line++; |
46 | |
47 | if (temp.length() == 0) |
48 | continue; |
49 | |
50 | //Create a new StringTokenizer, tokens are sparated with '!', ' ' or ',' |
51 | tokenizer = new StringTokenizer (temp, " !"); |
52 | count = tokenizer.countTokens(); |
53 | |
54 | //Every line has to have at least 3 tokes: name, number of parameters and boolean value |
55 | count = count - 3; |
56 | if (count < 0) |
57 | //Line has less than 3 tokens... |
58 | throw new SyntaxException ("Syntax error has been detected in user defined function file \"" + name + "\"\nLine " + line + " does not have enough arguments."); |
59 | |
60 | //First token, the name of the function, is read |
61 | nameOfFunction = tokenizer.nextToken(); |
62 | nameOfFunction = nameOfFunction.toLowerCase(); |
63 | if (!nameOfFunction.startsWith("user_")) |
64 | throw new SyntaxException ("Syntax error has been detected in user defined function file \"" + name + "\"" |
65 | + "\n Line " + line + " has an incorrect function name. The function name needs to start with \"user_\""); |
66 | |
67 | //Second token, the number of parameters, is compared to total number of tokens |
68 | try{ |
69 | userParameters = Integer.parseInt(tokenizer.nextToken()); |
70 | }catch (NumberFormatException e){ |
71 | throw new SyntaxException ("Syntax error has been detected in user defined function file \"" + name + "\", line " + line |
72 | + "\nNumber of parameters field is not an integer."); |
73 | } |
74 | |
75 | if (count != userParameters) |
76 | //Oops... number of parameters and calculated number of parameters vary from eachother! |
77 | throw new SyntaxException ("Syntax error has been detected in user defined function file \"" + name + |
78 | "\"\nNumber of arguments does not corespond to number of parameters in line" + line); |
79 | |
80 | type = new boolean [count]; |
81 | index = 0; |
82 | |
83 | //Parameter types... |
84 | while (index < count){ |
85 | temp = tokenizer.nextToken(); |
86 | temp = temp.toLowerCase(); |
87 | if (temp.equals("integer")) |
88 | type[index] = true; |
89 | else if (temp.equals("real")) |
90 | type[index] = false; |
91 | else |
92 | //Syntax error in parameter type |
93 | throw new SyntaxException ("Syntax error has been detected in user defined function file \"" + name + |
94 | "\"\nLine " + line + " has an invalid parameter type."); |
95 | index++; |
96 | } |
97 | |
98 | //Last boolean value... |
99 | temp = tokenizer.nextToken(); |
100 | temp = temp.toLowerCase(); |
101 | if (temp.equals(".true.")) |
102 | hasGen = true; |
103 | else if (temp.equals(".false.")) |
104 | hasGen = false; |
105 | else |
106 | //Syntax error... |
107 | throw new SyntaxException ("Syntax error has been detected in user defined function file \"" + name + |
108 | "\"\nLine " + line + " has an invalid boolean value."); |
109 | |
110 | //Everything is fine, new skeleton is created |
111 | skeleton = new DistributionSkeleton (nameOfFunction, count, type, true, hasGen); |
112 | DistributionSkeleton check = null; |
113 | check = userDistributions.get(nameOfFunction); |
114 | if(check != null) |
115 | throw new SyntaxException ("User defined distribution '" + nameOfFunction + "' has been defined twice in the user defined distribution file!" |
116 | + "\nPlease remove the second definition."); |
117 | userDistributions.put(nameOfFunction, skeleton); |
118 | } |
119 | } |
120 | |
121 | public Distribution getDistribution (String name) throws MissingDistributionException{ |
122 | |
123 | name = name.toLowerCase(); |
124 | |
125 | if (name.equals("discrete_uniform")) |
126 | { |
127 | return new DiscreteUniformDistribution(); |
128 | } |
129 | else if (name.equals("binomial")) |
130 | { |
131 | return new BinomialDistribution(); |
132 | } |
133 | else if (name.equals("poisson")) |
134 | { |
135 | return new PoissonDistribution(); |
136 | } |
137 | else if (name.equals("continuous_uniform")) |
138 | { |
139 | return new ContinuousUniformDistribution(); |
140 | } |
141 | else if (name.equals("beta")) |
142 | { |
143 | return new BetaDistribution(); |
144 | } |
145 | |
146 | DistributionSkeleton skeleton = userDistributions.get(name); |
147 | if (skeleton == null) |
148 | throw new MissingDistributionException ("Could not find user-defined distribution called \"" + name + "\"."); |
149 | |
150 | return new UserDefinedDistribution (skeleton); |
151 | |
152 | } |
153 | |
154 | |
155 | } |