001/* 002 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the Eclipse Public License v1.0 006 * which accompanies this distribution, and is available at 007 * http://www.eclipse.org/legal/epl-v10.html 008 * 009 * Contributors: 010 * bstefanescu 011 */ 012package org.nuxeo.ecm.webengine.jaxrs.servlet.mapping; 013 014/** 015 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> 016 */ 017public class WildcardSegmentMatcher extends SegmentMatcher { 018 019 protected final char[] pattern; 020 021 public WildcardSegmentMatcher(String pattern) { 022 this.pattern = pattern.replace("**", "*").toCharArray(); 023 } 024 025 public WildcardSegmentMatcher(char[] pattern) { 026 this.pattern = pattern; 027 } 028 029 @Override 030 public boolean matches(String segment) { 031 if (pattern.length == 0) { 032 return true; 033 } 034 return matches(segment.toCharArray(), 0, 0); 035 } 036 037 public boolean matches(char[] segment, int soff, int poff) { 038 if (poff == pattern.length) { 039 // pattern consumed 040 if (soff == segment.length) { 041 // segment consumed too 042 return true; 043 } 044 // segment is not yet consumed 045 if (pattern[pattern.length - 1] == '*') { 046 // last char is a wildcard => matched 047 return true; 048 } 049 return false; 050 } 051 if (soff == segment.length) { 052 // segment consumed but pattern is not yet consumed 053 if (poff + 1 == pattern.length && pattern[poff] == '*') { 054 // there is only one char remaining and it is a wildcard => matched 055 return true; 056 } 057 return false; 058 } 059 060 if (pattern[poff] == '*') { 061 // current pattern char is a wildcard - try all substrings 062 for (int i = soff; i < segment.length; i++) { 063 if (matches(segment, i, poff + 1)) { 064 return true; 065 } 066 } 067 return false; 068 } 069 070 // test is the current char is matching 071 if (pattern[poff] != '?' && pattern[poff] != segment[soff]) { 072 return false; // not matching 073 } 074 075 // continue iteration on segments and matchers 076 return matches(segment, soff + 1, poff + 1); 077 078 } 079 080 @Override 081 public String toString() { 082 return new String(pattern); 083 } 084}