001/* 002 * (C) Copyright 2010 Nuxeo SA (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 * Anahide Tchertchian 016 */ 017package org.nuxeo.ecm.platform.forms.layout.demo.jsf; 018 019import java.util.ArrayList; 020import java.util.HashMap; 021import java.util.List; 022import java.util.Map; 023import java.util.regex.Matcher; 024import java.util.regex.Pattern; 025 026import org.apache.commons.lang.StringUtils; 027import org.nuxeo.common.utils.URIUtils; 028import org.nuxeo.ecm.core.api.DocumentLocation; 029import org.nuxeo.ecm.core.api.impl.DocumentLocationImpl; 030import org.nuxeo.ecm.platform.url.DocumentViewImpl; 031import org.nuxeo.ecm.platform.url.api.DocumentView; 032import org.nuxeo.ecm.platform.url.service.AbstractDocumentViewCodec; 033 034/** 035 * Provides clean urls without conversation id to handle navigation inside the layout demo. 036 * 037 * @author Anahide Tchertchian 038 */ 039public class LayoutDemoURLCodec extends AbstractDocumentViewCodec { 040 041 // prefix/view_id/(tab/subtab)?requestParams 042 043 public static final String GET_URL_PATTERN = "/" // slash 044 + "([a-zA-Z_0-9\\-\\.]*)?" // view id (group 1) 045 + "(/([a-zA-Z_0-9\\-]*))?" // tab id (group 3) (optional) 046 + "(/([a-zA-Z_0-9\\-]*))?" // sub tab id (group 4) (optional) 047 + "(/)?" // final slash (optional) 048 + "(\\?(.*)?)?"; // query (group 8) (optional) 049 050 public static final String URL_PATTERN = "/" // slash 051 + "([\\w\\.]+)" // server name (group 1) 052 + "(?:/(.*))?" // path (group 2) (optional) 053 + "@([\\w\\-\\.]+)" // view id (group 3) 054 + "/?" // final slash (optional) 055 + "(?:\\?(.*)?)?"; // query (group 4) (optional) 056 057 // prefix/outcome/in/several/parts/template.faces?requestParams 058 public static final String POST_URL_PATTERN = "/([a-zA-Z_0-9\\-\\./]*)?(.faces)(/)?(\\?(.*)?)?"; 059 060 public static final String LAYOUT_PREVIEW_FRAME_VIEW_ID = "layoutPreviewFrame"; 061 062 public static final String DEFAULT_VIEW_ID = "layoutDemoIntroduction"; 063 064 public String getUrlFromDocumentView(DocumentView docView) { 065 DocumentLocation docLoc = docView.getDocumentLocation(); 066 if (docLoc != null) { 067 List<String> items = new ArrayList<String>(); 068 items.add(getPrefix()); 069 String viewId = docView.getViewId(); 070 if (viewId != null) { 071 items.add(viewId); 072 } else { 073 items.add(DEFAULT_VIEW_ID); 074 } 075 Map<String, String> docViewParams = docView.getParameters(); 076 Map<String, String> params = new HashMap<String, String>(); 077 if (docViewParams != null) { 078 params.putAll(docViewParams); 079 params.remove("conversationId"); 080 if (params.containsKey("tabId")) { 081 items.add(params.get("tabId")); 082 params.remove("tabId"); 083 if (params.containsKey("subTabId")) { 084 items.add(params.get("subTabId")); 085 params.remove("subTabId"); 086 } 087 } 088 } 089 String uri = StringUtils.join(items, "/"); 090 return URIUtils.addParametersToURIQuery(uri, params); 091 } 092 return null; 093 } 094 095 /** 096 * Extracts view id and parameters, for both get and post methods 097 */ 098 public DocumentView getDocumentViewFromUrl(String url) { 099 // strip url of any jsessionid param 100 int jsessionidIndex = url.indexOf(";jsessionid"); 101 if (jsessionidIndex != -1) { 102 url = url.substring(0, jsessionidIndex); 103 } 104 105 // try POST pattern 106 Pattern pattern = Pattern.compile(getPrefix() + POST_URL_PATTERN); 107 Matcher m = pattern.matcher(url); 108 if (m.matches()) { 109 if (m.groupCount() >= 1) { 110 111 // for debug 112 // for (int i = 1; i < m.groupCount() + 1; i++) { 113 // System.err.println(i + ": " + m.group(i)); 114 // } 115 116 // get other parameters 117 118 Map<String, String> params = null; 119 120 if (m.groupCount() > 4) { 121 String query = m.group(5); 122 params = URIUtils.getRequestParameters(query); 123 if (params != null) { 124 params.remove("conversationId"); 125 } 126 } 127 128 final DocumentLocation docLoc = new DocumentLocationImpl(null, null); 129 130 return new DocumentViewImpl(docLoc, null, params); 131 } 132 } 133 // try GET pattern 134 pattern = Pattern.compile(getPrefix() + GET_URL_PATTERN); 135 m = pattern.matcher(url); 136 if (m.matches()) { 137 if (m.groupCount() >= 1) { 138 139 // for debug 140 // for (int i = 1; i < m.groupCount() + 1; i++) { 141 // System.err.println(i + ": " + m.group(i)); 142 // } 143 144 String viewId = m.group(1); 145 if (viewId == null || "".equals(viewId)) { 146 viewId = DEFAULT_VIEW_ID; 147 } 148 149 Map<String, String> params = new HashMap<String, String>(); 150 151 String tabId = m.group(3); 152 if (tabId != null && !"".equals(tabId)) { 153 params.put("tabId", tabId); 154 } 155 156 String subTabId = m.group(5); 157 if (subTabId != null && !"".equals(subTabId)) { 158 params.put("subTabId", subTabId); 159 } 160 161 // get other parameters 162 163 if (m.groupCount() > 3) { 164 String query = m.group(8); 165 Map<String, String> queryParams = URIUtils.getRequestParameters(query); 166 if (queryParams != null) { 167 queryParams.remove("conversationId"); 168 params.putAll(queryParams); 169 } 170 } 171 172 final DocumentLocation docLoc = new DocumentLocationImpl(null, null); 173 174 return new DocumentViewImpl(docLoc, viewId, params); 175 } 176 } 177 178 return null; 179 } 180 181 public static boolean isPreview(String viewId) { 182 if (LAYOUT_PREVIEW_FRAME_VIEW_ID.equals(viewId)) { 183 return true; 184 } 185 return false; 186 } 187 188}