blob: c66a540057f2e71b4173e284716b7b6ad112c343 [file] [log] [blame]
//
// ========================================================================
// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.webapp;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
/* ------------------------------------------------------------ */
/**
* ClasspathPattern performs sequential pattern matching of a class name
* against an internal array of classpath pattern entries.
*
* When an entry starts with '-' (minus), reverse matching is performed.
* When an entry ends with '.' (period), prefix matching is performed.
*
* When class is initialized from a classpath pattern string, entries
* in this string should be separated by ':' (semicolon) or ',' (comma).
*/
public class ClasspathPattern
{
private static class Entry
{
public String classpath = null;
public boolean result = false;
public boolean partial = false;
}
final private List<String> _patterns = new ArrayList<String>();
final private List<Entry> _entries = new ArrayList<Entry>();
/* ------------------------------------------------------------ */
public ClasspathPattern()
{
}
/* ------------------------------------------------------------ */
public ClasspathPattern(String[] patterns)
{
setPatterns(patterns);
}
/* ------------------------------------------------------------ */
public ClasspathPattern(String pattern)
{
setPattern(pattern);
}
/* ------------------------------------------------------------ */
/**
* Initialize the matcher by parsing each classpath pattern in an array
*
* @param patterns array of classpath patterns
*/
private void setPatterns(String[] patterns)
{
_patterns.clear();
_entries.clear();
addPatterns(patterns);
}
/* ------------------------------------------------------------ */
/**
* Initialize the matcher by parsing each classpath pattern in an array
*
* @param patterns array of classpath patterns
*/
private void addPatterns(String[] patterns)
{
if (patterns != null)
{
Entry entry = null;
for (String pattern : patterns)
{
entry = createEntry(pattern);
if (entry != null) {
_patterns.add(pattern);
_entries.add(entry);
}
}
}
}
/* ------------------------------------------------------------ */
/**
* Create an entry object containing information about
* a single classpath pattern
*
* @param pattern single classpath pattern
* @return corresponding Entry object
*/
private Entry createEntry(String pattern)
{
Entry entry = null;
if (pattern != null)
{
String item = pattern.trim();
if (item.length() > 0)
{
entry = new Entry();
entry.result = !item.startsWith("-");
entry.partial = item.endsWith(".");
entry.classpath = entry.result ? item : item.substring(1).trim();
}
}
return entry;
}
/* ------------------------------------------------------------ */
/**
* Initialize the matcher by parsing a classpath pattern string
*
* @param pattern classpath pattern string
*/
public void setPattern(String pattern)
{
_patterns.clear();
_entries.clear();
addPattern(pattern);
}
/* ------------------------------------------------------------ */
/**
* Parse a classpath pattern string and appending the result
* to the existing configuration.
*
* @param pattern classpath pattern string
*/
public void addPattern(String pattern)
{
ArrayList<String> patterns = new ArrayList<String>();
StringTokenizer entries = new StringTokenizer(pattern, ":,");
while (entries.hasMoreTokens())
{
patterns.add(entries.nextToken());
}
addPatterns((String[])patterns.toArray(new String[patterns.size()]));
}
/* ------------------------------------------------------------ */
/**
* @return array of classpath patterns
*/
public String[] getPatterns()
{
String[] patterns = null;
if (_patterns!=null && _patterns.size() > 0)
{
patterns = _patterns.toArray(new String[_patterns.size()]);
}
return patterns;
}
/* ------------------------------------------------------------ */
/**
* Match the class name against the pattern
*
* @param name name of the class to match
* @return true if class matches the pattern
*/
public boolean match(String name)
{
boolean result=false;
if (_entries != null)
{
name = name.replace('/','.');
int startIndex = 0;
while(startIndex < name.length() && name.charAt(startIndex) == '.') {
startIndex++;
}
int dollar = name.indexOf("$");
int endIndex = dollar != -1 ? dollar : name.length();
for (Entry entry : _entries)
{
if (entry != null)
{
if (entry.partial)
{
if (name.regionMatches(startIndex, entry.classpath, 0, entry.classpath.length()))
{
result = entry.result;
break;
}
}
else
{
int regionLength = endIndex-startIndex;
if (regionLength == entry.classpath.length()
&& name.regionMatches(startIndex, entry.classpath, 0, regionLength))
{
result = entry.result;
break;
}
}
}
}
}
return result;
}
}