/* $Revision: 6707 $ $Author: egonw $ $Date: 2006-07-30 16:38:18 -0400 (Sun, 30 Jul 2006) $ * * Copyright (C) 2006 Egon Willighagen * * Contact: cdk-devel@lists.sourceforge.net * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 * of the License, or (at your option) any later version. * All we ask is that proper credit is given for our work, which includes * - but is not limited to - adding the above copyright notice to the beginning * of your source code files, and to any copyright notice that you may distribute * with programs based on this work. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ package net.sf.cdk.tools; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Map; /** * Class that creates the ${build}/*.javafiles. * * @author egonw */ public class MakeJavafilesFiles { private Map<String,List<String>> cdkPackages; private Map<String,List<String>> cdkSets; private String default_module; /** Java files that should not be processed because they are * listed in a *.autogenerated file. */ private List<String> blacklist; private String sourceDir = null; private String outputDir = null; private String metainfDir = null; public MakeJavafilesFiles(String metainfDir, String sourceDir, String outputDir) { cdkPackages = new Hashtable<String,List<String>>(); cdkSets = new Hashtable<String,List<String>>(); this.sourceDir = sourceDir; this.outputDir = outputDir; this.metainfDir = metainfDir; readBlackList(); if (sourceDir.contains("test")) { default_module = "test-extra"; } else { default_module = "extra"; } } private void readBlackList() { blacklist = new ArrayList<String>(); String metainfDirPath = this.metainfDir; File metinfDir = new File(metainfDirPath); File[] files = metinfDir.listFiles(); for (int i=0; i<files.length; i++) { if (files[i].getName().endsWith(".autogenerated")) { // add content to blacklist try { BufferedReader reader = new BufferedReader(new FileReader(files[i])); String line = reader.readLine(); while (line != null) { line.trim(); if (line.length() > 0) blacklist.add(line); line = reader.readLine(); } } catch (Exception e) { System.out.println("Error reading a *.autogenerated file: " + e.getMessage()); e.printStackTrace(); System.exit(1); } } } } public void outputResults() { // output information in .javafiles and .classes files try { Iterator<String> keys = cdkPackages.keySet().iterator(); while (keys.hasNext()) { String key = (String)keys.next(); // create one file for each cdk package = key PrintWriter outJava = new PrintWriter( new FileWriter(outputDir + "/" + key + ".javafiles") ); PrintWriter outClass = new PrintWriter( new FileWriter(outputDir + "/" + key + ".classes") ); List<String> packageClasses = cdkPackages.get(key); Iterator<String> classes = packageClasses.iterator(); while (classes.hasNext()) { String packageClass = toAPIPath(classes.next()); if (!blacklist.contains(packageClass + ".java")) { outJava.println(packageClass + ".java"); outClass.println(packageClass + "*.class"); } } outJava.flush(); outJava.close(); outClass.flush(); outClass.close(); } // output information in .set files keys = cdkSets.keySet().iterator(); while (keys.hasNext()) { String key = (String)keys.next(); // create one file for each cdk package = key PrintWriter outJava = new PrintWriter( new FileWriter(outputDir + "/" + key + ".set") ); List<String> packageClasses = cdkSets.get(key); Iterator<String> classes = packageClasses.iterator(); while (classes.hasNext()) { String packageClass = (String)classes.next(); outJava.println(packageClass); } outJava.flush(); outJava.close(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void processJavaSourceFiles(File path) { if (path.isDirectory()) { File[] files = path.listFiles(); for (int i=files.length;i>0;i--) { processJavaSourceFiles(files[i-1]); } } else if (path.isFile() && path.getPath().endsWith(".java") && !(path.getPath().indexOf("net/sf") != -1 || path.getPath().indexOf("net\\sf") != -1)) { String[] moduleAndSet = getModuleAndSet(path); if (moduleAndSet == null) { System.out.println("Something wrong with the Java source file: " + path); } else { if (moduleAndSet[0] != null) { addClassToCDKPackage(getSourceName(path), moduleAndSet[0]); } if (moduleAndSet[1] != null) { addClassToCDKSet(getClassName(path), moduleAndSet[1]); } } } } public String[] getModuleAndSet(File file) { try { String[] results = new String[2]; results[0] = default_module; results[1] = null; BufferedReader reader = new BufferedReader( new FileReader(file) ); String line = null; boolean inComment = false; while ((line = reader.readLine()) != null) { int index = line.indexOf("/**"); if (index != -1) { inComment = true; if (line.substring(index).indexOf("*/") != -1) inComment = false; } else { if (line.indexOf("*/") != -1) inComment = false; } if (!inComment && (line.indexOf("class") != -1 || line.indexOf("public enum") != -1 || line.indexOf("public interface") != -1 || line.indexOf("public @interface") != -1)) { // Nothing specified: return the default 'extra' reader.close(); return results; } index = line.indexOf("@cdk.module"); String name = ""; if (index != -1) { index += 11; // skip the first chars while (Character.isWhitespace(line.charAt(index))) index++; while (index < line.length() && !Character.isWhitespace(line.charAt(index))) { name += line.charAt(index); index++; } results[0] = name; } else { index = line.indexOf("@cdk.set"); String set = ""; if (index != -1) { index += 8; // skip the first chars while (Character.isWhitespace(line.charAt(index))) index++; while (index < line.length() && !Character.isWhitespace(line.charAt(index))) { set += line.charAt(index); index++; } results[1] = set; } } } } catch (Exception e) { e.printStackTrace(); } return null; } public static void main(String[] args) { if (args.length != 3) { System.out.println("Syntax: MakeJavafilesFiles <metainfDir> <sourceDir> <outputDir>"); System.exit(-1); } MakeJavafilesFiles processor = new MakeJavafilesFiles(args[0], args[1], args[2]); processor.processJavaSourceFiles(new File(args[1])); processor.outputResults(); } private String toAPIPath(String className) { StringBuffer sb = new StringBuffer(); for (int i=0; i<className.length(); i++) { if (className.charAt(i) == '.') { sb.append('/'); } else { sb.append(className.charAt(i)); } } return sb.toString(); } private String getSourceName(File classFile) { // assume the pattern src/package/className.java // return package/className String tmp = classFile.getPath().substring(sourceDir.length()+1); return tmp.substring(0, tmp.length()-5); } private String getClassName(File classFile) { // assume the pattern src/package/className.java // return package.className StringBuffer sb = new StringBuffer(); String className = classFile.getPath().substring(sourceDir.length()+1); for (int i=0; i<className.length()-5; i++) { if (className.charAt(i) == '/' || className.charAt(i) == '\\') { sb.append('.'); } else { sb.append(className.charAt(i)); } } return sb.toString(); } private void addClassToCDKPackage(String packageClass, String cdkPackageName) { List<String> packageClasses = cdkPackages.get(cdkPackageName); if (packageClasses == null) { packageClasses = new ArrayList<String>(); cdkPackages.put(cdkPackageName, packageClasses); } packageClasses.add(packageClass); } private void addClassToCDKSet(String packageClass, String cdkPackageName) { List<String> packageClasses = cdkSets.get(cdkPackageName); if (packageClasses == null) { packageClasses = new ArrayList<String>(); cdkSets.put(cdkPackageName, packageClasses); } packageClasses.add(packageClass); } }