001/* 002 * (C) Copyright 2006-2007 Nuxeo SAS (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * Nuxeo - initial API and implementation 016 * 017 * $Id$ 018 */ 019 020package org.nuxeo.ecm.platform.io.client; 021 022import java.io.IOException; 023import java.io.Serializable; 024import java.util.List; 025 026import javax.faces.context.FacesContext; 027import javax.servlet.ServletRequest; 028import javax.servlet.ServletResponse; 029import javax.servlet.http.HttpServletRequest; 030import javax.servlet.http.HttpServletResponse; 031 032import org.apache.commons.logging.Log; 033import org.apache.commons.logging.LogFactory; 034import org.jboss.seam.ScopeType; 035import org.jboss.seam.annotations.In; 036import org.jboss.seam.annotations.Name; 037import org.jboss.seam.annotations.Scope; 038import org.nuxeo.ecm.core.api.DocumentModel; 039import org.nuxeo.ecm.core.io.DocumentPipe; 040import org.nuxeo.ecm.core.io.DocumentReader; 041import org.nuxeo.ecm.core.io.DocumentWriter; 042import org.nuxeo.ecm.core.io.impl.DocumentPipeImpl; 043import org.nuxeo.ecm.core.io.impl.plugins.NuxeoArchiveWriter; 044import org.nuxeo.ecm.platform.io.selectionReader.DocumentModelListReader; 045import org.nuxeo.ecm.platform.ui.web.api.NavigationContext; 046import org.nuxeo.ecm.platform.ui.web.auth.NXAuthConstants; 047import org.nuxeo.ecm.platform.ui.web.util.BaseURL; 048import org.nuxeo.ecm.webapp.clipboard.ClipboardActions; 049 050@Name("importExportAction") 051@Scope(ScopeType.EVENT) 052public class ImportExportActionBean implements Serializable { 053 054 private static final String RESTLET_PREFIX = "restAPI"; 055 056 private static final Log log = LogFactory.getLog(ImportExportActionBean.class); 057 058 private static final long serialVersionUID = 1770386525984671333L; 059 060 @In(create = true) 061 protected transient NavigationContext navigationContext; 062 063 @In(create = true) 064 protected transient ClipboardActions clipboardActions; 065 066 private static StringBuffer getRestletBaseURL(DocumentModel doc) { 067 StringBuffer urlb = new StringBuffer(); 068 069 urlb.append(BaseURL.getBaseURL()); 070 urlb.append(RESTLET_PREFIX); 071 urlb.append('/'); 072 urlb.append(doc.getRepositoryName()); 073 urlb.append('/'); 074 urlb.append(doc.getRef().toString()); 075 urlb.append('/'); 076 return urlb; 077 } 078 079 private static HttpServletResponse getHttpServletResponse() { 080 ServletResponse response = null; 081 final FacesContext facesContext = FacesContext.getCurrentInstance(); 082 if (facesContext != null) { 083 response = (ServletResponse) facesContext.getExternalContext().getResponse(); 084 } 085 086 if (response != null && response instanceof HttpServletResponse) { 087 return (HttpServletResponse) response; 088 } 089 return null; 090 } 091 092 private static HttpServletRequest getHttpServletRequest() { 093 ServletRequest request = null; 094 final FacesContext facesContext = FacesContext.getCurrentInstance(); 095 if (facesContext != null) { 096 request = (ServletRequest) facesContext.getExternalContext().getRequest(); 097 } 098 099 if (request != null && request instanceof HttpServletRequest) { 100 return (HttpServletRequest) request; 101 } 102 return null; 103 } 104 105 private static void handleRedirect(HttpServletResponse response, String url) throws IOException { 106 response.resetBuffer(); 107 response.sendRedirect(url); 108 response.flushBuffer(); 109 getHttpServletRequest().setAttribute(NXAuthConstants.DISABLE_REDIRECT_REQUEST_KEY, true); 110 FacesContext.getCurrentInstance().responseComplete(); 111 } 112 113 public String doExportDocument() throws IOException { 114 HttpServletResponse response = getHttpServletResponse(); 115 if (response != null) { 116 handleRedirect(response, getDocumentExportURL()); 117 } 118 return null; 119 } 120 121 public String doExportFolder() throws IOException { 122 HttpServletResponse response = getHttpServletResponse(); 123 if (response != null) { 124 handleRedirect(response, getFolderExportURL()); 125 } 126 return null; 127 } 128 129 /** 130 * Returns the REST URL for export of given document. 131 * 132 * @since 5.4.2 133 * @param doc the document to export 134 * @param exportAsZip a boolean stating if export should be given in ZIP format. When exporting the tree, ZIP format 135 * is forced. 136 * @param exportAsTree a boolean stating if export should include the document children. 137 */ 138 public String getExportURL(DocumentModel doc, boolean exportAsZip, boolean exportAsTree) { 139 if (doc == null) { 140 return null; 141 } 142 StringBuffer urlb = getRestletBaseURL(doc); 143 if (exportAsTree) { 144 urlb.append("exportTree"); 145 } else { 146 if (exportAsZip) { 147 urlb.append("export?format=ZIP"); 148 } else { 149 urlb.append("export?format=XML"); 150 } 151 } 152 return urlb.toString(); 153 } 154 155 /** 156 * Generates URL to call export restlet on a leaf. 157 * 158 * @return export restlet URL 159 */ 160 public String getDocumentExportURL() { 161 return getExportURL(navigationContext.getCurrentDocument(), true, true); 162 } 163 164 /** 165 * Generates URL to call export restlet on a folder. 166 * 167 * @return export restlet URL 168 */ 169 public String getFolderExportURL() { 170 return getExportURL(navigationContext.getCurrentDocument(), true, true); 171 } 172 173 /** 174 * Returns the Rest URL for a document export in XML format 175 * 176 * @since 5.4.2 177 */ 178 public String getDocumentXMLExportURL() { 179 return getExportURL(navigationContext.getCurrentDocument(), false, false); 180 } 181 182 /** 183 * Returns the Rest URL for a document export in ZIP format 184 * 185 * @since 5.4.2 186 */ 187 public String getDocumentZIPExportURL() { 188 return getExportURL(navigationContext.getCurrentDocument(), true, false); 189 } 190 191 /** 192 * Returns the Rest URL for a document tree export in ZIP format 193 * 194 * @since 5.4.2 195 * @return 196 */ 197 public String getDocumentZIPTreeExportURL() { 198 return getExportURL(navigationContext.getCurrentDocument(), true, true); 199 } 200 201 public String exportCurrentList() { 202 List<DocumentModel> docList = clipboardActions.getCurrentSelectedList(); 203 if (docList != null) { 204 export(docList); 205 } 206 return null; 207 } 208 209 public static void export(List<DocumentModel> docList) { 210 HttpServletResponse response = getHttpServletResponse(); 211 if (response == null) { 212 return; 213 } 214 DocumentReader reader = null; 215 DocumentWriter writer = null; 216 try { 217 reader = new DocumentModelListReader(docList); 218 219 response.reset(); 220 writer = new NuxeoArchiveWriter(response.getOutputStream()); 221 222 DocumentPipe pipe = new DocumentPipeImpl(10); 223 pipe.setReader(reader); 224 pipe.setWriter(writer); 225 226 pipe.run(); 227 228 String filename = "export.zip"; 229 response.setHeader("Content-Disposition", "attachment; filename=\"" + filename + "\";"); 230 response.setHeader("Content-Type", "application/zip"); 231 FacesContext.getCurrentInstance().responseComplete(); 232 } catch (IOException e) { 233 log.error("Error during XML export " + e.getMessage()); 234 } finally { 235 if (reader != null) { 236 reader.close(); 237 } 238 if (writer != null) { 239 writer.close(); 240 } 241 } 242 } 243 244}