easyconf-0.9.5/ 40755 0 0 0 10337163174 10373 5ustar 0 0 easyconf-0.9.5/src/ 40755 0 0 0 10337163174 11162 5ustar 0 0 easyconf-0.9.5/src/test/ 40755 0 0 0 10337163174 12141 5ustar 0 0 easyconf-0.9.5/src/test/com/ 40755 0 0 0 10337163174 12717 5ustar 0 0 easyconf-0.9.5/src/test/com/germinus/ 40755 0 0 0 10337163174 14550 5ustar 0 0 easyconf-0.9.5/src/test/com/germinus/easyconf/ 40755 0 0 0 10337163174 16357 5ustar 0 0 easyconf-0.9.5/src/test/com/germinus/easyconf/jmx/ 40755 0 0 0 10337163174 17155 5ustar 0 0 easyconf-0.9.5/src/test/com/germinus/easyconf/systemtests/ 40755 0 0 0 10337163174 20766 5ustar 0 0 easyconf-0.9.5/src/java/ 40755 0 0 0 10337163174 12103 5ustar 0 0 easyconf-0.9.5/src/java/com/ 40755 0 0 0 10337163174 12661 5ustar 0 0 easyconf-0.9.5/src/java/com/germinus/ 40755 0 0 0 10337163174 14512 5ustar 0 0 easyconf-0.9.5/src/java/com/germinus/easyconf/ 40755 0 0 0 10337163174 16321 5ustar 0 0 easyconf-0.9.5/src/java/com/germinus/easyconf/servlet/ 40755 0 0 0 10337163174 20005 5ustar 0 0 easyconf-0.9.5/src/java/com/germinus/easyconf/taglib/ 40755 0 0 0 10337163174 17563 5ustar 0 0 easyconf-0.9.5/src/java/com/germinus/easyconf/jmx/ 40755 0 0 0 10337163174 17117 5ustar 0 0 easyconf-0.9.5/src/java/com/germinus/easyconf/struts/ 40755 0 0 0 10337163174 17665 5ustar 0 0 easyconf-0.9.5/src/webapp/ 40755 0 0 0 10337163174 12440 5ustar 0 0 easyconf-0.9.5/src/webapp/examples/ 40755 0 0 0 10337163174 14256 5ustar 0 0 easyconf-0.9.5/LICENSE.txt100644 0 0 26136 10337163174 12343 0ustar 0 0 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. easyconf-0.9.5/maven.xml100644 0 0 1100 10337163174 12310 0ustar 0 0 easyconf-0.9.5/project.xml100644 0 0 23566 10337163174 12714 0ustar 0 0 3 easyconf easyconf easyconf Easyconf library 0.9.5 EasyConf team http://www.sourceforge.net/projects/easyconf 2005 com.germinus.easyconf http://easyconf.sourceforge.net/easyconf.jpg EasyConf is a library to access configuration of software components and applications. It defines simple conventions to make it easier to use. It was born in a portlets-based portal and has several features useful for this and similar environments. Software configuration made easy http://easyconf.sourceforge.net https://sourceforge.net/tracker/?group_id=131552&atid=721404 shell.sourceforge.net /home/groups/e/ea/easyconf/htdocs /www/easyconf/builds/ scm:cvs:pserver:anonymous@cvs.sourceforge.net:/cvsroot/easyconf:easyconf scm:cvs:ext:jferrergerminus@cvs.sourceforge.net:/cvsroot/easyconf:easyconf http://cvs.sourceforge.net/viewcvs.py/easyconf/ easyconf-users easyconf-users-subscribe@sourceforge.net easyconf-users-unsubscribe@sourceforge.net http://sourceforge.net/mailarchive/forum.php?forum=easyconf-users Jorge Ferrer jferrer jferrer germinus.com Germinus XXI 0 Jesús Jaimez jjaimez 0 Ismael Ferrer ifolmedo iferrer germinus.com Germinus XXI 0 Álvaro González agonzalez agonzalez germinus.com Germinus XXI 0 log4j log4j 1.2.8 jar http://www.apache.org/ unknown servletapi servletapi 2.3 jar http://www.apache.org/ false struts struts 1.1 jar http://www.apache.org/ true commons-configuration commons-configuration 1.1 jar http://www.apache.org/ commons-collections commons-collections 3.1 jar true commons-lang commons-lang 2.0 jar true dom4j dom4j 1.4 jar commons-logging commons-logging 1.0.4 jar true commons-digester commons-digester 1.6 jar true xerces xerces 2.2.1 jar http://xml.apache.org/xerces2-j/ true xml-apis xml-apis 2.0.2 jar http://xml.apache.org/commons/ true xdoclet xdoclet 1.2.1 jar junit junit 3.8.1 jar commons-beanutils commons-beanutils-core 1.7.0 jar true commons-beanutils commons-beanutils-bean-collections 1.7.0 jar true xdoclet maven-xdoclet-plugin 1.2.1 plugin xdoclet xdoclet-web-module 1.2.1 jar mx4j mx4j-jmx 2.1.1 jar mx4j mx4j-impl 2.1.1 jar xstream xstream 1.1.2 jar xpp3 xpp3_min 1.1.3.4.I jar easyconf-users@sorceforge.net src/java src/test com/germinus/easyconf/${test.run.type}Tests.java src/test *.properties *.xml false src/conf *.properties *.xml *.dtd false 0.9.5 0.9.5 RELEASE_0_9_5 easyconf-0.9.5/project.properties100644 0 0 3413 10337163174 14255 0ustar 0 0 ####################### # MAVEN CONFIGURATION # ####################### #Whether generated documentation should have an xml declaration, e.g. maven.docs.omitXmlDeclaration=false #The character encoding for generated documentation maven.docs.outputencoding=ISO-8859-1 ######################### # PROJECT CONFIGURATION # ######################### #maven.repo.central=login.ibiblio.org #This is the directory that Maven will copy the distribution to during a dist:deploy. #maven.repo.central.directory=/public/html/maven #The repository maven should use to download artifacts (jars etc) that it can't find in the local repository. maven.repo.remote=http://www.ibiblio.org/maven,http://maven-plugins.sourceforge.net/maven,http://xdoclet.sourceforge.net/repository,http://www.extreme.indiana.edu/dist/java-repository maven.site.deploy.method=ssh #The executable to use for secure copies maven.scp.executable=scp #The executable to use for executing commands remotely maven.ssh.executable=ssh maven.junit.usefile=false maven.javadoc.overview=src/java/overview.html #maven.repo.list=local #maven.repo.list=sourceforge #maven.repo.sourceforge=ftp://upload.sourceforge.net/ #maven.repo.sourceforge.username=anonymous #maven.repo.sourceforge.password=xx #maven.repo.sourceforge.directory=/incoming #maven.repo.local=file:///tmp #maven.repo.local.directory=easyconf maven.xdoclet.webdoclet.deploymentdescriptor.0=false maven.xdoclet.webdoclet.jsptaglib.0.filename=${pom.artifactId}.tld ########################### # SYSTEM PROPERTIES # ########################### #maven.junit.sysproperties=system-property-1 #system-property-1=XX ########################### # TEST PROPERTIES # ########################### test.run.type=Unit #test.run.type=System #test.run.type=All easyconf-0.9.5/build.xml100644 0 0 23740 10337163174 12337 0ustar 0 0 easyconf-0.9.5/src/test/com/germinus/easyconf/FileUtil.java100644 0 0 21706 10337163174 21062 0ustar 0 0 /* * Copyright 2004-2005 Germinus XXI, Liferay LLC * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * This is a derived work from source code taken from Liferay. */ package com.germinus.easyconf; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.Reader; import java.nio.channels.FileChannel; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.Properties; import java.util.jar.JarEntry; import java.util.jar.JarOutputStream; import org.apache.commons.lang.StringUtils; /** * File utility methods * @author Brian Wing Shun Chan, Jorge Ferrer * */ public class FileUtil { public static void copyDirectory( String sourceDirName, String destinationDirName) { copyDirectory(new File(sourceDirName), new File(destinationDirName)); } public static void copyDirectory(File source, File destination) { if (source.exists() && source.isDirectory()) { if (!destination.exists()) { destination.mkdirs(); } File[] fileArray = source.listFiles(); for (int i = 0; i < fileArray.length; i++) { if (fileArray[i].isDirectory()) { copyDirectory( fileArray[i], new File(destination.getPath() + File.separator + fileArray[i].getName())); } else { copyFile( fileArray[i], new File(destination.getPath() + File.separator + fileArray[i].getName())); } } } } public static void copyFile( String sourceFileName, String destinationFileName) { copyFile(new File(sourceFileName), new File(destinationFileName)); } public static void copyFile(File source, File destination) { if (!source.exists()) { return; } if ((destination.getParentFile() != null) && (!destination.getParentFile().exists())) { destination.getParentFile().mkdirs(); } try { FileChannel srcChannel = new FileInputStream(source).getChannel(); FileChannel dstChannel = new FileOutputStream( destination).getChannel(); dstChannel.transferFrom(srcChannel, 0, srcChannel.size()); srcChannel.close(); dstChannel.close(); } catch (IOException ioe) { ioe.printStackTrace(); } } public static void copyFileLazy(String source, String destination) throws IOException { String oldContent = null; try { oldContent = FileUtil.read(source); } catch (FileNotFoundException fnfe) { return; } String newContent = null; try { newContent = FileUtil.read(destination); } catch (FileNotFoundException fnfe) { } if (oldContent == null || !oldContent.equals(newContent)) { FileUtil.copyFile(source, destination); } } public static void deltree(String directory) { deltree(new File(directory)); } public static void deltree(File directory) { if (directory.exists() && directory.isDirectory()) { File[] fileArray = directory.listFiles(); for (int i = 0; i < fileArray.length; i++) { if (fileArray[i].isDirectory()) { deltree(fileArray[i]); } else { fileArray[i].delete(); } } directory.delete(); } } public static byte[] getBytes(File file) throws IOException { if (file == null || !file.exists()) { return null; } ByteArrayOutputStream out = new ByteArrayOutputStream(); FileInputStream in = new FileInputStream(file); int c = in.read(); while (c != -1) { out.write(c); c = in.read(); } in.close(); out.close(); return out.toByteArray(); } public static String getPath(String fullFileName) { int pos = fullFileName.lastIndexOf("/"); if (pos == -1) { pos = fullFileName.lastIndexOf("\\"); } String shortFileName = fullFileName.substring(0, pos); if (StringUtils.isEmpty(shortFileName)) { return "/"; } return shortFileName; } public static String getShortFileName(String fullFileName) { int pos = fullFileName.lastIndexOf("/"); if (pos == -1) { pos = fullFileName.lastIndexOf("\\"); } String shortFileName = fullFileName.substring(pos + 1, fullFileName.length()); return shortFileName; } public static boolean exists(String fileName) { File file = new File(fileName); return file.exists(); } public static String[] listDirs(String fileName) throws IOException { return listDirs(new File(fileName)); } public static String[] listDirs(File file) throws IOException { List dirs = new ArrayList(); File[] fileArray = file.listFiles(); for (int i = 0; i < fileArray.length; i++) { if (fileArray[i].isDirectory()) { dirs.add(fileArray[i].getName()); } } return (String[])dirs.toArray(new String[0]); } public static String[] listFiles(String fileName) throws IOException { return listFiles(new File(fileName)); } public static String[] listFiles(File file) throws IOException { List files = new ArrayList(); File[] fileArray = file.listFiles(); for (int i = 0; i < fileArray.length; i++) { if (fileArray[i].isFile()) { files.add(fileArray[i].getName()); } } return (String[])files.toArray(new String[0]); } public static void mkdirs(String pathName) { File file = new File(pathName); file.mkdirs(); } public static boolean move( String sourceFileName, String destinationFileName) { return move(new File(sourceFileName), new File(destinationFileName)); } public static boolean move(File source, File destination) { if (!source.exists()) { return false; } destination.delete(); return source.renameTo(destination); } public static String read(String fileName) throws IOException { return read(new File(fileName)); } public static String read(File file) throws IOException { BufferedReader br = new BufferedReader(new FileReader(file)); StringBuffer sb = new StringBuffer(); String line = null; while ((line = br.readLine()) != null) { sb.append(line).append('\n'); } br.close(); return sb.toString().trim(); } public static String replaceSeparator(String fileName) { return StringUtils.replace(fileName, "\\", "/"); } public static List toList(Reader reader) { List list = new ArrayList(); try { BufferedReader br = new BufferedReader(reader); StringBuffer sb = new StringBuffer(); String line = null; while ((line = br.readLine()) != null) { list.add(line); } br.close(); } catch (IOException ioe) { } return list; } public static List toList(String fileName) { try { return toList(new FileReader(fileName)); } catch (IOException ioe) { return new ArrayList(); } } public static Properties toProperties(FileInputStream fis) { Properties props = new Properties(); try { props.load(fis); } catch (IOException ioe) { } return props; } public static Properties toProperties(String fileName) { try { return toProperties(new FileInputStream(fileName)); } catch (IOException ioe) { return new Properties(); } } public static void write(File file, String s) throws IOException { if (file.getParent() != null) { mkdirs(file.getParent()); } BufferedWriter bw = new BufferedWriter(new FileWriter(file)); bw.flush(); bw.write(s); bw.flush(); bw.close(); } public static void write(String fileName, String s) throws IOException { write(new File(fileName), s); } public static void write(String pathName, String fileName, String s) throws IOException { write(new File(pathName, fileName), s); } public static void write(File dest, Properties props) throws IOException { write(dest, propertiesToString(props)); } public static String propertiesToString(Properties p) { StringBuffer sb = new StringBuffer(); Enumeration enu = p.propertyNames(); while (enu.hasMoreElements()) { String key = (String)enu.nextElement(); sb.append(key); sb.append("="); sb.append(p.getProperty(key)); sb.append("\n"); } return sb.toString(); } public static void writeAsJAR(File dest, String propsFileName, Properties props) throws FileNotFoundException, IOException { JarOutputStream out = new JarOutputStream(new FileOutputStream(dest)); JarEntry propertiesFile = new JarEntry(propsFileName); propertiesFile.setExtra(propertiesToString(props).getBytes()); out.putNextEntry(propertiesFile); out.close(); } }easyconf-0.9.5/src/test/com/germinus/easyconf/ObjectAssert.java100644 0 0 2057 10337163174 21713 0ustar 0 0 /* * Copyright 2004-2005 Germinus XXI * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.germinus.easyconf; import junit.framework.Assert; /** * View Source * * @author Jorge Ferrer * @version $Revision: 1.2 $ * */ public class ObjectAssert extends Assert{ public static void assertInstanceOf(String msg, Class expected, Object real) { if (!expected.isInstance(real)) { fail(msg + ". Expected " + expected + " but was " + real.getClass()); } } } easyconf-0.9.5/src/test/com/germinus/easyconf/PerformanceTest.java100644 0 0 7133 10337163174 22424 0ustar 0 0 package com.germinus.easyconf; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.util.Properties; import org.apache.commons.configuration.PropertiesConfiguration; import org.apache.commons.configuration.reloading.FileChangedReloadingStrategy; import junit.framework.TestCase; public class PerformanceTest extends TestCase { private static final int REPETITIONS = 10000; private static final String CONFIGURATION_DIR = "target/test-classes"; private static final String COMPONENT_NAME = "performance-test"; private static final String COMPONENT_NAME_2 = "performance-test-2"; File confFile; File reloadedConfFile; protected void setUp() throws Exception { confFile = new File(CONFIGURATION_DIR+ "/" + COMPONENT_NAME + ".properties"); reloadedConfFile = new File(CONFIGURATION_DIR+ "/" + COMPONENT_NAME_2 + ".properties"); Properties props = new Properties(); props.setProperty("key1", "value1"); props.setProperty("key2", "value2"); props.setProperty("key3", "value3"); FileUtil.write(confFile, props); props.setProperty(Conventions.RELOAD_DELAY_PROPERTY, "1"); FileUtil.write(reloadedConfFile, props); } protected void tearDown() throws Exception { confFile.delete(); EasyConf.refreshAll(); } public void testPerformance() throws Exception { long javaUtilProperties = measureJavaUtilProperties(); long commons = measurePropertiesConfiguration(confFile, false); long commonsReloading = measurePropertiesConfiguration(reloadedConfFile, true); long withoutReloading = measureGetString(COMPONENT_NAME); long withReloading = measureGetString(COMPONENT_NAME_2); System.out.println("####### Performance test summary ######## "); System.out.println("java.utilProperties takes: " + javaUtilProperties + " miliseconds"); System.out.println("Commons takes: " + commons + " miliseconds"); System.out.println("Commons with reloading takes: " + commonsReloading + " miliseconds"); System.out.println("Using EasyConf takes: " + withoutReloading + " miliseconds"); System.out.println("Using EasyConf with reloading takes: " + withReloading + " miliseconds"); } public long measureJavaUtilProperties() throws Exception { setUp(); Properties props = new Properties(); props.load(new FileInputStream(confFile)); long start = System.currentTimeMillis(); String value; for (int i = 0; i < REPETITIONS; i++) { value = props.getProperty("key1"); } long end = System.currentTimeMillis(); long period = end - start; tearDown(); return period; } public long measurePropertiesConfiguration(File file, boolean reload) throws Exception { setUp(); PropertiesConfiguration props = new PropertiesConfiguration(file); if (reload) { props.setReloadingStrategy(new FileChangedReloadingStrategy()); } long start = System.currentTimeMillis(); String value; for (int i = 0; i < REPETITIONS; i++) { value = props.getString("key1"); } long end = System.currentTimeMillis(); long period = end - start; tearDown(); return period; } public long measureGetString(String componentName) throws Exception { setUp(); EasyConf.getConfiguration(componentName).getProperties(); long start = System.currentTimeMillis(); String value; for (int i = 0; i < REPETITIONS; i++) { value = EasyConf.getConfiguration(componentName).getProperties(). getString("key1"); } long end = System.currentTimeMillis(); long period = end - start; tearDown(); return period; } } easyconf-0.9.5/src/test/com/germinus/easyconf/ConfigurationLearningTest.java100644 0 0 4302 10337163174 24445 0ustar 0 0 /* * Copyright 2004-2005 Germinus XXI * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.germinus.easyconf; import java.net.URL; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.ConfigurationUtils; import org.apache.commons.configuration.PropertiesConfiguration; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** * View Source * * @author Jorge Ferrer * @version $Revision: 1.4 $ * */ public class ConfigurationLearningTest extends TestCase { public ConfigurationLearningTest(String testName) { super(testName); } public static Test suite() { TestSuite suite = new TestSuite(); suite.addTest(new ConfigurationLearningTest("testGetFromClasspath")); return suite; } public void testGetFromClasspath() throws ConfigurationException { URL result = ConfigurationUtils.locate(null, "test_module.properties"); assertNotNull(result); PropertiesConfiguration conf = new PropertiesConfiguration(); conf.load("test_module.properties"); assertEquals("Error reading properties file from classpath", "test_module", conf.getString("property-only-in-test-module")); } public void testSubset() { Configuration conf = new PropertiesConfiguration(); conf.setProperty("prefix.key", "value"); Configuration subset = conf.subset("prefix"); assertTrue("The subset functionality does not work", subset.containsKey("key")); } } easyconf-0.9.5/src/test/com/germinus/easyconf/jmx/JMXTest.java100644 0 0 32431 10337163174 21436 0ustar 0 0 /* * Copyright 2004-2005 Germinus XXI * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.germinus.easyconf.jmx; import java.io.File; import java.util.Properties; import javax.management.Attribute; import javax.management.AttributeList; import javax.management.AttributeNotFoundException; import javax.management.InstanceAlreadyExistsException; import javax.management.InstanceNotFoundException; import javax.management.MBeanException; import javax.management.MBeanInfo; import javax.management.MBeanOperationInfo; import javax.management.MBeanRegistrationException; import javax.management.MBeanServer; import javax.management.MBeanServerFactory; import javax.management.MalformedObjectNameException; import javax.management.NotCompliantMBeanException; import javax.management.ObjectInstance; import javax.management.ObjectName; import javax.management.ReflectionException; import com.germinus.easyconf.ComponentConfiguration; import com.germinus.easyconf.Conventions; import com.germinus.easyconf.EasyConf; import com.germinus.easyconf.FileUtil; import com.germinus.easyconf.jmx.ComponentConfigurationDynamicMBean; import junit.framework.TestCase; /** * View Source * * @author Alvaro Gonzalez * @version $Revision: 1.5 $ * */ public class JMXTest extends TestCase { private static final String CONFIGURATION_DIR = "target/test-classes"; private static final String JMX_NAME_PREFIX = "easyconf:component="; private static final String JMX_TEST_MODULE = "jmx_module"; private static final String TEST_MODULE = "test_module"; private static final String RELOAD_MODULE = "jmx_reload_module"; private static final String STRING_NOT_OVERRIDEN = "string-not-overridden"; private static final String RELOADED_PROPERTY = "reloaded"; private static final String RELOADED_PROPERTY_VALUE1 = "beforeReloaded"; private static final String RELOADED_PROPERTY_VALUE2 = "afterReloaded"; private static final String STRING_NOT_OVERRIDEN_VALUE = "jmx_module"; private static final String STRING_OVERRIDEN_IN_PRJ = "string-overridden-in-prj"; private static final String STRING_OVERRIDEN_IN_PRJ_VALUE = "prj"; private static final String NON_EXISTENT_ATTRIBUTE = "com.germinus.easyconf.JMXTest.NON_EXISTENT_ATTRIBUTE"; private static final String NEW_ATTRIBUTE = "com.germinus.easyconf.JMXTest.NEW_ATTRIBUTE"; private static final String WHATEVER_VALUE = "WHATEVER"; private MBeanServer mbeanServer; private ObjectName testMBeanName; private ObjectName testMBeanName2; private ObjectName testMBeanName3; private File toReloadFile; public void testDynamicMBeanGetAttribute() throws Exception{ try { Object attribute=mbeanServer.getAttribute(testMBeanName,STRING_NOT_OVERRIDEN); assertNotNull("Attribute not retrieved properly. Is null.",attribute); String attributeString=(String)attribute; assertEquals("Incorrect attribute value.",STRING_NOT_OVERRIDEN_VALUE,attributeString); } catch (AttributeNotFoundException e2) { fail("Attribute not found"); } catch (InstanceNotFoundException e2) { fail("Mbean not found"); } catch (MBeanException e2) { throw e2.getTargetException(); } } public void testDynamicMBeanGetAttributes() throws Exception{ AttributeList attributes=mbeanServer.getAttributes(testMBeanName,new String[]{STRING_NOT_OVERRIDEN}); assertEquals("Incorrect size of AttributeList.",1,attributes.size()); Attribute attribute=(Attribute)attributes.iterator().next(); assertAttribute("Attribute obtained form \"getAttributes\" doesn't match expected.",STRING_NOT_OVERRIDEN,STRING_NOT_OVERRIDEN_VALUE,attribute); attributes=mbeanServer.getAttributes(testMBeanName,new String[]{STRING_NOT_OVERRIDEN,STRING_OVERRIDEN_IN_PRJ}); assertEquals("Incorrect size of AttributeList.",2,attributes.size()); attribute=(Attribute)attributes.get(1); assertAttribute("Attribute obtained form \"getAttributes\" doesn't match expected.",STRING_OVERRIDEN_IN_PRJ,STRING_OVERRIDEN_IN_PRJ_VALUE,attribute); attributes=mbeanServer.getAttributes(testMBeanName,new String[]{STRING_NOT_OVERRIDEN,STRING_NOT_OVERRIDEN}); assertEquals("Incorrect size of AttributeList with one attribute name repeated.",1,attributes.size()); attribute=(Attribute)attributes.get(0); assertAttribute("Attribute obtained form \"getAttributes\" with one attribute name repeated doesn't match expected.",STRING_NOT_OVERRIDEN,STRING_NOT_OVERRIDEN_VALUE,attribute); } public void testDynamicMBeanSetAttribute() throws Exception{ final String STRING_NOT_OVERRIDEN_NEW_VALUE="jmx_module_new_value"; Attribute oldAttribute=new Attribute(STRING_NOT_OVERRIDEN,STRING_NOT_OVERRIDEN_NEW_VALUE); mbeanServer.setAttribute(testMBeanName,oldAttribute); Object newValue=mbeanServer.getAttribute(testMBeanName,STRING_NOT_OVERRIDEN); assertEquals("Incorrect new attribute value.",STRING_NOT_OVERRIDEN_NEW_VALUE,newValue); Attribute newAttribute=new Attribute(NON_EXISTENT_ATTRIBUTE,"whatever"); try { mbeanServer.setAttribute(testMBeanName,newAttribute); fail("Must throw an exception when trying to set a inexistent property"); } catch (AttributeNotFoundException e) { } oldAttribute=new Attribute(STRING_NOT_OVERRIDEN,null); mbeanServer.setAttribute(testMBeanName,oldAttribute); newValue=mbeanServer.getAttribute(testMBeanName,STRING_NOT_OVERRIDEN); assertNull("New value of property might be null",newValue); } public void testDynamicMBeanAddProperty() throws Exception{ mbeanServer.invoke( testMBeanName, ComponentConfigurationDynamicMBean.NEW_PROPERTY_OPERATION_NAME, new Object[]{NON_EXISTENT_ATTRIBUTE}, ComponentConfigurationDynamicMBean.NEW_PROPERTY_OPERATION_SIGNATURE_1); Attribute newAttribute=new Attribute(NON_EXISTENT_ATTRIBUTE,WHATEVER_VALUE); try { mbeanServer.setAttribute(testMBeanName,newAttribute); } catch (AttributeNotFoundException e){ fail("Property not added correctly"); } Attribute actuallyNewPorperty=(Attribute) mbeanServer.getAttributes(testMBeanName,new String[]{NON_EXISTENT_ATTRIBUTE}).get(0); assertAttribute("Incorrect value for new property",NON_EXISTENT_ATTRIBUTE,WHATEVER_VALUE,actuallyNewPorperty); mbeanServer.invoke( testMBeanName, ComponentConfigurationDynamicMBean.NEW_PROPERTY_OPERATION_NAME, new Object[]{NEW_ATTRIBUTE,WHATEVER_VALUE}, ComponentConfigurationDynamicMBean.NEW_PROPERTY_OPERATION_SIGNATURE_2); Object value=mbeanServer.getAttribute(testMBeanName,NEW_ATTRIBUTE); assertEquals("New Property value is incorrect with two arguments operation",WHATEVER_VALUE,value); try { mbeanServer.invoke( testMBeanName, ComponentConfigurationDynamicMBean.NEW_PROPERTY_OPERATION_NAME, new Object[]{STRING_NOT_OVERRIDEN}, ComponentConfigurationDynamicMBean.NEW_PROPERTY_OPERATION_SIGNATURE_1); fail("Adding existing property must throw an exception"); } catch (Exception e1) { } try { mbeanServer.invoke( testMBeanName, ComponentConfigurationDynamicMBean.NEW_PROPERTY_OPERATION_NAME, new Object[]{STRING_NOT_OVERRIDEN,WHATEVER_VALUE}, ComponentConfigurationDynamicMBean.NEW_PROPERTY_OPERATION_SIGNATURE_2); fail("Adding existing property must throw an exception"); } catch (Exception e1) { } value=mbeanServer.getAttribute(testMBeanName,STRING_NOT_OVERRIDEN); assertEquals("Adding an existing property must not change its value",STRING_NOT_OVERRIDEN_VALUE,value); } public void testDynamicMBeanOperationInfo() throws Exception{ MBeanInfo info=mbeanServer.getMBeanInfo(testMBeanName); MBeanOperationInfo[] operations=info.getOperations(); assertEquals("Incorrect number of operations returned by getMBeanInfo",3,operations.length); } public void testDynamicMBeanReload() throws Exception{ // Properties props=new Properties(); // props.setProperty(RELOADED_PROPERTY,RELOADED_PROPERTY_VALUE2); // boolean b=toReloadFile.delete(); // assertEquals("No se pudo borrar",true,b); // setReloadedFile(props); // try { // mbeanServer.invoke(testMBeanName3, // ComponentConfigurationDynamicMBean.RELOAD_OPERATION_NAME, // new Object[]{},new String[]{}); // } catch (InstanceNotFoundException e) { // fail("Reloaded module MBEan not found"); // } catch (MBeanException e) { // fail("Mbean problem: "+e); // } catch (ReflectionException e) { // fail("reflection problem: "+e); // } // try { // Object attribute=mbeanServer.getAttribute(testMBeanName3,RELOADED_PROPERTY); // assertNotNull("Attribute not retrieved properly. Is null.",attribute); // String attributeString=(String)attribute; // assertEquals("Incorrect reloaded attribute value.",RELOADED_PROPERTY_VALUE2,attributeString); // } catch (AttributeNotFoundException e2) { // fail("Attribute not found"); // } catch (InstanceNotFoundException e2) { // fail("Mbean not found"); // } catch (MBeanException e2) { // throw e2.getTargetException(); // } } protected void assertAttribute(String attributeName,Object attributeValue,Attribute attribute){ assertAttribute(null,attributeName,attributeValue,attribute); } protected void assertAttribute(String message,String attributeName,Object attributeValue,Attribute attribute){ String actuallyName=attribute.getName(); Object actuallyValue=attribute.getValue(); assertEquals(message+" Incorrect Name",attributeName,actuallyName); assertEquals(message+" Incorrect Value",attributeValue,actuallyValue); } /* (non-Javadoc) * @see junit.framework.TestCase#setUp() */ protected void setUp() throws Exception { mbeanServer=MBeanServerFactory.newMBeanServer(); Properties props = new Properties(); props.setProperty(RELOADED_PROPERTY, RELOADED_PROPERTY_VALUE1); setReloadedFile(props); registerMBeans(); } protected void setReloadedFile(Properties props) throws Exception{ toReloadFile = new File(CONFIGURATION_DIR+ "/" + RELOAD_MODULE + ".properties"); FileUtil.write(toReloadFile, props); } protected void registerMBeans() { ComponentConfiguration componentConfiguration = EasyConf.getConfiguration(JMX_TEST_MODULE); ComponentConfigurationDynamicMBean confMBean = new ComponentConfigurationDynamicMBean(componentConfiguration); ComponentConfigurationDynamicMBean confMBean2 = new ComponentConfigurationDynamicMBean(JMX_TEST_MODULE); ComponentConfigurationDynamicMBean confMBean3 = new ComponentConfigurationDynamicMBean(RELOAD_MODULE); assertNotNull("MBean not created properly with ComponentConfiguration constructor", confMBean); assertNotNull("MBean not created properly with String constructor", confMBean2); assertNotNull("Error creating ComponentConfiguration", confMBean2 .getComponentConfiguration()); assertNotNull("MBean not created properly with ComponentConfiguration.", confMBean3); try { testMBeanName = new ObjectName(JMX_NAME_PREFIX + "jmx_module"); } catch (MalformedObjectNameException e1) { fail("Malformed JMX name: " + JMX_NAME_PREFIX + "jmx_module"); } try { testMBeanName2 = new ObjectName(JMX_NAME_PREFIX + "test_module"); } catch (MalformedObjectNameException e1) { fail("Malformed JMX name: " + JMX_NAME_PREFIX + "test_module"); } try { testMBeanName3 = new ObjectName(JMX_NAME_PREFIX + RELOAD_MODULE); } catch (MalformedObjectNameException e1) { fail("Malformed JMX name: " + JMX_NAME_PREFIX + RELOAD_MODULE); } assertNotNull("JMX ObjectName not created porperly", testMBeanName); assertNotNull("JMX ObjectName not created porperly", testMBeanName2); assertNotNull("JMX ObjectName not created porperly", testMBeanName3); try { ObjectInstance instance = mbeanServer.registerMBean(confMBean, testMBeanName); assertNotNull("Object Instance not created properly", instance); } catch (InstanceAlreadyExistsException e) { } catch (MBeanRegistrationException e) { fail("Mbean not registerd properly"); } catch (NotCompliantMBeanException e) { fail("Not Mbean compliant(confMBean): " + e.getLocalizedMessage()); } try { ObjectInstance instance = mbeanServer.registerMBean(confMBean2, testMBeanName2); assertNotNull("Object Instance not created properly", instance); } catch (InstanceAlreadyExistsException e) { } catch (MBeanRegistrationException e) { fail("Mbean not registerd properly"); } catch (NotCompliantMBeanException e) { fail("Not Mbean compliant(confMBean2): " + e.getLocalizedMessage()); } try { ObjectInstance instance = mbeanServer.registerMBean(confMBean3, testMBeanName3); assertNotNull("Object Instance not created properly", instance); } catch (InstanceAlreadyExistsException e) { } catch (MBeanRegistrationException e) { fail("Mbean not registerd properly"); } catch (NotCompliantMBeanException e) { fail("Not Mbean compliant(confMBean2): " + e.getLocalizedMessage()); } } /* (non-Javadoc) * @see junit.framework.TestCase#tearDown() */ protected void tearDown() throws Exception { this.toReloadFile.delete(); } } easyconf-0.9.5/src/test/com/germinus/easyconf/Table.java100644 0 0 1736 10337163174 20355 0ustar 0 0 /* * Copyright 2004-2005 Germinus XXI * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.germinus.easyconf; /** * View Source * * @author Jorge Ferrer * @version $Revision: 1.2 $ * */ public class Table { private String tableType; public String getTableType() { return tableType; } public void setTableType(String tableType) { this.tableType = tableType; } } easyconf-0.9.5/src/test/com/germinus/easyconf/UnitTests.java100644 0 0 3152 10337163174 21262 0ustar 0 0 /* * Copyright 2004-2005 Germinus XXI * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.germinus.easyconf; import junit.framework.TestCase; import junit.framework.TestSuite; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.germinus.easyconf.jmx.JMXTest; /** * Launches all the tests of EasyConf * * @version $Revision: 1.4 $ */ public class UnitTests extends TestCase { private static final Log log = LogFactory.getLog(UnitTests.class); public UnitTests(String name) { super(name); } public static void main (String[] args) { junit.textui.TestRunner.run(suite()); } public static TestSuite suite () { TestSuite suite = new TestSuite("Junit Tests"); suite.addTest(EasyConfTest.suite()); suite.addTestSuite(JMXTest.class); return suite; } public void testSuccess() { assertTrue(true); } public void testFail() { fail("This test fails on purpose to check that junit is working. " + "You can now safely remove it from UnitTests.java"); } } easyconf-0.9.5/src/test/com/germinus/easyconf/DatabaseAssert.java100644 0 0 2175 10337163174 22212 0ustar 0 0 /* * Copyright 2004-2005 Germinus XXI * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.germinus.easyconf; import junit.framework.Assert; /** * View Source * * @author Jorge Ferrer * @version $Revision: 1.3 $ * */ public class DatabaseAssert extends Assert { public static void assertContents(Object configuration) { assertNotNull("The returned configuration is null", configuration); ObjectAssert.assertInstanceOf("The configuration is not of the correct class", DatabaseConf.class, configuration); } } easyconf-0.9.5/src/test/com/germinus/easyconf/EasyConfTest.java100644 0 0 55623 10337163174 21721 0ustar 0 0 /* * Copyright 2004-2005 Germinus XXI * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.germinus.easyconf; import java.math.BigDecimal; import java.math.BigInteger; import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; import java.util.Properties; import junit.framework.TestCase; import junit.framework.TestSuite; import junit.framework.Test; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * System Test of the whole functionality of easyconf. * Note that it depends on external files * * @author Jorge Ferrer * @author Ismael F. Olmedo */ public class EasyConfTest extends TestCase { public static final Log log = LogFactory.getLog(EasyConfTest.class); ComponentConfiguration componentConf; public EasyConfTest(String testName) { super(testName); } protected void setUp() throws Exception { componentConf = EasyConf.getConfiguration("test_module"); System.setProperty("easyconf-environment", "local"); System.setProperty("test_module:easyconf-environment", "local"); getProperties().setThrowExceptionOnMissing(true); } protected void tearDown() throws Exception { System.setProperty("easyconf-environment", "BAD-BAD-BAD"); System.setProperty("test_environment:easyconf-environment", "BAD-BAD-BAD"); getProperties().setThrowExceptionOnMissing(false); } public static Test suite() { TestSuite suite = new TestSuite(); suite.addTestSuite(EasyConfTest.class); // suite.addTest(new EasyConfTest("testNamedConfiguration")); return suite; } public void testGetExistentClass() throws ClassNotFoundException { Class theClass = getProperties().getClass("database-configuration-class"); assertEquals("An invalid class was loaded", DatabaseConf.class, theClass); theClass = getProperties().getClass("database-configuration-class", Table.class); assertEquals("An invalid class was loaded", DatabaseConf.class, theClass); theClass = getProperties().getClass("non-existent-property", Table.class); assertSame("The default class should have been used", Table.class, theClass); } public void testGetNonexistentClass() { try { Class theClass = getProperties().getClass("non-existent-class"); fail("A ClassNotFoundException should have been thrown"); } catch (ClassNotFoundException success) { } try { Class theClass = getProperties().getClass("non-existent-class", Table.class); fail("A ClassNotFoundException should have been thrown"); } catch (ClassNotFoundException success) { } } public void testGetClassArray() throws ClassNotFoundException { Class[] defaultClasses = new Class[]{Table.class}; String key = "database-configuration-classes"; Class[] result = getProperties().getClassArray(key); assertEquals("There should be two classes", 2, result.length); assertEquals("An invalid first class was loaded", DatabaseConf.class, result[0]); assertEquals("An invalid second class was loaded", Table.class, result[1]); result = getProperties().getClassArray(key, defaultClasses); assertEquals("The default should be ignored and there should be two classes", 2, result.length); result = getProperties().getClassArray("non-existent-property", defaultClasses); assertSame("The default class should have been used", defaultClasses, result); } public void testAllFilesHaveBeenRead() { assertTrue("File test_module.properties not loaded", getProperties().containsKey("property-only-in-test-module")); assertTrue("File global-configuration.properties not loaded", getProperties().containsKey("property-only-in-global-configuration")); assertTrue("File global-configuration-env.properties not loaded", getProperties().containsKey("property-only-in-env")); assertTrue("File global-configuration-prj.properties not loaded", getProperties().containsKey("property-only-in-prj")); } public void testReadStringNotOverridden() { assertEquals("Invalid value for string-not-overridden", "test_module", getProperties().getString("string-not-overridden")); } /** * Expected property keys and values: * property-with-filter[selector1.selector2] * long-with-filter[selector1.selector2]=1234 * short-with-filter[selector1.selector2]=1234 * int-with-filter[selector1.selector2]=1234 * byte-with-filter[selector1.selector2]=123 * biginteger-with-filter[selector1.selector2]=1234 * bigdecimal-with-filter[selector1.selector2]=1234 * double-with-filter[selector1.selector2]=1234 * float-with-filter[selector1.selector2]=1234 * list-with-filter[selector1.selector2]=1234,5678 * boolean-with-filter[selector1.selector2]=false */ public void testFilterWithDefault() { assertEquals("Invalid string value when specifying two selectors", "selector1-and-selector2", getProperties().getString("property-with-filter", Filter.by("selector1", "selector2"), "defaultvalue")); assertEquals("Invalid string value when specifying two selectors but second does not exists", "selector1", getProperties().getString("property-with-filter", Filter.by("selector1", "non-existent-selector"), "defaultvalue")); assertEquals("Invalid string value when specifying two inexistent selectors but default value in file", "no-selector", getProperties().getString("property-with-filter", Filter.by("non-existent-selector", "non-existent-selector"), "defaultvalue")); assertEquals("Invalid string value when specifying two inexistent selectors", "defaultvalue", getProperties().getString("property-with-filter2", Filter.by("non-existent-selector", "non-existent-selector"), "defaultvalue")); assertEquals("Invalid long value when specifying two selectors", 1234, getProperties().getLong("long-with-filter", Filter.by("selector1", "selector2"), 0l)); assertEquals("Invalid short value when specifying two selectors", 1234, getProperties().getShort("short-with-filter", Filter.by("selector1", "selector2"), (short)0)); assertEquals("Invalid int value when specifying two selectors", 1234, getProperties().getInt("int-with-filter", Filter.by("selector1", "selector2"), 0)); assertEquals("Invalid byte value when specifying two selectors", 123, getProperties().getByte("byte-with-filter", Filter.by("selector1", "selector2"), (byte)0)); assertEquals("Invalid BigInteger value when specifying two selectors", new BigInteger("1234"), getProperties().getBigInteger("biginteger-with-filter", Filter.by("selector1", "selector2"), new BigInteger("0"))); assertEquals("Invalid BigDecimal value when specifying two selectors", new BigDecimal(1234), getProperties().getBigDecimal("bigdecimal-with-filter", Filter.by("selector1", "selector2"), new BigDecimal(0d))); assertEquals("Invalid double value when specifying two selectors", 1234d, getProperties().getDouble("double-with-filter", Filter.by("selector1", "selector2"), 0), 0); assertEquals("Invalid float value when specifying two selectors", 1234f, getProperties().getFloat("float-with-filter", Filter.by("selector1", "selector2"), 0), 0); assertEquals("Invalid boolean value when specifying two selectors", false, getProperties().getBoolean("boolean-with-filter", Filter.by("selector1", "selector2"), true)); assertEquals("Invalid list value when specifying two selectors", Arrays.asList(new String[] {"1234","5678"}), getProperties().getList("list-with-filter", Filter.by("selector1", "selector2"), null)); assertEquals("Invalid string array value when specifying two selectors", new String[] {"1234","5678"}, getProperties().getStringArray("list-with-filter", Filter.by("selector1", "selector2"), null)); } public void testFilterWithoutDefault() { try { getProperties().getString("Inexistent property", Filter.by("selector1", "selector2")); fail("A NoSuchElementException should have been thrown"); } catch (NoSuchElementException success) {} try { getProperties().getLong("Inexistent property", Filter.by("selector1", "selector2")); fail("A NoSuchElementException should have been thrown"); } catch (NoSuchElementException success) {} try { getProperties().getShort("Inexistent property", Filter.by("selector1", "selector2")); fail("A NoSuchElementException should have been thrown"); } catch (NoSuchElementException success) {} try { getProperties().getInt("Inexistent property", Filter.by("selector1", "selector2")); fail("A NoSuchElementException should have been thrown"); } catch (NoSuchElementException success) {} try { getProperties().getByte("Inexistent property", Filter.by("selector1", "selector2")); fail("A NoSuchElementException should have been thrown"); } catch (NoSuchElementException success) {} try { getProperties().getBigInteger("Inexistent property", Filter.by("selector1", "selector2")); fail("A NoSuchElementException should have been thrown"); } catch (NoSuchElementException success) {} try { getProperties().getBigDecimal("Inexistent property", Filter.by("selector1", "selector2")); fail("A NoSuchElementException should have been thrown"); } catch (NoSuchElementException success) {} try { getProperties().getDouble("Inexistent property", Filter.by("selector1", "selector2")); fail("A NoSuchElementException should have been thrown"); } catch (NoSuchElementException success) {} try { getProperties().getFloat("Inexistent property", Filter.by("selector1", "selector2")); fail("A NoSuchElementException should have been thrown"); } catch (NoSuchElementException success) {} try { getProperties().getList("Inexistent property", Filter.by("selector1", "selector2")); fail("A NoSuchElementException should have been thrown"); } catch (NoSuchElementException success) {} try { getProperties().getStringArray("Inexistent property", Filter.by("selector1", "selector2")); fail("A NoSuchElementException should have been thrown"); } catch (NoSuchElementException success) {} } public void testSetThrowExceptionOnMissingToFalse() { getProperties().setThrowExceptionOnMissing(false); try { getProperties().getString("Inexistent property", Filter.by("selector1", "selector2")); assertTrue("A NoSuchElementException should NOT have been thrown", true); } finally { getProperties().setThrowExceptionOnMissing(true); } } public void testReadStringOverriddenInPrj() { assertEquals("Invalid value for string-overridden-in-prj", "prj", getProperties().getString("string-overridden-in-prj")); } public void testReadStringOverriddenInPrjWithPrefix() { assertEquals("Invalid value for string-overridden-in-prj-with-prefix", "prj", getProperties().getString("string-overridden-in-prj-with-prefix")); } public void testReadStringOverriddenInEnv() { assertEquals("Invalid value for string-overridden-in-env", "env", getProperties().getString("string-overridden-in-env")); } public void testReadStringOverriddenInPrjAndEnv() { assertEquals("Invalid value for string-overridden-in-prj-and-env", "env", getProperties().getString("string-overridden-in-prj-and-env")); } public void testReadListNotOverridden() { List expected = Arrays.asList(new String[]{"test_module1", "test_module2"}); assertEquals("Invalid value for list-not-overridden", expected, getProperties().getList("list-not-overridden")); } public void testReadListOverriddenInPrj() { List expected = Arrays.asList(new String[]{"prj1", "prj2"}); assertEquals("Invalid value for list-overridden-in-prj", expected, getProperties().getList("list-overridden-in-prj")); } public void testDefaultConfigurationObject() { DatabaseConf configuration = getConfigurationObject(); DatabaseAssert.assertContents(configuration); DatabaseConf dbConf = (DatabaseConf) configuration; assertEquals("Incorrect number of tables. The default configuration was not correclty read", 2, dbConf.getTables().size()); } public void testNamedConfigurationObject() { DatabaseConf conf = (DatabaseConf) componentConf.getConfigurationObject("myname"); DatabaseAssert.assertContents(getConfigurationObject()); DatabaseConf dbConf = (DatabaseConf) conf; assertEquals("Incorrect number of tables. The named configuration was not correclty read", 3, dbConf.getTables().size()); } public void testVariablesInObjectConfiguration() { Table table1 = (Table) getConfigurationObject().getTables().get(0); assertEquals("The table type is not the one specified as a property", getProperties().getString("default.table.type"), table1.getTableType()); } public void testComponentWithoutProperties() { ComponentConfiguration conf = EasyConf.getConfiguration("module_without_properties"); try { assertNotNull("The properties should not be null", conf.getProperties()); fail("An exception should have been thrown because the base file " + "does not exist"); } catch (ConfigurationNotFoundException ok) { } try { conf.getConfigurationObject(); } catch (ConfigurationNotFoundException e) { fail("When the getProperties method is not called explicitly, " + "the base properties file should not be mandatory"); } } public void testComponentWithoutXML() { ComponentConfiguration conf = EasyConf.getConfiguration("module_without_xml"); try { conf.getConfigurationObject(); fail("A Configuration exception should have been thrown"); } catch (ConfigurationException ok) {} } public void testComponentWithoutDigesterRules() { String name = "module_without_digesterRules"; try { EasyConf.getConfiguration(name); } catch (DigesterRulesNotFoundException expected) { assertNotNull("The exception should contain the name of the missing file", expected.getDigesterRulesFileName()); assertEquals("Invalid component name in the exception", name, expected.getComponentName()); } } public void testUsingSystemProperties() { // System.setProperty("easyconf-environment", "local"); // assertEquals("The environment was not correctly read from the system property", // "local", // getProperties().getString("test_module_environment")); // System.setProperty("easyconf-environment", ""); System.setProperty("sysproperty-without-prefix-and-default-value", "value-of-sysproperty-without-prefix-and-default-value"); assertEquals("A system property without prefix should not be read if there is a default value", "defaultValue", getProperties().getString("sysproperty-without-prefix-and-default-value")); System.setProperty("sysproperty-without-prefix", "value-of-sysproperty-without-prefix"); assertEquals("The value of the sysproperty should be returned if there isn't a default value", "value-of-sysproperty-without-prefix", getProperties().getString("sysproperty-without-prefix")); System.setProperty("test_module:sysproperty-with-prefix-and-default-value", "value-of-sysproperty-with-prefix"); assertEquals("The value of the sysproperty should be returned if a prefix is used", "value-of-sysproperty-with-prefix", getProperties().getString("sysproperty-with-prefix-and-default-value")); } public void testUsingSystemPropertiesInIncludes() { assertContains("The file with a sysproperty in the name was not loaded", "test_module-local.properties", getProperties().getLoadedSources()); assertContains("The file with a prefixed sysproperty in the name was not loaded", "test_module-local2.properties", getProperties().getLoadedSources()); } public void testPropertiesASPModel() { String companyId = "exampleCompany"; ComponentProperties props = EasyConf.getConfiguration(companyId, "test_module").getProperties(); assertContains("The company-specific file was not read", "test_module-"+companyId+Conventions.PROPERTIES_EXTENSION, props.getLoadedSources()); assertEquals("The property was not read from the company specific file", companyId, props.getString("company-name")); assertEquals("The property should have the default value if it is not" + " overridden by the company specific file", "test_module", props.getString("string-not-overridden")); assertEquals("The property was not read from the company specific global file", "exampleCompanyGlobal", props.getString("global-company-name")); } public void testJavaUtilPropertiesASPModel() { String companyId = "exampleCompany"; Properties props = EasyConf.getConfiguration(companyId, "test_module").getProperties().getProperties(); assertEquals("The property was not read from the company specific file", companyId, props.getProperty("company-name")); assertEquals("The property should have the default value if it is not" + " overridden by the company specific file", "test_module", props.getProperty("string-not-overridden")); assertEquals("The property was not read from the company specific global file", "exampleCompanyGlobal", props.getProperty("global-company-name")); } public void testXMLASPModel() { DatabaseConf conf = (DatabaseConf) EasyConf. getConfiguration("exampleCompany", "test_module"). getConfigurationObject(); assertEquals("The company specific conf should have only 1 table", 1, conf.getTables().size()); } public void testSpecifyingVariables() { String result = getProperties().getString("property-with-variable", Filter.usingVariables("exampleVariable", "my-value")); assertEquals("The variable has not been substituted successfully", "my-value", result); } public void testSettingPropertyAsDefaultVariableValue() { String result = getProperties().getString("property-with-variable"); assertEquals("The variable has not been substituted successfully", "default-exampleVariable-value", result); } public void testSetProperty() { getProperties().setProperty("new-property", "new-value"); assertEquals("The property has not been stored", "new-value", getProperties().getProperty("new-property")); getProperties().setProperty("string-not-overridden", "new-value"); assertEquals("The new value for an existent property has not been stored", "new-value", getProperties().getProperty("string-not-overridden")); } public void testStringListAsString() { String value = getProperties().getString("database-configuration-classes"); assertEquals("Invalid string value", "com.germinus.easyconf.DatabaseConf,com.germinus.easyconf.Table", value); } public void testNumberListAsString() { String value = getProperties().getString("some-numbers"); assertEquals("Invalid string value", "1,2,3,4,5", value); } /** * Does not work due to a bug in digester (TODO: confirm) */ public void bugtestXmlThatUsesNonExistentProperty() { ComponentConfiguration p2; String name = "module_with_xml_that_uses_non_existent_property"; try { ComponentConfiguration conf = EasyConf.getConfiguration(name); } catch (InvalidPropertyException expected) { assertEquals("Invalid component name in the exception", name, expected.getComponentName()); } } // .............. Helper methods ................... ComponentProperties getProperties() { return componentConf.getProperties(); } DatabaseConf getConfigurationObject() { Object configurationObject = componentConf.getConfigurationObject(); assertEquals("Invalid configurationObject class", DatabaseConf.class, configurationObject.getClass()); return (DatabaseConf) configurationObject; } private void assertEquals(String msg, String[] expected, String[] obtained) { if (expected.length != obtained.length) { fail(msg + ". Expected and obtained arrays length differ"); } for (int i = 0; i < expected.length; i++) { assertEquals(msg + ". (" + i + "th element)", expected[i], obtained[i]); } } private void assertContains(String msg, String item, List list) { boolean contained = list.contains(item); if (!contained) { for (Iterator it = list.iterator(); it.hasNext();) { String url = (String) it.next(); if (url.endsWith("/" + item)) { contained = true; break; } } } assertTrue(msg + ". " + item + " is not included in " + list, contained); } } easyconf-0.9.5/src/test/com/germinus/easyconf/AllTests.java100644 0 0 3101 10337163174 21045 0ustar 0 0 /* * Copyright 2004-2005 Germinus XXI * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.germinus.easyconf; import junit.framework.TestCase; import junit.framework.TestSuite; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Launches all the tests of EasyConf * * @version $Revision: 1.1 $ */ public class AllTests extends TestCase { private static final Log log = LogFactory.getLog(AllTests.class); public AllTests(String name) { super(name); } public static void main (String[] args) { junit.textui.TestRunner.run(suite()); } public static TestSuite suite () { TestSuite suite = new TestSuite("All EasyConf Tests"); suite.addTest(UnitTests.suite()); suite.addTest(SystemTests.suite()); return suite; } public void testSuccess() { assertTrue(true); } public void testFail() { fail("This test fails on purpose to check that junit is working. " + "You can now safely remove it from UnitTests.java"); } } easyconf-0.9.5/src/test/com/germinus/easyconf/SystemTests.java100644 0 0 3130 10337163174 21623 0ustar 0 0 /* * Copyright 2004-2005 Germinus XXI * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.germinus.easyconf; import junit.framework.TestCase; import junit.framework.TestSuite; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.germinus.easyconf.systemtests.ReloadTest; /** * Launches all the tests of EasyConf * * @version $Revision: 1.1 $ */ public class SystemTests extends TestCase { private static final Log log = LogFactory.getLog(SystemTests.class); public SystemTests(String name) { super(name); } public static void main (String[] args) { junit.textui.TestRunner.run(suite()); } public static TestSuite suite () { TestSuite suite = new TestSuite("EasyConf system Tests"); suite.addTest(ReloadTest.suite()); return suite; } public void testSuccess() { assertTrue(true); } public void testFail() { fail("This test fails on purpose to check that junit is working. " + "You can now safely remove it from UnitTests.java"); } } easyconf-0.9.5/src/test/com/germinus/easyconf/DatabaseConf.java100644 0 0 2007 10337163174 21630 0ustar 0 0 /* * Copyright 2004-2005 Germinus XXI * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.germinus.easyconf; import java.util.ArrayList; import java.util.List; /** * View Source * * @author Jorge Ferrer * @version $Revision: 1.2 $ * */ public class DatabaseConf { private List tables = new ArrayList(); public void addTable(Table table) { tables.add(table); } public List getTables() { return tables; } } easyconf-0.9.5/src/test/com/germinus/easyconf/DigesterLearningTest.java100644 0 0 6310 10337163174 23405 0ustar 0 0 /* * Copyright 2004-2005 Germinus XXI * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.germinus.easyconf; import java.io.IOException; import java.net.URL; import org.apache.commons.digester.Digester; import org.apache.commons.digester.xmlrules.DigesterLoader; import org.xml.sax.SAXException; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** * View Source * * @author Jorge Ferrer * @version $Revision: 1.3 $ * */ public class DigesterLearningTest extends TestCase { public DigesterLearningTest(String testName) { super(testName); } public static Test suite() { TestSuite suite = new TestSuite(); suite.addTest(new DigesterLearningTest("testXmlRulesDigester")); return suite; } public void testXmlRulesDigester() throws ClassNotFoundException, IOException, SAXException { URL digesterRulesUrl = ClasspathUtil.locateResource("test_module.digesterRules.xml"); Digester digester = DigesterLoader.createDigester(digesterRulesUrl); Object configuration = readConfig(digester); DatabaseAssert.assertContents(configuration); DatabaseConf dbConf = (DatabaseConf) configuration; assertEquals("Incorrect number of tables. The XML file was not read correctly", 2, dbConf.getTables().size()); } public void testProgramaticDigester() throws ClassNotFoundException, IOException, SAXException { Digester digester = new Digester(); digester.addObjectCreate("database", "com.germinus.easyconf.Databases"); digester.addObjectCreate("database/tables/table", "com.germinus.easyconf.Table"); digester.addSetProperties("database/tables/table"); digester.addSetNext("database/tables/table", "addTable", "com.germinus.easyconf.Table"); Object configuration = readConfig(digester); DatabaseAssert.assertContents(configuration); DatabaseConf dbConf = (DatabaseConf) configuration; assertEquals("Incorrect number of tables. The XML file was not read correclty", 2, dbConf.getTables().size()); } // .......................... Helper methods ......................... private Object readConfig(Digester digester) throws IOException, SAXException { Object configuration; digester.setUseContextClassLoader(true); digester.setValidating(false); URL confFile = ClasspathUtil.locateResource(null, "test_module.xml"); assertNotNull("Configuration file not found", confFile); configuration = digester.parse(confFile.openStream()); return configuration; } } easyconf-0.9.5/src/test/com/germinus/easyconf/systemtests/ReloadTest.java100644 0 0 22716 10337163174 24024 0ustar 0 0 /* * Copyright 2004-2005 Germinus XXI * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.germinus.easyconf.systemtests; import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.Properties; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.germinus.easyconf.ComponentConfiguration; import com.germinus.easyconf.ComponentProperties; import com.germinus.easyconf.Conventions; import com.germinus.easyconf.DatabaseConf; import com.germinus.easyconf.EasyConf; import com.germinus.easyconf.FileUtil; /** * System Test of the automatic reloading of files * * @author Jorge Ferrer */ public class ReloadTest extends TestCase { private static final String RELOADED_KEY_INITIAL_VALUE = "initial-value"; private static final String INCLUDED_FILE_1 = "reload_module_include.properties"; private static final String CONFIGURATION_DIR = "target/test-classes"; private static final String COMPONENT_NAME_1 = "reload_module"; private static final String COMPONENT_NAME_2 = "manual_reload_module"; public static final Log log = LogFactory.getLog(ReloadTest.class); private static final String XML_1 = "users
"; private static final String XML_2 = "users
" + "users
"; private static final String DIGESTER_RULES = ""+ ""+ ""+ ""+ ""+ ""+ ""+ ""+ ""; File baseConf; File baseConf2; File includedFile1; File xmlConf; File rules; public ReloadTest(String testName) { super(testName); } protected void setUp() throws Exception { baseConf = new File(CONFIGURATION_DIR+ "/" + COMPONENT_NAME_1 + ".properties"); Properties props = new Properties(); props.setProperty(Conventions.INCLUDE_PROPERTY, INCLUDED_FILE_1 + ", jar-conf.properties"); props.setProperty("reloaded-key", "invalid-value"); FileUtil.write(baseConf, props); includedFile1 = new File(CONFIGURATION_DIR + "/" + INCLUDED_FILE_1); Properties props1 = new Properties(); props1.setProperty(Conventions.RELOAD_DELAY_PROPERTY, "1"); props1.setProperty("reloaded-key", RELOADED_KEY_INITIAL_VALUE); FileUtil.write(includedFile1, props1); baseConf2 = new File(CONFIGURATION_DIR+ "/" + COMPONENT_NAME_2 + ".properties"); Properties props2 = new Properties(); props2.setProperty("reloaded-key", "invalid-value"); FileUtil.write(baseConf2, props2); xmlConf = new File(CONFIGURATION_DIR + "/" + COMPONENT_NAME_1 + ".xml"); FileUtil.write(xmlConf, XML_1); rules = new File(CONFIGURATION_DIR + "/" + COMPONENT_NAME_1 + Conventions.DIGESTERRULES_EXTENSION); FileUtil.write(rules, DIGESTER_RULES); EasyConf.refreshAll(); } protected void tearDown() throws Exception { baseConf.delete(); includedFile1.delete(); baseConf2.delete(); xmlConf.delete(); rules.delete(); } public static Test suite() { TestSuite suite = new TestSuite(); suite.addTestSuite(ReloadTest.class); return suite; } // .............. Test methods .................... /** * Assumes that reloaded_module1.xml has 1 table and reloaded_module2.xml * has two tables. * @throws IOException * @throws InterruptedException */ public void testReloadXmlFile() throws IOException, InterruptedException { DatabaseConf conf1 = getConfigurationObject(); assertEquals("After the first read there should be 1 table", 1, conf1 .getTables().size()); Thread.sleep(1100); FileUtil.write(xmlConf, XML_2); DatabaseConf conf2 = getConfigurationObject(); assertEquals("After the reload there should be 2 tables", 2, conf2 .getTables().size()); } public void testManualOneComponentReloading() throws IOException, InterruptedException { String componentName = COMPONENT_NAME_1; File dest = baseConf; ComponentProperties initialProperties = EasyConf. getConfiguration(componentName).getProperties(); assertEquals("The initial file value wasn't read correctly", RELOADED_KEY_INITIAL_VALUE, initialProperties.getString("reloaded-key")); Properties newProps = new Properties(); String newPropertyValue = "value-before-manual-specific-refreshing"; newProps.setProperty("reloaded-key", newPropertyValue); dest.delete(); FileUtil.write(dest, newProps); EasyConf.refreshComponent(componentName); ComponentProperties reloadedProperties = EasyConf. getConfiguration(componentName).getProperties(); assertEquals("The file has not been reloaded!!", newPropertyValue, reloadedProperties.getString("reloaded-key")); } public void testManualFullReloading() throws IOException { String componentName = COMPONENT_NAME_1; File dest = baseConf; ComponentProperties initialProperties = EasyConf. getConfiguration(componentName).getProperties(); assertEquals("The initial file value wasn't read correctly", RELOADED_KEY_INITIAL_VALUE, initialProperties.getString("reloaded-key")); Properties newProps = new Properties(); String newPropertyValue = "value-before-manual-refreshing"; newProps.setProperty("reloaded-key", newPropertyValue); dest.delete(); FileUtil.write(dest, newProps); EasyConf.refreshAll(); ComponentProperties reloadedProperties = EasyConf. getConfiguration(componentName).getProperties(); assertEquals("The file has not been reloaded!!", newPropertyValue, reloadedProperties.getString("reloaded-key")); // File dest = includedFile1; //// assertEquals("The initial property value is not correct. Cannot check functionality!", //// RELOADED_KEY_INITIAL_VALUE, //// getComponentConf().getProperties().getString("reloaded-key")); //// // Properties newProps = new Properties(); // String newPropertyValue = "value-before-manual-refresh"; // newProps.setProperty("reloaded-key", newPropertyValue); // dest.delete(); // FileUtil.write(dest, newProps); // EasyConf.refreshAll(); // assertEquals("The file has not been reloaded!!", newPropertyValue, // getComponentConf().getProperties().getString("reloaded-key")); } /** * I haven't found how to automate this test using maven */ public void unautomated_testReloadPropertiesFileInsideJAR() throws IOException, InterruptedException { // System.setProperty("test.classpath.dir", "target/test-classes"); // Properties props = new Properties(); // props.setProperty("jar-reloaded-key", "value1"); // File xmlConf = new File(System.getProperty("test.classpath.dir") // + "/test-conf.jar"); // FileUtil.writeAsJAR(xmlConf, "jar-conf.properties", props); assertEquals("After the first read the value should be value1", RELOADED_KEY_INITIAL_VALUE, getComponentConf().getProperties().getString( "jar-reloaded-key")); // props.setProperty("jar-reloaded-key", "value2"); System.out.println("Please, switch JAR files before 5 seconds..."); Thread.sleep(5000); // FileUtil.writeAsJAR(xmlConf, "user-conf.properties", props); assertEquals("After the first read the value should be value2", "value2", getComponentConf().getProperties().getString( "jar-reloaded-key")); // xmlConf.delete(); } // .............. Helper methods ................... DatabaseConf getConfigurationObject() { return (DatabaseConf) getComponentConf().getConfigurationObject(); } private ComponentConfiguration getComponentConf() { return EasyConf.getConfiguration(COMPONENT_NAME_1); } private void assertEquals(String msg, String[] expected, String[] obtained) { if (expected.length != obtained.length) { fail(msg + ". Expected and obtained arrays length differ"); } for (int i = 0; i < expected.length; i++) { assertEquals(msg + ". (" + i + "th element)", expected[i], obtained[i]); } } }easyconf-0.9.5/src/test/reloaded_module1.xml100644 0 0 241 10337163174 16142 0ustar 0 0 users
easyconf-0.9.5/src/test/module_with_xml_that_uses_non_existent_property.xml100644 0 0 404 10337163174 24756 0ustar 0 0 users uid long
easyconf-0.9.5/src/test/2test-conf-1.0.jar100644 0 0 301 10337163174 15166 0ustar 0 0 PK 2 2'jar-conf.propertiesUT 2B2BUxjar-reloaded-key=value2PK 2 2' jar-conf.propertiesUT2BUxPKN]easyconf-0.9.5/src/test/log4j.properties100644 0 0 523 10337163174 15353 0ustar 0 0 ### direct log messages to stdout ### log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.out log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c:%L - %m%n log4j.rootLogger=debug, stdout log4j.logger.org.apache.commons=INFO easyconf-0.9.5/src/test/test_module-local.properties100644 0 0 24 10337163174 17724 0ustar 0 0 test_module_db=mysqleasyconf-0.9.5/src/test/jmx_module.properties100644 0 0 441 10337163174 16476 0ustar 0 0 include-and-override=test_module-${easyconf-environment}.properties include-and-override=test_module-${test_module:easyconf-environment}2.properties easyconf:cache.enabled=false property-only-in-test-module=jmx_module string-not-overridden=jmx_module string-overridden-in-prj=jmx_module easyconf-0.9.5/src/test/module_without_xml.properties100644 0 0 24 10337163174 20240 0ustar 0 0 test_key=test_value easyconf-0.9.5/src/test/test_module-exampleCompany.properties100644 0 0 76 10337163174 21623 0ustar 0 0 company-name=exampleCompany global-company-name=exampleCompanyeasyconf-0.9.5/src/test/global-configuration-prj.properties100644 0 0 264 10337163174 21234 0ustar 0 0 string-overridden-in-prj=prj test_module:string-overridden-in-prj-with-prefix=prj string-overridden-in-prj-and-env=prj list-overridden-in-prj=prj1, prj2 property-only-in-prj=prjeasyconf-0.9.5/src/test/module_without_properties.digesterRules.xml100644 0 0 760 10337163174 23107 0ustar 0 0 easyconf-0.9.5/src/test/test_module-exampleCompany.xml100644 0 0 537 10337163174 20251 0ustar 0 0 example_company_users uid long
easyconf-0.9.5/src/test/module_without_digesterRules.xml100644 0 0 2064 10337163174 20733 0ustar 0 0 users uid long uname java.lang.String firstName java.lang.String lastName java.lang.String email java.lang.String
documents docid long name java.lang.String creationDate java.util.Date authorID long version int
easyconf-0.9.5/src/test/test_module.myname.xml100644 0 0 3106 10337163174 16571 0ustar 0 0 users uid long uname java.lang.String firstName java.lang.String lastName java.lang.String email java.lang.String
documents docid long name java.lang.String creationDate java.util.Date authorID long version int
clients uid long uname java.lang.String firstName java.lang.String lastName java.lang.String email java.lang.String
easyconf-0.9.5/src/test/test_module.properties100644 0 0 4013 10337163174 16676 0ustar 0 0 include-and-override=test_module-${easyconf:companyId}.properties include-and-override=test_module-${easyconf-environment}.properties include-and-override=test_module-${test_module:easyconf-environment}2.properties easyconf:cache.enabled=false property-only-in-test-module=test_module string-not-overridden=test_module string-overridden-in-prj=test_module string-overridden-in-env=test_module string-overridden-in-prj-and-env=test_module string-overridden-in-prj-with-prefix=test_module list-not-overridden=test_module1, test_module2 list-overridden-in-prj=test_module1, test_module2 default.table.type=system property-with-filter[selector1][selector2]=selector1-and-selector2 property-with-filter[selector1]=selector1 property-with-filter=no-selector property-with-filter2[selector1][selector2]=selector1-and-selector2 property-with-filter2[selector1]=selector1 long-with-filter[selector1][selector2]=1234 short-with-filter[selector1][selector2]=1234 int-with-filter[selector1][selector2]=1234 byte-with-filter[selector1][selector2]=123 biginteger-with-filter[selector1][selector2]=1234 bigdecimal-with-filter[selector1][selector2]=1234 double-with-filter[selector1][selector2]=1234 float-with-filter[selector1][selector2]=1234 list-with-filter[selector1][selector2]=1234,5678 boolean-with-filter[selector1][selector2]=false database-configuration-class=com.germinus.easyconf.DatabaseConf database-configuration-classes=com.germinus.easyconf.DatabaseConf,com.germinus.easyconf.Table some-numbers=1,2,3,4,5 non-existent-class=IDoNotExist test_module_db=unknown test_module_environment=${easyconf-environment} sysproperty-with-prefix-and-default-value=defaultValue sysproperty-without-prefix-and-default-value=defaultValue # # Properties to test the ASP model # company-name=default global-company-name=default # # Properties to test variables whose value is specified from the code # property-with-variable=${exampleVariable} # Using a property it is possible to set a default value for the property exampleVariable=default-exampleVariable-valueeasyconf-0.9.5/src/test/test_module.xml100644 0 0 2103 10337163174 15300 0ustar 0 0 users uid long uname java.lang.String firstName java.lang.String lastName java.lang.String email java.lang.String
documents docid long name java.lang.String creationDate java.util.Date authorID long version int
easyconf-0.9.5/src/test/global-configuration-env.properties100644 0 0 133 10337163174 21224 0ustar 0 0 string-overridden-in-env=env string-overridden-in-prj-and-env=env property-only-in-env=enveasyconf-0.9.5/src/test/global-configuration.properties100644 0 0 356 10337163174 20445 0ustar 0 0 include-and-override=global-configuration-${easyconf:companyId}.properties include-and-override=global-configuration-prj.properties include-and-override=global-configuration-env.properties property-only-in-global-configuration=global-confeasyconf-0.9.5/src/test/module_without_properties.xml100644 0 0 417 10337163174 20266 0ustar 0 0 users uid long
easyconf-0.9.5/src/test/digester-rules.dtd100644 0 0 12041 10337163174 15707 0ustar 0 0 easyconf-0.9.5/src/test/module_with_xml_that_uses_non_existent_property.digesterRules.xml100644 0 0 760 10337163174 27603 0ustar 0 0 easyconf-0.9.5/src/test/test_module.digesterRules.xml100644 0 0 760 10337163174 20107 0ustar 0 0 easyconf-0.9.5/src/test/test_module-local2.properties100644 0 0 26 10337163174 20010 0ustar 0 0 test_module_db2=mysql2easyconf-0.9.5/src/test/reloaded_module2.xml100644 0 0 346 10337163174 16151 0ustar 0 0 users
users
easyconf-0.9.5/src/test/reloaded_module.digesterRules.xml100644 0 0 760 10337163174 20707 0ustar 0 0 easyconf-0.9.5/src/test/global-configuration-exampleCompany.properties100644 0 0 50 10337163174 23374 0ustar 0 0 global-company-name=exampleCompanyGlobaleasyconf-0.9.5/src/test/1test-conf-1.0.jar100644 0 0 301 10337163174 15165 0ustar 0 0 PK 2X;jar-conf.propertiesUT !B !BUxjar-reloaded-key=value1PK 2X; jar-conf.propertiesUT!BUxPKN]easyconf-0.9.5/src/java/com/germinus/easyconf/servlet/RefreshConfigurationServlet.java100644 0 0 5504 10337163174 26444 0ustar 0 0 /** * Copyright (c) 2000-2004 Liferay, LLC. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package com.germinus.easyconf.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang.StringUtils; import com.germinus.easyconf.EasyConf; /** * View Source * * @author Jorge Ferrer * @version $Revision$ * */ public class RefreshConfigurationServlet extends HttpServlet { /* * Refresh the configuration */ protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String componentName = request.getParameter("componentName"); if (StringUtils.isBlank(componentName)) { EasyConf.refreshAll(); } else { EasyConf.refreshComponent(componentName); } writeSuccessResponse(response, componentName); } protected void writeSuccessResponse(HttpServletResponse response, String componentName) throws IOException { String msg; if (StringUtils.isBlank(componentName)) { msg = "The configuration of " + componentName + " has been reloaded"; } else { msg = "The configuration of all components has been reloaded"; } StringBuffer html = new StringBuffer(); html.append(""); html.append(msg); html.append(""); html.append("

"); html.append(msg); html.append("

"); response.getWriter().write(html.toString()); } } easyconf-0.9.5/src/java/com/germinus/easyconf/Conventions.java100644 0 0 3311 10337163174 21564 0ustar 0 0 /* * Copyright 2004-2005 Germinus XXI * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.germinus.easyconf; /** * Conventions used by EasyConf that can be expressed as contansts * @author Jorge Ferrer * @version $Revision: 1.7 $ * */ public interface Conventions { char SELECTOR_START = '['; char SELECTOR_END = ']'; char DOT = '.'; char SLASH = '-'; String INCLUDE_PROPERTY = "include-and-override"; String GLOBAL_CONFIGURATION_FILE = "global-configuration"; String DIGESTERRULES_EXTENSION = ".digesterRules.xml"; String XML_EXTENSION = ".xml"; String PROPERTIES_EXTENSION = ".properties"; String DATASOURCE_PREFIX = "datasource:"; String JNDI_PREFIX = "jndi:"; String RELOAD_DELAY_PROPERTY = "easyconf:reload-delay"; String CONFIGURATION_OBJECTS_SOURCE_PROPERTY = "easyconf:configuration-objects-source"; String CONFIGURATION_OBJECTS_TABLE = "easyconf_configuration_objects"; String PROPERTIES_TABLE = "easyconf_properties"; String COMPANY_ID_PROPERTY = "easyconf:companyId"; String COMPONENT_NAME_PROPERTY = "easyconf:componentName"; String PREFIX_SEPARATOR = ":"; String DEFAULT_CONF_OBJECT_NAME = "DEFAULT_CONF_OBJECT"; } easyconf-0.9.5/src/java/com/germinus/easyconf/semantic.cache100644 0 0 13715 10337163174 21235 0ustar 0 0 ;; Object semantic.cache ;; SEMANTICDB Tags save file (semanticdb-project-database "semantic.cache" :file "semantic.cache" :tables (list (semanticdb-table "ConfReader.java" :file "ConfReader.java" :pointmax 11728 :major-mode 'jde-mode :tokens '(("com.germinus.easyconf" package nil nil nil [1 31]) ("java.io.IOException" include nil nil nil [33 60]) ("java.net.URL" include nil nil nil [61 81]) ("java.util.*" include nil nil nil [82 101]) ("org.apache.commons.configuration.PropertiesConfiguration" include nil nil nil [103 167]) ("org.apache.commons.configuration.CompositeConfiguration" include nil nil nil [168 231]) ("org.apache.commons.configuration.Configuration" include nil nil nil [232 286]) ("org.apache.commons.digester.Digester" include nil nil nil [287 331]) ("org.apache.commons.digester.Substitutor" include nil nil nil [332 379]) ("org.apache.commons.digester.substitution.MultiVariableExpander" include nil nil nil [380 450]) ("org.apache.commons.digester.substitution.VariableSubstitutor" include nil nil nil [451 519]) ("org.apache.commons.digester.xmlrules.DigesterLoader" include nil nil nil [520 579]) ("org.apache.commons.logging.Log" include nil nil nil [580 618]) ("org.apache.commons.logging.LogFactory" include nil nil nil [619 664]) ("org.xml.sax.SAXException" include nil nil nil [665 697]) ("ConfReader" type "class" (("OVERRIDEN_PROPERTIES_FILES_PROPERTY" variable "String" nil ((typemodifiers "private" "static" "final")) nil ((reparse-symbol . class_body_declarations)) [4279 4368]) ("instance" variable "ConfReader" nil ((typemodifiers "private" "static" "final")) nil ((reparse-symbol . class_body_declarations)) [4370 4430]) ("log" variable "Log" nil ((typemodifiers "private" "static" "final")) nil ((reparse-symbol . class_body_declarations)) [4435 4502]) ("cache" variable "Map" nil ((typemodifiers "private" "static")) nil ((reparse-symbol . class_body_declarations)) [4507 4548]) ("GLOBAL_CONFIGURATION_FILE" variable "String" nil ((typemodifiers "private" "static" "final")) nil ((reparse-symbol . class_body_declarations)) [4553 4632]) ("ENVIRONMENT_NAME_VARIABLE" variable "String" nil ((typemodifiers "private" "static" "final")) nil ((reparse-symbol . class_body_declarations)) [4637 4713]) ("getInstance" function "ConfReader" nil ((typemodifiers "public" "static")) nil ((reparse-symbol . class_body_declarations)) [4719 4790]) ("ConfReader" function nil nil ((typemodifiers "private")) nil ((reparse-symbol . class_body_declarations)) [4796 4824]) ("getComponentConfiguration" function "ComponentConfiguration" (("componentName" variable "String" nil nil nil ((reparse-symbol . formal_parameter_list)) [5013 5033])) ((typemodifiers "public")) nil ((reparse-symbol . class_body_declarations)) [4957 5625]) ("refreshComponent" function "void" (("componentName" variable "String" nil nil nil ((reparse-symbol . formal_parameter_list)) [6013 6033])) ((typemodifiers "public")) nil ((reparse-symbol . class_body_declarations)) [5984 6304]) ("refreshAll" function "void" nil ((typemodifiers "public")) nil ((reparse-symbol . class_body_declarations)) [6657 6787]) ("getConfiguration" function "Configuration" (("componentName" variable "String" nil nil nil ((reparse-symbol . formal_parameter_list)) [7050 7070])) ((typemodifiers "public")) nil ((reparse-symbol . class_body_declarations)) [7012 7181]) ("readComponentConfiguration" function "ComponentConfiguration" (("componentName" variable "String" nil nil nil ((reparse-symbol . formal_parameter_list)) [7333 7353])) ((typemodifiers "private") (throws "IOException" "SAXException")) nil ((reparse-symbol . class_body_declarations)) [7275 7680]) ("readPropertiesConfiguration" function "Properties" (("componentName" variable "String" nil nil nil ((reparse-symbol . formal_parameter_list)) [7737 7757])) ((typemodifiers "private")) nil ((reparse-symbol . class_body_declarations)) [7690 8342]) ("readPropertiesFromFiles" function "CompositeConfiguration" (("fileNames" variable "List" nil nil nil ((reparse-symbol . formal_parameter_list)) [8404 8418])) ((typemodifiers "private")) nil ((reparse-symbol . class_body_declarations)) [8349 9145]) ("getBaseFileNames" function "List" (("componentName" variable "String" nil nil nil ((reparse-symbol . formal_parameter_list)) [9349 9369])) ((typemodifiers "private")) nil ((reparse-symbol . class_body_declarations)) [9319 9560]) ("getEnvironmentFileNames" function "List" (("componentName" variable "String" nil nil nil ((reparse-symbol . formal_parameter_list)) [9771 9791])) ((typemodifiers "private")) nil ((reparse-symbol . class_body_declarations)) [9734 10121]) ("getFilesWithOverriddenProperties" function "List" (("componentConf" variable "Configuration" nil nil nil ((reparse-symbol . formal_parameter_list)) [10173 10200])) ((typemodifiers "private")) nil ((reparse-symbol . class_body_declarations)) [10127 10284]) ("readObjectGraph" function "Object" (("componentName" variable "String" nil nil nil ((reparse-symbol . formal_parameter_list)) [10321 10342]) ("properties" variable "Properties" nil nil nil ((reparse-symbol . formal_parameter_list)) [10355 10376])) ((typemodifiers "private") (throws "IOException" "SAXException")) nil ((reparse-symbol . class_body_declarations)) [10290 11724])) nil ((typemodifiers "public")) nil nil [4249 11727])) :unmatched-syntax '((close-paren 11726 . 11727) (close-paren 10376 . 10377) (open-paren 10320 . 10321) (close-paren 10200 . 10201) (open-paren 10172 . 10173) (close-paren 9791 . 9792) (open-paren 9770 . 9771) (close-paren 9369 . 9370) (open-paren 9348 . 9349) (close-paren 8418 . 8419) (open-paren 8403 . 8404) (close-paren 7757 . 7758) (open-paren 7736 . 7737) (close-paren 7353 . 7354) (open-paren 7332 . 7333) (close-paren 7070 . 7071) (open-paren 7049 . 7050) (close-paren 6680 . 6681) (open-paren 6679 . 6680) (close-paren 6033 . 6034) (open-paren 6012 . 6013) (close-paren 5033 . 5034) (open-paren 5012 . 5013) (close-paren 4815 . 4816) (open-paren 4814 . 4815) (close-paren 4756 . 4757) (open-paren 4755 . 4756) (open-paren 4273 . 4274)) ) ) ) easyconf-0.9.5/src/java/com/germinus/easyconf/FileURLChangedReloadingStrategy.java100644 0 0 2260 10337163174 25345 0ustar 0 0 /* * Copyright 2004-2005 Germinus XXI * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.germinus.easyconf; import java.net.URL; /** * Detects changes in files specified in a URL * @author Jorge Ferrer * @version $Revision: 1.1 $ * */ public class FileURLChangedReloadingStrategy extends FileConfigurationChangedReloadingStrategy { public FileURLChangedReloadingStrategy(URL url) { setSourceURL(url); } public FileURLChangedReloadingStrategy(URL url, long refreshDelay) { this(url); super.setRefreshDelay(refreshDelay); } public boolean reloadingRequired() { return super.reloadingRequired(); } } easyconf-0.9.5/src/java/com/germinus/easyconf/taglib/PropertyTag.java100644 0 0 23114 10337163174 23024 0ustar 0 0 /* * Copyright 2004-2005 Germinus XXI * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.germinus.easyconf.taglib; import com.germinus.easyconf.EasyConf; import com.germinus.easyconf.ComponentProperties; import com.germinus.easyconf.Filter; import javax.servlet.jsp.tagext.BodyTagSupport; import javax.servlet.jsp.JspException; import org.apache.struts.util.RequestUtils; import org.apache.commons.lang.StringUtils; import java.util.List; import java.util.ArrayList; /** * Read a configuration property and expose it as a page variable and attribute * Examples of use: * * >%@ taglib uri="/WEB-INF/tld/easyconf.tld" prefix="easyconf" %> * * >easyconf:property id="registration_list" * component="registration" * property="registration.list" * type="java.util.List"/> * >logic:iterate id="item" name="registration_list"> * >bean:write name="item"/> >br/> * >/logic:iterate> * * >easyconf:property id="registration_disabled" * component="registration" * property="registration.disabled"/> * >logic:equal name="registration_disabled" value="true"> * The registration is disabled * >/logic:equal> * * @jsp.tag name="property" body-content="empty" tei-class="com.germinus.easyconf.taglib.PropertyTei" */ public class PropertyTag extends BodyTagSupport { private static final long serialVersionUID = 3546082471134573881L; private static final String DEFAULT_TYPE = "java.lang.String"; protected String id = null; protected String component = null; protected String property = null; protected String type = DEFAULT_TYPE; protected String selector1 = ""; protected String selector2 = ""; protected String selector3 = ""; protected String selector4 = ""; protected String selector5 = ""; protected String defaultValue; private static final List EMPTY_LIST = new ArrayList(); public PropertyTag() { super(); release(); } /** * @jsp.attribute required="true" rtexprvalue="true" */ public String getId() { return (this.id); } public void setId(String id) { this.id = id; } /** * @jsp.attribute required="true" rtexprvalue="true" */ public String getComponent() { return component; } public void setComponent(String component) { this.component = component; } /** * @jsp.attribute required="true" rtexprvalue="true" */ public String getProperty() { return (this.property); } public void setProperty(String property) { this.property = property; } /** * @jsp.attribute required="false" rtexprvalue="true" */ public String getType() { if (StringUtils.isEmpty(type)) { type = DEFAULT_TYPE; } return (this.type); } /** * @jsp.attribute required="false" rtexprvalue="true" */ public void setType(String type) { if (StringUtils.isNotEmpty(type)) { this.type = type; } } /** * @jsp.attribute required="false" rtexprvalue="true" */ public String getDefaultValue() { return (this.defaultValue); } /** * Note: currently this is only used if type is String * @param defaultValue */ public void setDefaultValue(String defaultValue) { this.defaultValue = defaultValue; } /** * @jsp.attribute required="false" rtexprvalue="true" */ public String getSelector1() { return selector1; } public void setSelector1(String selector1) { this.selector1 = selector1; } /** * @jsp.attribute required="false" rtexprvalue="true" */ public String getSelector2() { return selector2; } public void setSelector2(String selector2) { this.selector2 = selector2; } /** * @jsp.attribute required="false" rtexprvalue="true" */ public String getSelector3() { return selector3; } public void setSelector3(String selector3) { this.selector3 = selector3; } /** * @jsp.attribute required="false" rtexprvalue="true" */ public String getSelector4() { return selector4; } public void setSelector4(String selector4) { this.selector4 = selector4; } /** * @jsp.attribute required="false" rtexprvalue="true" */ public String getSelector5() { return selector5; } public void setSelector5(String selector5) { this.selector5 = selector5; } private String[] getSelectorArray() { List selectors = new ArrayList(); if (StringUtils.isNotEmpty(selector1)) { selectors.add(selector1); } if (StringUtils.isNotEmpty(selector2)) { selectors.add(selector2); } if (StringUtils.isNotEmpty(selector3)) { selectors.add(selector3); } if (StringUtils.isNotEmpty(selector4)) { selectors.add(selector4); } if (StringUtils.isNotEmpty(selector5)) { selectors.add(selector5); } return (String[]) selectors.toArray(new String[0]); } // .................. Taglib methods .................. /** * Check if we need to evaluate the body of the tag * * @exception javax.servlet.jsp.JspException if a JSP exception has occurred */ public int doStartTag() throws JspException { return (EVAL_BODY_BUFFERED); } /** * Save the body content of this tag (if any), or throw a JspException * if the value was already defined. * * @exception JspException if value was defined by an attribute */ public int doAfterBody() throws JspException { return (SKIP_BODY); } /** * Retrieve the required property and expose it as a scripting variable. * * @exception JspException if a JSP exception has occurred */ public int doEndTag() throws JspException { Object value = null; ComponentProperties conf = EasyConf.getConfiguration(component). getProperties(); value = readProperty(conf); if (value == null) { JspException e = new JspException("The value of the property is null"); RequestUtils.saveException(pageContext, e); throw e; } pageContext.setAttribute(id, value); return (EVAL_PAGE); } private Object readProperty(ComponentProperties conf) throws JspException { Object value; if (getType().equals("java.util.List")) { value = conf.getList(property, getPropertyFilter(), EMPTY_LIST); } else if (getType().equals("java.lang.Integer")) { value = conf.getInteger(property, getPropertyFilter(), new Integer(0)); } else if (getType().equals("java.lang.String[]")) { value = conf.getStringArray(property, getPropertyFilter(), new String[0]); } else if (getType().equals("java.lang.String")) { if (defaultValue != null) { value = conf.getString(property, getPropertyFilter(), defaultValue); } else { value = conf.getString(property, getPropertyFilter()); } } else if (getType().equals("java.lang.Double")) { value = new Double(conf.getDouble(property, getPropertyFilter())); } else if (getType().equals("java.lang.Float")) { value = new Float(conf.getFloat(property, getPropertyFilter())); } else if (getType().equals("java.lang.Byte")) { value = new Byte(conf.getByte(property, getPropertyFilter())); } else if (getType().equals("java.math.BigDecimal")) { value = conf.getBigDecimal(property, getPropertyFilter()); } else if (getType().equals("java.lang.BigInteger")) { value = conf.getBigInteger(property, getPropertyFilter()); } else if (getType().equals("java.lang.Boolean")) { value = new Boolean(conf.getBoolean(property, getPropertyFilter())); } else if (getType().equals("java.lang.Short")) { value = new Short(conf.getShort(property, getPropertyFilter())); } else if (getType().equals("java.lang.Long")) { value = new Long(conf.getLong(property, getPropertyFilter())); } else { JspException e = new JspException("Unsupported type: " +type); RequestUtils.saveException(pageContext, e); throw e; } return value; } private Filter getPropertyFilter() { return Filter.by(getSelectorArray()); } public void release() { super.release(); id = null; component = null; property = null; type = null; defaultValue = null; } } easyconf-0.9.5/src/java/com/germinus/easyconf/taglib/ConfigurationObjectTei.java100644 0 0 2533 10337163174 25126 0ustar 0 0 /* * Copyright 2004-2005 Germinus XXI * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.germinus.easyconf.taglib; import javax.servlet.jsp.tagext.TagData; import javax.servlet.jsp.tagext.TagExtraInfo; import javax.servlet.jsp.tagext.VariableInfo; /** * Used to declare the property value as a JSP scripting variable * * @author jferrer */ public class ConfigurationObjectTei extends TagExtraInfo { /** * Return information about the scripting variables to be created. */ public VariableInfo[] getVariableInfo(TagData data) { String type = (String)data.getAttribute("type"); return new VariableInfo[] { new VariableInfo(data.getAttributeString("id"), type, true, VariableInfo.AT_END ) }; } } easyconf-0.9.5/src/java/com/germinus/easyconf/taglib/PropertyTei.java100644 0 0 2727 10337163174 23021 0ustar 0 0 /* * Copyright 2004-2005 Germinus XXI * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.germinus.easyconf.taglib; import org.apache.commons.lang.StringUtils; import javax.servlet.jsp.tagext.TagExtraInfo; import javax.servlet.jsp.tagext.VariableInfo; import javax.servlet.jsp.tagext.TagData; /** * Used to declare the property value as a JSP scripting variable * * @author jferrer */ public class PropertyTei extends TagExtraInfo { /** * Return information about the scripting variables to be created. */ public VariableInfo[] getVariableInfo(TagData data) { String type = (String)data.getAttribute("type"); if (StringUtils.isEmpty(type)) { type = "java.lang.String"; } return new VariableInfo[] { new VariableInfo(data.getAttributeString("id"), type, true, VariableInfo.AT_END ) }; } } easyconf-0.9.5/src/java/com/germinus/easyconf/taglib/ConfigurationObjectTag.java100644 0 0 7100 10337163174 25113 0ustar 0 0 /* * Copyright 2004-2005 Germinus XXI * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.germinus.easyconf.taglib; import com.germinus.easyconf.EasyConf; import javax.servlet.jsp.tagext.BodyTagSupport; import javax.servlet.jsp.JspException; import org.apache.struts.util.RequestUtils; /** * Read a configuration property and expose it as a page variable and attribute * Examples of use: * * >%@ taglib uri="/WEB-INF/tld/easyconf.tld" prefix="easyconf" %> * * >easyconf:configurationObject id="dbConf" * component="test_module" * type="com.germinus.easyconf.example.DatabaseConf"/> * >bean:write name="dbConf" property="tables"/> * * @jsp.tag name="configurationObject" body-content="empty" * tei-class="com.germinus.easyconf.taglib.ConfigurationObjectTei" */ public class ConfigurationObjectTag extends BodyTagSupport { protected String id = null; protected String component = null; protected String type = "java.lang.Object"; /** * @jsp.attribute required="true" rtexprvalue="true" */ public String getId() { return (this.id); } public void setId(String id) { this.id = id; } /** * @jsp.attribute required="true" rtexprvalue="true" */ public String getComponent() { return component; } public void setComponent(String component) { this.component = component; } /** * @jsp.attribute required="false" rtexprvalue="true" */ public String getType() { return (this.type); } public void setType(String type) { this.type = type; } /** * Check if we need to evaluate the body of the tag * * @exception javax.servlet.jsp.JspException if a JSP exception has occurred */ public int doStartTag() throws JspException { return (EVAL_BODY_BUFFERED); } /** * Save the body content of this tag (if any), or throw a JspException * if the value was already defined. * * @exception JspException if value was defined by an attribute */ public int doAfterBody() throws JspException { return (SKIP_BODY); } /** * Retrieve the required property and expose it as a scripting variable. * * @exception JspException if a JSP exception has occurred */ public int doEndTag() throws JspException { Object confObj = EasyConf.getConfiguration(component). getConfigurationObject(); if (confObj == null) { JspException e = new JspException("The value of the configuration object is null. " + "Check the configuration files"); RequestUtils.saveException(pageContext, e); throw e; } pageContext.setAttribute(id, confObj); return (EVAL_PAGE); } public void release() { super.release(); id = null; component = null; type = null; } } easyconf-0.9.5/src/java/com/germinus/easyconf/XstreamSerializer.java100644 0 0 1315 10337163174 22736 0ustar 0 0 /* * Created on 06-nov-2005 * * TODO To change the template for this generated file go to * Window - Preferences - Java - Code Style - Code Templates */ package com.germinus.easyconf; import com.thoughtworks.xstream.XStream; /** * @author jorge * * TODO To change the template for this generated type comment go to * Window - Preferences - Java - Code Style - Code Templates */ public class XstreamSerializer extends ConfigurationSerializer { private static final XStream xstream = new XStream(); public Object deserialize(String serializedConf) { return xstream.fromXML(serializedConf); } public String serialize(Object configurationObject) { return xstream.toXML(configurationObject); } } easyconf-0.9.5/src/java/com/germinus/easyconf/Filter.java100644 0 0 10312 10337163174 20523 0ustar 0 0 /* * Copyright 2004-2005 Germinus XXI * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.germinus.easyconf; import java.util.HashMap; import java.util.Map; /** * Builds filters from arrays of strings or up to three string paramters * * @author jferrer */ public class Filter { private String[] selectors; private Map variables; // ............. Constructors ................ private Filter(String[] selectors) { this.selectors = selectors; } private Filter(Map variables) { this.variables = variables; } // ......... static methods ........... public static Filter by(String first) { return new Filter(new String[]{first}); } public static Filter by(String first, String second) { return new Filter(new String[]{first, second}); } public static Filter by(String first, String second, String third) { return new Filter(new String[]{first, second, third}); } public static Filter by(String[] selectors) { return new Filter(selectors); } public static Filter usingVariables(String var1, String value1) { Map vars = new HashMap(); vars.put(var1, value1); return new Filter(vars); } public static Filter usingVariables(String var1, String value1, String var2, String value2) { Map vars = new HashMap(); vars.put(var1, value1); vars.put(var2, value2); return new Filter(vars); } public static Filter usingVariables(String var1, String value1, String var2, String value2, String var3, String value3) { Map vars = new HashMap(); vars.put(var1, value1); vars.put(var2, value2); vars.put(var3, value3); return new Filter(vars); } public static Filter usingVariables(Map vars) { return new Filter(vars); } // .............. instance methods ................ public boolean hasVariables() { return (variables != null) && (!variables.isEmpty()); } public Filter setVariables(Map newVars) { this.variables = newVars; return this; } public Map getVariables() { return variables; } public String[] getSelectors() { return selectors; } public Filter setSelectors(String[] newSelectors) { this.selectors = newSelectors; return this; } public int numOfSelectors() { if (selectors == null) { return 0; } return selectors.length; } /** * Get a fragment of the filter which includes the first 'n' selectors * concatenated. * * Example: if the filter has two selectors (bar and foo). Fragments would * be: * * @param n * @return * @throws IllegalArgumentException if n < 1 or n > size() */ public String getFilterSuffix(int n) { if ((n<0) || (n > numOfSelectors())) { throw new IllegalArgumentException("Imposible to obtain filter fragment for n="+n); } if (n==0) { return ""; } StringBuffer filter = new StringBuffer(); for (int i = 0; i < n; i++) { filter.append(Conventions.SELECTOR_START); filter.append(selectors[i]); filter.append(Conventions.SELECTOR_END); } return filter.toString(); } public String toString() { return getFilterSuffix(numOfSelectors()); } } easyconf-0.9.5/src/java/com/germinus/easyconf/FileConfigurationChangedReloadingStrategy.java100644 0 0 6141 10337163174 27514 0ustar 0 0 /* * Copyright 2004-2005 Germinus XXI * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.germinus.easyconf; import java.io.File; import java.net.URL; import org.apache.commons.configuration.FileConfiguration; import org.apache.commons.configuration.reloading.FileChangedReloadingStrategy; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Reloads the configuration file even if a base path wasn't originally * specified. This happens for example when it has been loaded from * the classpath. It works too for files that are inside JAR files. * */ public class FileConfigurationChangedReloadingStrategy extends FileChangedReloadingStrategy { private URL sourceURL; private static final Log log = LogFactory.getLog(FileConfigurationChangedReloadingStrategy.class); public void setConfiguration(FileConfiguration configuration) { super.setConfiguration(configuration); setSourceURL(configuration.getURL()); } protected void setSourceURL(URL url) { sourceURL = url; } protected URL getSourceURL() { return sourceURL; } /** * Update the last modified time. */ protected void updateLastModified() { lastModified = getFile().lastModified(); } /** * Check if the configuration has changed since the last time it was loaded. */ protected boolean hasChanged() { File file = getFile(); if (!file.exists()) { if (log.isDebugEnabled()) { log.debug("File does not exist: " + file); } return false; } boolean result = (file.lastModified() > lastModified); lastChecked = System.currentTimeMillis(); return result; } protected File getFile() { if ("file".equals(sourceURL.getProtocol())) { return new File(sourceURL.getPath()); } else if ("jar".equals(sourceURL.getProtocol())) { String path = sourceURL.getPath(); String jarFilePath = path.substring("file:".length(), path.indexOf('!')); return new File(jarFilePath); } else if (configuration != null) { return configuration.getFile(); } else if ("classloader".equals(sourceURL.getProtocol())) { if (log.isDebugEnabled()) { log.debug("Reloading will not work for files loaded by the classloader: " + sourceURL); } return new File(sourceURL.getFile()); } log.warn("Cannot determine the filesystem file which contains the " + "configuration file for: " + sourceURL); return new File(sourceURL.getFile()); } } easyconf-0.9.5/src/java/com/germinus/easyconf/JndiURL.java100644 0 0 4115 10337163174 20531 0ustar 0 0 /* * Copyright 2004-2005 Germinus XXI * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.germinus.easyconf; import javax.naming.InitialContext; import javax.naming.NamingException; import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.JNDIConfiguration; /** * Represents the URL to a JNDI tree as specified in a properties file * TODO: Add support for ASP applications * @author Jorge Ferrer * @version $Revision: 1.2 $ * */ public class JndiURL { private static final String JNDI_PREFIX = Conventions.JNDI_PREFIX; private static InitialContext ctx = null; private String jndiPrefix; private String companyId; private String componentName; public JndiURL(String jndiPath, String companyId, String componentName) { this.jndiPrefix = jndiPrefix.substring(JNDI_PREFIX.length()); this.companyId = companyId; this.componentName = componentName; } private synchronized InitialContext getContext() throws NamingException { if (ctx == null) { ctx = new InitialContext(); } return ctx; } public static boolean isJndi(String sourcePath) { return sourcePath.startsWith(JNDI_PREFIX); } public String getPrefix() { return jndiPrefix; } public Configuration getConfiguration() { try { return new JNDIConfiguration(getPrefix()); } catch (NamingException e) { throw new ConfigurationException("Error loading JNDI configuration for " + getPrefix()); } } } easyconf-0.9.5/src/java/com/germinus/easyconf/ConfigurationException.java100644 0 0 3475 10337163174 23760 0ustar 0 0 /* * Copyright 2004-2005 Germinus XXI * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.germinus.easyconf; import org.apache.commons.lang.exception.NestableRuntimeException; /** * Some unrecoverable but important error has ocurred while reading the configuration * * @author Jorge Ferrer * @version $Revision: 1.3 $ * */ public class ConfigurationException extends NestableRuntimeException { private String componentName; public ConfigurationException() { super(); } public ConfigurationException(String componentName, String msg, Throwable thr) { super(msg, thr); this.componentName = componentName; } protected ConfigurationException(String componentName) { super(); this.componentName = componentName; } protected ConfigurationException(String componentName, Throwable e) { super(e); this.componentName = componentName; } public ConfigurationException(String componentName, String msg) { super(msg); this.componentName = componentName; } public String getComponentName() { return componentName; } public String getMessage() { return "Error reading configuration for " + componentName + ": " + super.getMessage(); } } easyconf-0.9.5/src/java/com/germinus/easyconf/ComponentProperties.java100644 0 0 62330 10337163174 23324 0ustar 0 0 /* * Copyright 2004-2005 Germinus XXI * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.germinus.easyconf; import java.math.BigDecimal; import java.math.BigInteger; import java.util.*; import org.apache.commons.beanutils.DynaBean; import org.apache.commons.configuration.beanutils.ConfigurationDynaBean; import org.apache.commons.configuration.CompositeConfiguration; import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.ConfigurationConverter; import org.apache.commons.configuration.DataConfiguration; import org.apache.commons.configuration.MapConfiguration; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Part of a component configuration which contains its properties. * * The properties can be accessed by type and automatic conversion will be * performed. The supported types are: BigDecimal, BigInteger, Boolean, Byte, * Double, Float, Integer, List, Long, Short, String and StringArray * * It is based on the Configuration interface from Jakarta * Commons Configuration but it is given a different name which makes more sense * inside EasyConf. * * The boolean flag throwExceptionOnMissing controls the behaviour of this class * when a property that does not exist is queried. If set to true (the default) * a NoSuchElementException will be thrown if the given key does not * exist and no default was provided. If set to false, null will be * returned except for the method getList() which will return an empty * unmodifyiable list. * * @author Jorge Ferrer * @version $Revision: 1.23 $ * */ public class ComponentProperties { public static final String NULL_STRING = null; private static final List EMPTY_LIST = Collections .unmodifiableList(new ArrayList()); private static final Log log = LogFactory.getLog(ComponentProperties.class); AggregatedProperties properties; ComponentProperties(AggregatedProperties conf) { this.properties = conf; setThrowExceptionOnMissing(false); } // .................. Conversion methods ................... /** * Returns a decorator of the configuration that implements the Map * interface. Note that any changes made to this decorator will be made to * the original configuration and viceversa. * * @return a java.util.Map instance */ public Map toMap() { return ConfigurationConverter.getMap(properties); } /** * Returns a decorator of the configuration that can be used as a DynaBean. * Note that any changes made to this decorator will be made to the original * configuration and viceversa. * * @return a DynaBean instance */ public DynaBean toDynaBean() { return new ConfigurationDynaBean(properties); } /** * Returns a decorator of the configuration of type * org.apache.commons.configuration.Configuration Note that any * changes made to this decorator will be made to the original configuration * and viceversa. * * @return a Configuration instance */ public Configuration toConfiguration() { return properties; } /** * Returns a decorator of the configuration of type * org.apache.commons.configuration.DataConfiguration. This * decorator has many extra methods for retrieving typed properties such as * color, URL, locale, Calendar and lists and array of any of these types. * * Note that any changes made to this decorator will be made to the original * configuration and viceversa. * * @return a DataConfiguration instance */ public DataConfiguration toDataConfiguration() { return new DataConfiguration(properties); } /** * Returns a copy of the configuration into a * java.util.Properties class. Multivalued properties will be * converted to comma-separated strings. Any changes made to the * configuration will not be available to the Properties and * viceversa. * * @return a Properties instance */ public java.util.Properties getProperties() { return ConfigurationConverter.getProperties(properties); } public Object getProperty(String key) { return properties.getProperty(key); } // ..................... Delegated methods ............... public boolean containsKey(String key) { return properties.containsKey(key); } public boolean equals(Object obj) { return properties.equals(obj); } public Iterator getKeys() { return properties.getKeys(); } public Iterator getKeys(String prefix) { return properties.getKeys(prefix); } public int hashCode() { return properties.hashCode(); } public boolean isEmpty() { return properties.isEmpty(); } public void setProperty(String key, Object value) { properties.setProperty(key, value); } public Configuration subset(String prefix) { return properties.subset(prefix); } public String toString() { return properties.toString(); } // ..................... BigDecimal ...................... public BigDecimal getBigDecimal(String key) { return properties.getBigDecimal(key); } public BigDecimal getBigDecimal(String key, BigDecimal defaultValue) { return properties.getBigDecimal(key, defaultValue); } public BigDecimal getBigDecimal(String key, Filter filter) { BigDecimal value = getBigDecimal(key, filter, null); validateValue(key, value); return value; } public BigDecimal getBigDecimal(String key, Filter filter, BigDecimal defaultValue) { return (BigDecimal) getPropertyWithFilter(key, filter, BigDecimal.class, defaultValue); } // ..................... BigInteger ...................... public BigInteger getBigInteger(String key) { return properties.getBigInteger(key); } public BigInteger getBigInteger(String key, BigInteger defaultValue) { return properties.getBigInteger(key, defaultValue); } public BigInteger getBigInteger(String key, Filter filter) { BigInteger value = getBigInteger(key, filter, null); validateValue(key, value); return value; } public BigInteger getBigInteger(String key, Filter filter, BigInteger defaultValue) { return (BigInteger) getPropertyWithFilter(key, filter, BigInteger.class, defaultValue); } // ..................... Boolean ...................... public boolean getBoolean(String key) { return properties.getBoolean(key); } public boolean getBoolean(String key, boolean defaultValue) { return properties.getBoolean(key, defaultValue); } public Boolean getBoolean(String key, Boolean defaultValue) throws NoClassDefFoundError { return properties.getBoolean(key, defaultValue); } public boolean getBoolean(String key, Filter filter) { Boolean value = getBoolean(key, filter, null); validateValue(key, value); return value.booleanValue(); } public Boolean getBoolean(String key, Filter filter, Boolean defaultValue) throws NoClassDefFoundError { return (Boolean) getPropertyWithFilter(key, filter, Boolean.class, defaultValue); } public boolean getBoolean(String key, Filter filter, boolean defaultValue) { return getBoolean(key, filter, new Boolean(defaultValue)) .booleanValue(); } // ..................... Byte ...................... public byte getByte(String key) { return properties.getByte(key); } public byte getByte(String key, byte defaultValue) { return properties.getByte(key, defaultValue); } public Byte getByte(String key, Byte defaultValue) { return properties.getByte(key, defaultValue); } public byte getByte(String key, Filter filter) { Byte value = getByte(key, filter, null); validateValue(key, value); return value.byteValue(); } public Byte getByte(String key, Filter filter, Byte defaultValue) { return (Byte) getPropertyWithFilter(key, filter, Byte.class, defaultValue); } public byte getByte(String key, Filter filter, byte defaultValue) { return getByte(key, filter, new Byte(defaultValue)).byteValue(); } // ..................... Double ...................... public double getDouble(String key) { return properties.getDouble(key); } public double getDouble(String key, double defaultValue) { return properties.getDouble(key, defaultValue); } public Double getDouble(String key, Double defaultValue) { return properties.getDouble(key, defaultValue); } public double getDouble(String key, Filter filter) { Double value = getDouble(key, filter, null); validateValue(key, value); return value.doubleValue(); } public Double getDouble(String key, Filter filter, Double defaultValue) { return (Double) getPropertyWithFilter(key, filter, Double.class, defaultValue); } public double getDouble(String key, Filter filter, double defaultValue) { return getDouble(key, filter, new Double(defaultValue)).doubleValue(); } // ..................... Class ...................... /** * Get the Class representation of the class name specified * in the given property * * @throws ClassNotFoundException * if the specified class is not found */ public Class getClass(String key) throws ClassNotFoundException { String className = getString(key); return ClasspathUtil.locateClass(className); } /** * Get the Class representation of the class name specified * in the given property. Or the defaultValue if no value has * been given to the property. * * @throws ClassNotFoundException * if a class has been configured but it is not found */ public Class getClass(String key, Class defaultValue) throws ClassNotFoundException { String defaultStringValue = null; String className = getString(key, defaultStringValue); if (className == defaultStringValue) { return defaultValue; } return ClasspathUtil.locateClass(className); } /** * Similar to the previous methods but complementing the property key with * the given filter */ public Class getClass(String key, Filter filter) throws ClassNotFoundException { String className = getString(key, filter); return ClasspathUtil.locateClass(className); } /** * Equivalent to the previous method but giving a default value which will * be used if no value has been specified in the configurations file */ public Class getClass(String key, Filter filter, Class defaultValue) throws ClassNotFoundException { String defaultStringValue = null; String className = getString(key, filter, null); if (className == defaultStringValue) { return defaultValue; } return ClasspathUtil.locateClass(className); } // ..................... Class ...................... /** * Get an array of Class objects for the class names * specified in the given property * * @throws ClassNotFoundException * if the any of the configured classes is not found */ public Class[] getClassArray(String key) throws ClassNotFoundException { String[] classNames = getStringArray(key); return ClasspathUtil.locateClasses(classNames); } /** * Get an array of Class objects for the class names * specified in the given property. Or the defaultValue if no * value has been given to the property. * * @throws ClassNotFoundException * if the any of the configured classes is not found */ public Class[] getClassArray(String key, Class[] defaultValue) throws ClassNotFoundException { String[] defaultStringArrayValue = null; String[] classNames = getStringArray(key, defaultStringArrayValue); if (classNames == defaultStringArrayValue) { return defaultValue; } return ClasspathUtil.locateClasses(classNames); } /** * Similar to the previous methods but complementing the property key with * the given filter */ public Class[] getClassArray(String key, Filter filter) throws ClassNotFoundException { String[] classNames = getStringArray(key, filter); return ClasspathUtil.locateClasses(classNames); } /** * Equivalent to the previous method but giving a default value which will * be used if no value has been specified in the configurations file */ public Class[] getClassArray(String key, Filter filter, Class[] defaultValue) throws ClassNotFoundException { String[] defaultStringArrayValue = null; String[] classNames = getStringArray(key, filter, defaultStringArrayValue); if (classNames == defaultStringArrayValue) { return defaultValue; } return ClasspathUtil.locateClasses(classNames); } // ..................... Float ...................... public float getFloat(String key) { return properties.getFloat(key); } public float getFloat(String key, float defaultValue) { return properties.getFloat(key, defaultValue); } public Float getFloat(String key, Float defaultValue) { return properties.getFloat(key, defaultValue); } public float getFloat(String key, Filter filter) { Float value = getFloat(key, filter, null); validateValue(key, value); return value.floatValue(); } public Float getFloat(String key, Filter filter, Float defaultValue) { return (Float) getPropertyWithFilter(key, filter, Float.class, defaultValue); } public float getFloat(String key, Filter filter, float defaultValue) { return getFloat(key, filter, new Float(defaultValue)).floatValue(); } // ..................... Integer ...................... public int getInt(String key) { return properties.getInt(key); } public int getInt(String key, int defaultValue) { return properties.getInt(key, defaultValue); } public Integer getInteger(String key, Integer defaultValue) { return properties.getInteger(key, defaultValue); } public int getInt(String key, Filter filter) { Integer value = getInteger(key, filter, null); validateValue(key, value); return value.intValue(); } public Integer getInteger(String key, Filter filter, Integer defaultValue) { return (Integer) getPropertyWithFilter(key, filter, Integer.class, defaultValue); } public int getInt(String key, Filter filter, int defaultValue) { return getInteger(key, filter, new Integer(defaultValue)).intValue(); } // ..................... List ...................... public List getList(String key) { return properties.getList(key); } public List getList(String key, List defaultValue) { return properties.getList(key, defaultValue); } public List getList(String key, Filter filter) { List value = (List) getPropertyWithFilter(key, filter, List.class, null); validateValue(key, value); if (value == null) { value = EMPTY_LIST; } return value; } public List getList(String key, Filter filter, List defaultValue) { return (List) getPropertyWithFilter(key, filter, List.class, defaultValue); } // ..................... Long ...................... public long getLong(String key) { return properties.getLong(key); } public Long getLong(String key, Long defaultValue) { return properties.getLong(key, defaultValue); } public long getLong(String key, long defaultValue) { return properties.getLong(key, defaultValue); } public long getLong(String key, Filter filter) { Long value = getLong(key, filter, null); validateValue(key, value); return value.longValue(); } public Long getLong(String key, Filter filter, Long defaultValue) { return (Long) getPropertyWithFilter(key, filter, Long.class, defaultValue); } public long getLong(String key, Filter filter, long defaultValue) { return getLong(key, filter, new Long(defaultValue)).longValue(); } // ..................... Short ...................... public short getShort(String key) { return properties.getShort(key); } public Short getShort(String key, Short defaultValue) { return properties.getShort(key, defaultValue); } public short getShort(String key, short defaultValue) { return properties.getShort(key, defaultValue); } public short getShort(String key, Filter filter) { Short value = getShort(key, filter, null); validateValue(key, value); return value.shortValue(); } public Short getShort(String key, Filter filter, Short defaultValue) { return (Short) getPropertyWithFilter(key, filter, Short.class, defaultValue); } public short getShort(String key, Filter filter, short defaultValue) { return getShort(key, filter, new Short(defaultValue)).shortValue(); } // ..................... String ...................... /** * Get the String value of the given key. If it contains a list of values, * they will be serialized to a comma-separated format (use getList or * getStringArray if you want separated list items) */ public String getString(String key) { Object value = properties.getProperty(key); String result; if (value instanceof List) { result = listToString((List) value); } else { result = properties.getString(key); } return result; // return properties.getString(key); } public String getString(String key, String defaultValue) { return properties.getString(key, defaultValue); } public String getString(String key, Filter filter) { String value = getString(key, filter, null); validateValue(key, value); return value; } public String getString(String key, Filter filter, String defaultValue) { return (String) getPropertyWithFilter(key, filter, String.class, defaultValue); } // ..................... StringArray ...................... public String[] getStringArray(String key) { return properties.getStringArray(key); } public String[] getStringArray(String key, Filter filter) { List value = getList(key, filter); return (String[]) value.toArray(new String[0]); } public String[] getStringArray(String key, Filter filter, String[] defaultValue) { List defaultList = null; if (defaultValue != null) { defaultList = Arrays.asList(defaultValue); } List value = getList(key, filter, defaultList); if (value == null) { //This should never happen return null; } else { return (String[]) value.toArray(new String[0]); } } public String[] getStringArray(String key, String[] defaultValue) { List defaultList = null; if (defaultValue != null) { defaultList = Arrays.asList(defaultValue); } List value = getList(key, defaultList); if (value == null) { return null; } else { return (String[]) value.toArray(new String[0]); } } // ................. Control methods ..................... public boolean hasBaseConfiguration() { return properties.hasBaseConfiguration(); } /** * Get a list of the sources which have been loaded for this component */ public List getLoadedSources() { return properties.loadedSources(); } /** * Set the flag throwExceptionOnMissing. See the class documentation for * more details. */ public void setThrowExceptionOnMissing(boolean throwExceptionOnMissing) { properties.setThrowExceptionOnMissing(throwExceptionOnMissing); } public boolean isThrowExceptionOnMissing() { return properties.isThrowExceptionOnMissing(); } /** * Returned the configured delay period for this component or null if * reloading is not being performed */ public Long getDelayPeriod() { Long nullLong = null; return getLong(Conventions.RELOAD_DELAY_PROPERTY, nullLong); } public String getComponentName() { return properties.getComponentName(); } // ............. Helper methods ...................... protected Object getPropertyWithFilter(String key, Filter filter, Class theClass, Object defaultValue) { CompositeConfiguration filteredConf = properties; Object value = null; for (int i = filter.numOfSelectors(); (i >= 0) && (value == null); i--) { MapConfiguration varsConf = null; if (filter.hasVariables()) { varsConf = new MapConfiguration(filter.getVariables()); filteredConf = new CompositeConfiguration(); filteredConf.addConfiguration(varsConf); filteredConf.addConfiguration(properties); } value = getTypedPropertyWithDefault( key + filter.getFilterSuffix(i), theClass, filteredConf, null); if (varsConf != null) { properties.removeConfiguration(varsConf); } log.debug("Value for " + key + filter.getFilterSuffix(i) + "=" + value); } if (value == null) { value = defaultValue; } return value; } protected static Object getTypedPropertyWithDefault( String key, Class theClass, Configuration properties, Object defaultValue) { if (theClass.equals(Float.class)) { return properties.getFloat(key, (Float) defaultValue); } else if (theClass.equals(Integer.class)) { return properties.getInteger(key, (Integer) defaultValue); } else if (theClass.equals(String.class)) { return properties.getString(key, (String) defaultValue); } else if (theClass.equals(Double.class)) { return properties.getDouble(key, (Double) defaultValue); } else if (theClass.equals(Long.class)) { return properties.getLong(key, (Long) defaultValue); } else if (theClass.equals(Boolean.class)) { return properties.getBoolean(key, (Boolean) defaultValue); } else if (theClass.equals(List.class)) { return properties.getList(key, (List) defaultValue); } else if (theClass.equals(BigInteger.class)) { return properties.getBigInteger(key, (BigInteger) defaultValue); } else if (theClass.equals(BigDecimal.class)) { return properties.getBigDecimal(key, (BigDecimal) defaultValue); } else if (theClass.equals(Byte.class)) { return properties.getByte(key, (Byte) defaultValue); } else if (theClass.equals(Short.class)) { return properties.getShort(key, (Short) defaultValue); } throw new IllegalArgumentException("Class " + theClass + " is not" + "supported for properties"); } protected void validateValue(String key, Object value) { if ((value == null) && isThrowExceptionOnMissing()) { throw new NoSuchElementException("Property with key=" + key + " was not found"); } } protected String listToString(List list) { StringBuffer property = new StringBuffer(); Iterator it = list.iterator(); while (it.hasNext()) { property.append(String.valueOf(it.next())); if (it.hasNext()) { property.append(","); } } return property.toString(); } } easyconf-0.9.5/src/java/com/germinus/easyconf/ConfigurationObjectCache.java100644 0 0 5610 10337163174 24145 0ustar 0 0 /* * Copyright 2004-2005 Germinus XXI * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.germinus.easyconf; import java.net.URL; import org.apache.commons.configuration.reloading.InvariantReloadingStrategy; import org.apache.commons.configuration.reloading.ReloadingStrategy; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Holds a configuration object and reloads it when necessary * * @author Jorge Ferrer * @version $Revision: 1.4 $ * */ public class ConfigurationObjectCache { Object configurationObject; ReloadingStrategy reloadingStrategy = new InvariantReloadingStrategy(); Object reloadLock = new Object(); ConfigurationLoader loader = new ConfigurationLoader(); private static final Log log = LogFactory.getLog(ConfigurationObjectCache.class); private URL confFileUrl; private ComponentProperties properties; private String confName; public ConfigurationObjectCache(Object confObj, URL confFileUrl, ComponentProperties properties, String confName) { this.configurationObject = confObj; this.confFileUrl = confFileUrl; this.properties = properties; this.confName = confName; } public Object getConfigurationObject() { reload(); return configurationObject; } public String getConfName() { // if (confName == null) { // try { // confName = (String) BeanUtils.getSimpleProperty(configurationObject, "id"); // } catch (Exception e) { // confName = Conventions.DEFAULT_CONF_OBJECT_NAME; // } // } return confName; } private void reload() { if (confFileUrl == null) { return; } synchronized (reloadLock) { if (reloadingStrategy.reloadingRequired()) { try { configurationObject = loader.loadXMLFile(confFileUrl, properties); reloadingStrategy.reloadingPerformed(); } catch (Exception e) { log.error("Error loading " + confFileUrl, e); } } } } private ReloadingStrategy getReloadingStrategy() { return reloadingStrategy; } public void setReloadingStrategy(ReloadingStrategy strategy) { this.reloadingStrategy = strategy; } } easyconf-0.9.5/src/java/com/germinus/easyconf/ConfigurationSerializer.java100644 0 0 1337 10337163174 24126 0ustar 0 0 package com.germinus.easyconf; /** * Factory class which creates serializer subclasses based on * availability of external classes in the classpath * * @author Jorge Ferrer * */ public abstract class ConfigurationSerializer { public static ConfigurationSerializer getSerializer() { return new XstreamSerializer(); } /** * Deserialize the configuration object from a String * @param serializedConf * @return A configuration object */ public abstract Object deserialize(String serializedConf); /** * Serialize a configuration object to a String * @param configurationObject * @return An string representing the configuration object */ public abstract String serialize(Object configurationObject); } easyconf-0.9.5/src/java/com/germinus/easyconf/EasyConf.java100644 0 0 11614 10337163174 21013 0ustar 0 0 /* * Copyright 2004-2005 Germinus XXI * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.germinus.easyconf; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import java.util.HashMap; import java.util.Hashtable; import java.util.Map; /** * Main class to obtain the configuration of a software component. * * The main method is getConfiguration which must be * given the name of a component. * * @author jferrer@germinus.com */ public class EasyConf { private static final Log log = LogFactory.getLog(EasyConf.class); private static Map cache = new HashMap(); private EasyConf() { } /** * Get the full configuration of the given component. * * The configuration will be cached so that next calls will not need * to reload the properties or XML files again. * @param componentName any String which can be used to identified a * configuration component. * @return a ComponentConf instance */ public static ComponentConfiguration getConfiguration(String componentName) { try { ComponentConfiguration componentConf = (ComponentConfiguration) cache.get(componentName); if (componentConf == null) { componentConf = new ComponentConfiguration(componentName); cache.put(componentName, componentConf); } return componentConf; } catch (ConfigurationException e) { throw e; } catch (Exception e) { throw new ConfigurationException(componentName, "Error reading the configuration", e); } } /** * Get the full configuration of the given component, for the given company. * This method should be used when the application is to be deployed in * an ASP model where several companies want different configurations for * the same running applications * * * The configuration will be cached so that next calls will not need * to reload the properties or XML files again. * @param companyId the identifier of the company whose specific * configuration should be read * @param componentName any String which can be used to identified a * configuration component. * @return a ComponentConf instance */ public static ComponentConfiguration getConfiguration(String companyId, String componentName) { try { final String cacheKey = companyId + componentName; ComponentConfiguration componentConf = (ComponentConfiguration) cache.get(cacheKey); if (componentConf == null) { componentConf = new ComponentConfiguration(companyId, componentName); cache.put(cacheKey, componentConf); } return componentConf; } catch (ConfigurationException e) { throw e; } catch (Exception e) { throw new ConfigurationException(componentName, "Error reading the configuration for " + companyId, e); } } /** * Refresh the configuration of the given component * * KNOWN BUG: this method does not refresh the properties configuration because the underlying * library Jakarta Commons Configuration also contains a cache which is not refreshable. This * issue is scheduled to be solved after version 1.0 of such library. */ public static void refreshComponent(String componentName) { ComponentConfiguration componentConf = (ComponentConfiguration) cache.get(componentName); if (componentConf != null) { cache.remove(componentName); log.info("Refreshed the configuration of component " + componentName); } } /** * Refresh the configuration of all components * * KNOWN BUG: this method does not refresh the properties configuration because the underlying * library Jakarta Commons Configuration also contains a cache which is not refreshable. This * issue is scheduled to be solved after version 1.0 of such library. */ public static void refreshAll() { cache = new HashMap(); log.info("Refreshed the configuration of all components"); } // ************************** Deprecated methods *************************** } easyconf-0.9.5/src/java/com/germinus/easyconf/DatasourceURL.java100644 0 0 7416 10337163174 21746 0ustar 0 0 /* * Copyright 2004-2005 Germinus XXI * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.germinus.easyconf; import javax.naming.InitialContext; import javax.naming.NameNotFoundException; import javax.naming.NamingException; import javax.sql.DataSource; import org.apache.commons.configuration.DatabaseConfiguration; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Represents the URL to a datasource as specified in a properties file * @author Jorge Ferrer */ public class DatasourceURL { private static final Log log = LogFactory.getLog(DatasourceURL.class); private static final String DATASOURCE_PREFIX = Conventions.DATASOURCE_PREFIX; public static final String CONFIGURATION_OBJECTS_TABLE = Conventions.CONFIGURATION_OBJECTS_TABLE; public static final String PROPERTIES_TABLE = Conventions.PROPERTIES_TABLE; private static InitialContext ctx = null; private String dataSourceName; private String companyId; private String componentName; private String tableName; public DatasourceURL(String datasourcePath, String companyId, String componentName, String tableName) { this.dataSourceName = datasourcePath.substring(DATASOURCE_PREFIX.length()); this.companyId = companyId; this.componentName = componentName; this.tableName = tableName; } public DataSource getDatasource() { try { DataSource ds = null; String[] dsFinders = { "java:/comp/env/" + dataSourceName, dataSourceName, }; for (int i = 0; i < dsFinders.length; i++) { try { ds = (DataSource)getContext().lookup(dsFinders[i]); break; } catch (NameNotFoundException e) { if (log.isDebugEnabled()) { log.debug("Datasource " + dataSourceName + " not found", e); } } } if (ds == null) { throw new ConfigurationException("Cannot find datasource: " + dataSourceName); } return ds; } catch (NamingException e) { throw new ConfigurationException("Error loading datasource " + dataSourceName); } } private synchronized InitialContext getContext() throws NamingException { if (ctx == null) { ctx = new InitialContext(); } return ctx; } protected String getTableName() { return tableName; } protected String getComponentColumnName() { return "component"; } protected String getKeyColumnName() { return "key"; } protected String getValueColumnName() { return "value"; } public static boolean isDatasource(String fileName) { if (fileName == null) return false; return fileName.startsWith(DATASOURCE_PREFIX); } public DatabaseConfiguration getConfiguration() { return new DatabaseConfiguration(getDatasource(), getTableName(), getComponentColumnName(), getKeyColumnName(), getValueColumnName(), getCompanyComponentValue()); } private String getCompanyComponentValue() { if (companyId != null) { return companyId + ":" + componentName; } else { return componentName; } } } easyconf-0.9.5/src/java/com/germinus/easyconf/ConfUtil.java100644 0 0 2323 10337163174 21004 0ustar 0 0 /* * Copyright 2004-2005 Germinus XXI * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.germinus.easyconf; import org.apache.commons.configuration.Configuration; import java.util.Iterator; /** * Utility methods * * @author jferrer */ class ConfUtil { public static String toString(Configuration configuration) { Iterator it = configuration.getKeys(); StringBuffer result = new StringBuffer(); result.append("{"); while (it.hasNext()) { String key = (String) it.next(); result.append(key + "=" + configuration.getProperty(key)); result.append(", "); } result.append("}"); return result.toString(); } } easyconf-0.9.5/src/java/com/germinus/easyconf/InvalidPropertyException.java100644 0 0 2521 10337163174 24273 0ustar 0 0 /* * Copyright 2004-2005 Germinus XXI * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.germinus.easyconf; /** * Thrown when an XML configuration file contains a variable which either * is not of the form ${variableName} or is not * defined in any of the properties files associated with its component * * @author Jorge Ferrer * @version $Revision: 1.2 $ * */ public class InvalidPropertyException extends ConfigurationException { public InvalidPropertyException(String componentName, Throwable e) { super(componentName, e); } public String getMessage() { return super.getMessage() + ". A variable is either malformed or " + "makes a reference to " + "a property which is not defined for this component in " + "any of its configuration files."; } } easyconf-0.9.5/src/java/com/germinus/easyconf/AggregatedProperties.java100644 0 0 16730 10337163174 23417 0ustar 0 0 /* * Copyright 2004-2005 Germinus XXI * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.germinus.easyconf; import org.apache.commons.configuration.AbstractFileConfiguration; import org.apache.commons.configuration.CompositeConfiguration; import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.FileConfiguration; import org.apache.commons.configuration.JNDIConfiguration; import org.apache.commons.configuration.PropertiesConfiguration; import org.apache.commons.configuration.SubsetConfiguration; import org.apache.commons.configuration.SystemConfiguration; import org.apache.commons.configuration.reloading.FileChangedReloadingStrategy; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import java.net.URL; import java.util.*; /** * Provides configuration properties from several sources making distintion * from: * * It also knows the source the a property to offer user information. * * @author jferrer */ public class AggregatedProperties extends CompositeConfiguration { private static final Log log = LogFactory .getLog(AggregatedProperties.class); private CompositeConfiguration baseConf = new CompositeConfiguration(); private CompositeConfiguration globalConf = new CompositeConfiguration(); private SystemConfiguration systemConfiguration = new SystemConfiguration(); private Configuration prefixedSystemConfiguration = new SubsetConfiguration( systemConfiguration, getPrefix(), null); private String componentName; private String companyId; private List loadedSources = new ArrayList(); private boolean baseConfigurationLoaded = false; public AggregatedProperties(String companyId, String componentName) { this.componentName = componentName; this.companyId = companyId; } /** * Look for the property in environment, global and base configuration, in * this order * * @param key * @return */ public Object getProperty(String key) { Object value = null; if (value == null) { // value = prefixedSystemConfiguration.getProperty(key); value = System.getProperty(getPrefix() + key); } if (value == null) { value = globalConf.getProperty(getPrefix() + key); } if (value == null) { value = globalConf.getProperty(key); } if (value == null) { value = baseConf.getProperty(key); } if (value == null) { value = super.getProperty(key); } if (value == null) { // value = systemConfiguration.getProperty(key); value = System.getProperty(key); } if ((value == null) && (key.equals(Conventions.COMPANY_ID_PROPERTY))) { value = companyId; } if ((value == null) && (key.equals(Conventions.COMPONENT_NAME_PROPERTY))) { value = componentName; } return value; } private String getPrefix() { return componentName + Conventions.PREFIX_SEPARATOR; } public void addBaseFileName(String fileName) { Configuration conf = addPropertiesSource(fileName, baseConf); if ((conf != null) && (!conf.isEmpty())) { baseConfigurationLoaded = true; } } public void addGlobalFileName(String fileName) { addPropertiesSource(fileName, globalConf); } /** * Read the given source of properties and add it to the composite * configuration. The added configuration will be returned. If it is not * found null will be returned. */ private Configuration addPropertiesSource(String sourceName, CompositeConfiguration loadedConf) { try { Configuration newConf; if (DatasourceURL.isDatasource(sourceName)) { newConf = addDatasourceProperties(sourceName); } else if (JndiURL.isJndi(sourceName)) { newConf = addJndiProperties(sourceName); } else { newConf = addFileProperties(sourceName, loadedConf); } if (newConf != null) { loadedConf.addConfiguration(newConf); super.addConfiguration(newConf); if (newConf instanceof AbstractFileConfiguration) { loadedSources.add(((AbstractFileConfiguration) newConf) .getURL().toString()); } else { loadedSources.add(sourceName); } } return newConf; } catch (Exception ignore) { if (log.isDebugEnabled()) { log.debug("Configuration source " + sourceName + " ignored"); } return null; } } private Configuration addFileProperties(String fileName, CompositeConfiguration loadedConf) throws ConfigurationException { try { FileConfiguration newConf = new PropertiesConfiguration(fileName); URL fileURL = newConf.getURL(); log.debug("Adding file: " + fileURL); Long delay = getReloadDelay(loadedConf, newConf); if (delay != null) { FileChangedReloadingStrategy reloadingStrategy = new FileConfigurationChangedReloadingStrategy(); if (log.isDebugEnabled()) { log.debug("File " + fileURL + " will be reloaded every " + delay + " seconds"); } long milliseconds = delay.longValue() * 1000; reloadingStrategy.setRefreshDelay(milliseconds); newConf.setReloadingStrategy(reloadingStrategy); } addIncludedPropertiesSources(newConf, loadedConf); return newConf; } catch (org.apache.commons.configuration.ConfigurationException e) { if (log.isDebugEnabled()) { log.debug("Configuration source " + fileName + " ignored"); } return null; } } private Long getReloadDelay(CompositeConfiguration loadedConf, FileConfiguration newConf) { Long delay = newConf.getLong(Conventions.RELOAD_DELAY_PROPERTY, null); if (delay == null) { delay = loadedConf.getLong(Conventions.RELOAD_DELAY_PROPERTY, null); } return delay; } private Configuration addDatasourceProperties(String datasourcePath) { DatasourceURL dsUrl = new DatasourceURL(datasourcePath, companyId, componentName, DatasourceURL.PROPERTIES_TABLE); return dsUrl.getConfiguration(); } private Configuration addJndiProperties(String sourcePath) { JNDIConfiguration conf = null; JndiURL jndiUrl = new JndiURL(sourcePath, companyId, componentName); return jndiUrl.getConfiguration(); } private void addIncludedPropertiesSources(Configuration newConf, CompositeConfiguration loadedConf) { CompositeConfiguration tempConf = new CompositeConfiguration(); tempConf.addConfiguration(prefixedSystemConfiguration); tempConf.addConfiguration(newConf); tempConf.addConfiguration(systemConfiguration); tempConf.addProperty(Conventions.COMPANY_ID_PROPERTY, companyId); tempConf .addProperty(Conventions.COMPONENT_NAME_PROPERTY, componentName); String[] fileNames = tempConf .getStringArray(Conventions.INCLUDE_PROPERTY); for (int i = fileNames.length - 1; i >= 0; i--) { String iteratedFileName = fileNames[i]; addPropertiesSource(iteratedFileName, loadedConf); } } public List loadedSources() { return loadedSources; } public boolean hasBaseConfiguration() { return baseConfigurationLoaded; } public String getComponentName() { return componentName; } } easyconf-0.9.5/src/java/com/germinus/easyconf/ConfigurationLoader.java100644 0 0 20563 10337163174 23245 0ustar 0 0 /* * Copyright 2004-2005 Germinus XXI * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.germinus.easyconf; import org.apache.commons.configuration.DatabaseConfiguration; import org.apache.commons.digester.Digester; import org.apache.commons.digester.Substitutor; import org.apache.commons.digester.substitution.MultiVariableExpander; import org.apache.commons.digester.substitution.VariableSubstitutor; import org.apache.commons.digester.xmlrules.DigesterLoader; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.xml.sax.SAXException; import java.io.IOException; import java.io.FileNotFoundException; import java.net.URL; /** * Handles the actual reading of the configuration * * @author jferrer */ class ConfigurationLoader { private static final Log log = LogFactory.getLog(ConfigurationLoader.class); private static final ConfigurationSerializer serializer = ConfigurationSerializer.getSerializer(); public ComponentProperties readPropertiesConfiguration(String companyId, String componentName) { AggregatedProperties properties = new AggregatedProperties(companyId, componentName); // if (companyId != null) { // properties.addGlobalFileName(Conventions.GLOBAL_CONFIGURATION_FILE + Conventions.SLASH + companyId // + Conventions.PROPERTIES_EXTENSION); // } properties.addGlobalFileName(Conventions.GLOBAL_CONFIGURATION_FILE + Conventions.PROPERTIES_EXTENSION); // if (companyId != null) { // properties.addBaseFileName(componentName + Conventions.SLASH + companyId + // Conventions.PROPERTIES_EXTENSION); // } properties.addBaseFileName(componentName + Conventions.PROPERTIES_EXTENSION); log.info("Properties for " + componentName + " loaded from " + properties.loadedSources()); return new ComponentProperties(properties); } public ConfigurationObjectCache readConfigurationObject(String companyId, String componentName, String confName, ComponentProperties properties) throws IOException, SAXException { log.info("Reading the configuration object for " + componentName); ConfigurationObjectCache result = null; String inexistentSource = null; String sourceName = properties.getString(Conventions.CONFIGURATION_OBJECTS_SOURCE_PROPERTY, inexistentSource); if (sourceName == inexistentSource) { // ignore } else if (DatasourceURL.isDatasource(sourceName)) { result = readConfigurationObjectFromDatabase( companyId, componentName, confName, properties, sourceName); } else { throw new ConfigurationException("The specified value for " + "easyconf:configuration-object-source is not valid: " + sourceName); } if (result == null) { result = readConfigurationObjectFromXMLFile( companyId, componentName, confName, properties); } return result; } private ConfigurationObjectCache readConfigurationObjectFromDatabase(String companyId, String componentName, String confName, ComponentProperties properties, String sourceName) { ConfigurationObjectCache result; DatasourceURL dsURL = new DatasourceURL(sourceName, companyId, componentName, DatasourceURL.CONFIGURATION_OBJECTS_TABLE); String confObjXML = dsURL.getConfiguration(). getString(confName); if (confObjXML == null) return null; Object confObject = serializer.deserialize(confObjXML); result = new ConfigurationObjectCache(confObject, null, properties, confName); return result; } private ConfigurationObjectCache readConfigurationObjectFromXMLFile(String companyId, String componentName, String confName, ComponentProperties properties) throws FileNotFoundException, IOException, SAXException { ConfigurationObjectCache result; String confFileName = null; URL confFile = null; if (companyId != null) { confFileName = componentName + Conventions.SLASH + companyId + Conventions.XML_EXTENSION; confFile = ClasspathUtil.locateResource(null, confFileName); log.info("Loaded " + confFileName + ": " + confFile); } if (confFile == null) { if (confName == Conventions.DEFAULT_CONF_OBJECT_NAME) { confFileName = componentName + Conventions.XML_EXTENSION; } else { confFileName = componentName + Conventions.DOT + confName + Conventions.XML_EXTENSION; } confFile = ClasspathUtil.locateResource(null, confFileName); } if (confFile == null) { throw new FileNotFoundException("File " + confFileName + " not found"); } Object confObj = loadXMLFile(confFile, properties); result = new ConfigurationObjectCache(confObj, confFile, properties, confName); Long delay = properties.getDelayPeriod(); if (delay != null) { result.setReloadingStrategy( new FileURLChangedReloadingStrategy(confFile, delay.longValue())); } return result; } /** * Read an XML file and return an Object representation of its contents */ Object loadXMLFile(URL confFileUrl, ComponentProperties properties) throws IOException, SAXException { log.debug("Loading XML file: " + confFileUrl); String componentName = properties.getComponentName(); String rulesFileName = componentName + Conventions.DIGESTERRULES_EXTENSION; URL digesterRulesUrl = ClasspathUtil.locateResource(rulesFileName); if (digesterRulesUrl == null) { throw new DigesterRulesNotFoundException(componentName, rulesFileName); } Digester digester = DigesterLoader.createDigester(digesterRulesUrl); digester.setUseContextClassLoader(true); digester.setValidating(false); MultiVariableExpander expander = new MultiVariableExpander(); expander.addSource("$", properties.toMap()); Substitutor substitutor = new VariableSubstitutor(expander); digester.setSubstitutor(substitutor); try { Object confObj = digester.parse(confFileUrl.openStream()); log.info("Read configuration from " + confFileUrl); return confObj; } catch (IllegalArgumentException e) { //FIXME: it does not catch the exception throw new InvalidPropertyException(properties.getComponentName(), e); } } public void saveConfigurationObjectIntoDatabase(Object configurationObject, String companyId, String componentName, String confName, ComponentProperties properties) { log.info("Saving the configuration object into the database for " + componentName); String inexistentSource = null; String sourceName = properties.getString(Conventions.CONFIGURATION_OBJECTS_SOURCE_PROPERTY, inexistentSource); if (sourceName == inexistentSource) { throw new ConfigurationException("It is imposible to save the configuration object. " + "Please specify a valid datasource in property " + Conventions.CONFIGURATION_OBJECTS_SOURCE_PROPERTY); } else if (DatasourceURL.isDatasource(sourceName)) { DatasourceURL dsURL = new DatasourceURL(sourceName, companyId, componentName, DatasourceURL.CONFIGURATION_OBJECTS_TABLE); DatabaseConfiguration dbConf = dsURL .getConfiguration(); String xml = serializer.serialize(configurationObject); dbConf.setProperty(confName, xml); } else { throw new ConfigurationException("The specified value for " + "easyconf:configuration-object-source is not valid: " + sourceName); } } } easyconf-0.9.5/src/java/com/germinus/easyconf/ClassParameter.java100644 0 0 3520 10337163174 22167 0ustar 0 0 /* * Copyright 2004-2005 Germinus XXI * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.germinus.easyconf; import org.apache.commons.configuration.Configuration; import java.util.Properties; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Mtodos de utilidad para trabajar con parmetros de configuracin que representan * clases * Fecha: 09-jul-2004 -- 12:06:34 * @author Jess Jimez Rodrguez */ public class ClassParameter { private static final Log log = LogFactory.getLog(ClassParameter.class); public static Object getNewInstance(Configuration conf, String propertyName) throws ClassNotFoundException, IllegalAccessException, InstantiationException { String className = conf.getString(propertyName); log.info("Returning " + className + " class instance."); return ClasspathUtil.locateClass(className).newInstance(); } public static Object getNewInstance(Properties props, String propertyName) throws ClassNotFoundException, IllegalAccessException, InstantiationException { String className = props.getProperty(propertyName); log.info("Returning " + className + " class instance."); return ClasspathUtil.locateClass(className).newInstance(); } }easyconf-0.9.5/src/java/com/germinus/easyconf/ConfigurationNotFoundException.java100644 0 0 2714 10337163174 25430 0ustar 0 0 /* * Copyright 2004-2005 Germinus XXI * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.germinus.easyconf; /** * Thrown when the base properties file is not found and the getProperties * method is explicitly called in the configuration * * @author jferrer */ public class ConfigurationNotFoundException extends ConfigurationException { public ConfigurationNotFoundException(String componentName, String msg, Throwable thr) { super(componentName, msg, thr); } protected ConfigurationNotFoundException(String componentName) { super(componentName); } protected ConfigurationNotFoundException(String componentName, Throwable e) { super(componentName, e); } public ConfigurationNotFoundException(String componentName, String msg) { super(componentName, msg); } } easyconf-0.9.5/src/java/com/germinus/easyconf/ComponentConfiguration.java100644 0 0 14612 10337163174 23777 0ustar 0 0 /* * Copyright 2004-2005 Germinus XXI * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.germinus.easyconf; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.xml.sax.SAXException; import java.io.IOException; import java.util.HashMap; import java.util.Map; /** * Contains the configuration of an EasyConf component including properties * configuration and an object graph configuration. * * @author Jorge Ferrer * @version $Revision: 1.11 $ * */ public class ComponentConfiguration { private static final Log log = LogFactory.getLog(ComponentConfiguration.class); private ComponentProperties properties; private String componentName; private ConfigurationLoader confManager = new ConfigurationLoader(); private String companyId; private Map confObjectsCache = new HashMap(); public ComponentConfiguration(String componentName) { this(null, componentName); } public ComponentConfiguration(String companyId, String componentName) { this.companyId = companyId; this.componentName = componentName; } /** * Get the name of the component which is associated with this configuration */ public String getComponentName() { return componentName; } /** * Get an object which represents the default configuration of component * * The object is populated using the digester rules defined in the file * componentName.digesterRules.xml which must be found in the classpath (first it is * searched in the context of the current thread and then in the context of the system * classpath) * @throws ConfigurationException if the object graph cannot be read */ public Object getConfigurationObject() { return getConfigurationObject(Conventions.DEFAULT_CONF_OBJECT_NAME); } /** * Get an object which represents a named configuration of the component * * The object is populated using the digester rules defined in the file * componentName.digesterRules.xml which must be found in the classpath (first it is * searched in the context of the current thread and then in the context of the system * classpath) * @throws ConfigurationException if the object graph cannot be read */ public Object getConfigurationObject(String confName) { if (confObjectsCache.get(confName) == null) { try { ConfigurationObjectCache confObjectCache = getConfigurationManager(). readConfigurationObject(companyId, componentName, confName, getAvailableProperties()); log.debug("Obtained confObjectCache for " + confName + ": " + confObjectCache); log.debug("Its confObjectis " + confObjectCache.getConfigurationObject()); confObjectsCache.put(confName, confObjectCache); } catch (IOException e) { throw new ConfigurationException(componentName, "Error reading object configuration", e); } catch (SAXException e) { throw new ConfigurationException(componentName, "Error parsing the XML file", e); } } ConfigurationObjectCache confObject = (ConfigurationObjectCache) confObjectsCache.get(confName); return confObject.getConfigurationObject(); } /** * Update or create a new default configuration Object to a persistent storage. * * In order to make this method work it should be stablished a * configuration-objects-source to a database as explained in the docs. * If the source of configuration objects does not allow persistent storage * (which is the default) an exception will be thrown. * * @param obj */ public void saveConfigurationObject(Object configurationObject) { saveConfigurationObject(Conventions.DEFAULT_CONF_OBJECT_NAME, configurationObject); } /** * Update or create a new Object with the given name to a persistent storage. * * In order to make this method work it should be stablished a * configuration-objects-source to a database as explained in the docs. * If the source of configuration objects does not allow persistent storage * (which is the default) an exception will be thrown. * * @param obj */ public void saveConfigurationObject(String confName, Object configurationObject) { ConfigurationObjectCache newConfObject = new ConfigurationObjectCache(configurationObject, null, getAvailableProperties(), confName); getConfigurationManager().saveConfigurationObjectIntoDatabase(configurationObject, companyId, componentName, confName, getAvailableProperties()); confObjectsCache.put(confName, newConfObject); } private ConfigurationLoader getConfigurationManager() { return confManager; } /** * Get a typed map of the properties associated with this component */ public ComponentProperties getProperties() { ComponentProperties properties = getAvailableProperties(); if ((!properties.hasBaseConfiguration())){ String msg = "The base properties file was not found"; throw new ConfigurationNotFoundException(componentName, msg); } return properties; } private ComponentProperties getAvailableProperties() { if (properties != null) { return properties; } properties = getConfigurationManager(). readPropertiesConfiguration(companyId, componentName); return properties; } public boolean equals(Object obj) { if (!(obj instanceof ComponentConfiguration)) { return false; } if (this == obj) { return true; } ComponentConfiguration cconf = (ComponentConfiguration) obj; return componentName.equals(cconf.getComponentName()); } public int hashCode() { return componentName.hashCode(); } } easyconf-0.9.5/src/java/com/germinus/easyconf/DigesterRulesNotFoundException.java100644 0 0 2746 10337163174 25407 0ustar 0 0 /* * Copyright 2004-2005 Germinus XXI * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.germinus.easyconf; /** * Thrown when an XML configuration file for a requested component exists * but there is not a file which defines de digester rules which should be * used to parse it * * @author Jorge Ferrer * @version $Revision: 1.2 $ * */ public class DigesterRulesNotFoundException extends ConfigurationException { private String digesterRulesFileName; public DigesterRulesNotFoundException(String componentName, String digesterRulesFileName) { super(componentName); this.digesterRulesFileName = digesterRulesFileName; } public String getDigesterRulesFileName() { return digesterRulesFileName; } public String getMessage() { return super.getMessage() + ". There should be a file named " + digesterRulesFileName + " which should contain the digester rules " + "for parsing the XML file"; } } easyconf-0.9.5/src/java/com/germinus/easyconf/jmx/ComponentConfigurationDynamicMBean.java100644 0 0 32130 10337163174 27000 0ustar 0 0 /* * Copyright 2004-2005 Germinus XXI * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.germinus.easyconf.jmx; import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import javax.management.Attribute; import javax.management.AttributeList; import javax.management.AttributeNotFoundException; import javax.management.DynamicMBean; import javax.management.InvalidAttributeValueException; import javax.management.MBeanAttributeInfo; import javax.management.MBeanConstructorInfo; import javax.management.MBeanException; import javax.management.MBeanInfo; import javax.management.MBeanOperationInfo; import javax.management.MBeanParameterInfo; import javax.management.ReflectionException; import com.germinus.easyconf.ComponentConfiguration; import com.germinus.easyconf.ComponentProperties; import com.germinus.easyconf.EasyConf; /** * MBean wrapper for a ComponentConfiguration. View Source * * * @author Alvaro Gonz�lez * @version $Revision: 1.4 $ * */ public class ComponentConfigurationDynamicMBean implements DynamicMBean { /** * Name of the reloadConfiguration operation. Used when invoking * invoke method. */ public static final String RELOAD_OPERATION_NAME = "reloadConfiguration"; /** * Name of the newProperty operations. Used when invoking * invoke method. */ public static final String NEW_PROPERTY_OPERATION_NAME = "newProperty"; /** * Signature of the reloadConfiguration operation. Used when invoking * invoke method. */ public static final String[] RELOAD_OPERATION_SIGNATURE = new String[0]; /** * Signature of the newProperty operation with one parameter. * Used when invoking invoke method. */ public static final String[] NEW_PROPERTY_OPERATION_SIGNATURE_1 = new String[] { String.class.toString() }; /** * Signature of the newProperty operation with two parameters. * Used when invoking invoke method. */ public static final String[] NEW_PROPERTY_OPERATION_SIGNATURE_2 = new String[] {String.class.toString(), Object.class.toString() }; private static final String NEW_PROPERTY_OPERATION_DESCRIPTION_1 = "Add new property to the Configuration Component. " + "The Param is the property name. Must not" + " exists another property with the same name."; private static final String NEW_PROPERTY_OPERATION_DESCRIPTION_2 = NEW_PROPERTY_OPERATION_DESCRIPTION_1 + " The second param is the initial value of the new property"; private static final String RELOAD_OPERATION_DESCRIPTION = "Reloads the configuration"; private static final String CONSTRUCTOR_DESCRIPTION_1 = "Constructs new MBean with the configuration of the named Component"; private String componentName; private ComponentConfiguration componentConfiguration; private MBeanAttributeInfo[] attributesInfo; private Map modifiedProperties; private Map newPropeties; private MBeanOperationInfo[] operationInfo; private MBeanConstructorInfo[] constructorsInfo; /** * Create a MBean wraping some loaded ComponentConfiguration * @param component */ public ComponentConfigurationDynamicMBean (ComponentConfiguration component) { super(); this.componentName=component.getComponentName(); this.componentConfiguration=component; init(); } /** * Loads and wraps a ComponentConfiguration * @param componentName */ public ComponentConfigurationDynamicMBean(String componentName) { super(); this.componentName = componentName; this.componentConfiguration = EasyConf.getConfiguration(componentName); init(); } /** * Some initializations common to both constructors */ private void init(){ this.modifiedProperties = new HashMap(); this.newPropeties = new HashMap(); } /** * Obtains the component attributes from the ComponentCongiguration * * @see javax.management.DynamicMBean#getAttribute(java.lang.String) */ public Object getAttribute(String attributeName) throws AttributeNotFoundException, MBeanException, ReflectionException { ComponentProperties prop = componentConfiguration.getProperties(); if (modifiedProperties.containsKey(attributeName)) return modifiedProperties.get(attributeName); if (prop.containsKey(attributeName)) return prop.getProperty(attributeName); else if (newPropeties.containsKey(attributeName)) return newPropeties.get(attributeName); else throw new AttributeNotFoundException(attributeName); } /** * Sets an attribute * * @see javax.management.DynamicMBean#setAttribute(javax.management.Attribute) */ public void setAttribute(Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException { if (componentConfiguration.getProperties().containsKey( attribute.getName())) modifiedProperties.put(attribute.getName(), attribute.getValue()); else if (newPropeties.containsKey(attribute.getName())) newPropeties.put(attribute.getName(), attribute.getValue()); else throw new AttributeNotFoundException(attribute.getName()); } /** * List named attributes * * @see javax.management.DynamicMBean#getAttributes(java.lang.String[]) */ public AttributeList getAttributes(String[] attributesNames) { Set includedAttributeNames = new HashSet(); AttributeList attributeList = new AttributeList(); for (int i = 0; i < attributesNames.length; i++) { String attributeName = attributesNames[i]; if (!includedAttributeNames.contains(attributeName)) { includedAttributeNames.add(attributeName); try { Object value = getAttribute(attributeName); Attribute attribute = new Attribute(attributeName, value); attributeList.add(attribute); } catch (AttributeNotFoundException e) { // Ignoring attribute } catch (MBeanException e) { } catch (ReflectionException e) { } } } return attributeList; } /** * Set named attributes * * @see javax.management.DynamicMBean#setAttributes(javax.management.AttributeList) */ public AttributeList setAttributes(AttributeList attributes) { AttributeList modifieds = new AttributeList(); Iterator it = attributes.iterator(); while (it.hasNext()) { Attribute attribute = (Attribute) it.next(); try { setAttribute(attribute); modifieds.add(attribute); } catch (AttributeNotFoundException e) { } catch (InvalidAttributeValueException e) { } catch (MBeanException e) { } catch (ReflectionException e) { } } return modifieds; } /** * Invoke one of the operations exposed by the MBeanas. * This Operations could be one of: * * * @see javax.management.DynamicMBean#invoke(java.lang.String, * java.lang.Object[], java.lang.String[]) */ public Object invoke(String operationName, Object[] params, String[] signature) throws MBeanException, ReflectionException { if (operationName.equals(RELOAD_OPERATION_NAME)) { reloadConfiguration(); return null; } if (operationName.equals(NEW_PROPERTY_OPERATION_NAME)) { if (signature.length == 1) newProperty((String) params[0]); else if (signature.length == 2) newProperty((String) params[0], params[1]); else throw new MBeanException(new IllegalArgumentException( "Operation not found in MBEan: " + operationName + "(" + signature + ")")); return null; } throw new MBeanException(new IllegalArgumentException( "Operation not found in MBEan: " + operationName + "(" + signature + ")")); } // ***** Implementations of the MBean's operations *****// private void reloadConfiguration() { // System.out.println("Old Properties: "+componentConfiguration.getProperties().toMap()); EasyConf.refreshComponent(componentName); this.componentConfiguration = EasyConf.getConfiguration(componentName); // System.out.println("New Properties: "+componentConfiguration.getProperties().toMap()); } private void newProperty(String propertyName) throws MBeanException { newProperty(propertyName, null); } private void newProperty(String propertyName, Object value) throws MBeanException { ComponentProperties prop = componentConfiguration.getProperties(); if ((newPropeties.containsKey(propertyName)) || prop.containsKey(propertyName)) throw new MBeanException(new IllegalArgumentException( "Cannot add new propert whith name: " + propertyName + ". There is a property whith that name yet")); newPropeties.put(propertyName, value); } /** * Return the Information exposed by the MBean: Attributes, Operations, * Constructors and Notifications. * * @see javax.management.DynamicMBean#getMBeanInfo() */ public MBeanInfo getMBeanInfo() { return new MBeanInfo(this.getClass().toString(), "Easyconf component: " + this.componentName, getAttributeInfo(), getConsturctorsInfo(), getOperationInfo(), null); } /** * Constructs the info of the MBean's attributes. * * @return Array of MBeanAttributeInfo */ protected MBeanAttributeInfo[] getAttributeInfo() { if (attributesInfo == null) { ComponentProperties properties = componentConfiguration .getProperties(); List auxList = new ArrayList(); Iterator it = properties.getKeys(); while (it.hasNext()) { String propertyName = (String) it.next(); Object value = properties.getProperty(propertyName); String type = value.getClass().getName(); boolean isIs = value.getClass().equals(Boolean.class); MBeanAttributeInfo attributeInfo = new MBeanAttributeInfo( propertyName, type, "Easyconf " + componentName + " component property: " + propertyName, true, true, isIs); auxList.add(attributeInfo); this.attributesInfo = (MBeanAttributeInfo[]) auxList .toArray(new MBeanAttributeInfo[auxList.size()]); } } return this.attributesInfo; } /** * Constructs the info of the MBean's operations. * * @return Array of MBeanOperationInfo */ protected MBeanOperationInfo[] getOperationInfo() { if (operationInfo == null) { operationInfo = new MBeanOperationInfo[] { new MBeanOperationInfo(NEW_PROPERTY_OPERATION_NAME, NEW_PROPERTY_OPERATION_DESCRIPTION_1, // Parameters new MBeanParameterInfo[] { new MBeanParameterInfo( "propertyName", String.class.getName(), "Name of the new property") }, void.class .getName(), MBeanOperationInfo.ACTION), new MBeanOperationInfo( NEW_PROPERTY_OPERATION_NAME, NEW_PROPERTY_OPERATION_DESCRIPTION_2, // Parameters new MBeanParameterInfo[] { new MBeanParameterInfo("propertyName", String.class.getName(), "Name of the new property"), new MBeanParameterInfo("value", Object.class.getName(), "Initial value of the new property") }, void.class.getName(), MBeanOperationInfo.ACTION), new MBeanOperationInfo(RELOAD_OPERATION_NAME, RELOAD_OPERATION_DESCRIPTION, // Parameters new MBeanParameterInfo[] {}, void.class.getName(), MBeanOperationInfo.ACTION) }; } return operationInfo; } /** * Constructs an array of the MBean's constructors. * * @return Array of MBeanConstructorInfo */ protected MBeanConstructorInfo[] getConsturctorsInfo() { if (constructorsInfo == null) { Constructor constructor = null; try { constructor = this.getClass().getConstructor( new Class[] { String.class }); } catch (Exception e) { } constructorsInfo = new MBeanConstructorInfo[] { new MBeanConstructorInfo( CONSTRUCTOR_DESCRIPTION_1, constructor) }; } return constructorsInfo; } /** * Returns the ComponentConfiguration associated with this MBean. * * @return ComponentConfiguration. */ protected ComponentConfiguration getComponentConfiguration() { return componentConfiguration; } /** * @param componentConfiguration * The componentConfiguration to set. */ protected void setComponentConfiguration( ComponentConfiguration componentConfiguration) { this.componentConfiguration = componentConfiguration; } private boolean propertyExists(String property) { if (componentConfiguration.getProperties().containsKey(property)) return true; if (newPropeties.containsKey(property)) return true; return false; } } easyconf-0.9.5/src/java/com/germinus/easyconf/struts/RefreshConfigurationAction.java100644 0 0 3464 10337163174 26120 0ustar 0 0 /* * Copyright 2004-2005 Germinus XXI * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.germinus.easyconf.struts; import org.apache.struts.action.*; import org.apache.commons.lang.StringUtils; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.germinus.easyconf.EasyConf; /** * Refresh the configuration of a given component which uses EasyConf. If * no component is specified all components of the current JVM are refreshed. * @author jferrer */ public class RefreshConfigurationAction extends Action { private static final String SUCCESS = "SUCCESS"; public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest req, HttpServletResponse response) throws Exception { DynaActionForm dform = (DynaActionForm) form; if (dform != null) { String componentName = (String) dform.get("componentName"); if (StringUtils.isBlank(componentName)) { EasyConf.refreshAll(); } else { EasyConf.refreshComponent(componentName); } } else { EasyConf.refreshAll(); } return mapping.findForward(SUCCESS); } } easyconf-0.9.5/src/java/com/germinus/easyconf/ClasspathUtil.java100644 0 0 7422 10337163174 22046 0ustar 0 0 /* * Copyright 2004-2005 Germinus XXI * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.germinus.easyconf; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.commons.configuration.ConfigurationUtils; import java.net.URL; /** * Contains util methods to search in the classpath * * @author jferrer */ public class ClasspathUtil { private static final Log log = LogFactory.getLog(ClasspathUtil.class); /** * Return the Class object of the specified class name by searching the * current classpath and the system classpath. * * @param name the name of the class * * @return the Class instance */ public static Class locateClass(String name) throws ClassNotFoundException { Class foundClass = null; if (foundClass == null) { ClassLoader loader = Thread.currentThread().getContextClassLoader(); try { foundClass = loader.loadClass(name); log.debug("Class loaded from the context classpath (" + name + ")"); } catch (ClassNotFoundException ignore) { } } if (foundClass == null) { try { foundClass = ClassLoader.getSystemClassLoader().loadClass(name); log.debug("Class loaded from the system classpath (" + name + ")"); } catch (ClassNotFoundException ignore) { } } if (foundClass == null) { throw new ClassNotFoundException("Class " + name + " was not found " + "in context classpath nor system classpath"); } return foundClass; } /** * Return an array of Class objects for each of the class names specified. Each * class will be searched for using the locateClass method. * If any of the class names does not exist a ClassNotFoundException * will be thrown * * @param classNames the names of the classes to load * * @return the Class[] array */ public static Class[] locateClasses(String[] classNames) throws ClassNotFoundException { Class[] classes = new Class[classNames.length]; for (int i = 0; i < classes.length; i++) { classes[i] = locateClass(classNames[i]); } return classes; } /** * Return the location of the specified resource by searching the user home * directory, the current classpath and the system classpath. * * @param base the base path of the resource * @param name the name of the resource * * @return the location of the resource or null if it has not * been found */ public static URL locateResource(String base, String name) { return ConfigurationUtils.locate(base, name); } /** * Return the location of the specified resource by searching the user home * directory, the current classpath and the system classpath. * * @param name the name of the resource * * @return the location of the resource or null if it has not * been found */ public static URL locateResource(String name) { return ConfigurationUtils.locate(null, name); } } easyconf-0.9.5/src/java/overview.html100644 0 0 30020 10337163174 14747 0ustar 0 0 Documentation for easyconf The purpose of easyconf is to provide an easy to use and centralized library to configure software components from XML and properties configuration files. Easyconf simplifies the management of different configuration of an application in different environments (preproduction, production, etc. or for different deployments). The purpose of easyconf is to provide an easy to use and centralized library to access documentation. Its main features are:
  1. Support for both properties and XML files (or a mix of both)
  2. Support for changing the configuration for different environments and subprojects
  3. Support for accessing properties from JSP files
  4. Support for several configuration modules (called components) to allow different software components running in the same JVM to use separate configuration files.

Quick start

Easyconf consist of a central component (ConfReader) that returns the configuration of a given component. This class has a static method called getConfiguration which must be given the name of a component. The name of the component can be any String which can be used to identify it within easyconf.

Reading the configuration from Java

Following is an example of how to use this class:

ComponentConfiguration conf = ConfReader.getConfiguration("my-component");

The result is an object with the configuration of the given component. The component configuration contains a properties based configuration and a XML based configuration. Let's start with the first one. Note that we'll asume from now on that we'll be working with the configuration of a component called my-component.
The properties are read from a file named after the component name. In our example the properties would be read from the file my-component.properties (later you'll see that other files will also be read to allow a property value to be overridden in different environments). This simple convention hides the name of the file from the program code.
Once you have the ComponentConfiguration you can just read the property values which are automatically converted to integers, booleans, lists, etc. Following are two examples of how to read typed properties:
  List portlets = conf.getProperties().getList("static.portlets");
  boolean disable = conf.getProperties().getBoolean("registration.disable");
On the other hand the XML configuration can be converted to any object by filling a digester rules file. The XML configuration of the previous example will be read from a file named my-component.xml and its digester rules from my-component.digesterRules.xml. The XML parsing converts the configuration to a set of user defined object classes. For example imagine that we want to configure some databases specifying it's tables and types of tables. We define two classes: DatabaseConf and Table. Then we write the XML configuration in my-component.xml, for example:
<database>
  <tables>
    <table tableType="type1"/>
  </tables>
</database>

Next we write the Digester rules in my-component.digesterRules.xml:
<!DOCTYPE digester-rules PUBLIC
   "-//Jakarta Apache //DTD digester-rules XML V1.0//EN"
   "digester-rules.dtd">
<digester-rules>
  <pattern value="database">
    <object-create-rule classname="com.foo.bar.DatabaseConf"/>
    <pattern value="tables/table">
      <object-create-rule classname="com.foo.bar.Table"/>
      <set-properties-rule/>
      <set-next-rule methodname="addTable" paramtype="com.foo.bar.Table"/>
    </pattern>
  </pattern>
</digester-rules>
Finally, just one line of code is necesary to obtain the objects which have resulted from parsing the configuration. Easyconf calls the result an object graph because it returns one object which can contain other objects inside, which can contain even more objects, etc. Here is an example of code of retrieving and using the object graph of the previous XML configuration:
    DatabaseConf dbconf = (DatabaseConf) conf.getConfigurationObject();
    Table firstTable = dbconf.getTables().get(0);
    String tableType = firstTable.getTableType();

For more information about how to write the rules files check the digester xml rules documentation A variant of this example is using properties from the properties based configuration in the XML file. For example:

<database>
  <tables>
    <table tableType="${table.type1}"/>
  </tables>
</database>
Where table.type1 is defined in a properties file as:
table.type1=type1
This allows to change this value for different environments.

In a next section is a more detailed description of a component configurations.

Reading the configuration from a JSP page

EasyConf provides a taglib to make it very easy to read the configuration of a component from a JSP. It is limited to properties because that's what is most commonly needed in this situations. Herea is a self explaining example:
    <%@ taglib uri="/WEB-INF/tld/easyconf.tld" prefix="easyconf" %>

        <easyconf:property id="static_portlets"
                   component="xpression-ui"
                   property="static.portlets"
                   type="java.util.List"/>
        <logic:iterate id="item" name="static_portlets">
           <bean:write name="item"/>
        </logic:iterate>

        <easyconf:property id="registration_disabled"
                   component="my-component"
                   property="registration.disabled"/>
        <logic:equal name="registration_disabled" value="true">
           <bean:message key="registration.disabled"/>
        </logic:equal>
Los valores soportados en el parametro type son: java.util.List, java.lang.Integer , java.lang.String java.lang.Double, java.lang.Float, java.lang.Byte java.math.BigDecimal, java.lang.BigInteger, java.lang.Boolean java.lang.Short y java.lang.Long.

Structure of a component configuration

The configuration is an instance of ComponentConfiguration which is composed of:

XML based configuration

The XML configuration of a component is read using Digester from Jakarta and is converted to objects using the information of two files: The result of reading this configuration is a graph of regular Java objects (POJOs) which can be used without limitations by the software component. A nice additional feature of the XML based configuration is that the values of any of its elements or attributes can contain variables whose values are defined in the properties based configuration. The variable should be of the form ${variableName}. For example, the following XML fragment can be used:

<welcome-msg> Bienvenido a ${server.name} </welcome-msg>

As long as there is a property named server.name as explained next.

Properties based configuration

The properties configuration of a module is obtained from a composition of the following files:
  1. ${componentName}.properties
  2. global-configuration.properties
In case of collision the values of global-configuration.properties will override the ones in the specific properties file. Furthermore, any of this files can include other files which contain overridden values for any of its properties. This is done with a special property whose key is include-and-override. This property is multivaluated so that several files can be included. In case of collision of values among the included files the ones specified last will override the previous ones. A usual pattern is to include the following properties in global-configuration.properties:

include-and-override=global-configuration-env.properties include-and-override=global-configuration-prj.properties

Which allows any property in any component to be redefined for a especific environment and for a specific project. Note that if the specified file does not exist it will be ignored silently.

Access to system properties

EasyConf makes available all system properties as variables that can be used in the values of the properties files. For example, if the application is run using the following command:

java ......... -Dinstallation-dir=/opt/application

You can use the variable ${installation-dir} in a properties file. For example:

readme.file.path=${installation-dir}/README

Support for environment configuration

The support for environment configuration is based on the access to system properties and the special include-and-override property. Using a system property you can set the name of the current environment. For example:

java ......... -Dconfiguration-environment=production

Then in global-configuration.properties you can set the following property:

include-and-override=global-configuration-${configuration-environment}.properties

Which in the previous example will cause EasyConf to load the file global-configuration-production.properties. Using this pattern you can have an application EAR, WAR or JAR which contains the configuration for all the environments and then set a system property when running the application to select which configuration should be used. As usual, the referenced files that do not exist they will be silently ignored. If the JVM property is not defined no file will be loaded.

Properties format

The format of the properties files is the same as the standard Java properties with the following additions: For more information about the format of the properties read: Note that not all the funcionalities of Commons Configuration are available in easyconf, particularly the way to read XML as EasyConf provides a more powerful mechanism. easyconf-0.9.5/src/changelog.txt100644 0 0 202 10337163174 13721 0ustar 0 0 ## ## Description of changes ## This file is obsolete!! Changes to 0.5 - Renamed easyconf.ext.files as overriden-properties.fileseasyconf-0.9.5/src/webapp/examples/taglibs.jsp100644 0 0 1236 10337163174 16520 0ustar 0 0 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib uri="/WEB-INF/tld/easyconf.tld" prefix="easyconf" %>