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