You are viewing a plain text version of this content. The canonical link for it is here.
Posted to pluto-scm@portals.apache.org by dd...@apache.org on 2005/11/22 20:39:11 UTC

svn commit: r348225 - in /portals/pluto/trunk/pluto-util/src/main/java/org/apache/pluto/util/assemble: ./ Assembler.java AssemblerFactory.java file/ file/AbstractAssembler.java file/ArchivedFileAssembler.java file/ExplodedFileAssembler.java

Author: ddewolf
Date: Tue Nov 22 11:39:07 2005
New Revision: 348225

URL: http://svn.apache.org/viewcvs?rev=348225&view=rev
Log:
Adding missing assemble package

Added:
    portals/pluto/trunk/pluto-util/src/main/java/org/apache/pluto/util/assemble/
    portals/pluto/trunk/pluto-util/src/main/java/org/apache/pluto/util/assemble/Assembler.java
    portals/pluto/trunk/pluto-util/src/main/java/org/apache/pluto/util/assemble/AssemblerFactory.java
    portals/pluto/trunk/pluto-util/src/main/java/org/apache/pluto/util/assemble/file/
    portals/pluto/trunk/pluto-util/src/main/java/org/apache/pluto/util/assemble/file/AbstractAssembler.java
    portals/pluto/trunk/pluto-util/src/main/java/org/apache/pluto/util/assemble/file/ArchivedFileAssembler.java
    portals/pluto/trunk/pluto-util/src/main/java/org/apache/pluto/util/assemble/file/ExplodedFileAssembler.java

Added: portals/pluto/trunk/pluto-util/src/main/java/org/apache/pluto/util/assemble/Assembler.java
URL: http://svn.apache.org/viewcvs/portals/pluto/trunk/pluto-util/src/main/java/org/apache/pluto/util/assemble/Assembler.java?rev=348225&view=auto
==============================================================================
--- portals/pluto/trunk/pluto-util/src/main/java/org/apache/pluto/util/assemble/Assembler.java (added)
+++ portals/pluto/trunk/pluto-util/src/main/java/org/apache/pluto/util/assemble/Assembler.java Tue Nov 22 11:39:07 2005
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * 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.
+ */
+package org.apache.pluto.util.assemble;
+
+import java.io.IOException;
+
+/**
+ * Used to assemble a web application into a portlet application.
+ *
+ * @author <a href="ddewolf@apache.org">David H. DeWolf</a>
+ * @version 1.0
+ * @since Oct 15, 2004
+ */
+public interface Assembler {
+
+    String PORTLET_XML = "WEB-INF/portlet.xml";
+
+    String SERVLET_XML = "WEB-INF/web.xml";
+    
+    String DISPATCH_SERVLET_CLASS =
+        "org.apache.pluto.core.PortletServlet";
+
+    /**
+     * Assemble a web applicaiton into a portlet
+     * web application which is deployable into
+     * the pluto-1.1 portlet container.  The
+     * specified web application will be overwritten
+     * with the new application.
+     *
+     */
+    void assemble() throws IOException;
+
+}
+

Added: portals/pluto/trunk/pluto-util/src/main/java/org/apache/pluto/util/assemble/AssemblerFactory.java
URL: http://svn.apache.org/viewcvs/portals/pluto/trunk/pluto-util/src/main/java/org/apache/pluto/util/assemble/AssemblerFactory.java?rev=348225&view=auto
==============================================================================
--- portals/pluto/trunk/pluto-util/src/main/java/org/apache/pluto/util/assemble/AssemblerFactory.java (added)
+++ portals/pluto/trunk/pluto-util/src/main/java/org/apache/pluto/util/assemble/AssemblerFactory.java Tue Nov 22 11:39:07 2005
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * 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.
+ */
+package org.apache.pluto.util.assemble;
+
+import org.apache.pluto.util.assemble.file.ExplodedFileAssembler;
+import org.apache.pluto.util.assemble.Assembler;
+import org.apache.pluto.util.assemble.file.ArchivedFileAssembler;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.jar.JarFile;
+
+/**
+ * <B>TODO</B>: Document
+ * @author <a href="ddewolf@apache.org">David H. DeWolf</a>
+ * @version 1.0
+ * @since Nov 8, 2004
+ */
+public class AssemblerFactory {
+
+    private static AssemblerFactory factory;
+
+    private AssemblerFactory() {
+
+    }
+
+    public static AssemblerFactory getFactory() {
+        if(factory == null) {
+            factory = new AssemblerFactory();
+        }
+        return factory;
+    }
+
+    public Assembler createAssembler(File webapp, File destination) {
+        if(webapp.isDirectory()) {
+            return new ExplodedFileAssembler(webapp, destination);
+        }
+        else {
+            try {
+                JarFile war = new JarFile(webapp);
+                return new ArchivedFileAssembler(war, destination);
+            }
+            catch(IOException io) {
+                return null;
+            }
+        }
+
+    }
+}
+

Added: portals/pluto/trunk/pluto-util/src/main/java/org/apache/pluto/util/assemble/file/AbstractAssembler.java
URL: http://svn.apache.org/viewcvs/portals/pluto/trunk/pluto-util/src/main/java/org/apache/pluto/util/assemble/file/AbstractAssembler.java?rev=348225&view=auto
==============================================================================
--- portals/pluto/trunk/pluto-util/src/main/java/org/apache/pluto/util/assemble/file/AbstractAssembler.java (added)
+++ portals/pluto/trunk/pluto-util/src/main/java/org/apache/pluto/util/assemble/file/AbstractAssembler.java Tue Nov 22 11:39:07 2005
@@ -0,0 +1,262 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * 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.
+ */
+package org.apache.pluto.util.assemble.file;
+
+import org.apache.pluto.util.assemble.Assembler;
+import org.apache.pluto.descriptors.portlet.PortletAppDD;
+import org.apache.pluto.descriptors.portlet.PortletDD;
+import org.apache.pluto.descriptors.services.PortletAppDescriptorService;
+import org.apache.pluto.descriptors.services.castor.EntityResolverImpl;
+import org.apache.pluto.descriptors.services.castor.PortletAppDescriptorServiceImpl;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.*;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.*;
+
+/**
+ *
+ * @author <a href="ddewolf@apache.org">David H. DeWolf</a>
+ * @version 1.0
+ * @since Nov 8, 2004
+ */
+public abstract class AbstractAssembler implements Assembler {
+
+    private static final String PORTLET_XML = "WEB-INF/portlet.xml";
+
+    private static final String SERVLET_XML = "WEB-INF/web.xml";
+
+    private static final String[] CLASSES = new String[] { };
+
+    private Properties properties;
+
+    public AbstractAssembler() {
+        properties = new Properties();
+        properties.setProperty(OutputKeys.INDENT, "yes");
+        //properties.setProperty("{http://xml.apache.org/xslt}indent-amount", "4");
+    }
+
+    public void assemble() throws IOException {
+        InputStream servletIn = getWebResource(SERVLET_XML);
+        InputStream portletIn = getWebResource(PORTLET_XML);
+
+        Document xml = updateWebXML(servletIn, portletIn);
+        setWebResource(SERVLET_XML, xml);
+
+        InputStream in = null;
+        for(int i = 0;i<CLASSES.length;i++) {
+            in = getClass().getClassLoader().getResourceAsStream(CLASSES[i]);
+            setWebResource("WEB-INF/classes/"+CLASSES[i], in);
+        }
+
+        close();
+    }
+
+    protected abstract InputStream getWebResource(String resource)
+        throws IOException;
+
+    protected abstract void setWebResource(String name, InputStream in)
+        throws IOException;
+
+    protected abstract void setWebResource(String name, Document dom)
+    throws IOException;
+
+    protected abstract void close()
+        throws IOException;
+
+    protected void save(Document doc, OutputStream out)
+    throws IOException {
+        try {
+            TransformerFactory fact = TransformerFactory.newInstance();
+            Transformer trans = fact.newTransformer();
+            trans.setOutputProperties(properties);
+            trans.transform(new DOMSource(doc), new StreamResult(out));
+        } catch (TransformerConfigurationException e) {
+            e.printStackTrace();
+            throw new IOException(e.getMessage());
+        } catch (TransformerException e) {
+            e.printStackTrace();
+            throw new IOException(e.getMessage());
+        } finally {
+            out.flush();
+            out.close();
+        }
+    }
+
+    protected void save(InputStream in, OutputStream out)
+    throws IOException {
+        try {
+            int bytesRead = -1;
+            byte[] buffer = new byte[256];
+            while ((bytesRead = in.read(buffer)) != -1) {
+                out.write(buffer, 0, bytesRead);
+            }
+        }
+        finally {
+            out.flush();
+            out.close();
+        }
+    }
+
+    /**
+     * @todo currently we rely specifically on the castor implementation.
+     * @param servletIn
+     * @param portletIn
+     * @return
+     * @throws IOException
+     */
+    protected Document updateWebXML(InputStream servletIn, InputStream portletIn)
+    throws IOException {
+        PortletAppDescriptorService portletService =
+                new PortletAppDescriptorServiceImpl();
+
+        Document doc = parse(servletIn);
+
+        Collection servlets = new ArrayList();
+        Collection mappings = new ArrayList();
+
+        PortletAppDD portletAppDD = portletService.read(portletIn);
+        List portlets = portletAppDD.getPortlets();
+        for(int i=0;i<portlets.size();i++) {
+            PortletDD portlet = (PortletDD)portlets.get(i);
+            String name = portlet.getPortletName();
+            Element servlet = doc.createElement("servlet");
+
+            Element servletName = doc.createElement("servlet-name");
+            servletName.appendChild(doc.createTextNode(name));
+            servlet.appendChild(servletName);
+
+            Element servletClass = doc.createElement("servlet-class");
+            servletClass.appendChild(doc.createTextNode(DISPATCH_SERVLET_CLASS));
+            servlet.appendChild(servletClass);
+
+            Element initParam = doc.createElement("init-param");
+            Element paramName = doc.createElement("param-name");
+            paramName.appendChild(doc.createTextNode("portlet-name"));
+
+            Element paramValue = doc.createElement("param-value");
+            paramValue.appendChild(doc.createTextNode(name));
+
+            initParam.appendChild(paramName);
+            initParam.appendChild(paramValue);
+            servlet.appendChild(initParam);
+
+            Element load = doc.createElement("load-on-startup");
+            load.appendChild(doc.createTextNode("1"));
+            servlet.appendChild(load);
+
+            Element mapping = doc.createElement("servlet-mapping");
+            servletName = doc.createElement("servlet-name");
+            servletName.appendChild(doc.createTextNode(name));
+            Element uri = doc.createElement("url-pattern");
+            uri.appendChild(doc.createTextNode("/PlutoInvoker/"+name));
+            mapping.appendChild(servletName);
+            mapping.appendChild(uri);
+
+            servlets.add(servlet);
+            mappings.add(mapping);
+        }
+
+
+        Element webAppNode = doc.getDocumentElement();
+        NodeList nodes = webAppNode.getChildNodes();
+
+        // Find the first node that shouldn't be before the servlet
+        // and start appending.  This is kind of ugly, but the hack
+        // works for now!
+        for(int i=0;i<nodes.getLength();i++) {
+            Node node = nodes.item(i);
+            if(node.getNodeType() == Node.ELEMENT_NODE) {
+                if(!BEFORE_SERVLET_DEF.contains(node.getNodeName())) {
+                    Iterator it = servlets.iterator();
+                    while(it.hasNext()) {
+                        Node servlet = (Node)it.next();
+                        webAppNode.insertBefore(servlet, node);
+                        it.remove();
+                    }
+                }
+
+                if(!BEFORE_SERVLET_MAPPING_DEF.contains(node.getNodeName())) {
+                    Iterator it = mappings.iterator();
+                    while(it.hasNext()) {
+                        Node mapping = (Node)it.next();
+                        webAppNode.insertBefore(mapping, node);
+                        it.remove();
+                    }
+                }
+            }
+        }
+
+        // Now, in case there are not any nodes after the servlet def!
+        Iterator it = servlets.iterator();
+        while(it.hasNext()) {
+            webAppNode.appendChild((Node)it.next());
+        }
+
+        it = mappings.iterator();
+        while(it.hasNext()) {
+            webAppNode.appendChild((Node)it.next());
+        }
+
+        return doc;
+    }
+
+    private static final Collection BEFORE_SERVLET_DEF = new ArrayList();
+
+    private static final Collection BEFORE_SERVLET_MAPPING_DEF = new ArrayList();
+
+    static {
+        BEFORE_SERVLET_DEF.add("icon");
+        BEFORE_SERVLET_DEF.add("display-name");
+        BEFORE_SERVLET_DEF.add("description");
+        BEFORE_SERVLET_DEF.add("distributable");
+        BEFORE_SERVLET_DEF.add("context-param");
+        BEFORE_SERVLET_DEF.add("filter");
+        BEFORE_SERVLET_DEF.add("filter-mapping");
+        BEFORE_SERVLET_DEF.add("listener");
+
+        BEFORE_SERVLET_MAPPING_DEF.addAll(BEFORE_SERVLET_DEF);
+        BEFORE_SERVLET_MAPPING_DEF.add("servlet");
+    }
+
+    private Document parse(InputStream in)
+    throws IOException {
+        Document doc = null;
+        try {
+            DocumentBuilderFactory fact = DocumentBuilderFactory.newInstance();
+            DocumentBuilder builder = fact.newDocumentBuilder();
+            builder.setEntityResolver(new EntityResolverImpl());
+            doc = builder.parse(in);
+        } catch (ParserConfigurationException e) {
+            throw new IOException(e.getMessage());
+        } catch (SAXException e) {
+            throw new IOException(e.getMessage());
+        }
+        return doc;
+    }
+}
+

Added: portals/pluto/trunk/pluto-util/src/main/java/org/apache/pluto/util/assemble/file/ArchivedFileAssembler.java
URL: http://svn.apache.org/viewcvs/portals/pluto/trunk/pluto-util/src/main/java/org/apache/pluto/util/assemble/file/ArchivedFileAssembler.java?rev=348225&view=auto
==============================================================================
--- portals/pluto/trunk/pluto-util/src/main/java/org/apache/pluto/util/assemble/file/ArchivedFileAssembler.java (added)
+++ portals/pluto/trunk/pluto-util/src/main/java/org/apache/pluto/util/assemble/file/ArchivedFileAssembler.java Tue Nov 22 11:39:07 2005
@@ -0,0 +1,232 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * 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.
+ */
+package org.apache.pluto.util.assemble.file;
+
+import org.w3c.dom.Document;
+import org.apache.pluto.util.assemble.file.AbstractAssembler;
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.JarOutputStream;
+
+/**
+ * Used to assemble a web application into a portlet application.
+ *
+ * @todo Refactor to have a default constructor and act as a service
+ * @author <a href="mailto:ddewolf@apache.org">David H. DeWolf</a>
+ * @author <a href="mailto:heavyzheng@gmail.com">Zhong ZHENG</a>
+ * @version 1.0
+ * @since Oct 15, 2004
+ */
+public class ArchivedFileAssembler extends AbstractAssembler {
+
+    private static final int BUFFER_SIZE = 2048;
+
+    private JarFile war;
+    private File destination;
+
+    private Map documents = new HashMap();
+    private Map streams = new HashMap();
+
+
+    public ArchivedFileAssembler(JarFile war, File destination) {
+        this.war = war;
+        this.destination = destination;
+    }
+
+
+    protected InputStream getWebResource(String name)
+    throws IOException {
+        JarEntry entry = war.getJarEntry(name);
+        if(entry!=null) {
+            return war.getInputStream(entry);
+        }
+        return null;
+    }
+
+    protected void setWebResource(String name, InputStream in)
+    throws IOException {
+        streams.put(name, in);
+    }
+
+    protected void setWebResource(String name, Document doc)
+    throws IOException {
+    	documents.put(name, doc);
+    }
+
+
+    protected void close() throws IOException  {
+
+    	// ensure temporary directory (use system temporary dir).
+    	String tempDirName = System.getProperty("java.io.tmpdir");
+    	String tempName = destination.getName();
+    	int index = tempName.indexOf(".war");
+    	if (index != -1) {
+    		tempName = tempName.substring(0, index);
+    	}
+        File tempDir = new File(tempDirName + File.separator + tempName);
+        long tempId = 0;
+        while (tempDir.exists()) {
+        	tempDir = new File(tempDir + String.valueOf(tempId));
+        	tempId++;
+        }
+        tempDir.mkdirs();
+
+        // copy files from original WAR.
+        for (Enumeration en = war.entries(); en.hasMoreElements(); ) {
+            JarEntry entry = (JarEntry) en.nextElement();
+            if (entry.isDirectory()) {
+            	File dir = new File(tempDir, entry.getName());
+            	dir.mkdirs();
+            } else if (!documents.containsKey(entry.getName()) &&
+            		!streams.containsKey(entry.getName())) {
+                File destFile = new File(tempDir, entry.getName());
+                destFile.getParentFile().mkdirs();
+                FileOutputStream fout = new FileOutputStream(destFile);
+            	InputStream is = war.getInputStream(entry);
+            	save(is, fout);
+            }
+        }
+
+        // copy updated files.
+        for (Iterator it = documents.keySet().iterator(); it.hasNext(); ) {
+            String name = it.next().toString();
+            Document doc = (Document) documents.get(name);
+            File destFile = new File(tempDir, name);
+            destFile.getParentFile().mkdirs();
+            OutputStream out = new FileOutputStream(destFile);
+            save(doc, out);
+        }
+
+        for (Iterator it = streams.keySet().iterator(); it.hasNext(); ) {
+            String name = it.next().toString();
+            InputStream is = (InputStream) streams.get(name);
+            File destFile = new File(tempDir, name);
+            destFile.getParentFile().mkdirs();
+            OutputStream out = new FileOutputStream(destFile);
+            save(is, out);
+        }
+
+        // archive contents of the temporary directory to destination war.
+        archiveWar(tempDir, destination);
+        deleteRecursive(tempDir);
+    }
+
+    /**
+     * Archive the source directory to a WAR file.
+     *
+     * @param sourceDir  source directory to archive
+     * @param warFile  destination WAR file
+     * @throws IOException
+     */
+    private void archiveWar(File sourceDir, File warFile)
+    throws IOException {
+    	if (warFile.exists()) {
+    		deleteRecursive(warFile);
+    	}
+    	JarOutputStream jout = new JarOutputStream(new BufferedOutputStream(
+    			new FileOutputStream(warFile)));
+    	List fileList = listRecursive(sourceDir);
+    	String[] fileNames = (String[]) fileList.toArray(
+    			new String[fileList.size()]);
+
+    	byte[] data = new byte[BUFFER_SIZE];
+    	for (int i = 0; i < fileNames.length; i++) {
+    		File sourceFile = new File(sourceDir, fileNames[i]);
+    		if (sourceFile.isFile()) {
+    			// put a jar entry representing a regular file.
+    			JarEntry entry = new JarEntry(toJarEntryName(fileNames[i]));
+        		jout.putNextEntry(entry);
+    			BufferedInputStream is = new BufferedInputStream(
+    					new FileInputStream(sourceFile));
+    			int count;
+    			while ((count = is.read(data, 0, BUFFER_SIZE)) != -1) {
+    				jout.write(data, 0, count);
+    			}
+    			is.close();
+
+    		} else if (sourceFile.isDirectory()) {
+    			// put a jar entry representing a directory. Jar entries
+    			// whose names end with '/' are considered as directory.
+    			JarEntry entry = new JarEntry(
+    					toJarEntryName(fileNames[i]) + '/');
+        		jout.putNextEntry(entry);
+    		}
+    	}
+    	jout.close();
+    }
+
+    /**
+     * List all files under the given directory recursively. This method's
+     * behavior is different from <code>File.list()</code>: all files and
+     * subdirectories are listed recursively.
+     *
+     * @param dir  directory whose files are to be listed
+     * @return a list of String containing relative file paths to the directory
+     */
+    private List listRecursive(File dir) {
+    	return listRecursive(dir, "");
+    }
+
+
+    private List listRecursive(File dir, String prefix) {
+    	List fileNameList = new ArrayList();
+    	String[] fileNames = dir.list();
+    	for (int i = 0; i < fileNames.length; i++) {
+    		fileNameList.add(prefix + fileNames[i]);
+    		File file = new File(dir, fileNames[i]);
+    		if (file.isDirectory()) {
+    			String subDirName = file.getName();
+    			List subList = listRecursive(file,
+    					prefix + subDirName + File.separator);
+    			fileNameList.addAll(subList);
+    		}
+    	}
+    	return fileNameList;
+    }
+
+    /**
+     * Delete file. If given file is a regular file, it is deleted. If it is
+     * a directory, its all contents and itself are deleted recursively.
+     *
+     * @param file  file to delete
+     */
+    private void deleteRecursive(File file) {
+    	if (file.isDirectory()) {
+    		File[] files = file.listFiles();
+    		for (int i = 0; i < files.length; i++) {
+    			deleteRecursive(files[i]);
+    		}
+    	}
+    	file.delete();
+    }
+
+    /**
+     * Convert given file name to a valid jar entry name by replacing all '\\'
+     * characters to '/'.
+     *
+     * @param name  file name to convert
+     * @return valid jar entry name for the file name
+     */
+    private String toJarEntryName(String name) {
+    	return name.replaceAll("\\\\", "/");
+    }
+
+}
+
+

Added: portals/pluto/trunk/pluto-util/src/main/java/org/apache/pluto/util/assemble/file/ExplodedFileAssembler.java
URL: http://svn.apache.org/viewcvs/portals/pluto/trunk/pluto-util/src/main/java/org/apache/pluto/util/assemble/file/ExplodedFileAssembler.java?rev=348225&view=auto
==============================================================================
--- portals/pluto/trunk/pluto-util/src/main/java/org/apache/pluto/util/assemble/file/ExplodedFileAssembler.java (added)
+++ portals/pluto/trunk/pluto-util/src/main/java/org/apache/pluto/util/assemble/file/ExplodedFileAssembler.java Tue Nov 22 11:39:07 2005
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * 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.
+ */
+package org.apache.pluto.util.assemble.file;
+
+import org.w3c.dom.Document;
+import org.apache.pluto.util.assemble.file.AbstractAssembler;
+
+import java.io.*;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * Used to assemble a web application into a portlet application.
+ *
+ * @author <a href="ddewolf@apache.org">David H. DeWolf</a>
+ * @version 1.0
+ * @since Oct 15, 2004
+ */
+public class ExplodedFileAssembler extends AbstractAssembler {
+
+
+    private File source;
+    private File destination;
+
+    private Map documents = new java.util.HashMap();
+    private Map streams = new java.util.HashMap();
+
+    public ExplodedFileAssembler(File webapp) {
+        this(webapp, webapp);
+    }
+
+    public ExplodedFileAssembler(File webapp, File destination) {
+        this.source = webapp;
+        this.destination = destination;
+        destination.mkdirs();
+    }
+
+
+    protected InputStream getWebResource(String resource) throws IOException {
+        File file = new File(source, resource);
+        return new FileInputStream(file);
+    }
+
+    protected void setWebResource(String name, InputStream in)
+        throws IOException {
+        streams.put(name, in);
+    }
+
+    protected void setWebResource(String name, Document dom)
+        throws IOException {
+        documents.put(name, dom);
+    }
+
+    protected void close() throws IOException {
+        if(!source.equals(destination)) {
+            copyRecursive(source, destination);
+        }
+
+        Iterator it = documents.keySet().iterator();
+        while(it.hasNext()) {
+            String name = it.next().toString();
+            Document doc = (Document)documents.get(name);
+            File file = new File(destination, name);
+            file.getParentFile().mkdirs();
+            OutputStream out = new FileOutputStream(file);
+            save(doc, out);
+        }
+
+        it = streams.keySet().iterator();
+        while(it.hasNext()) {
+            String name = it.next().toString();
+            InputStream in = (InputStream) streams.get(name);
+            File file = new File(destination, name);
+            file.getParentFile().mkdirs();
+            OutputStream out = new FileOutputStream(file);
+            save(in, out);
+        }
+    }
+
+    private void copyRecursive(File source, File dest) throws IOException {
+        File[] files = source.listFiles();
+        for(int i=0;i<files.length;i++) {
+            File destFile = new File(dest, files[i].getName());
+            if(files[i].isDirectory()) {
+                copyRecursive(files[i], destFile);
+            }
+            else {
+                FileInputStream in = new FileInputStream(files[i]);
+                FileOutputStream out = new FileOutputStream(destFile);
+                save(in, out);
+            }
+        }
+    }
+}
+