/* $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);
}
}