/* * Copyright (c) 2005-2011 Grameen Foundation USA * All rights reserved. * * 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. * * See also http://www.apache.org/licenses/LICENSE-2.0.html for an * explanation of the license and how it is applied. */ package org.mifos.reports; import java.io.File; import java.io.IOException; import java.net.URL; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import org.apache.commons.io.FileUtils; import org.eclipse.birt.report.listener.ViewerServletContextListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.io.Resource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.core.io.support.ResourcePatternResolver; /** * Servlet Context Listener for BIRT Resources. * * This copies classpath*:/birt/** (from inside the mifos-reporting-*.jar in the WAR) on start-up into a temporary * directory and sets the SYS_PROP_BIRT_ROOT_TEMP_DIR (mifos.birt.root.temp.dir) to that absolute location on the * filesystem, allowing BIRT to find it's *.rptdesign etc. via the same placeholder in web-fragment.xml. * * @see http://mifosforge.jira.com/browse/MIFOS-5089 * * @author Michael Vorburger */ public class MifosViewerServletContextListener extends ViewerServletContextListener { private static final Logger LOGGER = LoggerFactory.getLogger(MifosViewerServletContextListener.class); public static final String SYS_PROP_BIRT_ROOT_TEMP_DIR = "mifos.birt.root.temp.dir"; private static final String BIRT_RESOURCES_PATTERN = "/birt/"; private static final String LOCATION_PATTERN = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + BIRT_RESOURCES_PATTERN + "**"; /** * Sets the System Property IBirtConstants.SYS_PROP_ROOT_PATH to a temporary directory into which the *.rptdesign * files etc. are extracted into from the classpath, before invoking the parent ViewerServletContextListener's * {@link ViewerServletContextListener#contextInitialized(ServletContextEvent)}. * * @throws RuntimeException if BIRT_RESOURCES_PATTERN not found on Classpath */ @Override public void contextInitialized(ServletContextEvent event) { File birtRootDir = copyBIRTResourcesFromClassPathToFilesystemDirectory(event.getServletContext()); System.setProperty(SYS_PROP_BIRT_ROOT_TEMP_DIR, birtRootDir.getAbsolutePath()); LOGGER.info("System Property " + SYS_PROP_BIRT_ROOT_TEMP_DIR + " set to " + birtRootDir); super.contextInitialized(event); } /* package-local */ File copyBIRTResourcesFromClassPathToFilesystemDirectory(ServletContext servletContext) { File directory = new File(System.getProperty("java.io.tmpdir"), "MifosBirtFilesExtractedFromClasspath"); try { directory.mkdirs(); FileUtils.cleanDirectory(directory); copyFromClassPathToDirectory(BIRT_RESOURCES_PATTERN, directory); } catch (IOException e) { error(servletContext, "getResources(\"" + ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + BIRT_RESOURCES_PATTERN + "**\") failed: " + e.getMessage(), e); } return directory; } private void copyFromClassPathToDirectory(String directoryToScan, File rootDirectory) throws IOException { ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); Resource[] resources = resolver.getResources(LOCATION_PATTERN); LOGGER.info("Found " + resources.length + " Resources on " + LOCATION_PATTERN); for (Resource resource : resources) { if (resource.exists() & resource.isReadable() && resource.contentLength() > 0) { URL url = resource.getURL(); String urlString = url.toExternalForm(); String targetName = urlString.substring(urlString.indexOf(directoryToScan)); File destination = new File(rootDirectory, targetName); FileUtils.copyURLToFile(url, destination); LOGGER.info("Copied " + url + " to " + destination.getAbsolutePath()); } else { LOGGER.debug("Did not copy, seems to be directory: " + resource.getDescription()); } } } private void error(ServletContext servletContext, String msg, Exception e) throws RuntimeException { LOGGER.error(msg, e); if (servletContext != null) { servletContext.log(msg, e); } throw new RuntimeException(msg, e); } }