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.text.ParseException; 027import java.util.Iterator; 028import java.util.LinkedList; 029import java.util.List; 030import java.util.Set; 031import java.util.TreeMap; 032import java.util.Map; 033 034import org.vishia.mainCmd.Report; 035import org.vishia.util.SortedTree; 036 037/**Representation of an existing Folder in the Java pkg tree. 038 */ 039public class JavaSrcTreePkg implements SortedTree<JavaSrcTreePkg>, JavaSources.ClassDataOrJavaSrcFile 040{ 041 042 /**Version, history and license. 043 * <ul> 044 * <li>2014-09-05 Hartmut chg: {@link #setFileJava(String, File, String, org.vishia.java2C.ConfigSrcPathPkg_ifc.Set, String, boolean)} not used arguments removed. 045 * The arguments <code>String prefixCFile, String suffixCFile, String prefixNames, String suffixNames</code> are contained 046 * in the <code>ConfigSrcPathPkg_ifc.Set info</code> already. 047 * <li>2014-09-05 Hartmut new: {@link #setFileAndReadStcFile(String, org.vishia.java2C.ConfigSrcPathPkg_ifc.Set, String)}. This is one method which reads 048 * all information about a Java class from a existing stc file, especially used for C-written parts read in {@link CRuntimeJavalikeClassData}. 049 * <li>2008 Hartmut created: 050 * </ul> 051 * <br><br> 052 * <b>Copyright/Copyleft</b>: 053 * For this source the LGPL Lesser General Public License, 054 * published by the Free Software Foundation is valid. 055 * It means: 056 * <ol> 057 * <li> You can use this source without any restriction for any desired purpose. 058 * <li> You can redistribute copies of this source to everybody. 059 * <li> Every user of this source, also the user of redistribute copies 060 * with or without payment, must accept this license for further using. 061 * <li> But the LPGL is not appropriate for a whole software product, 062 * if this source is only a part of them. It means, the user 063 * must publish this part of source, 064 * but don't need to publish the whole source of the own product. 065 * <li> You can study and modify (improve) this source 066 * for own using or for redistribution, but you have to license the 067 * modified sources likewise under this LGPL Lesser General Public License. 068 * You mustn't delete this Copyright/Copyleft inscription in this source file. 069 * </ol> 070 * If you are intent to use this sources without publishing its usage, you can get 071 * a second license subscribing a special contract with the author. 072 * 073 * @author Hartmut Schorrig = hartmut.schorrig@vishia.de 074 */ 075 public final static String sVersion = "2014-09-05"; 076 077 private final String sPkgPath; 078 079 private final String sPkgName; 080 081 /**The parent pkg, it is only to see in debug and reports.*/ 082 private final JavaSrcTreePkg parent; 083 084 private TreeMap<String, JavaSrcTreePkg> subPkgs; 085 086 /**All file.java containing in this package. */ 087 private final TreeMap<String, JavaSrcTreeFile> XXXjavaFiles = new TreeMap<String, JavaSrcTreeFile>(); 088 089 090 /**Same content as {@link #javaFiles}, but the key is the class name. */ 091 //private final TreeMap<String, JavaSrcTreeFile> javaPublicClasses = new TreeMap<String, JavaSrcTreeFile>(); 092 private final List<JavaSources.ClassDataOrJavaSrcFile> javaPublicClasses = new LinkedList<JavaSources.ClassDataOrJavaSrcFile>(); 093 094 /**Set to true if {@link #setFileJava(String, File, String, String, String, boolean)} 095 * is called the first time. */ 096 private boolean pkgHasFiles = false; 097 098 /**If this info is found, a stc-file is determined for the package to replace structure info 099 * instead given Java-files. 100 */ 101 private ConfigSrcPathPkg_ifc.Set replaceCinfo; 102 103 /**Index of all sub-packages and classes available in the package, package privates too. 104 * Only the field {@link LocalIdents#typeIdents} is used, because a package has no fields. 105 * But the type {@link LocalIndents} is necessary to implement 106 * the method {@link JavaSources.ClassDataOrJavaSrcFile#getLocalIdents(String)} 107 * to support getting data to an identifier inside the package (may be sub-package or a file or a class known in package). 108 */ 109 private final LocalIdents pkgIdents; 110 111 112 /** 113 * @param pkgIdent 114 * @param javaSrcPath 115 */ 116 public JavaSrcTreePkg(JavaSrcTreePkg parent, String pkgPath, String pkgName, ConfigSrcPathPkg_ifc.Set replaceCinfo) //, LocalIdents identsToAssignPkgIdents) 117 { this.parent = parent; 118 this.sPkgPath = pkgPath; 119 this.sPkgName = pkgName; 120 this.replaceCinfo = replaceCinfo; //maybe null 121 pkgIdents = new LocalIdents(parent ==null ? null : parent.getPkgLevelIdents(), null); 122 } 123 124 125 126 /**returns the Instance, which represents the given package name. 127 * If the Instance doesn't exist, it is created. 128 * If it exists already before this call, and its {@link #replaceCinfo} is null, 129 * then the given parameter replaceCinfo is used to set it. 130 * If the {@link #replaceCinfo} was given before, and the parameter replaceCinfo is given here too, 131 * it is tested whether it contains the same. Elsewhere a IllegalArgumentException is thrown. 132 * 133 * @param pkgPath The full path from root 134 * @param pkgName The name of the new package 135 * @param replaceCinfo if not null, then it is the info to build the C-files /search the stc-file 136 * for all non-existing, but needed Java-files of the package. 137 * @return The package management instance. 138 */ 139 public JavaSrcTreePkg getOrAddPkg(String pkgPath, String pkgName, ConfigSrcPathPkg_ifc.Set replaceCinfo) //, LocalIdents identsToAssignPkgIdents) 140 { 141 JavaSrcTreePkg ret; 142 if(subPkgs == null){ 143 subPkgs = new TreeMap<String, JavaSrcTreePkg>(); 144 ret = null; 145 } else { 146 ret = subPkgs.get(pkgName); //try, maybe not found 147 } 148 if(ret == null){ 149 ret = new JavaSrcTreePkg(this, pkgPath, pkgName, replaceCinfo); //, identsToAssignPkgIdents); 150 Java2C_Main.singleton.javaSources.indexJavaSrcPkgs.put(pkgPath, ret); 151 subPkgs.put(pkgName,ret); 152 //javaPublicClasses.putClassType(pkgName, ret); 153 this.pkgIdents.putClassType(pkgName, ret); //to find as identifier while translating. 154 } else { 155 //found, check to replace the replaceCinfo 156 if(replaceCinfo != null){ 157 //maybe todo: check whether it is the same info, not only null-check 158 if(ret.replaceCinfo != null) throw new IllegalArgumentException("package: " + pkgName + " - second replaceinfo: " + replaceCinfo.toString()); 159 ret.replaceCinfo = replaceCinfo; 160 } 161 } 162 return ret; 163 } 164 165 /**Adds the given type info to the pkgIdents. 166 * @param data The type info. 167 */ 168 public void putClassType(ClassData data){ 169 pkgIdents.putClassType(data); 170 } 171 172 173 public String getPkgPath(){ return sPkgPath; } 174 175 public final TreeMap<String, JavaSrcTreeFile> XXXgetJavaFiles(){ 176 177 return XXXjavaFiles; 178 } 179 180 181 182 public final List<JavaSources.ClassDataOrJavaSrcFile> getPublicClasses() 183 { 184 return javaPublicClasses; 185 } 186 187 188 189 /**Adds all standard types to the package. This method will be called if any file is containing 190 * in the package. It means, the package is the immediate package of any class. 191 * This method will be called too while creating a standard package (java.lang). 192 * @param types 193 */ 194 public void xxxaddStdTypes(LocalIdents types) 195 { 196 //javaPublicClasses.putClassTypesAll(types); 197 pkgIdents.putClassTypesAll(types); 198 } 199 200 201 /**Registers the occurrence of a found Java file or set the {@link ConfigSrcPathPkg_ifc.Set} 202 * for an existing file without replaceCinfo 203 * @param javaSrcPath The source path where the file is found. It may be null for Classes, which are presented by its stc file only. 204 * @param fileJava The File instance ready to the open source file. null if javaSrcPath ==null. 205 * @param sFileNameJava The file name without path but with extension <code>.java</code> without directories. The class Name if a stc file will be registered. 206 * @param info informations to find out where the C-file is found and which pre/suffix are valid. 207 * @param stcPath null or a special path where the stc-file is located. 208 * @param translateToC false than the file should not be translate to C, 209 * instead the stc-file should be used any time. This is if it is a standard class 210 * or a users class, which is located in a library. 211 * @return 212 */ 213 public JavaSources.ClassDataOrJavaSrcFile setFileJava(String javaSrcPath, File fileJava, String sFileNameJava 214 , ConfigSrcPathPkg_ifc.Set info, String stcPath 215 , boolean translateToC 216 )//(String javaSrcPath, File fileJava, String nameFileJava, String pkgPath, String pathC, boolean bToTranslateToC) 217 { JavaSources.ClassDataOrJavaSrcFile javaSrc; 218 if(!pkgHasFiles){ 219 /** First call of this method, add all standard types at first. */ 220 pkgHasFiles =true; 221 } 222 223 //javaSrc = javaFiles.get(sFileNameJava); //check whether the file is known yet. 224 String sJavaClass = sFileNameJava.substring(0, sFileNameJava.indexOf(".java")); 225 javaSrc = pkgIdents.getTypeInfo(sJavaClass, null); //check whether the file is known yet. 226 if( javaSrc== null){ 227 /**register only the first occurrence of a Java file. If the file is located more than one time, 228 * the first occurrence should be used. 229 */ 230 javaSrc = new JavaSrcTreeFile( this, javaSrcPath, fileJava, sFileNameJava, info 231 , stcPath, translateToC); 232 /**assume that the file contains a public class and put the name in type list, without yet ClassData. */ 233 javaPublicClasses.add(javaSrc); 234 //TODO: a first first pass is necessary, with parsing file, to get all classes. 235 //up to now: only one class per file. 236 //it is done already: pkgIdents.putClassType(javaSrc.getPublicClassName(), javaSrc); 237 } 238 else if(javaSrc instanceof ClassData){ 239 //it isknown already, do nothing. 240 System.out.println("setFileJava unnecessary: " + sFileNameJava); 241 } else{ 242 //The package replacements are set already. 243 //notice, that it is found and maybe to translate! 244 //The Java-file may be exist already therefore, it is created in package replacement. 245 JavaSrcTreeFile javaSrcFile = (JavaSrcTreeFile)javaSrc; 246 javaSrcFile.infoSecondFile(fileJava, translateToC); 247 } 248 return javaSrc; 249 } 250 251 252 253 254 255 /**Registers a Java class inside the given package and reads the associated stc file. 256 * @param sClassname The class name 257 * @param info info about the path to C files 258 * @param stcPath Path to stc-File, maybe null if the stc file has the same path then the associated C file with extension .stc. 259 * @return the ClassData. That ClassData are stored in this {@link #pkgIdents} too, using {@link LocalIdents#getType(String, LocalIdents)} to get it. 260 * The return value is used inside {@link CRuntimeJavalikeClassData} if the ClassData are used there. 261 * @throws ParseException on faulty stc file. 262 */ 263 public ClassData setFileAndReadStcFile(String sClassname, ConfigSrcPathPkg_ifc.Set info, String stcPath) 264 throws ParseException 265 { String sFileNameJava = sClassname + ".java"; 266 setFileJava(null, null, sFileNameJava, info, stcPath, false); 267 ClassData ret = pkgIdents.getType(sClassname, null); //this forces reading the stc file 268 return ret; 269 } 270 271 272 273 274 275 public void reportClasses(Report report) 276 { 277 Set<Map.Entry<String, JavaSources.ClassDataOrJavaSrcFile>> entries = pkgIdents.getTypeSet(); 278 for(Map.Entry<String, JavaSources.ClassDataOrJavaSrcFile> entry: entries){ 279 JavaSources.ClassDataOrJavaSrcFile javaFile= entry.getValue(); 280 report.reportln(Report.fineInfo, " +- " + entry.getKey() + " = "+ (javaFile !=null ? javaFile.toString(): "???")); 281 } 282 283 } 284 285 286 public JavaSrcTreePkg getChild(String key) 287 { return subPkgs.get(key); 288 } 289 290 /**gets the pkg-level-idents. It contains all types which are known 291 * at this package level (all files of package.). 292 */ 293 public LocalIdents getPkgLevelIdents(){ return pkgIdents; } 294 295 public Iterator<JavaSrcTreePkg> iterChildren() 296 { 297 // TODO Auto-generated method stub 298 return null; 299 } 300 301 302 303 public Iterator<JavaSrcTreePkg> iterChildren(String key) 304 { 305 // TODO Auto-generated method stub 306 return null; 307 } 308 309 310 311 public List<JavaSrcTreePkg> listChildren() 312 { 313 List<JavaSrcTreePkg> ret = new LinkedList<JavaSrcTreePkg>(); 314 if(subPkgs != null){ 315 Set<Map.Entry<String, JavaSrcTreePkg>> entries = subPkgs.entrySet(); 316 for(Map.Entry<String, JavaSrcTreePkg> entry: entries){ 317 JavaSrcTreePkg folder= entry.getValue(); 318 ret.add(folder); 319 } 320 } 321 return ret; 322 } 323 324 325 326 public List<JavaSrcTreePkg> listChildren(String key) 327 { 328 // TODO Auto-generated method stub 329 return null; 330 } 331 332 333 334 public ClassData getClassData() 335 { 336 return null; 337 } 338 339 340 341 /**Implements {@link JavaSources.ClassDataOrJavaSrcFile#getJavaSrc()} 342 */ 343 public JavaSrcTreeFile getJavaSrc() 344 { 345 return null; // it isn't a JavaSrcTreeFile 346 } 347 348 /**Implements {@link JavaSources.ClassDataOrJavaSrcFile#getJavaPkg()} 349 */ 350 public JavaSrcTreePkg getJavaPkg() 351 { 352 return this; 353 } 354 355 356 357 358 /**Returns the identifier of classes or packages, which are available in this package. 359 * It may be sub-package or a file or a class known in package. 360 * implements {@link org.vishia.java2C.JavaSources.ClassDataOrJavaSrcFile#getLocalIdents(java.lang.String)} 361 * @param sPkgName: It is ignored. 362 */ 363 @Override public LocalIdents getLocalIdents(String sPkgName) 364 { 365 return pkgIdents; 366 } 367 368 /**Implements {@link JavaSources.ClassDataOrJavaSrcFile#getTypeName()} 369 */ 370 public String getTypeName() 371 { 372 return sPkgName; 373 } 374 375 @Override public String toString(){ 376 return sPkgPath; 377 /* 378 StringBuilder ret = new StringBuilder(200); 379 ret.append(sPkgPath); 380 if(subPkgs != null){ 381 ret.append(':').append(subPkgs.toString()); 382 } 383 return ret.toString(); 384 */ 385 } 386 387 388 389 /* (non-Javadoc) 390 * @see org.vishia.java2C.JavaSources.ClassDataOrJavaSrcFile#getReplaceCinfo() 391 */ 392 @Override 393 public org.vishia.java2C.ConfigSrcPathPkg_ifc.Set getReplaceCinfo() { 394 return replaceCinfo; 395 } 396 397 398 399 /**returns false because a package isn't to translate. 400 * @see org.vishia.java2C.JavaSources.ClassDataOrJavaSrcFile#isToTranslate() 401 */ 402 @Override 403 public boolean isToTranslate() { 404 return false; 405 } 406 407 @Override public void setClassData(ClassData data){ 408 throw new IllegalArgumentException("internal: ClassData for package"); 409 } 410 411 412 413 @Override 414 public JavaSrcTreePkg getParent() { 415 // TODO Auto-generated method stub 416 return null; 417 } 418 419 420}