001/* 002 * (C) Copyright 2006-2008 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Thierry Delprat 018 * Florent Guillaume 019 * 020 * $Id: ExportRestlet.java 30251 2008-02-18 19:17:33Z fguillaume $ 021 */ 022 023package org.nuxeo.ecm.platform.ui.web.restAPI; 024 025import java.io.IOException; 026import java.io.OutputStream; 027import java.io.Serializable; 028import java.util.Map; 029 030import org.nuxeo.ecm.core.api.CoreSession; 031import org.nuxeo.ecm.core.api.DocumentModel; 032import org.nuxeo.ecm.core.api.DocumentModelList; 033import org.nuxeo.ecm.core.api.DocumentSecurityException; 034import org.nuxeo.ecm.core.api.IdRef; 035import org.nuxeo.ecm.core.api.NuxeoException; 036import org.nuxeo.ecm.core.api.UnrestrictedSessionRunner; 037import org.nuxeo.ecm.core.api.security.SecurityConstants; 038import org.nuxeo.ecm.core.io.DocumentPipe; 039import org.nuxeo.ecm.core.io.DocumentReader; 040import org.nuxeo.ecm.core.io.DocumentWriter; 041import org.nuxeo.ecm.core.io.impl.DocumentPipeImpl; 042import org.nuxeo.ecm.core.io.impl.plugins.DocumentTreeReader; 043import org.nuxeo.ecm.core.io.impl.plugins.NuxeoArchiveWriter; 044import org.nuxeo.ecm.core.io.impl.plugins.SingleDocumentReader; 045import org.nuxeo.ecm.core.io.impl.plugins.XMLDocumentTreeWriter; 046import org.nuxeo.ecm.core.io.impl.plugins.XMLDocumentWriter; 047import org.restlet.data.CharacterSet; 048import org.restlet.data.Form; 049import org.restlet.data.MediaType; 050import org.restlet.data.Request; 051import org.restlet.data.Response; 052import org.restlet.resource.Representation; 053 054import com.noelios.restlet.http.HttpConstants; 055 056/** 057 * @deprecated since 7.2. Exports are now exposed directly as renditions on the document. Exports can be generated 058 * through the {@code ExportDocument} operation. See NXP-16585. 059 */ 060@Deprecated 061public class ExportRestlet extends BaseStatelessNuxeoRestlet implements Serializable { 062 063 private static final long serialVersionUID = 7831287875548588711L; 064 065 @Override 066 protected void doHandleStatelessRequest(Request req, Response res) { 067 boolean exportAsTree; 068 boolean exportAsZip; 069 String action = req.getResourceRef().getSegments().get(4); 070 if (action.equals("exportTree")) { 071 exportAsTree = true; 072 exportAsZip = true; 073 } else { 074 // "export", "exportSingle" 075 exportAsTree = false; 076 String format = req.getResourceRef().getQueryAsForm().getFirstValue("format"); 077 if (format != null) { 078 format = format.toLowerCase(); 079 } else { 080 format = "xml"; 081 } 082 exportAsZip = "zip".equals(format); 083 } 084 085 String repo = (String) req.getAttributes().get("repo"); 086 if (repo == null || repo.equals("*")) { 087 handleError(res, "you must specify a repository"); 088 return; 089 } 090 091 DocumentModel root; 092 String docid = (String) req.getAttributes().get("docid"); 093 boolean needUnrestricted = false; 094 095 try { 096 boolean init = initRepository(res, repo); 097 if (!init) { 098 handleError(res, "Unable to init repository"); 099 return; 100 } 101 if (docid == null || docid.equals("*")) { 102 root = session.getRootDocument(); 103 } else if (session.hasPermission(new IdRef(docid), SecurityConstants.READ)) { 104 root = session.getDocument(new IdRef(docid)); 105 } else { 106 UnrestrictedVersionExporter runner = new UnrestrictedVersionExporter(session, docid); 107 runner.runUnrestricted(); 108 root = runner.root; 109 needUnrestricted = true; 110 111 // if user can't read version, export is authorized 112 // if he can at least read a proxy pointing to this version 113 if (!root.isVersion()) { 114 throw new DocumentSecurityException("Not enough rights to export " + root.getPathAsString()); 115 } 116 DocumentModelList docs = session.getProxies(root.getRef(), null); 117 boolean hasReadableProxy = false; 118 for (DocumentModel doc : docs) { 119 if (session.hasPermission(doc.getRef(), SecurityConstants.READ)) { 120 hasReadableProxy = true; 121 break; 122 } 123 } 124 if (!hasReadableProxy) { 125 throw new DocumentSecurityException( 126 "Current user doesn't have access to any proxy pointing to version " 127 + root.getPathAsString()); 128 } 129 } 130 } catch (NuxeoException e) { 131 handleError(res, e); 132 return; 133 } 134 135 if (exportAsZip) { 136 // set the content disposition and file name 137 String FILENAME = "export.zip"; 138 139 // use the Facelets APIs to set a new header 140 Map<String, Object> attributes = res.getAttributes(); 141 Form headers = (Form) attributes.get(HttpConstants.ATTRIBUTE_HEADERS); 142 if (headers == null) { 143 headers = new Form(); 144 } 145 headers.add("Content-Disposition", String.format("attachment; filename=\"%s\";", FILENAME)); 146 attributes.put(HttpConstants.ATTRIBUTE_HEADERS, headers); 147 } 148 149 MediaType mediaType = exportAsZip ? MediaType.APPLICATION_ZIP : MediaType.TEXT_XML; 150 Representation entity = makeRepresentation(mediaType, root, exportAsTree, exportAsZip, needUnrestricted); 151 152 res.setEntity(entity); 153 if (mediaType == MediaType.TEXT_XML) { 154 res.getEntity().setCharacterSet(CharacterSet.UTF_8); 155 } 156 } 157 158 protected Representation makeRepresentation(MediaType mediaType, DocumentModel root, final boolean exportAsTree, 159 final boolean exportAsZip, final boolean isUnrestricted) { 160 161 return new ExportRepresentation(mediaType, root, isUnrestricted) { 162 163 @Override 164 protected DocumentPipe makePipe() { 165 if (exportAsTree) { 166 return new DocumentPipeImpl(10); 167 } else { 168 return new DocumentPipeImpl(); 169 } 170 } 171 172 @Override 173 protected DocumentReader makeDocumentReader(CoreSession documentManager, DocumentModel root) 174 { 175 DocumentReader documentReader; 176 if (exportAsTree) { 177 documentReader = new DocumentTreeReader(documentManager, root, false); 178 if (!exportAsZip) { 179 ((DocumentTreeReader) documentReader).setInlineBlobs(true); 180 } 181 } else { 182 documentReader = new SingleDocumentReader(documentManager, root); 183 } 184 return documentReader; 185 } 186 187 @Override 188 protected DocumentWriter makeDocumentWriter(OutputStream outputStream) throws IOException { 189 DocumentWriter documentWriter; 190 if (exportAsZip) { 191 documentWriter = new NuxeoArchiveWriter(outputStream); 192 } else { 193 if (exportAsTree) { 194 documentWriter = new XMLDocumentTreeWriter(outputStream); 195 } else { 196 documentWriter = new XMLDocumentWriter(outputStream); 197 } 198 } 199 return documentWriter; 200 } 201 }; 202 } 203 204 protected static class UnrestrictedVersionExporter extends UnrestrictedSessionRunner { 205 206 private final String docid; 207 208 public DocumentModel root; 209 210 protected UnrestrictedVersionExporter(CoreSession session, String docId) { 211 super(session); 212 docid = docId; 213 } 214 215 @Override 216 public void run() { 217 root = session.getDocument(new IdRef(docid)); 218 } 219 220 } 221 222}