/* * This software is distributed under the terms of the FSF * Gnu Lesser General Public License (see lgpl.txt). * * This program is distributed WITHOUT ANY WARRANTY. See the * GNU General Public License for more details. */ package com.scooterframework.autoloader; import java.io.File; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Observable; import java.util.Observer; import java.util.Properties; import java.util.Set; import com.scooterframework.admin.ApplicationConfig; import com.scooterframework.admin.PropertyFileChangeMonitor; import com.scooterframework.admin.PropertyReader; import com.scooterframework.common.logging.LogUtil; import com.scooterframework.common.util.Converters; /** * AutoLoaderConfig class configs autoloading related properties. * * @author (Fei) John Chen */ public class AutoLoaderConfig implements Observer { private LogUtil log = LogUtil.getLogger(this.getClass().getName()); private static final AutoLoaderConfig me = new AutoLoaderConfig(); private Properties appProperties = null; private String outputClassLocation = ""; private String classpath = ""; private String sourcepath = ""; private String pluginsLocation = ""; private String referencesLocation = ""; private long period = 0;//in milliseconds private String forbiddenFilesPrefix = "java., javax., com.sun., org.apache., com.scooterframework."; private Set<String> forbiddenSet = new HashSet<String>(); private List<String> jarFiles = new ArrayList<String>(); private FileMonitor fm = null; public static final String DATA_PROPERTIES_FILE = "autoloader.properties"; public static final String GENERATED_MODEL_CLASS_PREFIX = "_"; public static final String GENERATED_MODEL_CLASS_SUFFIX = "ModelHelper"; private AutoLoaderConfig() { init(); PropertyFileChangeMonitor.getInstance().registerObserver(this, DATA_PROPERTIES_FILE); } private void init() { loadProperties(); jarFiles.clear(); outputClassLocation = ""; outputClassLocation = ApplicationConfig.getInstance().getClassFileLocationPath(); outputClassLocation = unifySeparator(getProperty(ApplicationConfig.SYSTEM_KEY_CLASSFILE, outputClassLocation)); setProperty(ApplicationConfig.SYSTEM_KEY_CLASSFILE, outputClassLocation); log.debug("output class location: " + outputClassLocation); pluginsLocation = ""; pluginsLocation = ApplicationConfig.getInstance().getPluginsPath(); pluginsLocation = unifySeparator(getProperty(ApplicationConfig.SYSTEM_KEY_PLUGINFILE, pluginsLocation)); setProperty(ApplicationConfig.SYSTEM_KEY_PLUGINFILE, pluginsLocation); log.debug("plugins location: " + pluginsLocation); referencesLocation = ""; referencesLocation = ApplicationConfig.getInstance().getReferencesLibPath(); referencesLocation = unifySeparator(getProperty(ApplicationConfig.SYSTEM_KEY_REFERENCEFILE, referencesLocation)); setProperty(ApplicationConfig.SYSTEM_KEY_REFERENCEFILE, referencesLocation); log.debug("references location: " + referencesLocation); classpath = ""; classpath = appendClassPath(outputClassLocation, getProperty("additional_classpath", classpath)); classpath = appendClassPath(classpath, getAllWebInfLibFiles()); classpath = appendClassPath(classpath, getAllOtherLibFiles(pluginsLocation)); classpath = appendClassPath(classpath, getAllOtherLibFiles(referencesLocation)); String supportPath = System.getProperty("scooter.home") + File.separatorChar + "support"; classpath = appendClassPath(classpath, getAllOtherLibFiles(supportPath)); //classpath = appendClassPath(classpath, getJDKToolsJar()); log.debug("class path: " + classpath); sourcepath = ""; sourcepath = ApplicationConfig.getInstance().getSourceFileLocationPath(); sourcepath = unifySeparator(getProperty(ApplicationConfig.SYSTEM_KEY_SOURCEFILE, sourcepath)); setProperty(ApplicationConfig.SYSTEM_KEY_SOURCEFILE, sourcepath); log.debug("source file location: " + sourcepath); forbiddenSet.addAll(Converters.convertStringToSet(forbiddenFilesPrefix)); String additionalTypes = getProperty("additional_forbidden_files_prefix", null); if (additionalTypes != null) forbiddenSet.addAll(Converters.convertStringToSet(additionalTypes)); log.debug("compiler forbidden files: " + forbiddenSet); try { period = Long.parseLong(getProperty("source_file_monitor_period", "0")); } catch(NumberFormatException nfex) { period = 0; } } private void loadProperties() { if (appProperties != null) appProperties.clear(); appProperties = PropertyReader.loadPropertiesFromFile(DATA_PROPERTIES_FILE); if (appProperties == null) appProperties = new Properties(); } private String unifySeparator(String name) { if (name == null) return null; char separator = File.separatorChar; if (name.indexOf('\\') != -1 && '\\' != separator) { name = name.replace('\\', separator); } else if (name.indexOf('/') != -1 && '/' != separator) { name = name.replace('/', separator); } return name; } private String appendClassPath(String current, String additional) { String result = ""; if (additional == null || "".equals(additional)) return current; if (current != null) { if (current.trim().endsWith(File.pathSeparator)) { result = current + additional; } else { result = current + File.pathSeparatorChar + additional; } } return result; } private String getAllWebInfLibFiles() { String libdirPath = ApplicationConfig.getInstance().getWebappLibPath(); File libdir = new File(libdirPath); if (!libdir.isDirectory()) { log.warn("Path [" + libdirPath + "] is not a directory path under WEB-INF/."); return ""; } StringBuilder sb = new StringBuilder(); File[] files = libdir.listFiles(); int length = files.length; for (int i=0; i<length; i++) { File file = files[i]; String fileName = file.getName(); if (isLibraryFile(fileName) && !jarFiles.contains(fileName)) { jarFiles.add(fileName); sb.append(file.getAbsolutePath()).append(File.pathSeparatorChar); } } return sb.toString(); } private boolean isLibraryFile(String fileName) { return (fileName.endsWith(".jar") || fileName.endsWith(".zip"))?true:false; } private String getAllOtherLibFiles(String location) { String libdirPath = location; File libdir = new File(libdirPath); if (!libdir.isDirectory()) { log.warn("Path for references [" + libdirPath + "] is not a directory path."); return ""; } libdirPath = libdirPath + File.separator; List<File> files = getAllFiles(libdirPath); StringBuilder sb = new StringBuilder(); Iterator<File> it = files.iterator(); while(it.hasNext()) { File file = (File)it.next(); String fileName = file.getName(); if (!jarFiles.contains(fileName) && (fileName.endsWith(".jar") || (fileName.endsWith(".zip")) || (fileName.endsWith(".tar")) || (fileName.endsWith(".class")))) { jarFiles.add(fileName); sb.append(file.getAbsolutePath()).append(File.pathSeparatorChar); } } return sb.toString(); } private List<File> getAllFiles(String path) { File dir = new File(path); List<File> l = new ArrayList<File>(); appendFilesToList(l, dir); return l; } private void appendFilesToList(List<File> list, File file) { if (file.isDirectory()) { File[] files = file.listFiles(); int length = files.length; for (int i=0; i<length; i++) { File f = files[i]; appendFilesToList(list, f); } } else if (file.isFile()) { list.add(file); } } public static AutoLoaderConfig getInstance() { return me; } public void update(Observable o, Object arg) { init(); if (fm != null) { fm.update(); } } /** * Returns all properties. */ public Properties getProperties() { return appProperties; } /** * Returns a String property corresponding to a key. The method returns the * default value argument if the property is not found. */ public String getProperty(String key, String defaultValue) { return appProperties.getProperty(key, defaultValue); } /** * Sets a property. */ public void setProperty(String key, String value) { appProperties.setProperty(key, value); } public long getPeriod() { return period; } public String getClassPath() { return classpath; } public String getOutputClassLocation() { return outputClassLocation; } public String getSourcePath() { return sourcepath; } public String getPluginsLocation() { return pluginsLocation; } public String getReferencesLocation() { return referencesLocation; } public boolean notAllowedToChange(String className) { if (className == null) return true; if (className.endsWith(GENERATED_MODEL_CLASS_SUFFIX)) { int lastDot = className.lastIndexOf('.'); String tmp = className; if (lastDot != -1) tmp = className.substring(lastDot + 1); if (tmp.startsWith(GENERATED_MODEL_CLASS_PREFIX)) return true; } boolean result = false; Iterator<String> it = forbiddenSet.iterator(); while(it.hasNext()) { String item = it.next(); if (className.startsWith(item)) { result = true; break; } } return result; } public void registerFileMonitor(FileMonitor fm) { this.fm = fm; } }