View Javadoc

1   /**
2    * This file Copyright (c) 2003-2011 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.i18n.Messages;
39  import info.magnolia.cms.i18n.MessagesManager;
40  import info.magnolia.cms.security.AccessDeniedException;
41  import info.magnolia.cms.security.AccessManager;
42  import info.magnolia.cms.security.Permission;
43  import info.magnolia.cms.util.AlertUtil;
44  import info.magnolia.context.MgnlContext;
45  import info.magnolia.importexport.DataTransporter;
46  import info.magnolia.module.admininterface.TemplatedMVCHandler;
47  
48  import org.apache.commons.lang.StringUtils;
49  import org.slf4j.Logger;
50  import org.slf4j.LoggerFactory;
51  
52  import javax.jcr.Session;
53  import javax.jcr.Workspace;
54  import javax.servlet.ServletException;
55  import javax.servlet.http.HttpServletRequest;
56  import javax.servlet.http.HttpServletResponse;
57  import java.io.IOException;
58  import java.io.OutputStream;
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 45868 2011-06-06 08:04:22Z ochytil $
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             AlertUtil.setMessage("Write permission needed for export. User not allowed to WRITE path [" + mgnlPath + "]");
241 
242             throw new ServletException(new AccessDeniedException(
243                 "Write permission needed for export. User not allowed to WRITE path [" //$NON-NLS-1$
244                     + mgnlPath
245                     + "]")); //$NON-NLS-1$
246         }
247         HierarchyManager hr = MgnlContext.getHierarchyManager(mgnlRepository);
248         Workspace ws = hr.getWorkspace();
249         Session session = ws.getSession();
250 
251         if (ext.equalsIgnoreCase(DataTransporter.ZIP)) {
252             response.setContentType(MIME_APPLICATION_ZIP);
253         }
254         else if (ext.equalsIgnoreCase(DataTransporter.GZ)) {
255             response.setContentType(MIME_GZIP);
256         }
257         else {
258             response.setContentType(MIME_TEXT_XML);
259             response.setCharacterEncoding("UTF-8"); //$NON-NLS-1$
260         }
261 
262         String pathName = StringUtils.replace(mgnlPath, DataTransporter.SLASH, DataTransporter.DOT); //$NON-NLS-1$ //$NON-NLS-2$
263         pathName = DataTransporter.encodePath(pathName, DataTransporter.DOT, DataTransporter.UTF8);
264         if (DataTransporter.DOT.equals(pathName)) { //$NON-NLS-1$
265             // root node
266             pathName = StringUtils.EMPTY; 
267         } 
268         
269         response.setHeader("content-disposition", "attachment; filename=" + mgnlRepository + pathName + ext); //$NON-NLS-1$ //$NON-NLS-2$
270         OutputStream baseOutputStream = response.getOutputStream();
271  
272         try {
273             DataTransporter.executeExport(
274                 baseOutputStream,
275                 mgnlKeepVersions,
276                 mgnlFormat,
277                 session,
278                 mgnlPath,
279                 mgnlRepository,
280                 ext);
281         }
282         catch (RuntimeException e) {
283             response.setContentType("text/html; charset=UTF-8");
284             response.setHeader("content-disposition", "inline"); //$NON-NLS-1$ //$NON-NLS-2$
285             throw e;
286         }
287 
288         return VIEW_EXPORT;
289     }
290 
291     /**
292      * Uses access manager to authorise this request.
293      * @param request HttpServletRequest as received by the service method
294      * @return boolean true if read access is granted
295      */
296     protected boolean checkPermissions(HttpServletRequest request, String repository, String basePath,
297         long permissionType) {
298 
299         AccessManager accessManager = MgnlContext.getAccessManager(repository);
300         if (accessManager != null) {
301             if (!accessManager.isGranted(basePath, permissionType)) {
302                 return false;
303             }
304         }
305         return true;
306     }
307     
308     public void renderHtml(String view) throws IOException {
309         // if we are exporing the file, everything is already done --> do not render
310         if(VIEW_EXPORT.equals(view)){
311             return;
312         }
313         super.renderHtml(view);
314     }
315 
316     public Messages getMessages() {
317         return MessagesManager.getMessages();
318     }
319 
320     public Iterator getRepositories() {
321         return ContentRepository.getAllRepositoryNames();
322     }
323 
324 }