001/* 002 * (C) Copyright 2006-2012 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 * Bogdan Stefanescu 016 * Florent Guillaume 017 */ 018package org.nuxeo.ecm.webengine; 019 020import org.nuxeo.common.xmap.annotation.XNode; 021import org.nuxeo.common.xmap.annotation.XObject; 022import org.nuxeo.ecm.webengine.util.PathMatcher; 023 024/** 025 * Configure how a given path is handled by the WebEngine filter. 026 * <p> 027 * If <b>autoTx</b> is true (which is the default) then a transaction will be started each time a path matching the 028 * given path specification is requested. (the transaction is started in a filter before the JAX-RS resource is called 029 * and closed after the response is sent to the output stream). If false then no transaction handling is done. The 030 * default is to start a transaction for any path but: [^/]+/skin/.* 031 * <p> 032 * The <b>value</b> attribute is required and must be used to specify the path pattern. The path pattern is either a 033 * prefix or a regular expression. If the <b>regex</b> parameter is true (the default is false) then the value will be 034 * expected to be a regular expression. A prefix denotes a path starting with 'prefix'. Paths are relative to the 035 * webengine servlet (i.e. they correspond to the servlet path info in the JAX-RS servlet) - and always begin with a 036 * '/'. 037 */ 038@XObject("path") 039public class PathDescriptor implements Comparable<PathDescriptor> { 040 041 @XNode("@value") 042 protected String value; 043 044 @XNode("@regex") 045 protected boolean regex = false; 046 047 @XNode("@autoTx") 048 protected Boolean autoTx; 049 050 protected PathMatcher matcher; 051 052 public PathDescriptor() { 053 } 054 055 public PathMatcher getMatcher() { 056 return matcher; 057 } 058 059 public String getValue() { 060 return value; 061 } 062 063 public Boolean getAutoTx() { 064 return autoTx; 065 } 066 067 public boolean isAutoTx(boolean defaultValue) { 068 return autoTx == null ? defaultValue : autoTx.booleanValue(); 069 } 070 071 public PathMatcher createMatcher() { 072 if (value != null) { 073 if (!value.startsWith("/")) { 074 value = "/" + value; 075 } 076 matcher = regex ? PathMatcher.getRegexMatcher(value) : PathMatcher.getPrefixMatcher(value); 077 } else { 078 throw new IllegalArgumentException("Path value is required"); 079 } 080 return matcher; 081 } 082 083 public boolean match(String path) { 084 return matcher.match(path); 085 } 086 087 @Override 088 public boolean equals(Object obj) { 089 if (obj == this) { 090 return true; 091 } 092 if (obj instanceof PathDescriptor) { 093 PathDescriptor pd = ((PathDescriptor) obj); 094 return value != null && value.equals(pd.value) || value == pd.value; 095 } 096 return false; 097 } 098 099 @Override 100 public int hashCode() { 101 return value.hashCode(); 102 } 103 104 @Override 105 public String toString() { 106 return value + "; autoTx: " + autoTx; 107 } 108 109 @Override 110 public int compareTo(PathDescriptor o) { 111 if (regex != o.regex) { 112 return regex ? 1 : -1; 113 } 114 int len1 = value.length(); 115 int len2 = o.value.length(); 116 if (len1 == len2) { 117 return value.compareTo(o.value); 118 } 119 return len2 - len1; 120 } 121 122}