001/**************************************************************************** 002 * Copyright/Copyleft: 003 * 004 * For this source the LGPL Lesser General Public License, 005 * published by the Free Software Foundation is valid. 006 * It means: 007 * 1) You can use this source without any restriction for any desired purpose. 008 * 2) You can redistribute copies of this source to everybody. 009 * 3) Every user of this source, also the user of redistribute copies 010 * with or without payment, must accept this license for further using. 011 * 4) But the LPGL is not appropriate for a whole software product, 012 * if this source is only a part of them. It means, the user 013 * must publish this part of source, 014 * but don't need to publish the whole source of the own product. 015 * 5) You can study and modify (improve) this source 016 * for own using or for redistribution, but you have to license the 017 * modified sources likewise under this LGPL Lesser General Public License. 018 * You mustn't delete this Copyright/Copyleft inscription in this source file. 019 * 020 * @author Hartmut Schorrig: hartmut.schorrig@vishia.de, www.vishia.org 021 * @version 0.93 2011-01-05 (year-month-day) 022 *******************************************************************************/ 023package org.vishia.java2C; 024 025import java.io.File; 026import java.io.FileFilter; 027import java.text.ParseException; 028import java.util.Iterator; 029import java.util.List; 030 031import org.vishia.mainCmd.Report; 032 033/**This class is a helper to get the java source tree from given class path. 034 * The class may be used only temporary, 035 * it is wrapped around its method {@link JavaSrcTreeGetter#gatherAllJavaSrcFiles(JavaFolder, List)}. 036 * The usage is (new JavaSrcTreeGetter(report)).captureAllJavaSrcFiles(dst, src). 037 * 038 */ 039public class JavaSrcTreeGetter 040{ 041 042 /**Version, history and license. 043 * <ul> 044 * <li>2008 Hartmut created: 045 * </ul> 046 * <br><br> 047 * <b>Copyright/Copyleft</b>: 048 * For this source the LGPL Lesser General Public License, 049 * published by the Free Software Foundation is valid. 050 * It means: 051 * <ol> 052 * <li> You can use this source without any restriction for any desired purpose. 053 * <li> You can redistribute copies of this source to everybody. 054 * <li> Every user of this source, also the user of redistribute copies 055 * with or without payment, must accept this license for further using. 056 * <li> But the LPGL is not appropriate for a whole software product, 057 * if this source is only a part of them. It means, the user 058 * must publish this part of source, 059 * but don't need to publish the whole source of the own product. 060 * <li> You can study and modify (improve) this source 061 * for own using or for redistribution, but you have to license the 062 * modified sources likewise under this LGPL Lesser General Public License. 063 * You mustn't delete this Copyright/Copyleft inscription in this source file. 064 * </ol> 065 * If you are intent to use this sources without publishing its usage, you can get 066 * a second license subscribing a special contract with the author. 067 * 068 * @author Hartmut Schorrig = hartmut.schorrig@vishia.de 069 */ 070 public final static String sVersion = "2014-09-05"; 071 072 private final Report console; 073 074 private final ConfigSrcPathPkg_ifc inputCfg; 075 076 /**Aggregation to the Instance, which stores the produced data 077 * while call of {@link #captureAllJavaSrcFiles(List, JavaSrcTreePkg, List)}. 078 */ 079 private final JavaSources dstJavaSrcData; 080 081 private final List<String> listInputToTranslate; 082 083 private FileFilter javaFileFilter = new FileFilter(){ 084 public boolean accept(File file) 085 { return file.isFile() && file.getName().endsWith(".java"); 086 } 087 }; 088 089 private FileFilter dirFilter = new FileFilter(){ 090 public boolean accept(File file) 091 { return file.isDirectory(); 092 } 093 }; 094 095 096 /**Constructs an instance, which should be used only temporary to capture the tree. 097 * @param inputCfg Association to the instance, which knows the assignment between Java-Packages and C-Pre- and Suffixes. 098 * @param console 099 */ 100 public JavaSrcTreeGetter(JavaSources dstJavaSrcData, ConfigSrcPathPkg_ifc inputCfg, List<String> listInputToTranslate, Report console) 101 { 102 this.console = console; 103 this.inputCfg = inputCfg; 104 this.dstJavaSrcData = dstJavaSrcData; 105 this.listInputToTranslate = listInputToTranslate; 106 } 107 108 /**Captures all Java Files, which are found at file system in all given Java Source pathes 109 * evaluates the content of {@link ConfigSrcPathPkg_ifc} (association given on constructor) 110 * and sets respectively completes the input files. 111 * Uses the {@link #inputCfg} aggregation to get the source path and the package replacement 112 * 113 * @param javaSrcTree The destination, it should be an empty List before. 114 * @param listJavaSrcpath List of all source pathes. The list won't be changed here. 115 * @param listInputToTranslate List of all sources to translate. The list won't be changed here. 116 * @throws ParseException 117 */ 118 public void gatherAllJavaSrcFiles(LocalIdents identsToAssignFirstPkgIdents, List<String> listJavaSrcpath) throws ParseException 119 { console.reportln(4, "gatherAllJavaSrcFiles"); 120 for(String srcPath: listJavaSrcpath){ 121 console.reportln(4, "* Folder: " + srcPath); 122 File javaFolder = new File(srcPath); 123 if(!javaFolder.isDirectory()) throw new IllegalArgumentException("Java-Srcpath should be a directory: " + srcPath); 124 File[] firstPkgs = javaFolder.listFiles(dirFilter); 125 for(File firstPkg: firstPkgs){ 126 captureAllJavaSrcFilesRecursive(identsToAssignFirstPkgIdents, firstPkg, dstJavaSrcData.javaSrcTree, "", srcPath, false); 127 } 128 } 129 if(console.getReportLevel()>=Report.fineInfo){ 130 console.reportln(Report.fineInfo, "===All found Java source files==="); 131 reportAllJavaSrcFiles(dstJavaSrcData.javaSrcTree); 132 } 133 } 134 135 136 /**Captures the package folders and java files of the given file directory level. 137 * Creates a {@link JavaSrcTreeFile} for all found files, but not if the FileInfo 138 * exists already. It exists, if the file is found in another source-path already 139 * or if it is defined in the {@link CRuntimeJavalikeClassData} 140 * or it is defined by a package.file-replacement in the config-file, 141 * see {@link Java2C_Main#inputCfg}. 142 * 143 * @param identsToAssignPkgIdents 144 * @param dirPkg The directory in file tree for package. 145 * @param dstParent write packages and files into it. 146 * @param sPkgPathParent package path with / as separator and at end for the given level 147 * @param javaSrcPath The source path which is captured yet. Path before package tree. 148 * @param bTranslatePkg 149 * @throws ParseException 150 */ 151 private void captureAllJavaSrcFilesRecursive(LocalIdents identsToAssignPkgIdents 152 , File dirPkg, JavaSrcTreePkg dstParent, String sPkgPathParent 153 , String javaSrcPath, boolean bTranslatePkg) throws ParseException 154 { String sNamePkg = dirPkg.getName(); 155 String sPkgPath = sPkgPathParent + sNamePkg + "/"; 156 /**Register the package. */ 157 JavaSrcTreePkg dstJavaPkg = dstParent.getOrAddPkg(sPkgPath, sNamePkg, null); //, identsToAssignPkgIdents); 158 dstJavaSrcData.indexJavaSrcPkgs.put(sPkgPath, dstJavaPkg); 159 identsToAssignPkgIdents.putClassType(sNamePkg, dstJavaPkg); //add in LocalIdents 160 /**Check whether the whole package is to translate to C: */ 161 { Iterator<String> iter = listInputToTranslate.iterator(); 162 while(!bTranslatePkg && iter.hasNext()){ 163 String sPkgCheckTranslate = iter.next(); 164 if(sPkgCheckTranslate.equals(sPkgPath)){ 165 bTranslatePkg = true; 166 } 167 } 168 } 169 console.reportln(Report.info, " + Package" + (bTranslatePkg? "-transl:" : ":")+ sPkgPath + " dst:" + dstJavaPkg); 170 /**check packages (directories) */ 171 File[] javaPkgs = dirPkg.listFiles(dirFilter); 172 for(File subFolder: javaPkgs){ 173 captureAllJavaSrcFilesRecursive(dstJavaPkg.getLocalIdents(""), subFolder, dstJavaPkg, sPkgPath, javaSrcPath, bTranslatePkg); 174 } 175 /**check files */ 176 File[] javaFiles = dirPkg.listFiles(javaFileFilter); 177 if(javaFiles.length>0){ 178 /**Get prefix and suffix for C-name: */ 179 //dstJavaPkg.addStdTypes(Java2C_Main.singleton.standardClassData.stdTypes); 180 if(sPkgPath.equals("org/vishia/java2C/test/")) 181 stop(); 182 /**Prefix and suffix from packageReplacement from config file. */ 183 final String sFilePrefixPkg, sFileSuffixPkg, sNamePrefixPkg, sNameSuffixPkg; 184 ConfigSrcPathPkg_ifc.Set preSuffixPkg = inputCfg.getCPathPrePostfixForPackage(sPkgPath); 185 if(preSuffixPkg == null){ /**The package is not found in package replacement: */ 186 sFilePrefixPkg = ""; 187 sFileSuffixPkg = ""; 188 sNamePrefixPkg = ""; 189 sNameSuffixPkg = ""; 190 } 191 else{ /**Use the package replacement: */ 192 sFilePrefixPkg = preSuffixPkg.getFilePrefix(); 193 sFileSuffixPkg = preSuffixPkg.getFileSuffix(); 194 sNamePrefixPkg = preSuffixPkg.getNamePrefix(); 195 sNameSuffixPkg = preSuffixPkg.getNameSuffix(); 196 } 197 /**Iterate all files: */ 198 for(File fileJava: javaFiles){ 199 String nameFileJava = fileJava.getName(); 200 String nameJava = nameFileJava.substring(0, nameFileJava.length()-5); //always extension ".java", without it! 201 /**Prefix and suffix from packageReplacement from config file. */ 202 final String sFilePrefix, sFileSuffix, sNamePrefix, sNameSuffix; 203 ConfigSrcPathPkg_ifc.Set preSuffix = inputCfg.getCPathPrePostfixForPackage(sPkgPath+nameJava); 204 if(preSuffix == null){ /**The file is not found in file replacement, use package replacement: */ 205 preSuffix = preSuffixPkg; 206 sFilePrefix = sFilePrefixPkg; 207 sFileSuffix = sFileSuffixPkg; 208 sNamePrefix = sNamePrefixPkg; 209 sNameSuffix = sNameSuffixPkg; 210 } 211 else{ /**Use the file replacement: */ 212 sFilePrefix = preSuffix.getFilePrefix(); 213 sFileSuffix = preSuffix.getFileSuffix(); 214 sNamePrefix = preSuffix.getNamePrefix(); 215 sNameSuffix = preSuffix.getNameSuffix(); 216 } 217 //String pathC = sFilePrefix + nameJava + sFileSuffix; 218 /**Check whether it is to translate to C:*/ 219 assert(nameFileJava.endsWith(".java")); 220 String sPublicClassName = nameFileJava.substring(0, nameFileJava.length()-5); // without ".java" 221 if(sPublicClassName.equals("AllocInBlock")) 222 stop(); 223 String sFullPathName = sPkgPath + sPublicClassName; 224 console.reportln(Report.info, "source: " + sFullPathName); 225 //Check whether the file-info for the found file exists already. 226 //create a JavaSrcTreeFile while checking the sources only if the file isn't known already. 227 JavaSources.ClassDataOrJavaSrcFile javaFile = Java2C_Main.getRootLevelIdents().getTypeInfo(sFullPathName, null); 228 if(javaFile == null){ 229 javaFile = Java2C_Main.singleton.standardClassData.stdTypes.getTypeInfo(sPublicClassName, null); 230 if(javaFile != null) 231 stop(); 232 } 233 if(javaFile == null){ 234 /**If the type is registered already as standard type (at ex from org/vishia/bridgeC), than do not handle.*/ 235 console.report(Report.info, ": found in srcTree"); 236 javaFile = dstJavaPkg.setFileJava( 237 javaSrcPath, fileJava, nameFileJava, preSuffix, null, false); 238 } else { 239 console.report(Report.info, ": stdType"); 240 } 241 boolean bTranslate= bTranslatePkg; 242 if(!bTranslate) 243 { /**Search whether the java-file is to translate: look in the listInputToTranslate. */ 244 Iterator<String> iter = listInputToTranslate.iterator(); 245 String sFilePathName = sPkgPath + nameFileJava; 246 if(sFilePathName.startsWith("org/vishia/java2C/test")) 247 stop(); 248 while(!bTranslate && iter.hasNext()){ 249 String sCheckTranslate = iter.next(); 250 if(sFilePathName.startsWith(sCheckTranslate)) { 251 //if(sCheckTranslate.startsWith(sFilePathName)){ 252 bTranslate = true; 253 } 254 } 255 } 256 console.report(Report.info, bTranslate ? ": translate" : ": not translate"); 257 if(bTranslate){ 258 assert(javaFile instanceof JavaSrcTreeFile); 259 JavaSrcTreeFile javaSrc = (JavaSrcTreeFile)javaFile; 260 javaSrc.setToTranslate(fileJava); 261 dstJavaSrcData.listJavaSrcFilesToTranslate.add(javaSrc); 262 } 263 console.reportln(4, " --File" + (bTranslate? "-transl:" : ":") + javaFile.toString()); 264 } 265 } 266 267 268 } 269 270 271 private void reportAllJavaSrcFiles(JavaSrcTreePkg javaPkgParent) 272 { 273 for(JavaSrcTreePkg javaPkg: javaPkgParent.listChildren()){ 274 console.reportln(Report.fineInfo, javaPkg.getPkgPath()); 275 javaPkg.reportClasses(console); 276 reportAllJavaSrcFiles(javaPkg); 277 } 278 } 279 280 void stop(){} 281 282} 283