/**
* Automatically build classpath from *.jar files located in the './lib' directory under the current project directory
* Contributor(s):
* Duy Dinh <dinhbaduy@gmail.com> (original author)
*/
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Hashtable;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
/**
* Build classpath file from several directories containing .jar files
*
*/
public class buildClassPath {
static String FILE_EXTENSION = ".jar"; // file extension
static boolean USE_ABSOLUTE_PATH = false;
static String CURRENT_DIRECTORY = "";// current directory (absolute path)
// lib directories containing .jar files to be added in clsspath
// change this value if library name is different from those values
static String[] LIB_DIRECTORY_NAMES = { "lib" }; // , "installer" };
static String FILE_SEPERATOR = "/";
static String CLASSPATH = ".classpath"; // class path file name
public static void main(String[] args) {
// gets system current dir
CURRENT_DIRECTORY = System.getProperty("user.dir");
// make classpath file name absolute
CLASSPATH = CURRENT_DIRECTORY + "/.classpath";
// build classpath using XML DOM
BuildClassPath(CLASSPATH, LIB_DIRECTORY_NAMES);
System.out.println("Build classpath successfully!");
}
/**
* Build classpath from .jar files
*
* @param dir
* input directory containing .jar files
* @param classPathFileName
* classpath filename
*/
static void BuildClassPath(String classPathFileName, String[] directories) {
try {
// test if .classpath file name does exist
File f = new File(classPathFileName);
// if (!f.exists()) {
f.createNewFile();
// minimum XML content of a classpath XML file
StringBuilder sb = new StringBuilder();
sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
sb.append("<classpath>\n");
sb.append(" <classpathentry kind=\"src\" path=\"src\"/>\n");
sb.append(" <classpathentry kind=\"con\" path=\"org.eclipse.jdt.launching.JRE_CONTAINER\"/>\n");
sb.append(" <classpathentry kind=\"output\" path=\"bin\"/>\n\t\n");
sb.append("</classpath>");
// write xml structure for a classpath
System.out
.println("Overwriting classpath file content and building XML structure for adding new entries...");
WriteToFile(sb.toString(), classPathFileName);
// }
// list all .jar files in the lib directory
// collect .jar files
for (int i = 0; i < directories.length; i++) {
ArrayList<String> fileList = new ArrayList<String>();
browseFolder(directories[i], directories[i], fileList);
// update .classpath
updateClasspath(classPathFileName, fileList);
}
} catch (Exception ex) {
}
}
/**
* Update classpath file name
*
* @param classPathFileName
* @param fileList
*/
private static void updateClasspath(String classPathFileName,
ArrayList<String> fileList) {
// load .classpath using XML DOM
Document doc = LoadXMLDocument(classPathFileName);
// get root node (classpath)
Element root = doc.getDocumentElement();
// get already imported .jar files
Hashtable<String, Integer> htb = getClassEntryValues(classPathFileName);
for (String filename : fileList) {
String[] fields = filename.split(String.format("[%s]+",
FILE_SEPERATOR));
String shortname = fields[fields.length - 1];
if (htb.get(shortname) == null) {
// insert/add external unique .jar files
Element element = doc.createElement("classpathentry");
Attr attribute = doc.createAttribute("kind");
attribute.setNodeValue("lib");
element.setAttributeNode(attribute);
attribute = doc.createAttribute("path");
attribute.setNodeValue(filename);
element.setAttributeNode(attribute);
System.out.println("Adding file " + filename);
root.appendChild(element);
htb.put(shortname, 1);
} else {
System.out.format(
"File '%s' has been already added to classpath\n",
filename);
}
}
SaveXMLDocument(doc, classPathFileName);
String text = ReadFile(classPathFileName);
// System.out.println(text);
text = text.replaceAll("/><", "/>\n\t<");
WriteToFile(text, classPathFileName);
}
/**
*
* Gets a list of already imported .jar files
*/
private static Hashtable<String, Integer> getClassEntryValues(
String filename) {
Hashtable<String, Integer> htb = new Hashtable<String, Integer>();
Document doc = LoadXMLDocument(filename);
Element root = doc.getDocumentElement();
NodeList nodeList = root.getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
if (node.getNodeName().equalsIgnoreCase("classpathentry")) {
NamedNodeMap attributes = node.getAttributes();
String kind = attributes.getNamedItem("kind").getNodeValue();
if (kind.equalsIgnoreCase("lib")) {
// put shortname into hashtable
filename = attributes.getNamedItem("path").getNodeValue();
String[] fields = filename.split(String.format("[%s]+",
FILE_SEPERATOR));
String shortname = fields[fields.length - 1];
htb.put(shortname, i);
}
}
}
return htb;
}
/**
* Browse recursively a directory
*
* @param inputDir
* input directory
* @param list
* file list (by reference)
* @return file list
*/
static void browseFolder(String inputDir, String shortDirName,
ArrayList<String> fileList) {
File dirFile = new File(inputDir);
File[] filesAndDirs = dirFile.listFiles();
List<File> filesDirs = Arrays.asList(filesAndDirs);
for (File file : filesDirs) {
if (!file.isFile()) { // must be a directory
// a recursive call
browseFolder(file.getAbsolutePath(), shortDirName, fileList);
} else
// must not be a hidden file
if (!isHiddenFile(file)) {
String filename = file.getAbsolutePath();
if (isValid(filename)) {
if (!USE_ABSOLUTE_PATH) {
int index = filename.lastIndexOf(FILE_SEPERATOR
+ shortDirName + FILE_SEPERATOR);
if (index > 0)
filename = filename.substring(index + 1);
}
fileList.add(filename);
}
}
}
}
/**
* Tests if a filename is valid for including to the file list
*
* @param fileName
* input file name
* @return yes if filename is valid
*/
static boolean isValid(String fileName) {
boolean valid = FILE_EXTENSION.equals("");
if (!valid)
valid = fileName.endsWith(FILE_EXTENSION);
return valid;
}
/**
* Tests if a file is hidden
*
* @param file
* input file
* @return true if the file is hidden
*/
static boolean isHiddenFile(File file) {
return file.isHidden() || file.getName().endsWith("~");
}
/**
* Browse recursively a directory
*
* @param inputDir
* input directory
* @param list
* file list (by reference)
* @return file list
*/
static void browseFolder(String inputDir, String shortDirName,
ArrayList<String> fileList, String extension) {
File dirFile = new File(inputDir);
File[] filesAndDirs = dirFile.listFiles();
List<File> filesDirs = Arrays.asList(filesAndDirs);
for (File file : filesDirs) {
if (!file.isFile()) { // must be a directory
// a recursive call
browseFolder(file.getAbsolutePath(), shortDirName, fileList);
} else
// must not be a hidden file
if (!file.isHidden() && !file.getName().endsWith("~")) {
fileList.add(file.getAbsolutePath());
}
}
}
/**
* Reads text from an input file
*
* @returns Returns the text content, each line is seperated by '\n'
**/
public static String ReadFile(String fileName) {
StringBuilder sb = new StringBuilder();
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(
new FileInputStream(fileName)));
String s;
while ((s = reader.readLine()) != null) {
sb.append(s).append("\n");
}
reader.close();
} catch (Exception e1) {
}
return sb.toString();
}
/**
* Loads XML content from file
*
* @param filename
* input XML filename
* @return XML document object
*/
public static Document LoadXMLDocument(String filename) {
/**
* Defines a factory API that enables applications to obtain a parser
* that produces DOM object trees from XML documents
*/
DocumentBuilderFactory fact = null;
/**
* Defines the API to obtain DOM Document instances from an XML
* document.
* */
DocumentBuilder builder = null;
/***
* The Document interface represents the entire HTML or XML document.
*/
Document doc = null;
// initialize DOM API
fact = DocumentBuilderFactory.newInstance();
try {
// creates a document builder (loader)
builder = fact.newDocumentBuilder();
} catch (ParserConfigurationException e) {
e.printStackTrace();
}
try {
// parse XML into a DOM tree and loads it into memory
doc = builder.parse(filename);
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return doc;
}
/**
* Saves XML content to output file
*
* @param doc
* XML document object
* @param filename
* output XML filename
*
*/
public static void SaveXMLDocument(Document doc, String filename) {
try {
// clear file content
WriteToFile("", filename);
StringBuilder sb = new StringBuilder();
sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
sb.append("<classpath>\n");
Element root = doc.getDocumentElement();
NodeList nodeList = root.getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
// attributes
NamedNodeMap attributes = node.getAttributes();
if (attributes != null && attributes.getLength() > 0) {
sb.append("\t<");
sb.append(node.getNodeName() + " ");
for (int j = 0; j < attributes.getLength(); j++)
sb.append(attributes.item(j) + " ");
sb.append(" />\n");
}
}
sb.append("</classpath>");
AppendFile(sb.toString(), filename);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Writes text content to the output file
*/
public static void WriteToFile(String text, String outputFileName,
String charsetName) {
try {
if ((text == null || text.equals(""))) {
return;
}
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(outputFileName), charsetName));
writer.write(text);
writer.flush();
writer.close();
} catch (Exception ex) {
}
}
public static void WriteToFile(String text, String outputFileName) {
try {
if (text == null) {
return;
}
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(outputFileName)));
writer.write(text);
writer.flush();
writer.close();
} catch (Exception ex) {
}
}
/**
* Reads text from an input file
*
* @returns Returns the text content, each line is separated by '\n'
**/
public static String ReadFile(String fileName, String charsetName) {
StringBuilder sb = new StringBuilder();
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(
new FileInputStream(fileName), charsetName));
String s;
while ((s = reader.readLine()) != null) {
sb.append(s).append("\n");
}
reader.close();
} catch (Exception e1) {
}
// remove the bizar character in the UTF file
if (charsetName.contains("UTF")) {
sb.delete(0, 1);
}
return sb.toString();
}
public static void AppendFile(String text, String outputFileName) {
try {
if (text.equals("") || text == null) {
return;
}
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(outputFileName, true)));
writer.write(text);
writer.flush();
writer.close();
} catch (Exception ex) {
}
}
public static void AppendFile(String text, String outputFileName,
String charset) {
try {
if (text.equals("") || text == null) {
return;
}
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(outputFileName, true), charset));
writer.write(text);
writer.flush();
writer.close();
} catch (Exception ex) {
}
}
}