diff --git a/config/alfresco/core-services-context.xml b/config/alfresco/core-services-context.xml index 09264d4250..16dc901e4b 100644 --- a/config/alfresco/core-services-context.xml +++ b/config/alfresco/core-services-context.xml @@ -129,76 +129,17 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + classpath*:alfresco/module/*/log4j.properties - - classpath*:alfresco/enterprise/*-log4j.properties - classpath*:alfresco/extension/*-log4j.properties diff --git a/source/java/org/alfresco/repo/admin/Log4JHierarchyInit.java b/source/java/org/alfresco/repo/admin/Log4JHierarchyInit.java index 67c795c3af..302998a02b 100644 --- a/source/java/org/alfresco/repo/admin/Log4JHierarchyInit.java +++ b/source/java/org/alfresco/repo/admin/Log4JHierarchyInit.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2007 Alfresco Software Limited. + * Copyright (C) 2005-2008 Alfresco Software Limited. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -15,205 +15,138 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * As a special exception to the terms and conditions of version 2.0 of - * the GPL, you may redistribute this Program in connection with Free/Libre - * and Open Source Software ("FLOSS") applications as described in Alfresco's - * FLOSS exception. You should have recieved a copy of the text describing - * the FLOSS exception, and it is also available here: + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: * http://www.alfresco.com/legal/licensing" */ package org.alfresco.repo.admin; -import java.io.BufferedInputStream; -import java.io.InputStream; +import java.lang.reflect.Method; +import java.net.URL; import java.util.ArrayList; -import java.util.Enumeration; import java.util.List; -import java.util.Properties; -import org.apache.log4j.jmx.HierarchyDynamicMBean; -import org.apache.log4j.Logger; -import org.apache.log4j.LogManager; -import org.apache.log4j.PropertyConfigurator; -import org.apache.log4j.spi.LoggerRepository; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.springframework.core.io.Resource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; - /** - * Initialises Log4j's HierarchyDynamicMBean (refer to core-services-context.xml) - * and any overriding log4.properties files. + * Initialises Log4j's HierarchyDynamicMBean (refer to core-services-context.xml) and any overriding log4.properties files. + * The actual implementation uses introspection to avoid any hard-coded references to Log4J classes. If Log4J is + * not present, this class will do nothing. *

- * Alfresco modules can provide their own log4j.properties file, - * which augments/overrides the global log4j.properties within - * the Alfresco webapp. Within the module's source tree, suppose - * you create:

- *      config/alfresco/module/{module.id}/log4j.properties
- * At deployment time, this log4j.properties file will be placed in:
- *      WEB-INF/classes/alfresco/module/{module.id}/log4j.properties
- * Where {module.id} is whatever value is set within the AMP's - * module.properties file. For details, see: - * Developing an Alfresco Module - *

- * For example, if {module.id} is "org.alfresco.module.avmCompare", then - * within your source code you'll have:

- *      config/alfresco/module/org.alfresco.module.avmCompare/log4j.properties
- * This would be deployed to:
- *      WEB-INF/classes/alfresco/module/org.alfresco.module.avmCompare/log4j.properties
- * By default the 'overriding_log4j_properties' property of the - * 'log4JHierarchyInit' bean within core-services-context.xml is:
- *      classpath*:alfresco/module/*/log4j.properties
- * Therefore, Log4JHierarchyInit will discover this supplimentary log4j.properties - * file, and merge it with the main log4j.file (WEB-INF/classes/log4j.properties). - * For example, the org.alfresco.module.avmCompare log4j.properties file might look like this: + * Alfresco modules can provide their own log4j.properties file, which augments/overrides the global log4j.properties + * within the Alfresco webapp. Within the module's source tree, suppose you create: *
- *    #-----------------------------------------------------------------------
- *    # webscript module log4j.properties
- *    #                                  
- *    #   NOTE                           
- *    #   ----
- *    #
- *    #      Log4j uses the following logging levels:
- *    #      debug,info,warn,error,fatal
- *    #
- *    #      To set the logging level of {fullClassName} to {loglevel},
- *    #      add a line to this file of the following form:
- *    #
- *    #               log4j.logger.{fullClassName}={loglevel}
- *    #
- *    #      For example, to make 'com.example.MyExample' produce 'debug'
- *    #      logs, add a line like this:
- *    #
- *    #               log4j.logger.com.example.MyExample=debug
- *    #
- *    #
- *    #   WARNING
- *    #   -------
- *    #       Log properties in this log4j.properties file override/augment
- *    #       those in the webapp's main log4j.properties.
- *    #
- *    #-----------------------------------------------------------------------
- *    
- *    log4j.logger.org.alfresco.module.avmCompare.AvmCompare=info
- *    
- * - * This system allows the author of any module to provide rich logging control - * without concern for corrupting the central log4j.properties file during - * AMP installation/deinstallation. For details, see: - * Module Management Tool + * config/alfresco/module/{module.id}/log4j.properties + * + * At deployment time, this log4j.properties file will be placed in: + *
+ *      WEB-INF/classes/alfresco/module/{module.id}/log4j.properties
+ * 
+ * Where {module.id} is whatever value is set within the AMP's module.properties file. For details, see: Developing an Alfresco Module + *

+ * For example, if {module.id} is "org.alfresco.module.avmCompare", then within your source code you'll have: + * + *

+ * config / alfresco / module / org.alfresco.module.avmCompare / log4j.properties
+ * 
+ * + * This would be deployed to: + *
+ * WEB - INF / classes / alfresco / module / org.alfresco.module.avmCompare / log4j.properties
+ * 
*/ public class Log4JHierarchyInit { - private HierarchyDynamicMBean log4jHierarchy; - private List extra_log4j_urls; - - public Log4JHierarchyInit() - { - extra_log4j_urls = new ArrayList(); - } + private static Log logger = LogFactory.getLog(Log4JHierarchyInit.class); + private List extraLog4jUrls; + public Log4JHierarchyInit() + { + extraLog4jUrls = new ArrayList(); + } /** - * Loads a set of augmenting/overriding log4j.properties files - * from locations specified via an array of 'spring_urls' - * (typically provided by a core-services-context.xml). - * - * This function supports Spring's syntax for retrieving - * multiple class path resources with the same name, - * via the "classpath*:" prefix. For details, see: - * PathMatchingResourcePatternResolver. - */ - public void setOverriding_log4j_properties(List spring_urls) + * Loads a set of augmenting/overriding log4j.properties files from locations specified via an array of Srping URLS. + *

+ * This function supports Spring's syntax for retrieving multiple class path resources with the same name, + * via the "classpath*:" prefix. For details, see: {@link PathMatchingResourcePatternResolver}. + */ + public void setExtraLog4jUrls(List urls) { - for ( String url : spring_urls ) { extra_log4j_urls.add( url ); } + for (String url : urls) + { + extraLog4jUrls.add(url); + } } - public void setLog4jHierarchy(HierarchyDynamicMBean log4jHierarchy) - { - this.log4jHierarchy = log4jHierarchy; - } - @SuppressWarnings("unchecked") public void init() { - // Add each logger (that has a level set) from - // the Log4J Repository to the Hierarchy MBean + importLogSettings(); + } - LoggerRepository r = LogManager.getLoggerRepository(); - - - // Include overriding loggers - // - // Typically, extra loggers come from AMP modules, but you - // could add others by augmenting core-services-context.xml - // This mechanism allows modules to have their own local - // log4j.properties file within: - // - // WEB-INF/classes/alfresco/module/{module.id}/log4j.properties - // - // Where: module.id is whatever value is set within the AMP's - // 'module.properties' file. - // - // See also: - // http://wiki.alfresco.com/wiki/Developing_an_Alfresco_Module - // (the module.properties section) - // - // And: - // core-services-context.xml - - set_overriding_loggers( r ); - - - Enumeration loggers = r.getCurrentLoggers(); - Logger logger = null; - - while (loggers.hasMoreElements()) + @SuppressWarnings("unchecked") + private void importLogSettings() + { + try { - logger = (Logger)loggers.nextElement(); - if (logger.getLevel() != null) + // Get the PropertyConfigurator + Class clazz = Class.forName("org.apache.log4j.PropertyConfigurator"); + Method method = clazz.getMethod("configure", URL.class); + // Import using this method + for (String url : extraLog4jUrls) { - log4jHierarchy.addLoggerMBean(logger.getName()); + importLogSettings(method, url); } } - } - - void set_overriding_loggers( LoggerRepository hierarchy ) - { - for ( String spring_url : extra_log4j_urls ) + catch (ClassNotFoundException e) { - set_overriding_logger( spring_url, hierarchy ); + // Log4J not present + return; } + catch (NoSuchMethodException e) + { + throw new RuntimeException("Unable to find method 'configure' on class 'org.apache.log4j.PropertyConfigurator'"); + } + } - void set_overriding_logger( String spring_url, - LoggerRepository hierarchy ) + private void importLogSettings(Method method, String springUrl) { - PathMatchingResourcePatternResolver resolver; - PropertyConfigurator prop_config; - - prop_config = new PropertyConfigurator(); - resolver = new PathMatchingResourcePatternResolver(); - - Resource[] resources = null; + PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); + Resource[] resources = null; try { - resources = resolver.getResources( spring_url ); + resources = resolver.getResources(springUrl); + } + catch (Exception e) + { + logger.warn("Failed to find additional Logger configuration: " + springUrl); } - catch (Exception e) { return ; } - // Read each resource - for (Resource resource : resources ) + for (Resource resource : resources) { try { - InputStream istream = new BufferedInputStream(resource.getInputStream()); - Properties properties = new Properties(); - properties.load(istream); - - prop_config.doConfigure(properties, hierarchy); + URL url = resource.getURL(); + method.invoke(null, url); + } + catch (Throwable e) + { + if (logger.isDebugEnabled()) + { + logger.debug("Failed to add extra Logger configuration: \n" + " URL: " + springUrl + "\n" + " Error: " + e.getMessage(), e); + } } - catch (Throwable e) { /* do nothing */ } } } } diff --git a/source/java/org/alfresco/repo/admin/Log4JHierarchyInitTest.java b/source/java/org/alfresco/repo/admin/Log4JHierarchyInitTest.java new file mode 100644 index 0000000000..81fb31620c --- /dev/null +++ b/source/java/org/alfresco/repo/admin/Log4JHierarchyInitTest.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2005-2008 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ +package org.alfresco.repo.admin; + +import junit.framework.TestCase; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +/** + * @see Log4JHierarchyInit + * + * @author Derek Hulley + * @since 2.2.3 + */ +public class Log4JHierarchyInitTest extends TestCase +{ + private static ApplicationContext ctx = new ClassPathXmlApplicationContext( + new String[] {"classpath:log4j/log4j-test-context.xml"} + ); + + public void setUp() throws Exception + { + } + + public void testSetUp() throws Throwable + { + // Check that the bean is present + ctx.getBean("log4JHierarchyInit"); + // Make sure that the default log4j.properties is being picked up + Log log = LogFactory.getLog("log4j.logger.org.alfresco"); + assertFalse("Expect log level ERROR for 'org.alfresco'.", log.isWarnEnabled()); + } + + public void testAddingLog4jProperties() throws Throwable + { + Log log = LogFactory.getLog(this.getClass()); + // We expect DEBUG to be on + assertTrue("DEBUG was not enabled for logger " + this.getClass(), log.isDebugEnabled()); + } +} diff --git a/source/java/org/alfresco/repo/jscript/ScriptUtils.java b/source/java/org/alfresco/repo/jscript/ScriptUtils.java index de917e6a6d..9b02368ddd 100644 --- a/source/java/org/alfresco/repo/jscript/ScriptUtils.java +++ b/source/java/org/alfresco/repo/jscript/ScriptUtils.java @@ -98,19 +98,6 @@ public final class ScriptUtils extends BaseScopableProcessorExtension return Boolean.parseBoolean(booleanString); } - /** - * Converts the specified Date object to an - * ISO 8601-formatted - * String. - * - * @param d date - * @return an ISO 8601-formatted date String. - */ - public String toISO8601(Date d) - { - return ISO8601DateFormat.format(d); - } - /** * Function to check if a module is installed * diff --git a/source/java/org/alfresco/repo/site/script/test_siteService.js b/source/java/org/alfresco/repo/site/script/test_siteService.js index b00c14ea2e..c6249220a7 100644 --- a/source/java/org/alfresco/repo/site/script/test_siteService.js +++ b/source/java/org/alfresco/repo/site/script/test_siteService.js @@ -61,20 +61,20 @@ function testMembership() var site = siteService.getSite("siteShortName"); test.assertNotNull(site); - var members = site.listMembers(null, null); + var members = site.listMembers(null, null, 0); test.assertNotNull(members); test.assertEquals(1, members.length); test.assertEquals("SiteManager", members["UserOne_SiteServiceImplTest"]); site.setMembership("UserTwo_SiteServiceImplTest", "SiteCollaborator"); - members = site.listMembers(null, null); + members = site.listMembers(null, null, 0); test.assertNotNull(members); test.assertEquals(2, members.length); test.assertEquals("SiteManager", members["UserOne_SiteServiceImplTest"]); test.assertEquals("SiteCollaborator", members["UserTwo_SiteServiceImplTest"]); site.removeMembership("UserTwo_SiteServiceImplTest"); - members = site.listMembers(null, null); + members = site.listMembers(null, null, 0); test.assertNotNull(members); test.assertEquals(1, members.length); test.assertEquals("SiteManager", members["UserOne_SiteServiceImplTest"]); diff --git a/source/test-resources/log4j/log4j-test-context.xml b/source/test-resources/log4j/log4j-test-context.xml new file mode 100644 index 0000000000..e753a4f07e --- /dev/null +++ b/source/test-resources/log4j/log4j-test-context.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + classpath*:log4j/log4j.properties + + + + + \ No newline at end of file diff --git a/source/test-resources/log4j/log4j.properties b/source/test-resources/log4j/log4j.properties new file mode 100644 index 0000000000..610d1e9e21 --- /dev/null +++ b/source/test-resources/log4j/log4j.properties @@ -0,0 +1,2 @@ +## Test to see that Log4J additions are picked up +log4j.logger.org.alfresco.repo.admin.Log4JHierarchyInitTest=DEBUG \ No newline at end of file