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: DocumentFileCodec.java 29556 2008-01-23 00:59:39Z jcarsique $ 018 */ 019 020package org.nuxeo.ecm.platform.url.codec; 021 022import java.io.UnsupportedEncodingException; 023import java.net.URLDecoder; 024import java.util.HashMap; 025import java.util.Map; 026import java.util.regex.Matcher; 027import java.util.regex.Pattern; 028 029import org.apache.commons.logging.Log; 030import org.apache.commons.logging.LogFactory; 031import org.nuxeo.common.utils.StringUtils; 032import org.nuxeo.common.utils.URIUtils; 033import org.nuxeo.ecm.core.api.DocumentLocation; 034import org.nuxeo.ecm.core.api.DocumentModel; 035import org.nuxeo.ecm.core.api.DocumentRef; 036import org.nuxeo.ecm.core.api.IdRef; 037import org.nuxeo.ecm.core.api.impl.DocumentLocationImpl; 038import org.nuxeo.ecm.core.utils.DocumentModelUtils; 039import org.nuxeo.ecm.platform.url.DocumentViewImpl; 040import org.nuxeo.ecm.platform.url.api.DocumentView; 041import org.nuxeo.ecm.platform.url.service.AbstractDocumentViewCodec; 042 043public class DocumentFileCodec extends AbstractDocumentViewCodec { 044 045 public static final String FILE_PROPERTY_PATH_KEY = "FILE_PROPERTY_PATH"; 046 047 /** 048 * @deprecated soon will be part of the file property, passed as parameter for now 049 */ 050 @Deprecated 051 public static final String FILENAME_PROPERTY_PATH_KEY = "FILENAME_PROPERTY_PATH"; 052 053 public static final String FILENAME_KEY = "FILENAME"; 054 055 private static final Log log = LogFactory.getLog(DocumentFileCodec.class); 056 057 // nxdoc/server/docId/property_path/filename/?requestParams 058 public static final String URLPattern = "/(\\w+)/([a-zA-Z_0-9\\-]+)(/([a-zA-Z_0-9/:\\-\\.\\]\\[]*))+(/([^\\?]*))+(\\?)?(.*)?"; 059 060 public DocumentFileCodec() { 061 } 062 063 public DocumentFileCodec(String prefix) { 064 this.prefix = prefix; 065 } 066 067 @Override 068 public String getUrlFromDocumentView(DocumentView docView) { 069 DocumentLocation docLoc = docView.getDocumentLocation(); 070 String filepath = docView.getParameter(FILE_PROPERTY_PATH_KEY); 071 String filename = docView.getParameter(FILENAME_KEY); 072 if (docLoc != null && filepath != null && filename != null) { 073 StringBuilder buf = new StringBuilder(); 074 buf.append(getPrefix()); 075 buf.append("/"); 076 buf.append(docLoc.getServerName()); 077 buf.append("/"); 078 buf.append(docLoc.getDocRef().toString()); 079 buf.append("/"); 080 buf.append(filepath); 081 buf.append("/"); 082 buf.append(URIUtils.quoteURIPathToken(filename)); 083 String uri = buf.toString(); 084 Map<String, String> requestParams = new HashMap<String, String>(docView.getParameters()); 085 requestParams.remove(FILE_PROPERTY_PATH_KEY); 086 requestParams.remove(FILENAME_KEY); 087 return URIUtils.addParametersToURIQuery(uri, requestParams); 088 } 089 return null; 090 } 091 092 /** 093 * Extracts document location from a Zope-like URL ie : server/path_or_docId/view_id/tab_id . 094 */ 095 @Override 096 public DocumentView getDocumentViewFromUrl(String url) { 097 final Pattern pattern = Pattern.compile(getPrefix() + URLPattern); 098 Matcher m = pattern.matcher(url); 099 if (m.matches()) { 100 if (m.groupCount() >= 4) { 101 102 // for debug 103 // for (int i = 1; i < m.groupCount() + 1; i++) { 104 // System.err.println(i + ": " + m.group(i)); 105 // } 106 107 final String server = m.group(1); 108 String uuid = m.group(2); 109 final DocumentRef docRef = new IdRef(uuid); 110 111 // get other parameters 112 113 Map<String, String> params = new HashMap<String, String>(); 114 if (m.groupCount() >= 4) { 115 String filePropertyPath = m.group(4); 116 params.put(FILE_PROPERTY_PATH_KEY, filePropertyPath); 117 } 118 119 if (m.groupCount() >= 6) { 120 String filename = m.group(6); 121 try { 122 filename = URLDecoder.decode(filename, "UTF-8"); 123 } catch (UnsupportedEncodingException e) { 124 filename = StringUtils.toAscii(filename); 125 } 126 int jsessionidIndex = filename.indexOf(";jsessionid"); 127 if (jsessionidIndex != -1) { 128 filename = filename.substring(0, jsessionidIndex); 129 } 130 params.put(FILENAME_KEY, filename); 131 } 132 133 if (m.groupCount() >= 8) { 134 String query = m.group(8); 135 Map<String, String> requestParams = URIUtils.getRequestParameters(query); 136 if (requestParams != null) { 137 params.putAll(requestParams); 138 } 139 } 140 141 final DocumentLocation docLoc = new DocumentLocationImpl(server, docRef); 142 143 return new DocumentViewImpl(docLoc, null, params); 144 } 145 } 146 147 return null; 148 } 149 150 public static String getFilename(DocumentModel doc, DocumentView docView) { 151 String filename = docView.getParameter(FILENAME_KEY); 152 if (filename == null) { 153 // try to get it from document 154 String propertyPath = docView.getParameter(FILENAME_PROPERTY_PATH_KEY); 155 String propertyName = DocumentModelUtils.decodePropertyName(propertyPath); 156 if (propertyName != null) { 157 filename = (String) DocumentModelUtils.getPropertyValue(doc, propertyName); 158 } 159 } 160 return filename; 161 } 162 163}