📄 pathmap.java
字号:
// ========================================================================// Copyright 1999-2005 Mort Bay Consulting Pty. Ltd.// ------------------------------------------------------------------------// Licensed 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.mortbay.jetty.servlet;import java.io.Externalizable;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Set;import java.util.StringTokenizer;import org.mortbay.util.LazyList;import org.mortbay.util.SingletonList;import org.mortbay.util.StringMap;import org.mortbay.util.URIUtil;/* ------------------------------------------------------------ *//** URI path map to Object. * This mapping implements the path specification recommended * in the 2.2 Servlet API. * * Path specifications can be of the following forms:<PRE> * /foo/bar - an exact path specification. * /foo/* - a prefix path specification (must end '/*'). * *.ext - a suffix path specification. * / - the default path specification. * </PRE> * Matching is performed in the following order <NL> * <LI>Exact match. * <LI>Longest prefix match. * <LI>Longest suffix match. * <LI>default. * </NL> * Multiple path specifications can be mapped by providing a list of * specifications. The list is separated by the characters specified * in the "org.mortbay.http.PathMap.separators" System property, which * defaults to : * <P> * Special characters within paths such as '?� and ';' are not treated specially * as it is assumed they would have been either encoded in the original URL or * stripped from the path. * <P> * This class is not synchronized for get's. If concurrent modifications are * possible then it should be synchronized at a higher level. * * @author Greg Wilkins (gregw) */public class PathMap extends HashMap implements Externalizable{ /* ------------------------------------------------------------ */ private static String __pathSpecSeparators = System.getProperty("org.mortbay.http.PathMap.separators",":,"); /* ------------------------------------------------------------ */ /** Set the path spec separator. * Multiple path specification may be included in a single string * if they are separated by the characters set in this string. * The default value is ":," or whatever has been set by the * system property org.mortbay.http.PathMap.separators * @param s separators */ public static void setPathSpecSeparators(String s) { __pathSpecSeparators=s; } /* --------------------------------------------------------------- */ StringMap _prefixMap=new StringMap(); StringMap _suffixMap=new StringMap(); StringMap _exactMap=new StringMap(); List _defaultSingletonList=null; Entry _prefixDefault=null; Entry _default=null; Set _entrySet; boolean _nodefault=false; /* --------------------------------------------------------------- */ /** Construct empty PathMap. */ public PathMap() { super(11); _entrySet=entrySet(); } /* --------------------------------------------------------------- */ /** Construct empty PathMap. */ public PathMap(boolean nodefault) { super(11); _entrySet=entrySet(); _nodefault=nodefault; } /* --------------------------------------------------------------- */ /** Construct empty PathMap. */ public PathMap(int capacity) { super (capacity); _entrySet=entrySet(); } /* --------------------------------------------------------------- */ /** Construct from dictionary PathMap. */ public PathMap(Map m) { putAll(m); _entrySet=entrySet(); } /* ------------------------------------------------------------ */ public void writeExternal(java.io.ObjectOutput out) throws java.io.IOException { HashMap map = new HashMap(this); out.writeObject(map); } /* ------------------------------------------------------------ */ public void readExternal(java.io.ObjectInput in) throws java.io.IOException, ClassNotFoundException { HashMap map = (HashMap)in.readObject(); this.putAll(map); } /* --------------------------------------------------------------- */ /** Add a single path match to the PathMap. * @param pathSpec The path specification, or comma separated list of * path specifications. * @param object The object the path maps to */ public synchronized Object put(Object pathSpec, Object object) { StringTokenizer tok = new StringTokenizer(pathSpec.toString(),__pathSpecSeparators); Object old =null; while (tok.hasMoreTokens()) { String spec=tok.nextToken(); if (!spec.startsWith("/") && !spec.startsWith("*.")) throw new IllegalArgumentException("PathSpec "+spec+". must start with '/' or '*.'"); old = super.put(spec,object); // Make entry that was just created. Entry entry = new Entry(spec,object); if (entry.getKey().equals(spec)) { if (spec.equals("/*")) _prefixDefault=entry; else if (spec.endsWith("/*")) { String mapped=spec.substring(0,spec.length()-2); entry.setMapped(mapped); _prefixMap.put(mapped,entry); _exactMap.put(mapped,entry); _exactMap.put(spec.substring(0,spec.length()-1),entry); } else if (spec.startsWith("*.")) _suffixMap.put(spec.substring(2),entry); else if (spec.equals(URIUtil.SLASH)) { if (_nodefault) _exactMap.put(spec,entry); else { _default=entry; _defaultSingletonList= SingletonList.newSingletonList(_default); } } else { entry.setMapped(spec); _exactMap.put(spec,entry); } } } return old; } /* ------------------------------------------------------------ */ /** Get object matched by the path. * @param path the path. * @return Best matched object or null. */ public Object match(String path) { Map.Entry entry = getMatch(path); if (entry!=null) return entry.getValue(); return null; } /* --------------------------------------------------------------- */ /** Get the entry mapped by the best specification. * @param path the path. * @return Map.Entry of the best matched or null. */ public Entry getMatch(String path) { Map.Entry entry; if (path==null) return null; int l=path.length(); // try exact match entry=_exactMap.getEntry(path,0,l); if (entry!=null) return (Entry) entry.getValue(); // prefix search int i=l; while((i=path.lastIndexOf('/',i-1))>=0) { entry=_prefixMap.getEntry(path,0,i); if (entry!=null) return (Entry) entry.getValue(); } // Prefix Default if (_prefixDefault!=null) return _prefixDefault; // Extension search i=0; while ((i=path.indexOf('.',i+1))>0) { entry=_suffixMap.getEntry(path,i+1,l-i-1); if (entry!=null) return (Entry) entry.getValue(); } // Default return _default; } /* --------------------------------------------------------------- */ /** Get all entries matched by the path. * Best match first. * @param path Path to match * @return LazyList of Map.Entry instances key=pathSpec */ public Object getLazyMatches(String path) { Map.Entry entry; Object entries=null; if (path==null) return LazyList.getList(entries); int l=path.length(); // try exact match entry=_exactMap.getEntry(path,0,l); if (entry!=null) entries=LazyList.add(entries,entry.getValue());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -