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