| <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../../jacoco-resources/report.gif" type="image/gif"/><title>AntPathMatcher.java</title><link rel="stylesheet" href="../../jacoco-resources/prettify.css" type="text/css"/><script type="text/javascript" src="../../jacoco-resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../../index.html" class="el_report">Apache Shiro :: All (aggregate jar)</a> > <a href="../index.html" class="el_bundle">shiro-core</a> > <a href="index.source.html" class="el_package">org.apache.shiro.util</a> > <span class="el_source">AntPathMatcher.java</span></div><h1>AntPathMatcher.java</h1><pre class="source lang-java linenums">/* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.shiro.util; |
| |
| /** |
| * <p>PathMatcher implementation for Ant-style path patterns. |
| * Examples are provided below.</p> |
| * |
| * <p>Part of this mapping code has been kindly borrowed from |
| * <a href="http://ant.apache.org">Apache Ant</a>. |
| * |
| * <p>The mapping matches URLs using the following rules:<br> |
| * <ul> |
| * <li>? matches one character</li> |
| * <li>* matches zero or more characters</li> |
| * <li>** matches zero or more 'directories' in a path</li> |
| * </ul> |
| * |
| * <p>Some examples:<br> |
| * <ul> |
| * <li><code>com/t?st.jsp</code> - matches <code>com/test.jsp</code> but also |
| * <code>com/tast.jsp</code> or <code>com/txst.jsp</code></li> |
| * <li><code>com/*.jsp</code> - matches all <code>.jsp</code> files in the |
| * <code>com</code> directory</li> |
| * <li><code>com/&#42;&#42;/test.jsp</code> - matches all <code>test.jsp</code> |
| * files underneath the <code>com</code> path</li> |
| * <li><code>org/apache/shiro/&#42;&#42;/*.jsp</code> - matches all <code>.jsp</code> |
| * files underneath the <code>org/apache/shiro</code> path</li> |
| * <li><code>org/&#42;&#42;/servlet/bla.jsp</code> - matches |
| * <code>org/apache/shiro/servlet/bla.jsp</code> but also |
| * <code>org/apache/shiro/testing/servlet/bla.jsp</code> and |
| * <code>org/servlet/bla.jsp</code></li> |
| * </ul> |
| * |
| * <p><b>N.B.</b>: This class was borrowed (with much appreciation) from the |
| * <a href="http://www.springframework.org">Spring Framework</a> with modifications. We didn't want to reinvent the |
| * wheel of great work they've done, but also didn't want to force every Shiro user to depend on Spring</p> |
| * |
| * <p>As per the Apache 2.0 license, the original copyright notice and all author and copyright information have |
| * remained in tact.</p> |
| * |
| * @since 16.07.2003 |
| */ |
| <span class="fc" id="L60">public class AntPathMatcher implements PatternMatcher {</span> |
| |
| //TODO - complete JavaDoc |
| |
| /** |
| * Default path separator: "/" |
| */ |
| public static final String DEFAULT_PATH_SEPARATOR = "/"; |
| |
| <span class="fc" id="L69"> private String pathSeparator = DEFAULT_PATH_SEPARATOR;</span> |
| |
| |
| /** |
| * Set the path separator to use for pattern parsing. |
| * Default is "/", as in Ant. |
| */ |
| public void setPathSeparator(String pathSeparator) { |
| <span class="nc bnc" id="L77" title="All 2 branches missed."> this.pathSeparator = (pathSeparator != null ? pathSeparator : DEFAULT_PATH_SEPARATOR);</span> |
| <span class="nc" id="L78"> }</span> |
| |
| |
| public boolean isPattern(String path) { |
| <span class="nc bnc" id="L82" title="All 4 branches missed."> return (path.indexOf('*') != -1 || path.indexOf('?') != -1);</span> |
| } |
| |
| public boolean matches(String pattern, String source) { |
| <span class="fc" id="L86"> return match(pattern, source);</span> |
| } |
| |
| public boolean match(String pattern, String path) { |
| <span class="fc" id="L90"> return doMatch(pattern, path, true);</span> |
| } |
| |
| public boolean matchStart(String pattern, String path) { |
| <span class="nc" id="L94"> return doMatch(pattern, path, false);</span> |
| } |
| |
| |
| /** |
| * Actually match the given <code>path</code> against the given <code>pattern</code>. |
| * |
| * @param pattern the pattern to match against |
| * @param path the path String to test |
| * @param fullMatch whether a full pattern match is required |
| * (else a pattern match as far as the given base path goes is sufficient) |
| * @return <code>true</code> if the supplied <code>path</code> matched, |
| * <code>false</code> if it didn't |
| */ |
| protected boolean doMatch(String pattern, String path, boolean fullMatch) { |
| <span class="pc bpc" id="L109" title="1 of 2 branches missed."> if (path.startsWith(this.pathSeparator) != pattern.startsWith(this.pathSeparator)) {</span> |
| <span class="nc" id="L110"> return false;</span> |
| } |
| |
| <span class="fc" id="L113"> String[] pattDirs = StringUtils.tokenizeToStringArray(pattern, this.pathSeparator);</span> |
| <span class="fc" id="L114"> String[] pathDirs = StringUtils.tokenizeToStringArray(path, this.pathSeparator);</span> |
| |
| <span class="fc" id="L116"> int pattIdxStart = 0;</span> |
| <span class="fc" id="L117"> int pattIdxEnd = pattDirs.length - 1;</span> |
| <span class="fc" id="L118"> int pathIdxStart = 0;</span> |
| <span class="fc" id="L119"> int pathIdxEnd = pathDirs.length - 1;</span> |
| |
| // Match all elements up to the first ** |
| <span class="fc bfc" id="L122" title="All 4 branches covered."> while (pattIdxStart <= pattIdxEnd && pathIdxStart <= pathIdxEnd) {</span> |
| <span class="fc" id="L123"> String patDir = pattDirs[pattIdxStart];</span> |
| <span class="pc bpc" id="L124" title="1 of 2 branches missed."> if ("**".equals(patDir)) {</span> |
| <span class="nc" id="L125"> break;</span> |
| } |
| <span class="fc bfc" id="L127" title="All 2 branches covered."> if (!matchStrings(patDir, pathDirs[pathIdxStart])) {</span> |
| <span class="fc" id="L128"> return false;</span> |
| } |
| <span class="fc" id="L130"> pattIdxStart++;</span> |
| <span class="fc" id="L131"> pathIdxStart++;</span> |
| <span class="fc" id="L132"> }</span> |
| |
| <span class="pc bpc" id="L134" title="1 of 2 branches missed."> if (pathIdxStart > pathIdxEnd) {</span> |
| // Path is exhausted, only match if rest of pattern is * or **'s |
| <span class="fc bfc" id="L136" title="All 2 branches covered."> if (pattIdxStart > pattIdxEnd) {</span> |
| <span class="pc bpc" id="L137" title="1 of 2 branches missed."> return (pattern.endsWith(this.pathSeparator) ?</span> |
| <span class="pc bpc" id="L138" title="1 of 2 branches missed."> path.endsWith(this.pathSeparator) : !path.endsWith(this.pathSeparator));</span> |
| } |
| <span class="pc bpc" id="L140" title="1 of 2 branches missed."> if (!fullMatch) {</span> |
| <span class="nc" id="L141"> return true;</span> |
| } |
| <span class="pc bpc" id="L143" title="2 of 4 branches missed."> if (pattIdxStart == pattIdxEnd && pattDirs[pattIdxStart].equals("*") &&</span> |
| <span class="nc bnc" id="L144" title="All 2 branches missed."> path.endsWith(this.pathSeparator)) {</span> |
| <span class="nc" id="L145"> return true;</span> |
| } |
| <span class="fc bfc" id="L147" title="All 2 branches covered."> for (int i = pattIdxStart; i <= pattIdxEnd; i++) {</span> |
| <span class="fc bfc" id="L148" title="All 2 branches covered."> if (!pattDirs[i].equals("**")) {</span> |
| <span class="fc" id="L149"> return false;</span> |
| } |
| } |
| <span class="fc" id="L152"> return true;</span> |
| <span class="nc bnc" id="L153" title="All 2 branches missed."> } else if (pattIdxStart > pattIdxEnd) {</span> |
| // String not exhausted, but pattern is. Failure. |
| <span class="nc" id="L155"> return false;</span> |
| <span class="nc bnc" id="L156" title="All 4 branches missed."> } else if (!fullMatch && "**".equals(pattDirs[pattIdxStart])) {</span> |
| // Path start definitely matches due to "**" part in pattern. |
| <span class="nc" id="L158"> return true;</span> |
| } |
| |
| // up to last '**' |
| <span class="nc bnc" id="L162" title="All 4 branches missed."> while (pattIdxStart <= pattIdxEnd && pathIdxStart <= pathIdxEnd) {</span> |
| <span class="nc" id="L163"> String patDir = pattDirs[pattIdxEnd];</span> |
| <span class="nc bnc" id="L164" title="All 2 branches missed."> if (patDir.equals("**")) {</span> |
| <span class="nc" id="L165"> break;</span> |
| } |
| <span class="nc bnc" id="L167" title="All 2 branches missed."> if (!matchStrings(patDir, pathDirs[pathIdxEnd])) {</span> |
| <span class="nc" id="L168"> return false;</span> |
| } |
| <span class="nc" id="L170"> pattIdxEnd--;</span> |
| <span class="nc" id="L171"> pathIdxEnd--;</span> |
| <span class="nc" id="L172"> }</span> |
| <span class="nc bnc" id="L173" title="All 2 branches missed."> if (pathIdxStart > pathIdxEnd) {</span> |
| // String is exhausted |
| <span class="nc bnc" id="L175" title="All 2 branches missed."> for (int i = pattIdxStart; i <= pattIdxEnd; i++) {</span> |
| <span class="nc bnc" id="L176" title="All 2 branches missed."> if (!pattDirs[i].equals("**")) {</span> |
| <span class="nc" id="L177"> return false;</span> |
| } |
| } |
| <span class="nc" id="L180"> return true;</span> |
| } |
| |
| <span class="nc bnc" id="L183" title="All 4 branches missed."> while (pattIdxStart != pattIdxEnd && pathIdxStart <= pathIdxEnd) {</span> |
| <span class="nc" id="L184"> int patIdxTmp = -1;</span> |
| <span class="nc bnc" id="L185" title="All 2 branches missed."> for (int i = pattIdxStart + 1; i <= pattIdxEnd; i++) {</span> |
| <span class="nc bnc" id="L186" title="All 2 branches missed."> if (pattDirs[i].equals("**")) {</span> |
| <span class="nc" id="L187"> patIdxTmp = i;</span> |
| <span class="nc" id="L188"> break;</span> |
| } |
| } |
| <span class="nc bnc" id="L191" title="All 2 branches missed."> if (patIdxTmp == pattIdxStart + 1) {</span> |
| // '**/**' situation, so skip one |
| <span class="nc" id="L193"> pattIdxStart++;</span> |
| <span class="nc" id="L194"> continue;</span> |
| } |
| // Find the pattern between padIdxStart & padIdxTmp in str between |
| // strIdxStart & strIdxEnd |
| <span class="nc" id="L198"> int patLength = (patIdxTmp - pattIdxStart - 1);</span> |
| <span class="nc" id="L199"> int strLength = (pathIdxEnd - pathIdxStart + 1);</span> |
| <span class="nc" id="L200"> int foundIdx = -1;</span> |
| |
| strLoop: |
| <span class="nc bnc" id="L203" title="All 2 branches missed."> for (int i = 0; i <= strLength - patLength; i++) {</span> |
| <span class="nc bnc" id="L204" title="All 2 branches missed."> for (int j = 0; j < patLength; j++) {</span> |
| <span class="nc" id="L205"> String subPat = (String) pattDirs[pattIdxStart + j + 1];</span> |
| <span class="nc" id="L206"> String subStr = (String) pathDirs[pathIdxStart + i + j];</span> |
| <span class="nc bnc" id="L207" title="All 2 branches missed."> if (!matchStrings(subPat, subStr)) {</span> |
| <span class="nc" id="L208"> continue strLoop;</span> |
| } |
| } |
| <span class="nc" id="L211"> foundIdx = pathIdxStart + i;</span> |
| <span class="nc" id="L212"> break;</span> |
| } |
| |
| <span class="nc bnc" id="L215" title="All 2 branches missed."> if (foundIdx == -1) {</span> |
| <span class="nc" id="L216"> return false;</span> |
| } |
| |
| <span class="nc" id="L219"> pattIdxStart = patIdxTmp;</span> |
| <span class="nc" id="L220"> pathIdxStart = foundIdx + patLength;</span> |
| <span class="nc" id="L221"> }</span> |
| |
| <span class="nc bnc" id="L223" title="All 2 branches missed."> for (int i = pattIdxStart; i <= pattIdxEnd; i++) {</span> |
| <span class="nc bnc" id="L224" title="All 2 branches missed."> if (!pattDirs[i].equals("**")) {</span> |
| <span class="nc" id="L225"> return false;</span> |
| } |
| } |
| |
| <span class="nc" id="L229"> return true;</span> |
| } |
| |
| /** |
| * Tests whether or not a string matches against a pattern. |
| * The pattern may contain two special characters:<br> |
| * '*' means zero or more characters<br> |
| * '?' means one and only one character |
| * |
| * @param pattern pattern to match against. |
| * Must not be <code>null</code>. |
| * @param str string which must be matched against the pattern. |
| * Must not be <code>null</code>. |
| * @return <code>true</code> if the string matches against the |
| * pattern, or <code>false</code> otherwise. |
| */ |
| private boolean matchStrings(String pattern, String str) { |
| <span class="fc" id="L246"> char[] patArr = pattern.toCharArray();</span> |
| <span class="fc" id="L247"> char[] strArr = str.toCharArray();</span> |
| <span class="fc" id="L248"> int patIdxStart = 0;</span> |
| <span class="fc" id="L249"> int patIdxEnd = patArr.length - 1;</span> |
| <span class="fc" id="L250"> int strIdxStart = 0;</span> |
| <span class="fc" id="L251"> int strIdxEnd = strArr.length - 1;</span> |
| char ch; |
| |
| <span class="fc" id="L254"> boolean containsStar = false;</span> |
| <span class="fc bfc" id="L255" title="All 2 branches covered."> for (char aPatArr : patArr) {</span> |
| <span class="pc bpc" id="L256" title="1 of 2 branches missed."> if (aPatArr == '*') {</span> |
| <span class="nc" id="L257"> containsStar = true;</span> |
| <span class="nc" id="L258"> break;</span> |
| } |
| } |
| |
| <span class="pc bpc" id="L262" title="1 of 2 branches missed."> if (!containsStar) {</span> |
| // No '*'s, so we make a shortcut |
| <span class="fc bfc" id="L264" title="All 2 branches covered."> if (patIdxEnd != strIdxEnd) {</span> |
| <span class="fc" id="L265"> return false; // Pattern and string do not have the same size</span> |
| } |
| <span class="fc bfc" id="L267" title="All 2 branches covered."> for (int i = 0; i <= patIdxEnd; i++) {</span> |
| <span class="fc" id="L268"> ch = patArr[i];</span> |
| <span class="pc bpc" id="L269" title="1 of 2 branches missed."> if (ch != '?') {</span> |
| <span class="fc bfc" id="L270" title="All 2 branches covered."> if (ch != strArr[i]) {</span> |
| <span class="fc" id="L271"> return false;// Character mismatch</span> |
| } |
| } |
| } |
| <span class="fc" id="L275"> return true; // String matches against pattern</span> |
| } |
| |
| |
| <span class="nc bnc" id="L279" title="All 2 branches missed."> if (patIdxEnd == 0) {</span> |
| <span class="nc" id="L280"> return true; // Pattern contains only '*', which matches anything</span> |
| } |
| |
| // Process characters before first star |
| <span class="nc bnc" id="L284" title="All 4 branches missed."> while ((ch = patArr[patIdxStart]) != '*' && strIdxStart <= strIdxEnd) {</span> |
| <span class="nc bnc" id="L285" title="All 2 branches missed."> if (ch != '?') {</span> |
| <span class="nc bnc" id="L286" title="All 2 branches missed."> if (ch != strArr[strIdxStart]) {</span> |
| <span class="nc" id="L287"> return false;// Character mismatch</span> |
| } |
| } |
| <span class="nc" id="L290"> patIdxStart++;</span> |
| <span class="nc" id="L291"> strIdxStart++;</span> |
| } |
| <span class="nc bnc" id="L293" title="All 2 branches missed."> if (strIdxStart > strIdxEnd) {</span> |
| // All characters in the string are used. Check if only '*'s are |
| // left in the pattern. If so, we succeeded. Otherwise failure. |
| <span class="nc bnc" id="L296" title="All 2 branches missed."> for (int i = patIdxStart; i <= patIdxEnd; i++) {</span> |
| <span class="nc bnc" id="L297" title="All 2 branches missed."> if (patArr[i] != '*') {</span> |
| <span class="nc" id="L298"> return false;</span> |
| } |
| } |
| <span class="nc" id="L301"> return true;</span> |
| } |
| |
| // Process characters after last star |
| <span class="nc bnc" id="L305" title="All 4 branches missed."> while ((ch = patArr[patIdxEnd]) != '*' && strIdxStart <= strIdxEnd) {</span> |
| <span class="nc bnc" id="L306" title="All 2 branches missed."> if (ch != '?') {</span> |
| <span class="nc bnc" id="L307" title="All 2 branches missed."> if (ch != strArr[strIdxEnd]) {</span> |
| <span class="nc" id="L308"> return false;// Character mismatch</span> |
| } |
| } |
| <span class="nc" id="L311"> patIdxEnd--;</span> |
| <span class="nc" id="L312"> strIdxEnd--;</span> |
| } |
| <span class="nc bnc" id="L314" title="All 2 branches missed."> if (strIdxStart > strIdxEnd) {</span> |
| // All characters in the string are used. Check if only '*'s are |
| // left in the pattern. If so, we succeeded. Otherwise failure. |
| <span class="nc bnc" id="L317" title="All 2 branches missed."> for (int i = patIdxStart; i <= patIdxEnd; i++) {</span> |
| <span class="nc bnc" id="L318" title="All 2 branches missed."> if (patArr[i] != '*') {</span> |
| <span class="nc" id="L319"> return false;</span> |
| } |
| } |
| <span class="nc" id="L322"> return true;</span> |
| } |
| |
| // process pattern between stars. padIdxStart and patIdxEnd point |
| // always to a '*'. |
| <span class="nc bnc" id="L327" title="All 4 branches missed."> while (patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd) {</span> |
| <span class="nc" id="L328"> int patIdxTmp = -1;</span> |
| <span class="nc bnc" id="L329" title="All 2 branches missed."> for (int i = patIdxStart + 1; i <= patIdxEnd; i++) {</span> |
| <span class="nc bnc" id="L330" title="All 2 branches missed."> if (patArr[i] == '*') {</span> |
| <span class="nc" id="L331"> patIdxTmp = i;</span> |
| <span class="nc" id="L332"> break;</span> |
| } |
| } |
| <span class="nc bnc" id="L335" title="All 2 branches missed."> if (patIdxTmp == patIdxStart + 1) {</span> |
| // Two stars next to each other, skip the first one. |
| <span class="nc" id="L337"> patIdxStart++;</span> |
| <span class="nc" id="L338"> continue;</span> |
| } |
| // Find the pattern between padIdxStart & padIdxTmp in str between |
| // strIdxStart & strIdxEnd |
| <span class="nc" id="L342"> int patLength = (patIdxTmp - patIdxStart - 1);</span> |
| <span class="nc" id="L343"> int strLength = (strIdxEnd - strIdxStart + 1);</span> |
| <span class="nc" id="L344"> int foundIdx = -1;</span> |
| strLoop: |
| <span class="nc bnc" id="L346" title="All 2 branches missed."> for (int i = 0; i <= strLength - patLength; i++) {</span> |
| <span class="nc bnc" id="L347" title="All 2 branches missed."> for (int j = 0; j < patLength; j++) {</span> |
| <span class="nc" id="L348"> ch = patArr[patIdxStart + j + 1];</span> |
| <span class="nc bnc" id="L349" title="All 2 branches missed."> if (ch != '?') {</span> |
| <span class="nc bnc" id="L350" title="All 2 branches missed."> if (ch != strArr[strIdxStart + i + j]) {</span> |
| <span class="nc" id="L351"> continue strLoop;</span> |
| } |
| } |
| } |
| |
| <span class="nc" id="L356"> foundIdx = strIdxStart + i;</span> |
| <span class="nc" id="L357"> break;</span> |
| } |
| |
| <span class="nc bnc" id="L360" title="All 2 branches missed."> if (foundIdx == -1) {</span> |
| <span class="nc" id="L361"> return false;</span> |
| } |
| |
| <span class="nc" id="L364"> patIdxStart = patIdxTmp;</span> |
| <span class="nc" id="L365"> strIdxStart = foundIdx + patLength;</span> |
| <span class="nc" id="L366"> }</span> |
| |
| // All characters in the string are used. Check if only '*'s are left |
| // in the pattern. If so, we succeeded. Otherwise failure. |
| <span class="nc bnc" id="L370" title="All 2 branches missed."> for (int i = patIdxStart; i <= patIdxEnd; i++) {</span> |
| <span class="nc bnc" id="L371" title="All 2 branches missed."> if (patArr[i] != '*') {</span> |
| <span class="nc" id="L372"> return false;</span> |
| } |
| } |
| |
| <span class="nc" id="L376"> return true;</span> |
| } |
| |
| /** |
| * Given a pattern and a full path, determine the pattern-mapped part. |
| * <p>For example: |
| * <ul> |
| * <li>'<code>/docs/cvs/commit.html</code>' and '<code>/docs/cvs/commit.html</code> -> ''</li> |
| * <li>'<code>/docs/*</code>' and '<code>/docs/cvs/commit</code> -> '<code>cvs/commit</code>'</li> |
| * <li>'<code>/docs/cvs/*.html</code>' and '<code>/docs/cvs/commit.html</code> -> '<code>commit.html</code>'</li> |
| * <li>'<code>/docs/**</code>' and '<code>/docs/cvs/commit</code> -> '<code>cvs/commit</code>'</li> |
| * <li>'<code>/docs/**\/*.html</code>' and '<code>/docs/cvs/commit.html</code> -> '<code>cvs/commit.html</code>'</li> |
| * <li>'<code>/*.html</code>' and '<code>/docs/cvs/commit.html</code> -> '<code>docs/cvs/commit.html</code>'</li> |
| * <li>'<code>*.html</code>' and '<code>/docs/cvs/commit.html</code> -> '<code>/docs/cvs/commit.html</code>'</li> |
| * <li>'<code>*</code>' and '<code>/docs/cvs/commit.html</code> -> '<code>/docs/cvs/commit.html</code>'</li> |
| * </ul> |
| * <p>Assumes that {@link #match} returns <code>true</code> for '<code>pattern</code>' |
| * and '<code>path</code>', but does <strong>not</strong> enforce this. |
| */ |
| public String extractPathWithinPattern(String pattern, String path) { |
| <span class="nc" id="L396"> String[] patternParts = StringUtils.tokenizeToStringArray(pattern, this.pathSeparator);</span> |
| <span class="nc" id="L397"> String[] pathParts = StringUtils.tokenizeToStringArray(path, this.pathSeparator);</span> |
| |
| <span class="nc" id="L399"> StringBuilder buffer = new StringBuilder();</span> |
| |
| // Add any path parts that have a wildcarded pattern part. |
| <span class="nc" id="L402"> int puts = 0;</span> |
| <span class="nc bnc" id="L403" title="All 2 branches missed."> for (int i = 0; i < patternParts.length; i++) {</span> |
| <span class="nc" id="L404"> String patternPart = patternParts[i];</span> |
| <span class="nc bnc" id="L405" title="All 6 branches missed."> if ((patternPart.indexOf('*') > -1 || patternPart.indexOf('?') > -1) && pathParts.length >= i + 1) {</span> |
| <span class="nc bnc" id="L406" title="All 6 branches missed."> if (puts > 0 || (i == 0 && !pattern.startsWith(this.pathSeparator))) {</span> |
| <span class="nc" id="L407"> buffer.append(this.pathSeparator);</span> |
| } |
| <span class="nc" id="L409"> buffer.append(pathParts[i]);</span> |
| <span class="nc" id="L410"> puts++;</span> |
| } |
| } |
| |
| // Append any trailing path parts. |
| <span class="nc bnc" id="L415" title="All 2 branches missed."> for (int i = patternParts.length; i < pathParts.length; i++) {</span> |
| <span class="nc bnc" id="L416" title="All 4 branches missed."> if (puts > 0 || i > 0) {</span> |
| <span class="nc" id="L417"> buffer.append(this.pathSeparator);</span> |
| } |
| <span class="nc" id="L419"> buffer.append(pathParts[i]);</span> |
| } |
| |
| <span class="nc" id="L422"> return buffer.toString();</span> |
| } |
| |
| } |
| </pre><div class="footer"><span class="right">Created with <a href="http://www.jacoco.org/jacoco">JaCoCo</a> 0.8.3.201901230119</span></div></body></html> |