Package com.cfinkel.reports.web

Source Code of com.cfinkel.reports.web.AppData

package com.cfinkel.reports.web;

import com.cfinkel.reports.ReportSessionInfo;
import com.cfinkel.reports.exceptions.BadReportSyntaxException;
import com.cfinkel.reports.generatedbeans.ReportElement;
import com.cfinkel.reports.util.DirectoryIterator;
import com.cfinkel.reports.util.RunnerException;
import com.cfinkel.reports.util.RunnerForFile;
import com.cfinkel.reports.wrappers.Report;
import org.apache.log4j.Logger;
import org.springframework.jdbc.core.JdbcTemplate;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.sql.DataSource;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.sql.SQLException;
import java.util.*;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.regex.Pattern;

/**
* $Author: charles $
* $Revision: 8904 $
* $Date: 2006-05-01 18:02:06 -0400 (Mon, 01 May 2006) $
* <p/>
* Created by IntelliJ IDEA.
* User: charles
* Date: Apr 14, 2006
* Time: 1:41:10 AM
* <p/>
* Stores all app-scoped data:
* Lots of static data
*/
public class AppData {
    private static final Logger log = Logger.getLogger(AppData.class);

    /**
     * holds custom classes for QueryGenerator and PostQueryProcessor interfaces
     */
    private static URLClassLoader customClassLoader;
    static File classDirectory;
    static Unmarshaller reportUnmarshaller;
    static Context initContext;
    private static ServletContext context;

    public static ReentrantReadWriteLock getReportsLock() {
        return reportsLock;
    }

    static List<HttpSession> sessions = Collections.synchronizedList(new ArrayList<HttpSession>());

    private static final ReentrantReadWriteLock reportsLock = new ReentrantReadWriteLock();

    /**
     * all the datasources:
     */
    private static Map<String, DataSource> dataSources;
    //  must start with a slash:
    private static String reportsURL = "/report";
    private static File reportsDirectory;

    static {
        try {
            initContext = new InitialContext();
        } catch (NamingException e) {
            log.error("Error getting initial context", e);
            throw new RuntimeException(e);
        }
    }

    static JAXBContext getJAXBContext() {
        return jaxBContext;
    }

    static JAXBContext jaxBContext;


    /**
     * Data structure that holds all reports:
     */
    private static Map<String, Report> reports = Collections.synchronizedMap(new HashMap<String, Report>());


    static void setReportsDirectory(File reportsDirectory) {
        AppData.reportsDirectory = reportsDirectory;
    }

    static void setDataSources(Map<String, DataSource> dataSources) {
        AppData.dataSources = dataSources;
    }


    static void setCustomClassLoader(URLClassLoader customClassLoader) {
        AppData.customClassLoader = customClassLoader;

    }

    public static URLClassLoader getCustomClassLoader() {
        return customClassLoader;
    }


    public static Map<String, DataSource> getDataSources() {
        return dataSources;
    }

    public static DataSource addAndReturnDataSource(String datasource) throws NamingException, SQLException {

        String jndiPrefix = "java:comp/env/jdbc/" + datasource;

        DataSource ds = (DataSource) initContext.lookup(jndiPrefix);

        // runReport dummy query if not HSQL (probably should do if not other DB's as well)
        if (!ds.getConnection().getMetaData().getDriverName().equals("HSQL Database Engine Driver")) {
            JdbcTemplate jdbcTemplate = new JdbcTemplate(ds);
            jdbcTemplate.execute("select null from dual");
        }

        dataSources.put(datasource, ds);
        log.info("Added Datasource " + datasource);
        return ds;
    }

    public static String getReportsURL() {
        return reportsURL;
    }

    public static File getReportsDirectory() {
        return reportsDirectory;
    }

    public static Map<String, Report> getReports() {
        return reports;
    }

    static void loadAllClassFiles(File dir, final String baseDir) throws RunnerException {

        RunnerForFile runnerForFile = new RunnerForFile() {
            public void run(File file) throws RunnerException {
                try {
                    // convert to string:
                    String classString = file.toURI().toURL().toString();
                    // remove .class:
                    classString = classString.substring(0, classString.length() - 6);
                    // remove c:/etc:
                    classString = classString.substring(baseDir.length(), classString.length());
                    // convert / to .:
                    classString = classString.replaceAll("/", ".");

                    getCustomClassLoader().loadClass(classString);
                } catch (MalformedURLException e) {
                    throw new RunnerException("Malformed URL Exception", e);
                } catch (ClassNotFoundException e) {
                    throw new RunnerException("Class not found exception", e);
                }
            }
        };

        DirectoryIterator directoryIterator = new DirectoryIterator(Pattern.compile(".*\\.class"), runnerForFile);
        directoryIterator.iterateForDirectory(dir);

    }

    /**
     * updates custom classes
     */
    static void updateCustomClasses() {

        for (String reportPath : getReports().keySet()) {
            Report report = getReports().get(reportPath);
            try {
                report.updateCustomClasses();
            } catch (BadReportSyntaxException e) {
                log.error("Error updating class for report at path " + reportPath + ", unloading report from the app.");
                getReports().remove(reportPath);
            }
        }
    }

    static void reloadClasses() throws IOException, RunnerException {

        // call classloader to clear all references to old classes:
        URL[] classURLs = new URL[1];
        classURLs[0] = classDirectory.toURI().toURL();
        setCustomClassLoader(new URLClassLoader(classURLs, Thread.currentThread().getContextClassLoader()));

        loadAllClassFiles(classDirectory, classDirectory.toURI().toURL().toString());
    }


    /**
     * get all paths to reports
     *
     * @return list of paths to reports
     */
    public static List<String> getReportPaths() throws RunnerException {
        return getReportPaths(reportsDirectory);
    }

    private static List<String> getReportPaths(File dir) throws RunnerException {

        final List<String> reportPaths = new ArrayList<String>();

        RunnerForFile runnerForFile = new RunnerForFile() {
            public void run(File file) throws RunnerException {

                try {
                    // convert to string:
                    String xmlString = file.toURI().toURL().toString();
                    // remove .xml:
                    xmlString = xmlString.substring(0, xmlString.length() - 4);

                    // remove c:/etc:
                    xmlString = xmlString.substring(
                            reportsDirectory.toURI().toURL().toString().length() - 1,
                            xmlString.length());

                    reportPaths.add(xmlString);
                } catch (MalformedURLException e) {
                    throw new RunnerException("malformedURLException", e);
                }
            }
        };

        DirectoryIterator directoryIterator = new DirectoryIterator(Pattern.compile(".*\\.xml"), runnerForFile);
        directoryIterator.iterateForDirectory(dir);


        return reportPaths;
    }

    static void unloadReports() {
        getReports().clear();
    }

    public static void loadAllReports(OutputStream outputStream) throws IOException {

        List<String> reportPaths;
        try {
            reportPaths = getReportPaths();
            for (String reportPath : reportPaths) {
                loadReport(reportPath, outputStream);
            }
        } catch (RunnerException e) {
            log.error(e);
            outputStream.write(("Exception getting all report paths: " + e.getMessage() + "\n").getBytes());
        }
    }


    public static void loadReport(String reportPath, OutputStream outputStream) throws IOException {
        // first check ti see that this report isn't already here:
        if (reports.get(reportPath) != null) {
            String message = "Report at path " + reportPath + " is already loaded.\n";
            outputStream.write(message.getBytes());
            return;
        }

        try {
            ReportElement reportElement = (ReportElement) reportUnmarshaller.unmarshal
                    (new File(AppData.getReportsDirectory() + reportPath + ".xml"));
            Report report = new Report(reportElement, reportPath);
            reports.put(reportPath, report);
            String message = "Successfully loaded report at path " + reportPath + "\n\r";
            outputStream.write(message.getBytes());

        } catch (BadReportSyntaxException e) {
            String message = "Failed to load report at path '" + reportPath + "' with exception: " + e + "\n";
            log.info(message, e);
            outputStream.write(message.getBytes());
        } catch (JAXBException e) {
            String message = "Failed to load report at path '" + reportPath + "' with JAXB exception: " + e + "\n";
            log.info(message);
            outputStream.write(message.getBytes());
        }

    }

    public static void unloadReport(String reportPath, OutputStream outputStream) throws IOException {
        Report report = getReports().get(reportPath);
        if (report == null) {
            outputStream.write(("No report at '" + reportPath + "' is loaded.\n").getBytes());
        }

        // remove session data that attaches to this report:
        for (HttpSession session : sessions) {
            if (session.getAttribute(AttributeNames.reportSessionInfos) != null) {
                Map<String, ReportSessionInfo> reportSessionInfos =
                        (Map<String, ReportSessionInfo>) session.getAttribute(AttributeNames.reportSessionInfos);
                if (reportSessionInfos.get(reportPath) != null) {
                    reportSessionInfos.remove(reportPath);
                    outputStream.write(("Removed session data for this report for session id #"
                            + session.getId() + "\n").getBytes());
                }

            }
        }

        // remove report from app scope:
        getReports().remove(reportPath);

        outputStream.write(("Successfully unloaded report at " + reportPath + "\n").getBytes());

    }

    public static void clearSessionData(OutputStream outputStream) throws IOException {
        for (HttpSession session : sessions) {
            if (session.getAttribute(AttributeNames.reportSessionInfos) != null) {
                session.removeAttribute(AttributeNames.reportSessionInfos);
                outputStream.write(("Removed session info for session id #" + session.getId() + "\n").getBytes());
            }
        }
    }

    public static void reloadReport(String reportPath, OutputStream outputStream) throws IOException {
        unloadReport(reportPath, outputStream);
        loadReport(reportPath, outputStream);
    }

    public static void reloadLoadedReports(ByteArrayOutputStream outputStream) throws IOException {

        // clone report names:
        String[] reportPaths = reports.keySet().toArray(new String[0]).clone();

        for (String reportPath : reportPaths) {
            reloadReport(reportPath, outputStream);
        }

    }

    public static void setServletContext(ServletContext c) {
        context = c;
    }

    public static ServletContext getContext() {
        return context;
    }
}
TOP

Related Classes of com.cfinkel.reports.web.AppData

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.