1 /*
   2  * Copyright (c) 2015, 2016 Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  */
   5 
   6 package com.oracle.appbundlers.utils;
   7 
   8 import static com.oracle.appbundlers.utils.Config.CONFIG_INSTANCE;
   9 import static java.nio.file.Files.write;
  10 import static java.util.stream.Collectors.joining;
  11 
  12 import java.io.File;
  13 import java.io.IOException;
  14 import java.nio.file.Files;
  15 import java.nio.file.Path;
  16 import java.nio.file.Paths;
  17 import java.util.HashMap;
  18 import java.util.Iterator;
  19 import java.util.Map;
  20 import java.util.Map.Entry;
  21 import java.util.Set;
  22 import java.util.regex.Matcher;
  23 import java.util.regex.Pattern;
  24 
  25 public class Source {
  26 
  27     private String packageName;
  28     private String simpleName;
  29     private String fileContent;
  30     private String jarName;
  31     private Map<String, String> replacementsInSrcCode;
  32     /*
  33      * JDK 9 Parameters
  34      */
  35 
  36     private String moduleName;
  37     private String moduleInfoContent;
  38     private Map<String, String> classNameToTemplateMap = new HashMap<>();
  39     private Map<String, Map<String, String>> classNameToReplacementsInSrcMap = new HashMap<>();
  40     private boolean isModule;
  41     private boolean mainModule;
  42 
  43     /*
  44      * Jar Source
  45      */
  46     public Source(String fullName, String templateFileName, String jarName,
  47             Map<String, String> replacements) throws IOException {
  48         init(fullName, jarName);
  49         this.fileContent = readFileAsString(templateFileName, replacements);
  50         this.isModule = false;
  51     }
  52 
  53     /*
  54      * Module Source
  55      */
  56 
  57     public Source(String moduleName, String moduleInfoFileName,
  58             Map<String, String> classNameToTemplateMap, String fullName,
  59             String jar, Map<String, String> replacementsInSourceCode)
  60                     throws IOException {
  61         init(fullName, jar);
  62         if (moduleName == null) {
  63             throw new NullPointerException("Module Name cannot be null");
  64         }
  65         this.moduleName = moduleName;
  66         if (moduleInfoFileName == null) {
  67             throw new NullPointerException(
  68                     "Module Info File Name cannot be null");
  69         }
  70         this.isModule = true;
  71         this.replacementsInSrcCode = replacementsInSourceCode;
  72         this.moduleInfoContent = readFileAsString(moduleInfoFileName,
  73                 this.replacementsInSrcCode);
  74         this.classNameToTemplateMap = classNameToTemplateMap;
  75     }
  76 
  77     /*
  78      * Module Source
  79      */
  80 
  81     public Source(String moduleName, String moduleInfoFileName,
  82             Map<String, String> classNameToTemplateMap,
  83             String mainClassfullyQualifiedName, String jar,
  84             Map<String, String> replacementsInSrcCode, boolean mainModule)
  85                     throws IOException {
  86         this(moduleName, moduleInfoFileName, classNameToTemplateMap,
  87                 mainClassfullyQualifiedName, jar, replacementsInSrcCode);
  88         this.mainModule = mainModule;
  89     }
  90 
  91     /*
  92      * Module Source
  93      */
  94     public Source(String moduleName, String moduleInfoFileName,
  95             Map<String, String> classNameToTemplateMap,
  96             String mainClassfullyQualifiedName,
  97             Map<String, Map<String, String>> classNameToReplacementsInSrcMap,
  98             String jar) throws IOException {
  99         init(mainClassfullyQualifiedName, jar);
 100         if (moduleName == null) {
 101             throw new NullPointerException("Module Name cannot be null");
 102         }
 103         this.moduleName = moduleName;
 104         if (moduleInfoFileName == null) {
 105             throw new NullPointerException(
 106                     "Module Info File Name cannot be null");
 107         }
 108         this.classNameToReplacementsInSrcMap = classNameToReplacementsInSrcMap;
 109         this.classNameToTemplateMap = classNameToTemplateMap;
 110         this.moduleInfoContent = readFileAsString(moduleInfoFileName,
 111                 this.classNameToReplacementsInSrcMap.get(Constants.MODULE_INFO_DOT_JAVA));
 112         this.isModule = true;
 113     }
 114 
 115     private void init(String fullName, String jarName) {
 116         int lastDot = fullName.lastIndexOf(".");
 117         this.packageName = fullName.substring(0, lastDot);
 118         this.simpleName = fullName.substring(lastDot + 1);
 119         this.jarName = jarName;
 120     }
 121 
 122     public String getPackageName() {
 123         return packageName;
 124     }
 125 
 126     public void setPackageName(String packageName) {
 127         this.packageName = packageName;
 128     }
 129 
 130     public String getSimpleName() {
 131         return this.simpleName;
 132     }
 133 
 134     public void setSimpleName(String simpleName) {
 135         this.simpleName = simpleName;
 136     }
 137 
 138     public String getSource() {
 139         return this.fileContent;
 140     }
 141 
 142     public void setFileContent(String fileContent) {
 143         this.fileContent = fileContent;
 144     }
 145 
 146     public String getJarName() {
 147         return this.jarName;
 148     }
 149 
 150     public void setJarName(String jarName) {
 151         this.jarName = jarName;
 152     }
 153 
 154     public String getFullName() {
 155         return this.packageName + "." + this.simpleName;
 156     }
 157 
 158     public String getModuleName() {
 159         return this.moduleName;
 160     }
 161 
 162     public boolean isModule() {
 163         return this.isModule;
 164     }
 165 
 166     void generateSourceForJar(Path srcDir) throws IOException {
 167         Path dir = srcDir
 168                 .resolve(this.packageName.replace('.', File.separatorChar));
 169         Utils.createDir(dir);
 170         Path sourceFilePath = dir.resolve(this.simpleName + ".java");
 171         write(sourceFilePath, this.fileContent.getBytes());
 172     }
 173 
 174     void generateSourceForModule(Path srcDir) throws IOException {
 175         Path moduleDir = srcDir.resolve(moduleName);
 176         Utils.createDir(moduleDir);
 177         Path moduleInfoPath = moduleDir.resolve(Constants.MODULE_INFO_DOT_JAVA);
 178         write(moduleInfoPath, moduleInfoContent.getBytes());
 179         Set<Entry<String, String>> entrySet = this.classNameToTemplateMap
 180                 .entrySet();
 181         Iterator<Entry<String, String>> classNameToTemplateItr = entrySet
 182                 .iterator();
 183         while (classNameToTemplateItr.hasNext()) {
 184             Entry<String, String> next = classNameToTemplateItr.next();
 185             String className = next.getKey();
 186             String templateName = next.getValue();
 187             if (this.replacementsInSrcCode != null) {
 188                 writeJavaSourceFilesToDir(moduleDir, className, templateName,
 189                         this.replacementsInSrcCode);
 190             } else {
 191                 writeJavaSourceFilesToDir(moduleDir, className, templateName,
 192                         this.classNameToReplacementsInSrcMap.get(className
 193                                 .substring(className.lastIndexOf('.') + 1)));
 194             }
 195         }
 196     }
 197 
 198     private String readFileAsString(String templateFileName,
 199             Map<String, String> replacementsInSrcCode) throws IOException {
 200         String content = Files
 201                 .lines(CONFIG_INSTANCE.getResourceFilePath(templateFileName))
 202                 .collect(joining(System.lineSeparator()));
 203         for (Map.Entry<String, String> entry : replacementsInSrcCode
 204                 .entrySet()) {
 205             content = content.replace(entry.getKey(), entry.getValue());
 206         }
 207         return content;
 208     }
 209 
 210     private void writeJavaSourceFilesToDir(Path moduleDir,
 211             String fullyQualifiedJavaClassName, String templatename,
 212             Map<String, String> replacementsInSrcCode) throws IOException {
 213         int lastIndex = fullyQualifiedJavaClassName.lastIndexOf('.');
 214         String appNameDir = fullyQualifiedJavaClassName.substring(0, lastIndex);
 215         String replaceAll = appNameDir.replaceAll(Pattern.quote("."),
 216                 Matcher.quoteReplacement(File.separator));
 217         File file = new File(
 218                 moduleDir.toString() + File.separator + replaceAll);
 219         file.mkdirs();
 220         String fileContent = readFileAsString(templatename,
 221                 replacementsInSrcCode);
 222         String fileName = fullyQualifiedJavaClassName.substring(
 223                 fullyQualifiedJavaClassName.lastIndexOf('.') + 1) + ".java";
 224         write(Paths.get(moduleDir.toString() + File.separator + replaceAll)
 225                 .resolve(fileName), fileContent.getBytes());
 226     }
 227 
 228     public boolean isMainModule() {
 229         return this.mainModule;
 230     }
 231 
 232     public void setMainModule(boolean mainModule) {
 233         this.mainModule = mainModule;
 234     }
 235 }