View Javadoc

1   /**
2    * This file Copyright (c) 2003-2010 Magnolia International
3    * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10   * This file is distributed in the hope that it will be
11   * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12   * implied warranty of MERCHANTABILITY or FITNESS FOR A
13   * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14   * Redistribution, except as permitted by whichever of the GPL
15   * or MNA you select, is prohibited.
16   *
17   * 1. For the GPL license (GPL), you can redistribute and/or
18   * modify this file under the terms of the GNU General
19   * Public License, Version 3, as published by the Free Software
20   * Foundation.  You should have received a copy of the GNU
21   * General Public License, Version 3 along with this program;
22   * if not, write to the Free Software Foundation, Inc., 51
23   * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24   *
25   * 2. For the Magnolia Network Agreement (MNA), this file
26   * and the accompanying materials are made available under the
27   * terms of the MNA which accompanies this distribution, and
28   * is available at http://www.magnolia-cms.com/mna.html
29   *
30   * Any modifications to this file must keep this entire header
31   * intact.
32   *
33   */
34  package info.magnolia.module.admininterface.pages;
35  
36  import info.magnolia.cms.beans.config.ContentRepository;
37  import info.magnolia.cms.core.HierarchyManager;
38  import info.magnolia.cms.core.SystemProperty;
39  import info.magnolia.cms.i18n.Messages;
40  import info.magnolia.cms.i18n.MessagesManager;
41  import info.magnolia.cms.security.AccessDeniedException;
42  import info.magnolia.cms.security.AccessManager;
43  import info.magnolia.cms.security.Permission;
44  import info.magnolia.context.MgnlContext;
45  import info.magnolia.importexport.DataTransporter;
46  import info.magnolia.module.admininterface.TemplatedMVCHandler;
47  import org.apache.commons.lang.StringUtils;
48  import org.slf4j.Logger;
49  import org.slf4j.LoggerFactory;
50  
51  import javax.jcr.Session;
52  import javax.jcr.Workspace;
53  import javax.servlet.ServletException;
54  import javax.servlet.http.HttpServletRequest;
55  import javax.servlet.http.HttpServletResponse;
56  import java.io.IOException;
57  import java.io.OutputStream;
58  import java.net.URLEncoder;
59  import java.util.Iterator;
60  
61  
62  /**
63   * Simple servlet used to import/export data from jcr using the standard jcr import/export features.
64   * @author Fabrizio Giustina
65   * @version $Id: ExportPage.java 32667 2010-03-13 00:37:06Z gjoseph $
66   */
67  public class ExportPage extends TemplatedMVCHandler {
68  
69      /**
70       * Stable serialVersionUID.
71       */
72      public static final long serialVersionUID = 222L;
73  
74      public static final String MIME_TEXT_XML = "text/xml";
75  
76      public static final String MIME_GZIP = "application/x-gzip";
77  
78      public static final String MIME_APPLICATION_ZIP = "application/zip";
79  
80      /**
81       * View value for the export file stream (won't render anything)
82       */
83      public static final String VIEW_EXPORT="export";
84      
85      /**
86       * Logger.
87       */
88      private static Logger log = LoggerFactory.getLogger(ExportPage.class);
89  
90      protected String mgnlRepository;
91  
92      protected String mgnlPath;
93  
94      protected boolean mgnlKeepVersions;
95  
96      private boolean mgnlFormat;
97  
98      private String ext;
99  
100     private boolean exportxml;
101 
102     /**
103      * Getter for <code>ext</code>.
104      * @return Returns the ext.
105      */
106     public String getExt() {
107         return this.ext;
108     }
109 
110     /**
111      * Setter for <code>ext</code>.
112      * @param ext The ext to set.
113      */
114     public void setExt(String ext) {
115         this.ext = ext;
116     }
117 
118     /**
119      * Getter for <code>mgnlFormat</code>.
120      * @return Returns the mgnlFormat.
121      */
122     public boolean isMgnlFormat() {
123         return this.mgnlFormat;
124     }
125 
126     /**
127      * Setter for <code>mgnlFormat</code>.
128      * @param mgnlFormat The mgnlFormat to set.
129      */
130     public void setMgnlFormat(boolean mgnlFormat) {
131         this.mgnlFormat = mgnlFormat;
132     }
133 
134     /**
135      * Getter for <code>mgnlKeepVersions</code>.
136      * @return Returns the mgnlKeepVersions.
137      */
138     public boolean isMgnlKeepVersions() {
139         return this.mgnlKeepVersions;
140     }
141 
142     /**
143      * Setter for <code>mgnlKeepVersions</code>.
144      * @param mgnlKeepVersions The mgnlKeepVersions to set.
145      */
146     public void setMgnlKeepVersions(boolean mgnlKeepVersions) {
147         this.mgnlKeepVersions = mgnlKeepVersions;
148     }
149 
150     /**
151      * Getter for <code>mgnlPath</code>.
152      * @return Returns the mgnlPath.
153      */
154     public String getMgnlPath() {
155         return this.mgnlPath;
156     }
157 
158     /**
159      * Setter for <code>mgnlPath</code>.
160      * @param mgnlPath The mgnlPath to set.
161      */
162     public void setMgnlPath(String mgnlPath) {
163         this.mgnlPath = mgnlPath;
164     }
165 
166     /**
167      * Getter for <code>mgnlRepository</code>.
168      * @return Returns the mgnlRepository.
169      */
170     public String getMgnlRepository() {
171         return this.mgnlRepository;
172     }
173 
174     /**
175      * Setter for <code>mgnlRepository</code>.
176      * @param mgnlRepository The mgnlRepository to set.
177      */
178     public void setMgnlRepository(String mgnlRepository) {
179         this.mgnlRepository = mgnlRepository;
180     }
181 
182     /**
183      * Getter for <code>exportxml</code>.
184      * @return Returns the exportxml.
185      */
186     public boolean isExportxml() {
187         return this.exportxml;
188     }
189 
190     /**
191      * Setter for <code>exportxml</code>.
192      * @param exportxml The exportxml to set.
193      */
194     public void setExportxml(boolean exportxml) {
195         this.exportxml = exportxml;
196     }
197 
198     /**
199      * @param name
200      * @param request
201      * @param response
202      */
203     public ExportPage(String name, HttpServletRequest request, HttpServletResponse response) {
204         super(name, request, response);
205     }
206 
207     /**
208      * @see info.magnolia.cms.servlets.MVCServletHandlerImpl#getCommand()
209      */
210     public String getCommand() {
211         if (this.exportxml) {
212             return "exportxml";
213         }
214         return super.getCommand();
215     }
216 
217     /**
218      * Actually perform export. The generated file is sent to the client.
219      * @param response HttpServletResponse
220      * @param repository selected repository
221      * @param basepath base path in repository
222      * @param format should we format the resulting xml
223      * @param keepVersionHistory if <code>false</code> version info will be stripped from the exported document
224      * @throws IOException for errors while accessing the servlet output stream
225      */
226     public String exportxml() throws Exception {
227 
228         if (StringUtils.isEmpty(mgnlRepository)) {
229             mgnlRepository = ContentRepository.WEBSITE;
230         }
231         if (StringUtils.isEmpty(mgnlPath)) {
232             mgnlPath = "/"; //$NON-NLS-1$
233         }
234         if (StringUtils.isEmpty(ext)) {
235             ext = DataTransporter.XML;
236         }
237 
238         if (!checkPermissions(request, mgnlRepository, mgnlPath, Permission.WRITE)) {
239 
240             throw new ServletException(new AccessDeniedException(
241                 "Write permission needed for export. User not allowed to WRITE path [" //$NON-NLS-1$
242                     + mgnlPath
243                     + "]")); //$NON-NLS-1$
244 
245         }
246         HierarchyManager hr = MgnlContext.getHierarchyManager(mgnlRepository);
247         Workspace ws = hr.getWorkspace();
248         Session session = ws.getSession();
249 
250         if (ext.equalsIgnoreCase(DataTransporter.ZIP)) {
251             response.setContentType(MIME_APPLICATION_ZIP);
252         }
253         else if (ext.equalsIgnoreCase(DataTransporter.GZ)) {
254             response.setContentType(MIME_GZIP);
255         }
256         else {
257             response.setContentType(MIME_TEXT_XML);
258             response.setCharacterEncoding("UTF-8"); //$NON-NLS-1$
259         }
260 
261         String pathName = StringUtils.replace(mgnlPath, DataTransporter.SLASH, DataTransporter.DOT); //$NON-NLS-1$ //$NON-NLS-2$
262         pathName = DataTransporter.encodePath(pathName, DataTransporter.DOT, DataTransporter.UTF8);
263         if (DataTransporter.DOT.equals(pathName)) { //$NON-NLS-1$
264             // root node
265             pathName = StringUtils.EMPTY; 
266         } 
267         
268         response.setHeader("content-disposition", "attachment; filename=" + mgnlRepository + pathName + ext); //$NON-NLS-1$ //$NON-NLS-2$
269         OutputStream baseOutputStream = response.getOutputStream();
270  
271         try {
272             DataTransporter.executeExport(
273                 baseOutputStream,
274                 mgnlKeepVersions,
275                 mgnlFormat,
276                 session,
277                 mgnlPath,
278                 mgnlRepository,
279                 ext);
280         }
281         catch (RuntimeException e) {
282             response.setContentType("text/html; charset=UTF-8");
283             response.setHeader("content-disposition", "inline"); //$NON-NLS-1$ //$NON-NLS-2$
284             throw e;
285         }
286 
287         return VIEW_EXPORT;
288     }
289 
290     /**
291      * Uses access manager to authorise this request.
292      * @param request HttpServletRequest as received by the service method
293      * @return boolean true if read access is granted
294      */
295     protected boolean checkPermissions(HttpServletRequest request, String repository, String basePath,
296         long permissionType) {
297 
298         AccessManager accessManager = MgnlContext.getAccessManager(repository);
299         if (accessManager != null) {
300             if (!accessManager.isGranted(basePath, permissionType)) {
301                 return false;
302             }
303         }
304         return true;
305     }
306     
307     public void renderHtml(String view) throws IOException {
308         // if we are exporing the file, everything is already done --> do not render
309         if(VIEW_EXPORT.equals(view)){
310             return;
311         }
312         super.renderHtml(view);
313     }
314 
315     public Messages getMessages() {
316         return MessagesManager.getMessages();
317     }
318 
319     public Iterator getRepositories() {
320         return ContentRepository.getAllRepositoryNames();
321     }
322 
323 }