View Javadoc
1   package org.djunits.generator;
2   
3   import java.io.BufferedReader;
4   import java.io.File;
5   import java.io.FileNotFoundException;
6   import java.io.FileReader;
7   import java.io.IOException;
8   import java.io.PrintWriter;
9   import java.net.URISyntaxException;
10  import java.net.URL;
11  import java.nio.file.Files;
12  import java.nio.file.Paths;
13  import java.util.ArrayList;
14  import java.util.HashMap;
15  import java.util.List;
16  import java.util.Map;
17  
18  /**
19   * <p>
20   * Copyright (c) 2013-2018 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
21   * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
22   * <p>
23   * $LastChangedDate: 2018-01-28 03:21:11 +0100 (Sun, 28 Jan 2018) $, @version $Revision: 258 $, by $Author: averbraeck $,
24   * initial version Sep 1, 2015 <br>
25   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
26   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
27   */
28  public class GenerateDJUNIT
29  {
30      /** The output folder of the writer -- will be written in Eclipse project-root/generated-code/org/djunits folder. */
31      private static final String generatedCodeRelativePath = "/generated-code/org/djunits/";
32  
33      /**
34       * The calculated absolute output path (root of the executable or Jar file). In case of an Eclipse run, ../../ is added to
35       * the path to place the results in the root of the project, rather than in target/classes.
36       */
37      private static String absoluteRootPath;
38  
39      /** List of Abs + Rel types. */
40      private static List<String[]> typesAbsRel = new ArrayList<>();
41  
42      /** List of Rel types. */
43      private static List<String> typesRel = new ArrayList<>();
44  
45      /** List of Money types. */
46      private static List<String> typesMoney = new ArrayList<>();
47  
48      /** Map of types to formulas. */
49      private static Map<String, List<String>> formulas = new HashMap<>();
50  
51      /** Map of replacement tags to replacement string. */
52      private static Map<String, String> replaceMap = new HashMap<>();
53  
54      /** Map of replacement tags to type for which the replacement has to be done. */
55      private static Map<String, String> replaceType = new HashMap<>();
56  
57      /**
58       * Read the types from the file /TYPES_ABS_REL.txt.
59       * @throws IOException on I/O error
60       */
61      private static void readAbsRelTypes() throws IOException
62      {
63          URL typesURL = URLResource.getResource("/TYPES_ABS_REL.txt");
64          FileReader fileReader = new FileReader(new File(typesURL.getPath()));
65          BufferedReader bufferedReader = new BufferedReader(fileReader);
66          String line = null;
67          while ((line = bufferedReader.readLine()) != null)
68          {
69              if (line.length() > 0)
70              {
71                  typesAbsRel.add(line.split(","));
72              }
73          }
74          bufferedReader.close();
75      }
76  
77      /**
78       * Read the types from the file /TYPES_REL.txt.
79       * @throws IOException on I/O error
80       */
81      private static void readRelTypes() throws IOException
82      {
83          URL typesURL = URLResource.getResource("/TYPES_REL.txt");
84          FileReader fileReader = new FileReader(new File(typesURL.getPath()));
85          BufferedReader bufferedReader = new BufferedReader(fileReader);
86          String line = null;
87          while ((line = bufferedReader.readLine()) != null)
88          {
89              if (line.length() > 0)
90              {
91                  typesRel.add(line);
92              }
93          }
94          bufferedReader.close();
95      }
96  
97      /**
98       * Read the types from the file /TYPES_MONEY.txt.
99       * @throws IOException on I/O error
100      */
101     private static void readMoneyTypes() throws IOException
102     {
103         URL typesURL = URLResource.getResource("/TYPES_MONEY.txt");
104         FileReader fileReader = new FileReader(new File(typesURL.getPath()));
105         BufferedReader bufferedReader = new BufferedReader(fileReader);
106         String line = null;
107         while ((line = bufferedReader.readLine()) != null)
108         {
109             if (line.length() > 0)
110             {
111                 typesMoney.add(line);
112             }
113         }
114         bufferedReader.close();
115     }
116 
117     /**
118      * Read the formulas from the file /FORMULAS.txt.
119      * @throws IOException on I/O error
120      */
121     private static void readFormulas() throws IOException
122     {
123         URL typesURL = URLResource.getResource("/FORMULAS.txt");
124         FileReader fileReader = new FileReader(new File(typesURL.getPath()));
125         BufferedReader bufferedReader = new BufferedReader(fileReader);
126         String type = null;
127         String line = null;
128         List<String> flist = new ArrayList<>();
129         while ((line = bufferedReader.readLine()) != null)
130         {
131             if (line.startsWith("%"))
132             {
133                 if (type != null)
134                 {
135                     formulas.put(type, flist);
136                 }
137                 type = line.replaceAll("%", "").trim();
138                 flist = new ArrayList<>();
139             }
140             else
141             {
142                 if (line.trim().length() > 0)
143                 {
144                     flist.add(line.trim());
145                 }
146             }
147         }
148         formulas.put(type, flist);
149         bufferedReader.close();
150     }
151 
152     /**
153      * Read the replacement strings from the file /REPLACE.txt.
154      * @throws IOException on I/O error
155      */
156     private static void readReplace() throws IOException
157     {
158         URL typesURL = URLResource.getResource("/REPLACE.txt");
159         FileReader fileReader = new FileReader(new File(typesURL.getPath()));
160         BufferedReader bufferedReader = new BufferedReader(fileReader);
161         String tag = null;
162         String line = null;
163         String type = null;
164         String replacementLines = "";
165         while ((line = bufferedReader.readLine()) != null)
166         {
167             if (line.startsWith("##"))
168             {
169                 if (tag != null)
170                 {
171                     replaceMap.put(tag, replacementLines);
172                     replaceType.put(tag, type);
173                     tag = null;
174                 }
175                 else
176                 {
177                     tag = line.trim();
178                     type = bufferedReader.readLine();
179                     replacementLines = "";
180                 }
181             }
182             else
183             {
184                 replacementLines += line + "\n";
185             }
186         }
187         bufferedReader.close();
188     }
189 
190     /****************************************************************************************************************/
191     /********************************************* SCALAR ***********************************************************/
192     /****************************************************************************************************************/
193 
194     /**
195      * Insert formulas based on FORMULAS.txt into the %FORMULAS% marker within the Java file.
196      * @param java the java file
197      * @param errorType the type for error messaging
198      * @param prefix e.g., Float for Float types, or blank for Double types
199      * @return the file with replacements
200      */
201     private static String formulas(String java, String errorType, String prefix)
202     {
203         String ret = java;
204         while (ret.contains("%FORMULAS%"))
205         {
206             int pos = ret.indexOf("%FORMULAS%");
207             ret = ret.replaceFirst("%FORMULAS%", "");
208             int end = ret.indexOf("%", pos);
209             if (end == -1)
210             {
211                 System.err.println("Closing % not found for %FORMULAS% in file for type " + errorType);
212                 return ret;
213             }
214             String type = ret.substring(pos, end);
215             String pType = prefix + type;
216             if (!formulas.containsKey(type))
217             {
218                 System.err.println("Formulas in FORMULAS.txt does not contain entry for type " + errorType);
219                 return ret.substring(0, pos - 1) + ret.substring(pos + type.length() + 2, ret.length() - 1);
220             }
221             String fStr = "";
222             for (String f : formulas.get(type))
223             {
224                 String dm = f.startsWith("/") ? "division" : "multiplication";
225                 String method = f.startsWith("/") ? "divideBy" : "multiplyBy";
226                 String mdsign = f.startsWith("/") ? "/" : "*";
227                 f = f.substring(1, f.length());
228                 String param = f.split("=")[0].trim();
229                 String result = f.split("=")[1].trim();
230                 String siOrMoney = (result.startsWith("Money")) ? ".getStandard" + result + "Unit()" : ".SI";
231                 String pParam = prefix + param;
232                 String pResult = prefix + result;
233 
234                 fStr += "        /**\n";
235                 fStr += "         * Calculate the " + dm + " of " + pType + " and " + pParam + ", which results in a ";
236                 fStr += pResult + " scalar.\n";
237                 fStr += "         * @param v " + pType + " scalar\n";
238                 fStr += "         * @return " + pResult + " scalar as a " + dm + " of " + pType + " and " + pParam + "\n";
239                 fStr += "         */\n";
240                 fStr += "        public final " + pResult + " " + method;
241                 fStr += "(final " + pParam + " v)\n";
242                 fStr += "        {\n";
243                 fStr += "            return new " + pResult + "(this.si " + mdsign + " v.si, ";
244                 fStr += result + "Unit" + siOrMoney + ");\n";
245                 fStr += "        }\n\n";
246             }
247             ret = ret.substring(0, pos - 1) + fStr + ret.substring(pos + type.length() + 1, ret.length() - 1);
248         }
249         return ret;
250     }
251 
252     /**
253      * Insert replacements based on REPLACCE.txt into the Java file.
254      * @param java the file
255      * @param type the type
256      * @return the file with replacements
257      */
258     private static String replace(String java, String type)
259     {
260         // replace the "replacement" tags
261         for (String tag : replaceMap.keySet())
262         {
263             String replacement = (replaceType.get(tag).equals(type)) ? replaceMap.get(tag) : "";
264             while (java.contains(tag))
265             {
266                 java = java.replace(tag, replacement);
267             }
268         }
269         return java;
270     }
271 
272     /**
273      * Replace the %TypeAbs%, %TypeRel%, %TypeAbsUnit%, and %TypeRelUnit% tags in the java string.
274      * @param in the original java string
275      * @param type the types: [abs, rel, unit]
276      * @return the java string with replacements
277      */
278     private static String replaceAbsRel(final String in, final String[] type)
279     {
280         String typeAbs = type[0];
281         String typeRel = type[1];
282         String typeAbsUnit = type[2];
283         String typeRelUnit = type[3];
284         String java = in.replaceAll("%TypeAbs%", typeAbs);
285         java = java.replaceAll("%typeabs%", typeAbs.toLowerCase());
286         java = java.replaceAll("%TYPEABS%", typeAbs.toUpperCase());
287         java = java.replaceAll("%TypeRel%", typeRel);
288         java = java.replaceAll("%typerel%", typeRel.toLowerCase());
289         java = java.replaceAll("%TYPEREL%", typeRel.toUpperCase());
290         java = java.replaceAll("%TypeAbsUnit%", typeAbsUnit);
291         java = java.replaceAll("%typeabsunit%", typeAbsUnit.toLowerCase());
292         java = java.replaceAll("%TYPEABSUNIT%", typeAbsUnit.toUpperCase());
293         java = java.replaceAll("%TypeRelUnit%", typeRelUnit);
294         java = java.replaceAll("%typerelunit%", typeRelUnit.toLowerCase());
295         java = java.replaceAll("%TYPERELUNIT%", typeRelUnit.toUpperCase());
296         return java;
297     }
298 
299     /**
300      * Generate all Abs + Rel classes in value.vdouble.scalar.
301      * @throws IOException on I/O error
302      * @throws URISyntaxException when file could not be found on thhe file system
303      */
304     private static void generateDoubleScalarAbsRel() throws IOException, URISyntaxException
305     {
306         for (int i = 0; i <= 1; i++)
307         {
308             String relativePath = "value/vdouble/scalar/";
309             URL scalarURL = URLResource
310                     .getResource("/" + relativePath + ((i == 0) ? "DOUBLE_SCALAR_AR_ABS.java" : "DOUBLE_SCALAR_AR_REL.java"));
311             String scalarJava = new String(Files.readAllBytes(Paths.get(scalarURL.toURI())));
312 
313             for (String[] type : typesAbsRel)
314             {
315                 File outPath = new File(absoluteRootPath + relativePath);
316                 outPath.mkdirs();
317                 PrintWriter out = new PrintWriter(absoluteRootPath + relativePath + type[i] + ".java");
318                 String java = new String(scalarJava);
319                 java = replaceAbsRel(java, type);
320                 java = formulas(java, "DoubleScalar => " + type[i], "");
321                 java = replace(java, type[i]);
322                 out.print(java);
323                 out.close();
324                 System.out.println("built: " + absoluteRootPath + relativePath + type[i] + ".java");
325             }
326         }
327     }
328 
329     /**
330      * Generate all Rel classes in value.vdouble.scalar.
331      * @throws IOException on I/O error
332      * @throws URISyntaxException when file could not be found on thhe file system
333      */
334     private static void generateDoubleScalarRel() throws IOException, URISyntaxException
335     {
336         String relativePath = "value/vdouble/scalar/";
337         URL scalarURL = URLResource.getResource("/" + relativePath + "DOUBLE_SCALAR_REL.java");
338         String scalarJava = new String(Files.readAllBytes(Paths.get(scalarURL.toURI())));
339 
340         for (String type : typesRel)
341         {
342             File outPath = new File(absoluteRootPath + relativePath);
343             outPath.mkdirs();
344             PrintWriter out = new PrintWriter(absoluteRootPath + relativePath + type + ".java");
345             String java = new String(scalarJava);
346             java = java.replaceAll("%Type%", type);
347             java = java.replaceAll("%type%", type.toLowerCase());
348             java = java.replaceAll("%TYPE%", type.toUpperCase());
349             if (java.contains("class Dimensionless"))
350             {
351                 java = java.replace("%DIMLESS%", " implements MathFunctionsDimensionless<Dimensionless>");
352                 URL dimlessURL = URLResource.getResource("/" + relativePath + "DimlessFunctions.java");
353                 String dimlessFunctions = new String(Files.readAllBytes(Paths.get(dimlessURL.toURI())));
354                 int pos = java.indexOf("%FORMULAS%");
355                 java = java.substring(0, pos - 1) + dimlessFunctions + java.substring(pos, java.length() - 1);
356             }
357             java = java.replace("%DIMLESS%", "");
358             java = formulas(java, "DoubleScalar => " + type, "");
359             java = replace(java, type);
360             out.print(java);
361             out.close();
362             System.out.println("built: " + absoluteRootPath + relativePath + type + ".java");
363         }
364     }
365 
366     /**
367      * Generate all Money classes in value.vdouble.scalar.
368      * @throws IOException on I/O error
369      * @throws URISyntaxException when file could not be found on thhe file system
370      */
371     private static void generateDoubleScalarMoney() throws IOException, URISyntaxException
372     {
373         String relativePath = "value/vdouble/scalar/";
374         URL scalarURL = URLResource.getResource("/" + relativePath + "DOUBLE_SCALAR_MONEY.java");
375         String scalarJava = new String(Files.readAllBytes(Paths.get(scalarURL.toURI())));
376 
377         for (String type : typesMoney)
378         {
379             File outPath = new File(absoluteRootPath + relativePath);
380             outPath.mkdirs();
381             PrintWriter out = new PrintWriter(absoluteRootPath + relativePath + type + ".java");
382             String java = new String(scalarJava);
383             java = java.replaceAll("%Type%", type);
384             java = java.replaceAll("%type%", type.toLowerCase());
385             java = java.replaceAll("%TYPE%", type.toUpperCase());
386             java = java.replace("%DIMLESS%", "");
387             java = formulas(java, "DoubleScalar => " + type, "");
388             java = replace(java, type);
389             out.print(java);
390             out.close();
391             System.out.println("built: " + absoluteRootPath + relativePath + type + ".java");
392         }
393     }
394 
395     /**
396      * Generate all Abs + Rel classes in value.vfloat.scalar.
397      * @throws IOException on I/O error
398      * @throws URISyntaxException when file could not be found on thhe file system
399      */
400     private static void generateFloatScalarAbsRel() throws IOException, URISyntaxException
401     {
402         for (int i = 0; i <= 1; i++)
403         {
404             String relativePath = "value/vfloat/scalar/";
405             URL scalarURL = URLResource
406                     .getResource("/" + relativePath + ((i == 0) ? "FLOAT_SCALAR_AR_ABS.java" : "FLOAT_SCALAR_AR_REL.java"));
407             String scalarJava = new String(Files.readAllBytes(Paths.get(scalarURL.toURI())));
408 
409             for (String type[] : typesAbsRel)
410             {
411                 String fType = "Float" + type[i];
412                 File outPath = new File(absoluteRootPath + relativePath);
413                 outPath.mkdirs();
414                 PrintWriter out = new PrintWriter(absoluteRootPath + relativePath + fType + ".java");
415                 String java = new String(scalarJava);
416                 java = replaceAbsRel(java, type);
417                 java = formulas(java, "FloatScalar => " + type[i], "Float");
418                 java = replace(java, type[i]);
419                 out.print(java);
420                 out.close();
421                 System.out.println("built: " + absoluteRootPath + relativePath + fType + ".java");
422             }
423         }
424     }
425 
426     /**
427      * Generate all Rel classes in value.vfloat.scalar.
428      * @throws IOException on I/O error
429      * @throws URISyntaxException when file could not be found on thhe file system
430      */
431     private static void generateFloatScalarRel() throws IOException, URISyntaxException
432     {
433         String relativePath = "value/vfloat/scalar/";
434         URL scalarURL = URLResource.getResource("/" + relativePath + "FLOAT_SCALAR_REL.java");
435         String scalarJava = new String(Files.readAllBytes(Paths.get(scalarURL.toURI())));
436 
437         for (String type : typesRel)
438         {
439             String fType = "Float" + type;
440             File outPath = new File(absoluteRootPath + relativePath);
441             outPath.mkdirs();
442             PrintWriter out = new PrintWriter(absoluteRootPath + relativePath + fType + ".java");
443             String java = new String(scalarJava);
444             java = java.replaceAll("%Type%", type);
445             java = java.replaceAll("%type%", type.toLowerCase());
446             java = java.replaceAll("%TYPE%", type.toUpperCase());
447             if (java.contains("class FloatDimensionless"))
448             {
449                 java = java.replace("%DIMLESS%", " implements MathFunctionsDimensionless<FloatDimensionless>");
450                 URL dimlessURL = URLResource.getResource("/" + relativePath + "DimlessFunctions.java");
451                 String dimlessFunctions = new String(Files.readAllBytes(Paths.get(dimlessURL.toURI())));
452                 int pos = java.indexOf("%FORMULAS%");
453                 java = java.substring(0, pos - 1) + dimlessFunctions + java.substring(pos, java.length() - 1);
454             }
455             java = java.replace("%DIMLESS%", "");
456             java = formulas(java, "FloatScalar => " + type, "Float");
457             java = replace(java, type);
458             out.print(java);
459             out.close();
460             System.out.println("built: " + absoluteRootPath + relativePath + fType + ".java");
461         }
462     }
463 
464     /**
465      * Generate all Money classes in value.vfloat.scalar.
466      * @throws IOException on I/O error
467      * @throws URISyntaxException when file could not be found on thhe file system
468      */
469     private static void generateFloatScalarMoney() throws IOException, URISyntaxException
470     {
471         String relativePath = "value/vfloat/scalar/";
472         URL scalarURL = URLResource.getResource("/" + relativePath + "FLOAT_SCALAR_MONEY.java");
473         String scalarJava = new String(Files.readAllBytes(Paths.get(scalarURL.toURI())));
474 
475         for (String type : typesMoney)
476         {
477             String fType = "Float" + type;
478             File outPath = new File(absoluteRootPath + relativePath);
479             outPath.mkdirs();
480             PrintWriter out = new PrintWriter(absoluteRootPath + relativePath + fType + ".java");
481             String java = new String(scalarJava);
482             java = java.replaceAll("%Type%", type);
483             java = java.replaceAll("%type%", type.toLowerCase());
484             java = java.replaceAll("%TYPE%", type.toUpperCase());
485             java = java.replace("%DIMLESS%", "");
486             java = formulas(java, "FloatScalar => " + type, "Float");
487             java = replace(java, type);
488             out.print(java);
489             out.close();
490             System.out.println("built: " + absoluteRootPath + relativePath + fType + ".java");
491         }
492     }
493 
494     /****************************************************************************************************************/
495     /************************************************ VECTOR ********************************************************/
496     /****************************************************************************************************************/
497 
498     /**
499      * Insert formulas based on FORMULAS.txt into the %FORMULAS% marker within the Java file.
500      * @param java the java file
501      * @param errorType the type for error messaging
502      * @param prefix e.g., Float for Float types, or blank for Double types
503      * @return the file with replacements
504      */
505     private static String formulasVector(String java, String errorType, String prefix)
506     {
507         String ret = java;
508         while (ret.contains("%FORMULAS%"))
509         {
510             int pos = ret.indexOf("%FORMULAS%");
511             ret = ret.replaceFirst("%FORMULAS%", "");
512             int end = ret.indexOf("%", pos);
513             if (end == -1)
514             {
515                 System.err.println("Closing % not found for %FORMULAS% in file for type " + errorType);
516                 return ret;
517             }
518             String type = ret.substring(pos, end);
519             if (!formulas.containsKey(type))
520             {
521                 System.err.println("Formulas in FORMULAS.txt does not contain entry for type " + errorType);
522                 return ret.substring(0, pos - 1) + ret.substring(pos + type.length() + 2, ret.length() - 1);
523             }
524             String fStr = "";
525             ret = ret.substring(0, pos - 1) + fStr + ret.substring(pos + type.length() + 1, ret.length() - 1);
526         }
527         return ret;
528     }
529 
530     /****************************************************************************************************************/
531     /********************************************* DOUBLEVECTOR *****************************************************/
532     /****************************************************************************************************************/
533 
534     /**
535      * Generate all Abs + Rel classes in value.vdouble.vector.
536      * @throws IOException on I/O error
537      * @throws URISyntaxException when file could not be found on thhe file system
538      */
539     private static void generateDoubleVectorAbsRel() throws IOException, URISyntaxException
540     {
541         for (int i = 0; i <= 1; i++)
542         {
543             String relativePath = "value/vdouble/vector/";
544             URL vectorURL = URLResource
545                     .getResource("/" + relativePath + ((i == 0) ? "DOUBLE_VECTOR_AR_ABS.java" : "DOUBLE_VECTOR_AR_REL.java"));
546             String vectorJava = new String(Files.readAllBytes(Paths.get(vectorURL.toURI())));
547 
548             for (String type[] : typesAbsRel)
549             {
550                 File outPath = new File(absoluteRootPath + relativePath);
551                 outPath.mkdirs();
552                 PrintWriter out = new PrintWriter(absoluteRootPath + relativePath + type[i] + "Vector.java");
553                 String java = new String(vectorJava);
554                 java = replaceAbsRel(java, type);
555                 java = formulasVector(java, "DoubleVector => " + type[i], "");
556                 java = replace(java, type[i]);
557                 out.print(java);
558                 out.close();
559                 System.out.println("built: " + absoluteRootPath + relativePath + type[i] + "Vector.java");
560             }
561 
562             vectorURL = URLResource.getResource("/" + relativePath
563                     + ((i == 0) ? "MUTABLE_DOUBLE_VECTOR_AR_ABS.java" : "MUTABLE_DOUBLE_VECTOR_AR_REL.java"));
564             vectorJava = new String(Files.readAllBytes(Paths.get(vectorURL.toURI())));
565 
566             for (String type[] : typesAbsRel)
567             {
568                 File outPath = new File(absoluteRootPath + relativePath);
569                 outPath.mkdirs();
570                 PrintWriter out = new PrintWriter(absoluteRootPath + relativePath + "Mutable" + type[i] + "Vector.java");
571                 String java = new String(vectorJava);
572                 java = replaceAbsRel(java, type);
573                 java = formulasVector(java, "MutableDoubleVector => " + type[i], "Mutable");
574                 java = replace(java, type[i]);
575                 out.print(java);
576                 out.close();
577                 System.out.println("built: " + absoluteRootPath + relativePath + "Mutable" + type[i] + "Vector.java");
578             }
579         }
580     }
581 
582     /**
583      * Generate all Rel classes in value.vdouble.vector.
584      * @throws IOException on I/O error
585      * @throws URISyntaxException when file could not be found on thhe file system
586      */
587     private static void generateDoubleVectorRel() throws IOException, URISyntaxException
588     {
589         String relativePath = "value/vdouble/vector/";
590         URL vectorURL = URLResource.getResource("/" + relativePath + "DOUBLE_VECTOR_REL.java");
591         String vectorJava = new String(Files.readAllBytes(Paths.get(vectorURL.toURI())));
592 
593         for (String type : typesRel)
594         {
595             File outPath = new File(absoluteRootPath + relativePath);
596             outPath.mkdirs();
597             PrintWriter out = new PrintWriter(absoluteRootPath + relativePath + type + "Vector.java");
598             String java = new String(vectorJava);
599             java = java.replaceAll("%Type%", type);
600             java = java.replaceAll("%type%", type.toLowerCase());
601             java = java.replaceAll("%TYPE%", type.toUpperCase());
602             java = formulasVector(java, "DoubleVector => " + type, "");
603             java = replace(java, type);
604             out.print(java);
605             out.close();
606             System.out.println("built: " + absoluteRootPath + relativePath + type + "Vector.java");
607         }
608 
609         vectorURL = URLResource.getResource("/" + relativePath + "MUTABLE_DOUBLE_VECTOR_REL.java");
610         vectorJava = new String(Files.readAllBytes(Paths.get(vectorURL.toURI())));
611 
612         for (String type : typesRel)
613         {
614             File outPath = new File(absoluteRootPath + relativePath);
615             outPath.mkdirs();
616             PrintWriter out = new PrintWriter(absoluteRootPath + relativePath + "Mutable" + type + "Vector.java");
617             String java = new String(vectorJava);
618             java = java.replaceAll("%Type%", type);
619             java = java.replaceAll("%type%", type.toLowerCase());
620             java = java.replaceAll("%TYPE%", type.toUpperCase());
621             if (java.contains("class MutableDimensionlessVector"))
622             {
623                 java = java.replace("%DIMLESS%", " implements MathFunctionsDimensionless<MutableDimensionlessVector>");
624                 URL dimlessURL = URLResource.getResource("/" + relativePath + "DimlessFunctions.java");
625                 String dimlessFunctions = new String(Files.readAllBytes(Paths.get(dimlessURL.toURI())));
626                 int pos = java.indexOf("%FORMULAS%");
627                 java = java.substring(0, pos - 1) + dimlessFunctions + java.substring(pos, java.length() - 1);
628             }
629             java = java.replace("%DIMLESS%", "");
630             java = formulasVector(java, "MutableDoubleVector => " + type, "Mutable");
631             java = replace(java, type);
632             out.print(java);
633             out.close();
634             System.out.println("built: " + absoluteRootPath + relativePath + "Mutable" + type + "Vector.java");
635         }
636     }
637 
638     /**
639      * Generate all Money classes in value.vdouble.vector.
640      * @throws IOException on I/O error
641      * @throws URISyntaxException when file could not be found on thhe file system
642      */
643     private static void generateDoubleVectorMoney() throws IOException, URISyntaxException
644     {
645         String relativePath = "value/vdouble/vector/";
646         URL vectorURL = URLResource.getResource("/" + relativePath + "DOUBLE_VECTOR_REL.java");
647         String vectorJava = new String(Files.readAllBytes(Paths.get(vectorURL.toURI())));
648 
649         for (String type : typesMoney)
650         {
651             File outPath = new File(absoluteRootPath + relativePath);
652             outPath.mkdirs();
653             PrintWriter out = new PrintWriter(absoluteRootPath + relativePath + type + "Vector.java");
654             String java = new String(vectorJava);
655             java = java.replaceAll("%Type%", type);
656             java = java.replaceAll("%type%", type.toLowerCase());
657             java = java.replaceAll("%TYPE%", type.toUpperCase());
658             java = java.replace("%DIMLESS%", "");
659             java = formulasVector(java, "DoubleVector => " + type, "");
660             java = replace(java, type);
661             out.print(java);
662             out.close();
663             System.out.println("built: " + absoluteRootPath + relativePath + type + "Vector.java");
664         }
665 
666         vectorURL = URLResource.getResource("/" + relativePath + "MUTABLE_DOUBLE_VECTOR_REL.java");
667         vectorJava = new String(Files.readAllBytes(Paths.get(vectorURL.toURI())));
668 
669         for (String type : typesMoney)
670         {
671             File outPath = new File(absoluteRootPath + relativePath);
672             outPath.mkdirs();
673             PrintWriter out = new PrintWriter(absoluteRootPath + relativePath + "Mutable" + type + "Vector.java");
674             String java = new String(vectorJava);
675             java = java.replaceAll("%Type%", type);
676             java = java.replaceAll("%type%", type.toLowerCase());
677             java = java.replaceAll("%TYPE%", type.toUpperCase());
678             java = java.replace("%DIMLESS%", "");
679             java = formulasVector(java, "MutableDoubleVector => " + type, "Mutable");
680             java = replace(java, type);
681             out.print(java);
682             out.close();
683             System.out.println("built: " + absoluteRootPath + relativePath + "Mutable" + type + "Vector.java");
684         }
685 
686     }
687 
688     /****************************************************************************************************************/
689     /********************************************** FLOATVECTOR *****************************************************/
690     /****************************************************************************************************************/
691 
692     /**
693      * Generate all Abs + Rel classes in value.vfloat.vector.
694      * @throws IOException on I/O error
695      * @throws URISyntaxException when file could not be found on thhe file system
696      */
697     private static void generateFloatVectorAbsRel() throws IOException, URISyntaxException
698     {
699         for (int i = 0; i <= 1; i++)
700         {
701             String relativePath = "value/vfloat/vector/";
702             URL vectorURL = URLResource
703                     .getResource("/" + relativePath + ((i == 0) ? "FLOAT_VECTOR_AR_ABS.java" : "FLOAT_VECTOR_AR_REL.java"));
704             String vectorJava = new String(Files.readAllBytes(Paths.get(vectorURL.toURI())));
705 
706             for (String type[] : typesAbsRel)
707             {
708                 String fType = "Float" + type[i];
709                 File outPath = new File(absoluteRootPath + relativePath);
710                 outPath.mkdirs();
711                 PrintWriter out = new PrintWriter(absoluteRootPath + relativePath + fType + "Vector.java");
712                 String java = new String(vectorJava);
713                 java = replaceAbsRel(java, type);
714                 java = formulasVector(java, "FloatVector => " + fType, "");
715                 java = replace(java, type[i]);
716                 out.print(java);
717                 out.close();
718                 System.out.println("built: " + absoluteRootPath + relativePath + fType + "Vector.java");
719             }
720 
721             vectorURL = URLResource.getResource(
722                     "/" + relativePath + ((i == 0) ? "MUTABLE_FLOAT_VECTOR_AR_ABS.java" : "MUTABLE_FLOAT_VECTOR_AR_REL.java"));
723             vectorJava = new String(Files.readAllBytes(Paths.get(vectorURL.toURI())));
724 
725             for (String type[] : typesAbsRel)
726             {
727                 String fType = "Float" + type[i];
728                 File outPath = new File(absoluteRootPath + relativePath);
729                 outPath.mkdirs();
730                 PrintWriter out = new PrintWriter(absoluteRootPath + relativePath + "Mutable" + fType + "Vector.java");
731                 String java = new String(vectorJava);
732                 java = replaceAbsRel(java, type);
733                 java = formulasVector(java, "MutableFloatVector => " + fType, "Mutable");
734                 java = replace(java, type[i]);
735                 out.print(java);
736                 out.close();
737                 System.out.println("built: " + absoluteRootPath + relativePath + "Mutable" + fType + "Vector.java");
738             }
739         }
740     }
741 
742     /**
743      * Generate all Rel classes in value.vfloat.vector.
744      * @throws IOException on I/O error
745      * @throws URISyntaxException when file could not be found on thhe file system
746      */
747     private static void generateFloatVectorRel() throws IOException, URISyntaxException
748     {
749         String relativePath = "value/vfloat/vector/";
750         URL vectorURL = URLResource.getResource("/" + relativePath + "FLOAT_VECTOR_REL.java");
751         String vectorJava = new String(Files.readAllBytes(Paths.get(vectorURL.toURI())));
752 
753         for (String type : typesRel)
754         {
755             String fType = "Float" + type;
756             File outPath = new File(absoluteRootPath + relativePath);
757             outPath.mkdirs();
758             PrintWriter out = new PrintWriter(absoluteRootPath + relativePath + fType + "Vector.java");
759             String java = new String(vectorJava);
760             java = java.replaceAll("%Type%", type);
761             java = java.replaceAll("%type%", type.toLowerCase());
762             java = java.replaceAll("%TYPE%", type.toUpperCase());
763             java = formulasVector(java, "FloatVector => " + fType, "");
764             java = replace(java, type);
765             out.print(java);
766             out.close();
767             System.out.println("built: " + absoluteRootPath + relativePath + fType + "Vector.java");
768         }
769 
770         vectorURL = URLResource.getResource("/" + relativePath + "MUTABLE_FLOAT_VECTOR_REL.java");
771         vectorJava = new String(Files.readAllBytes(Paths.get(vectorURL.toURI())));
772 
773         for (String type : typesRel)
774         {
775             String fType = "Float" + type;
776             File outPath = new File(absoluteRootPath + relativePath);
777             outPath.mkdirs();
778             PrintWriter out = new PrintWriter(absoluteRootPath + relativePath + "Mutable" + fType + "Vector.java");
779             String java = new String(vectorJava);
780             java = java.replaceAll("%Type%", type);
781             java = java.replaceAll("%type%", type.toLowerCase());
782             java = java.replaceAll("%TYPE%", type.toUpperCase());
783             if (java.contains("class MutableFloatDimensionlessVector"))
784             {
785                 java = java.replace("%DIMLESS%", " implements MathFunctionsDimensionless<MutableFloatDimensionlessVector>");
786                 URL dimlessURL = URLResource.getResource("/" + relativePath + "DimlessFunctions.java");
787                 String dimlessFunctions = new String(Files.readAllBytes(Paths.get(dimlessURL.toURI())));
788                 int pos = java.indexOf("%FORMULAS%");
789                 java = java.substring(0, pos - 1) + dimlessFunctions + java.substring(pos, java.length() - 1);
790             }
791             java = java.replace("%DIMLESS%", "");
792             java = formulasVector(java, "MutableFloatVector => " + fType, "Mutable");
793             java = replace(java, type);
794             out.print(java);
795             out.close();
796             System.out.println("built: " + absoluteRootPath + relativePath + "Mutable" + fType + "Vector.java");
797         }
798     }
799 
800     /**
801      * Generate all Money classes in value.vfloat.vector.
802      * @throws IOException on I/O error
803      * @throws URISyntaxException when file could not be found on thhe file system
804      */
805     private static void generateFloatVectorMoney() throws IOException, URISyntaxException
806     {
807         String relativePath = "value/vfloat/vector/";
808         URL vectorURL = URLResource.getResource("/" + relativePath + "FLOAT_VECTOR_REL.java");
809         String vectorJava = new String(Files.readAllBytes(Paths.get(vectorURL.toURI())));
810 
811         for (String type : typesMoney)
812         {
813             String fType = "Float" + type;
814             File outPath = new File(absoluteRootPath + relativePath);
815             outPath.mkdirs();
816             PrintWriter out = new PrintWriter(absoluteRootPath + relativePath + fType + "Vector.java");
817             String java = new String(vectorJava);
818             java = java.replaceAll("%Type%", type);
819             java = java.replaceAll("%type%", type.toLowerCase());
820             java = java.replaceAll("%TYPE%", type.toUpperCase());
821             java = java.replace("%DIMLESS%", "");
822             java = formulasVector(java, "FloatVector => " + fType, "");
823             java = replace(java, type);
824             out.print(java);
825             out.close();
826             System.out.println("built: " + absoluteRootPath + relativePath + fType + "Vector.java");
827         }
828 
829         vectorURL = URLResource.getResource("/" + relativePath + "MUTABLE_FLOAT_VECTOR_REL.java");
830         vectorJava = new String(Files.readAllBytes(Paths.get(vectorURL.toURI())));
831 
832         for (String type : typesMoney)
833         {
834             String fType = "Float" + type;
835             File outPath = new File(absoluteRootPath + relativePath);
836             outPath.mkdirs();
837             PrintWriter out = new PrintWriter(absoluteRootPath + relativePath + "Mutable" + fType + "Vector.java");
838             String java = new String(vectorJava);
839             java = java.replaceAll("%Type%", type);
840             java = java.replaceAll("%type%", type.toLowerCase());
841             java = java.replaceAll("%TYPE%", type.toUpperCase());
842             java = java.replace("%DIMLESS%", "");
843             java = formulasVector(java, "MutableFloatVector => " + fType, "Mutable");
844             java = replace(java, type);
845             out.print(java);
846             out.close();
847             System.out.println("built: " + absoluteRootPath + relativePath + "Mutable" + fType + "Vector.java");
848         }
849 
850     }
851 
852     /****************************************************************************************************************/
853     /************************************************ MATRIX ********************************************************/
854     /****************************************************************************************************************/
855 
856     /**
857      * Insert formulas based on FORMULAS.txt into the %FORMULAS% marker within the Java file.
858      * @param java the java file
859      * @param errorType the type for error messaging
860      * @param prefix e.g., Float for Float types, or blank for Double types
861      * @return the file with replacements
862      */
863     private static String formulasMatrix(String java, String errorType, String prefix)
864     {
865         String ret = java;
866         while (ret.contains("%FORMULAS%"))
867         {
868             int pos = ret.indexOf("%FORMULAS%");
869             ret = ret.replaceFirst("%FORMULAS%", "");
870             int end = ret.indexOf("%", pos);
871             if (end == -1)
872             {
873                 System.err.println("Closing % not found for %FORMULAS% in file for type " + errorType);
874                 return ret;
875             }
876             String type = ret.substring(pos, end);
877             if (!formulas.containsKey(type))
878             {
879                 System.err.println("Formulas in FORMULAS.txt does not contain entry for type " + errorType);
880                 return ret.substring(0, pos - 1) + ret.substring(pos + type.length() + 2, ret.length() - 1);
881             }
882             String fStr = "";
883             ret = ret.substring(0, pos - 1) + fStr + ret.substring(pos + type.length() + 1, ret.length() - 1);
884         }
885         return ret;
886     }
887 
888     /****************************************************************************************************************/
889     /********************************************* DOUBLEMATRIX *****************************************************/
890     /****************************************************************************************************************/
891 
892     /**
893      * Generate all Abs + Rel classes in value.vdouble.matrix.
894      * @throws IOException on I/O error
895      * @throws URISyntaxException when file could not be found on thhe file system
896      */
897     private static void generateDoubleMatrixAbsRel() throws IOException, URISyntaxException
898     {
899         for (int i = 0; i <= 1; i++)
900         {
901             String relativePath = "value/vdouble/matrix/";
902             URL matrixURL = URLResource
903                     .getResource("/" + relativePath + ((i == 0) ? "DOUBLE_MATRIX_AR_ABS.java" : "DOUBLE_MATRIX_AR_REL.java"));
904             String matrixJava = new String(Files.readAllBytes(Paths.get(matrixURL.toURI())));
905 
906             for (String[] type : typesAbsRel)
907             {
908                 File outPath = new File(absoluteRootPath + relativePath);
909                 outPath.mkdirs();
910                 PrintWriter out = new PrintWriter(absoluteRootPath + relativePath + type[i] + "Matrix.java");
911                 String java = new String(matrixJava);
912                 java = replaceAbsRel(java, type);
913                 java = formulasMatrix(java, "DoubleMatrix => " + type[i], "");
914                 java = replace(java, type[i]);
915                 out.print(java);
916                 out.close();
917                 System.out.println("built: " + absoluteRootPath + relativePath + type[i] + "Matrix.java");
918             }
919 
920             matrixURL = URLResource.getResource("/" + relativePath
921                     + ((i == 0) ? "MUTABLE_DOUBLE_MATRIX_AR_ABS.java" : "MUTABLE_DOUBLE_MATRIX_AR_REL.java"));
922             matrixJava = new String(Files.readAllBytes(Paths.get(matrixURL.toURI())));
923 
924             for (String[] type : typesAbsRel)
925             {
926                 File outPath = new File(absoluteRootPath + relativePath);
927                 outPath.mkdirs();
928                 PrintWriter out = new PrintWriter(absoluteRootPath + relativePath + "Mutable" + type[i] + "Matrix.java");
929                 String java = new String(matrixJava);
930                 java = replaceAbsRel(java, type);
931                 java = formulasMatrix(java, "MutableDoubleMatrix => " + type[i], "Mutable");
932                 java = replace(java, type[i]);
933                 out.print(java);
934                 out.close();
935                 System.out.println("built: " + absoluteRootPath + relativePath + "Mutable" + type[i] + "Matrix.java");
936             }
937         }
938     }
939 
940     /**
941      * Generate all Rel classes in value.vdouble.matrix.
942      * @throws IOException on I/O error
943      * @throws URISyntaxException when file could not be found on thhe file system
944      */
945     private static void generateDoubleMatrixRel() throws IOException, URISyntaxException
946     {
947         String relativePath = "value/vdouble/matrix/";
948         URL matrixURL = URLResource.getResource("/" + relativePath + "DOUBLE_MATRIX_REL.java");
949         String matrixJava = new String(Files.readAllBytes(Paths.get(matrixURL.toURI())));
950 
951         for (String type : typesRel)
952         {
953             File outPath = new File(absoluteRootPath + relativePath);
954             outPath.mkdirs();
955             PrintWriter out = new PrintWriter(absoluteRootPath + relativePath + type + "Matrix.java");
956             String java = new String(matrixJava);
957             java = java.replaceAll("%Type%", type);
958             java = java.replaceAll("%type%", type.toLowerCase());
959             java = java.replaceAll("%TYPE%", type.toUpperCase());
960             java = formulasMatrix(java, "DoubleMatrix => " + type, "");
961             java = replace(java, type);
962             out.print(java);
963             out.close();
964             System.out.println("built: " + absoluteRootPath + relativePath + type + "Matrix.java");
965         }
966 
967         matrixURL = URLResource.getResource("/" + relativePath + "MUTABLE_DOUBLE_MATRIX_REL.java");
968         matrixJava = new String(Files.readAllBytes(Paths.get(matrixURL.toURI())));
969 
970         for (String type : typesRel)
971         {
972             File outPath = new File(absoluteRootPath + relativePath);
973             outPath.mkdirs();
974             PrintWriter out = new PrintWriter(absoluteRootPath + relativePath + "Mutable" + type + "Matrix.java");
975             String java = new String(matrixJava);
976             java = java.replaceAll("%Type%", type);
977             java = java.replaceAll("%type%", type.toLowerCase());
978             java = java.replaceAll("%TYPE%", type.toUpperCase());
979             if (java.contains("class MutableDimensionlessMatrix"))
980             {
981                 java = java.replace("%DIMLESS%", " implements MathFunctionsDimensionless<MutableDimensionlessMatrix>");
982                 URL dimlessURL = URLResource.getResource("/" + relativePath + "DimlessFunctions.java");
983                 String dimlessFunctions = new String(Files.readAllBytes(Paths.get(dimlessURL.toURI())));
984                 int pos = java.indexOf("%FORMULAS%");
985                 java = java.substring(0, pos - 1) + dimlessFunctions + java.substring(pos, java.length() - 1);
986             }
987             java = java.replace("%DIMLESS%", "");
988             java = formulasMatrix(java, "MutableDoubleMatrix => " + type, "Mutable");
989             java = replace(java, type);
990             out.print(java);
991             out.close();
992             System.out.println("built: " + absoluteRootPath + relativePath + "Mutable" + type + "Matrix.java");
993         }
994     }
995 
996     /**
997      * Generate all Money classes in value.vdouble.matrix.
998      * @throws IOException on I/O error
999      * @throws URISyntaxException when file could not be found on thhe file system
1000      */
1001     private static void generateDoubleMatrixMoney() throws IOException, URISyntaxException
1002     {
1003         String relativePath = "value/vdouble/matrix/";
1004         URL matrixURL = URLResource.getResource("/" + relativePath + "DOUBLE_MATRIX_REL.java");
1005         String matrixJava = new String(Files.readAllBytes(Paths.get(matrixURL.toURI())));
1006 
1007         for (String type : typesMoney)
1008         {
1009             File outPath = new File(absoluteRootPath + relativePath);
1010             outPath.mkdirs();
1011             PrintWriter out = new PrintWriter(absoluteRootPath + relativePath + type + "Matrix.java");
1012             String java = new String(matrixJava);
1013             java = java.replaceAll("%Type%", type);
1014             java = java.replaceAll("%type%", type.toLowerCase());
1015             java = java.replaceAll("%TYPE%", type.toUpperCase());
1016             java = java.replace("%DIMLESS%", "");
1017             java = formulasMatrix(java, "DoubleMatrix => " + type, "");
1018             java = replace(java, type);
1019             out.print(java);
1020             out.close();
1021             System.out.println("built: " + absoluteRootPath + relativePath + type + "Matrix.java");
1022         }
1023 
1024         matrixURL = URLResource.getResource("/" + relativePath + "MUTABLE_DOUBLE_MATRIX_REL.java");
1025         matrixJava = new String(Files.readAllBytes(Paths.get(matrixURL.toURI())));
1026 
1027         for (String type : typesMoney)
1028         {
1029             File outPath = new File(absoluteRootPath + relativePath);
1030             outPath.mkdirs();
1031             PrintWriter out = new PrintWriter(absoluteRootPath + relativePath + "Mutable" + type + "Matrix.java");
1032             String java = new String(matrixJava);
1033             java = java.replaceAll("%Type%", type);
1034             java = java.replaceAll("%type%", type.toLowerCase());
1035             java = java.replaceAll("%TYPE%", type.toUpperCase());
1036             java = java.replace("%DIMLESS%", "");
1037             java = formulasMatrix(java, "MutableDoubleMatrix => " + type, "Mutable");
1038             java = replace(java, type);
1039             out.print(java);
1040             out.close();
1041             System.out.println("built: " + absoluteRootPath + relativePath + "Mutable" + type + "Matrix.java");
1042         }
1043 
1044     }
1045 
1046     /****************************************************************************************************************/
1047     /********************************************** FLOATMATRIX *****************************************************/
1048     /****************************************************************************************************************/
1049 
1050     /**
1051      * Generate all Abs + Rel classes in value.vfloat.matrix.
1052      * @throws IOException on I/O error
1053      * @throws URISyntaxException when file could not be found on thhe file system
1054      */
1055     private static void generateFloatMatrixAbsRel() throws IOException, URISyntaxException
1056     {
1057         for (int i = 0; i <= 1; i++)
1058         {
1059             String relativePath = "value/vfloat/matrix/";
1060             URL matrixURL = URLResource
1061                     .getResource("/" + relativePath + ((i == 0) ? "FLOAT_MATRIX_AR_ABS.java" : "FLOAT_MATRIX_AR_REL.java"));
1062             String matrixJava = new String(Files.readAllBytes(Paths.get(matrixURL.toURI())));
1063 
1064             for (String type[] : typesAbsRel)
1065             {
1066                 String fType = "Float" + type[i];
1067                 File outPath = new File(absoluteRootPath + relativePath);
1068                 outPath.mkdirs();
1069                 PrintWriter out = new PrintWriter(absoluteRootPath + relativePath + fType + "Matrix.java");
1070                 String java = new String(matrixJava);
1071                 java = replaceAbsRel(java, type);
1072                 java = formulasMatrix(java, "FloatMatrix => " + fType, "");
1073                 java = replace(java, type[i]);
1074                 out.print(java);
1075                 out.close();
1076                 System.out.println("built: " + absoluteRootPath + relativePath + fType + "Matrix.java");
1077             }
1078 
1079             matrixURL = URLResource.getResource(
1080                     "/" + relativePath + ((i == 0) ? "MUTABLE_FLOAT_MATRIX_AR_ABS.java" : "MUTABLE_FLOAT_MATRIX_AR_REL.java"));
1081             matrixJava = new String(Files.readAllBytes(Paths.get(matrixURL.toURI())));
1082 
1083             for (String type[] : typesAbsRel)
1084             {
1085                 String fType = "Float" + type[i];
1086                 File outPath = new File(absoluteRootPath + relativePath);
1087                 outPath.mkdirs();
1088                 PrintWriter out = new PrintWriter(absoluteRootPath + relativePath + "Mutable" + fType + "Matrix.java");
1089                 String java = new String(matrixJava);
1090                 java = replaceAbsRel(java, type);
1091                 java = formulasMatrix(java, "MutableFloatMatrix => " + fType, "Mutable");
1092                 java = replace(java, type[i]);
1093                 out.print(java);
1094                 out.close();
1095                 System.out.println("built: " + absoluteRootPath + relativePath + "Mutable" + fType + "Matrix.java");
1096             }
1097         }
1098     }
1099 
1100     /**
1101      * Generate all Rel classes in value.vfloat.matrix.
1102      * @throws IOException on I/O error
1103      * @throws URISyntaxException when file could not be found on thhe file system
1104      */
1105     private static void generateFloatMatrixRel() throws IOException, URISyntaxException
1106     {
1107         String relativePath = "value/vfloat/matrix/";
1108         URL matrixURL = URLResource.getResource("/" + relativePath + "FLOAT_MATRIX_REL.java");
1109         String matrixJava = new String(Files.readAllBytes(Paths.get(matrixURL.toURI())));
1110 
1111         for (String type : typesRel)
1112         {
1113             String fType = "Float" + type;
1114             File outPath = new File(absoluteRootPath + relativePath);
1115             outPath.mkdirs();
1116             PrintWriter out = new PrintWriter(absoluteRootPath + relativePath + fType + "Matrix.java");
1117             String java = new String(matrixJava);
1118             java = java.replaceAll("%Type%", type);
1119             java = java.replaceAll("%type%", type.toLowerCase());
1120             java = java.replaceAll("%TYPE%", type.toUpperCase());
1121             java = formulasMatrix(java, "FloatMatrix => " + fType, "");
1122             java = replace(java, type);
1123             out.print(java);
1124             out.close();
1125             System.out.println("built: " + absoluteRootPath + relativePath + fType + "Matrix.java");
1126         }
1127 
1128         matrixURL = URLResource.getResource("/" + relativePath + "MUTABLE_FLOAT_MATRIX_REL.java");
1129         matrixJava = new String(Files.readAllBytes(Paths.get(matrixURL.toURI())));
1130 
1131         for (String type : typesRel)
1132         {
1133             String fType = "Float" + type;
1134             File outPath = new File(absoluteRootPath + relativePath);
1135             outPath.mkdirs();
1136             PrintWriter out = new PrintWriter(absoluteRootPath + relativePath + "Mutable" + fType + "Matrix.java");
1137             String java = new String(matrixJava);
1138             java = java.replaceAll("%Type%", type);
1139             java = java.replaceAll("%type%", type.toLowerCase());
1140             java = java.replaceAll("%TYPE%", type.toUpperCase());
1141             if (java.contains("class MutableFloatDimensionlessMatrix"))
1142             {
1143                 java = java.replace("%DIMLESS%", " implements MathFunctionsDimensionless<MutableFloatDimensionlessMatrix>");
1144                 URL dimlessURL = URLResource.getResource("/" + relativePath + "DimlessFunctions.java");
1145                 String dimlessFunctions = new String(Files.readAllBytes(Paths.get(dimlessURL.toURI())));
1146                 int pos = java.indexOf("%FORMULAS%");
1147                 java = java.substring(0, pos - 1) + dimlessFunctions + java.substring(pos, java.length() - 1);
1148             }
1149             java = java.replace("%DIMLESS%", "");
1150             java = formulasMatrix(java, "MutableFloatMatrix => " + fType, "Mutable");
1151             java = replace(java, type);
1152             out.print(java);
1153             out.close();
1154             System.out.println("built: " + absoluteRootPath + relativePath + "Mutable" + fType + "Matrix.java");
1155         }
1156     }
1157 
1158     /**
1159      * Generate all Money classes in value.vfloat.matrix.
1160      * @throws IOException on I/O error
1161      * @throws URISyntaxException when file could not be found on thhe file system
1162      */
1163     private static void generateFloatMatrixMoney() throws IOException, URISyntaxException
1164     {
1165         String relativePath = "value/vfloat/matrix/";
1166         URL matrixURL = URLResource.getResource("/" + relativePath + "FLOAT_MATRIX_REL.java");
1167         String matrixJava = new String(Files.readAllBytes(Paths.get(matrixURL.toURI())));
1168 
1169         for (String type : typesMoney)
1170         {
1171             String fType = "Float" + type;
1172             File outPath = new File(absoluteRootPath + relativePath);
1173             outPath.mkdirs();
1174             PrintWriter out = new PrintWriter(absoluteRootPath + relativePath + fType + "Matrix.java");
1175             String java = new String(matrixJava);
1176             java = java.replaceAll("%Type%", type);
1177             java = java.replaceAll("%type%", type.toLowerCase());
1178             java = java.replaceAll("%TYPE%", type.toUpperCase());
1179             java = java.replace("%DIMLESS%", "");
1180             java = formulasMatrix(java, "FloatMatrix => " + fType, "");
1181             java = replace(java, type);
1182             out.print(java);
1183             out.close();
1184             System.out.println("built: " + absoluteRootPath + relativePath + fType + "Matrix.java");
1185         }
1186 
1187         matrixURL = URLResource.getResource("/" + relativePath + "MUTABLE_FLOAT_MATRIX_REL.java");
1188         matrixJava = new String(Files.readAllBytes(Paths.get(matrixURL.toURI())));
1189 
1190         for (String type : typesMoney)
1191         {
1192             String fType = "Float" + type;
1193             File outPath = new File(absoluteRootPath + relativePath);
1194             outPath.mkdirs();
1195             PrintWriter out = new PrintWriter(absoluteRootPath + relativePath + "Mutable" + fType + "Matrix.java");
1196             String java = new String(matrixJava);
1197             java = java.replaceAll("%Type%", type);
1198             java = java.replaceAll("%type%", type.toLowerCase());
1199             java = java.replaceAll("%TYPE%", type.toUpperCase());
1200             java = java.replace("%DIMLESS%", "");
1201             java = formulasMatrix(java, "MutableFloatMatrix => " + fType, "Mutable");
1202             java = replace(java, type);
1203             out.print(java);
1204             out.close();
1205             System.out.println("built: " + absoluteRootPath + relativePath + "Mutable" + fType + "Matrix.java");
1206         }
1207 
1208     }
1209 
1210     /****************************************************************************************************************/
1211     /********************************************* GENERIC **********************************************************/
1212     /****************************************************************************************************************/
1213 
1214     /**
1215      * Determine calculated absolute output path (root of the executable or Jar file). In case of an Eclipse run, ../../ is
1216      * added to the path to place the results in the root of the project, rather than in target/classes.<br>
1217      * See https://weblogs.java.net/blog/kohsuke/archive/2007/04/how_to_convert.html and
1218      * http://stackoverflow.com/questions/320542/how-to-get-the-path-of-a-running-jar-file and
1219      * http://stackoverflow.com/questions/3153337/get-current-working-directory-in-java
1220      * @throws FileNotFoundException in case file could not be found
1221      */
1222     private static void makeAndCleanAbsolutePath() throws FileNotFoundException
1223     {
1224         URL mainURL = URLResource.getResource("/");
1225         String path;
1226         try
1227         {
1228             path = mainURL.toURI().getPath();
1229         }
1230         catch (URISyntaxException exception)
1231         {
1232             path = mainURL.getPath();
1233         }
1234         if (path.endsWith("/target/classes/"))
1235         {
1236             path = path.substring(0, path.length() - "/target/classes/".length());
1237         }
1238         path += generatedCodeRelativePath;
1239         if (!new File(path).exists())
1240         {
1241             new File(path).mkdirs();
1242         }
1243         else
1244         {
1245             System.out.println("about to delete: " + path);
1246             // if (!deleteRecursive(new File(path)))
1247             // {
1248             // System.err.println("Could not empty directory " + path);
1249             // System.exit(-1);
1250             // }
1251         }
1252         absoluteRootPath = path;
1253         System.out.println("writing into: " + path);
1254     }
1255 
1256     /**
1257      * By default File#delete fails for non-empty directories, it works like "rm". We need something a little more brutual -
1258      * this does the equivalent of "rm -r". From: http://stackoverflow.com/questions/779519/delete-files-recursively-in-java.
1259      * Note: USE CAREFULLY.
1260      * @param path Root File Path
1261      * @return true iff the file and all sub files/directories have been removed
1262      * @throws FileNotFoundException on error (e.g., locked file)
1263      */
1264     public static boolean deleteRecursive(File path) throws FileNotFoundException
1265     {
1266         if (!path.exists())
1267         {
1268             throw new FileNotFoundException(path.getAbsolutePath());
1269         }
1270         boolean ret = true;
1271         if (path.isDirectory())
1272         {
1273             for (File f : path.listFiles())
1274             {
1275                 ret = ret && deleteRecursive(f);
1276             }
1277         }
1278         return ret && path.delete();
1279     }
1280 
1281     /**
1282      * @param args args, should be blank
1283      * @throws IOException on I/O error
1284      * @throws URISyntaxException when file could not be found on thhe file system
1285      */
1286     public static void main(String[] args) throws IOException, URISyntaxException
1287     {
1288         makeAndCleanAbsolutePath();
1289         readAbsRelTypes();
1290         readRelTypes();
1291         readMoneyTypes();
1292         readFormulas();
1293         readReplace();
1294 
1295         generateDoubleScalarAbsRel();
1296         generateDoubleScalarRel();
1297         generateDoubleScalarMoney();
1298         generateFloatScalarAbsRel();
1299         generateFloatScalarRel();
1300         generateFloatScalarMoney();
1301 
1302         generateDoubleVectorAbsRel();
1303         generateDoubleVectorRel();
1304         generateDoubleVectorMoney();
1305         generateFloatVectorAbsRel();
1306         generateFloatVectorRel();
1307         generateFloatVectorMoney();
1308 
1309         generateDoubleMatrixAbsRel();
1310         generateDoubleMatrixRel();
1311         generateDoubleMatrixMoney();
1312         generateFloatMatrixAbsRel();
1313         generateFloatMatrixRel();
1314         generateFloatMatrixMoney();
1315     }
1316 
1317 }