eu.planets_project.pp.plato.action.TestDataLoaderImpl.java Source code

Java tutorial

Introduction

Here is the source code for eu.planets_project.pp.plato.action.TestDataLoaderImpl.java

Source

/*******************************************************************************
 * Copyright (c) 2006-2010 Vienna University of Technology, 
 * Department of Software Technology and Interactive Systems
 *
 * All rights reserved. This program and the accompanying
 * materials are made available under the terms of the
 * Apache License, Version 2.0 which accompanies
 * this distribution, and is available at
 * http://www.apache.org/licenses/LICENSE-2.0 
 *******************************************************************************/

package eu.planets_project.pp.plato.action;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import javax.ejb.Remove;
import javax.ejb.Stateful;
import javax.faces.application.FacesMessage;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.apache.commons.logging.Log;
import org.jboss.annotation.ejb.cache.Cache;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Destroy;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.RaiseEvent;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.faces.FacesMessages;
import org.xml.sax.SAXException;

import eu.planets_project.pp.plato.action.interfaces.IProjectImport;
import eu.planets_project.pp.plato.action.project.LoadPlanAction;
import eu.planets_project.pp.plato.bean.PrepareChangesForPersist;
import eu.planets_project.pp.plato.model.Plan;
import eu.planets_project.pp.plato.model.PlanProperties;
import eu.planets_project.pp.plato.model.User;
import eu.planets_project.pp.plato.util.PlatoLogger;
import eu.planets_project.pp.plato.xml.ProjectImporter;

/**
 * This class inserts test data into the persistence layer, including import of
 * objective trees from case studies.
 *
 * TODO why not application scope or request scope?
 * it's only used once and wouldn't need to stay in the session.
 *
 * @author Christoph Becker
 */
@Stateful
@Scope(ScopeType.SESSION)
@Name("testDataLoader")
@Cache(org.jboss.ejb3.cache.NoPassivationCache.class)
public class TestDataLoaderImpl implements Serializable, TestDataLoader {

    private static final long serialVersionUID = 2155152208617526555L;

    private static final Log log = PlatoLogger.getLogger(TestDataLoaderImpl.class);

    /**
     * pointing to the server-side directory (within the plato.ear deployment)
     * containing exported XML planning projects that shall be imported automatically.
     * @see #importAutoloadPlans()
     */
    public static final String AUTOLOAD_DIRECTORY_NAME = "data/projects/autoload/";
    public static final String DEMOPLANS_DIRECTORY_NAME = "data/projects/demos/";

    public static final String PUBLIC_TEMPLATES_DIRECTORY_NAME = "data/templates/public_templates/";

    public static final String PUBLIC_FRAGMENTS_DIRECTORY_NAME = "data/templates/public_fragments/";

    @PersistenceContext(unitName = "platoDatabase")
    EntityManager em;

    @In(create = true)
    private IProjectImport projectImport;

    /**
     * This method iterates through the directory defined in {@link #AUTOLOAD_DIRECTORY_NAME}
     * and imports all projects contained in the XML files that are in this directory.
     * @see ProjectImporter
     * @see ProjectImporter#importProjects(InputStream)
     * @see JarFileIterator
     */
    public String importAutoloadPlans() {

        log.info("TestDataLoaderImpl starts");
        try {
            List<String> files = listFiles(AUTOLOAD_DIRECTORY_NAME, ".xml");

            for (String xmlFileName : files) {

                if (xmlFileName.startsWith(AUTOLOAD_DIRECTORY_NAME) && xmlFileName.endsWith(".xml")) {
                    log.info("Adding Case Study XML " + xmlFileName + ".");
                    InputStream in = Thread.currentThread().getContextClassLoader()
                            .getResourceAsStream(xmlFileName);
                    ProjectImporter projectImporter = new ProjectImporter();
                    try {
                        for (Plan plan : projectImporter.importProjects(in)) {

                            em.persist(plan);
                            em.flush();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    } catch (SAXException e) {
                        e.printStackTrace();
                    }
                }
            }

        } catch (IOException e1) {
            log.error("Unable to open JAR file for case study import.", e1);
        }
        return "success";

    }

    /**
     *  Lists all files in a certain directory and with specific extension, e.g. list all files in directory data/project/autoload
     *  with extension .xml. The method can handle both, files in .jar archives and plain ones.
     *  
     *  This method has been introduced to be able to handle both, directories in .jar archives and plain directories. We need to be 
     *  able to handle both, zipped and exploded archives, i.e. plato.ear zipped or exploded.
     *  
     *  @param directory directory that shall be browsed
     *  @param fileExtension filter by file extension, e.g. ".xml", ".mm" 
     *  
     *  @return files in the directory
     */
    private List<String> listFiles(String directory, String fileExtension)
            throws MalformedURLException, IOException {

        URL url = Thread.currentThread().getContextClassLoader().getResource(directory);
        File dir = new File(url.getFile());
        String directoryPath = dir.getAbsolutePath();

        List<String> files = new ArrayList<String>();

        if (directoryPath.indexOf(".jar!") != -1) {
            URL urlJar = new URL(
                    directoryPath.substring(directoryPath.indexOf("file:"), directoryPath.indexOf('!')));

            Enumeration<JarEntry> entries = new JarFile(urlJar.getFile()).entries();

            while (entries.hasMoreElements()) {
                String fileName = entries.nextElement().getName();

                fileName = fileName.replace('\\', '/');

                if (fileName.startsWith(directory) && fileName.endsWith(fileExtension)) {
                    files.add(fileName);
                }
            }

        } else {
            File[] fileArray = dir.listFiles();

            for (int i = 0; fileArray != null && i < fileArray.length; i++) {
                String fileName = fileArray[i].getAbsolutePath();

                fileName = fileName.replace('\\', '/');

                int dirStart = fileName.indexOf(directory);

                if (dirStart != -1 && fileName.endsWith(fileExtension)) {
                    files.add(fileName.substring(dirStart));
                }
            }
        }
        return files;
    }

    private void insertTemplateTree(String directory) {

        /** dont forget to prepare changed entities e.g. set current user */
        PrepareChangesForPersist prep = new PrepareChangesForPersist("admin");

        List<String> files = new ArrayList<String>();

        try {
            files = listFiles(directory, ".xml");
        } catch (MalformedURLException e1) {
            FacesMessages.instance().add(FacesMessage.SEVERITY_ERROR, "Template library couldn't be populated. ");
            return;
        } catch (IOException e1) {
            FacesMessages.instance().add(FacesMessage.SEVERITY_ERROR, "Template library couldn't be populated. ");
            return;
        }

        for (String filename : files) {

            try {
                log.info("Inserting templates from " + filename);
                InputStream istream = Thread.currentThread().getContextClassLoader().getResourceAsStream(filename);

                ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
                byte[] bytes = new byte[512];

                int readBytes;
                while ((readBytes = istream.read(bytes)) > 0) {
                    out.write(bytes, 0, readBytes);
                }

                byte[] data = out.toByteArray();

                istream.close();
                out.close();

                projectImport.storeTemplatesInLibrary(data);
            } catch (IOException e) {
                log.error("Failed to insert templates: " + e.getMessage());
                FacesMessages.instance().add(FacesMessage.SEVERITY_ERROR,
                        "Template library couldn't be populated. ");
                return;
            } catch (SAXException e) {
                log.error("Failed to insert templates: " + e.getMessage());
                FacesMessages.instance().add(FacesMessage.SEVERITY_ERROR,
                        "Template library couldn't be populated. ");
                return;
            }
        }
    }

    public String insertTemplateTree() {

        insertTemplateTree(PUBLIC_FRAGMENTS_DIRECTORY_NAME);
        insertTemplateTree(PUBLIC_TEMPLATES_DIRECTORY_NAME);

        return "success";
    }

    @Remove
    @Destroy
    public void destroy() {

    }

    @In(create = true)
    private LoadPlanAction loadPlan;

    @In(required = false)
    private User user;

    /**
     * This convenience function is accessible at the end of the project list screen.
     * It creates a demo project, based on the XML file <code>Demo_Project__Preservation_Plan_for_Papers.xml</code>,
     * sets it to private and sets the current user as the owner.
     * Also slightly changes the name and description to
     * reflect the fact that it is meant to be a demo project.
     * The user can then do whatever she wants to that project.
     */
    @RaiseEvent("projectListChanged")
    public String createDemoProject(String type) {
        try {

            List<String> files = listFiles(DEMOPLANS_DIRECTORY_NAME, ".xml");

            for (String xmlFileName : files) {
                if (xmlFileName.startsWith(DEMOPLANS_DIRECTORY_NAME) && xmlFileName.endsWith(type + ".xml")) {
                    log.info("Adding DEMO PLAN " + xmlFileName + " for user " + user.getUsername() + ".");
                    InputStream in = Thread.currentThread().getContextClassLoader()
                            .getResourceAsStream(xmlFileName);
                    ProjectImporter projectImporter = new ProjectImporter();
                    try {
                        for (Plan plan : projectImporter.importProjects(in)) {
                            PlanProperties pp = plan.getPlanProperties();
                            // We set the current user as the owner of the project.
                            if (user == null) {
                                log.error("user is null! why?");
                            } else {
                                pp.setOwner(user.getUsername());
                            }
                            pp.setName("MY DEMO PLAN: " + pp.getName());
                            pp.setDescription("This is a DEMO plan for the user '" + user.getUsername() + "'. "
                                    + pp.getDescription());
                            pp.setPrivateProject(true);

                            /*
                            for (Trigger trigger : project
                                .getProjectBasis().getTriggers()
                                .keySet()) {
                            em.persist(em.merge(trigger));
                            }
                            */
                            em.persist(plan);
                            em.flush();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    } catch (SAXException e) {
                        e.printStackTrace();
                    }

                }
            }

        } catch (IOException e1) {
            log.error("Unable to open JAR file for case study import.", e1);
        }
        loadPlan.listMyProjects();
        FacesMessages.instance().add("Your demo plan has been created. Please load it from the list below.");
        return null;
    }
}