Java tutorial
/******************************************************************************* * 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; } }