KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mortbay > util > URI


1 // ========================================================================
2
// $Id: URI.java,v 1.39 2006/01/04 13:55:31 gregwilkins Exp $
3
// Copyright 199-2004 Mort Bay Consulting Pty. Ltd.
4
// ------------------------------------------------------------------------
5
// Licensed under the Apache License, Version 2.0 (the "License");
6
// you may not use this file except in compliance with the License.
7
// You may obtain a copy of the License at
8
// http://www.apache.org/licenses/LICENSE-2.0
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
// ========================================================================
15
package org.mortbay.util;
16
17 import java.io.UnsupportedEncodingException JavaDoc;
18 import java.util.Collections JavaDoc;
19 import java.util.List JavaDoc;
20 import java.util.Map JavaDoc;
21 import java.util.Set JavaDoc;
22
23 import org.apache.commons.logging.Log;
24 import org.mortbay.log.LogFactory;
25
26 /* ------------------------------------------------------------ */
27 /** URI Holder.
28  * This class assists with the decoding and encoding or HTTP URI's.
29  * It differs from the java.net.URL class as it does not provide
30  * communications ability, but it does assist with query string
31  * formatting.
32  * <P>ISO_8859_1 encoding is used by default for % encoded characters. This
33  * may be overridden with the org.mortbay.util.URI.charset system property.
34  * @see UrlEncoded
35  * @version $Id: URI.java,v 1.39 2006/01/04 13:55:31 gregwilkins Exp $
36  * @author Greg Wilkins (gregw)
37  */

38 public class URI
39     implements Cloneable JavaDoc
40 {
41     private static Log log = LogFactory.getLog(URI.class);
42
43     public static final String JavaDoc __CHARSET=System.getProperty("org.mortbay.util.URI.charset",StringUtil.__UTF_8);
44     public static final boolean __CHARSET_IS_DEFAULT=__CHARSET.equals(StringUtil.__UTF_8);
45     
46     /* ------------------------------------------------------------ */
47     private String JavaDoc _uri;
48     private String JavaDoc _scheme;
49     private String JavaDoc _host;
50     private int _port;
51     private String JavaDoc _path;
52     private String JavaDoc _encodedPath;
53     private String JavaDoc _query;
54     private UrlEncoded _parameters;
55     private boolean _dirty;
56     
57     /* ------------------------------------------------------------ */
58     /** Copy Constructor .
59      * @param uri
60      */

61     public URI(URI uri)
62         throws IllegalArgumentException JavaDoc
63     {
64         _uri=uri.toString();
65         _scheme=uri._scheme;
66         _host=uri._host;
67         _port=uri._port;
68         _path=uri._path;
69         _encodedPath=uri._encodedPath;
70         _query=uri._query;
71         if (uri._parameters!=null)
72             _parameters=(UrlEncoded)uri._parameters.clone();
73         _dirty=false;
74     }
75     
76     /* ------------------------------------------------------------ */
77     /** Construct from a String.
78      * The string must contain a URI path, but optionaly may contain a
79      * scheme, host, port and query string.
80      *
81      * @param uri [scheme://host[:port]]/path[?query]
82      */

83     public URI(String JavaDoc uri)
84         throws IllegalArgumentException JavaDoc
85     {
86         setURI(uri);
87     }
88     
89     /* ------------------------------------------------------------ */
90     public void setURI(String JavaDoc uri)
91         throws IllegalArgumentException JavaDoc
92     {
93         try
94         {
95             _uri=uri;
96             _scheme=null;
97             _host=null;
98             _port=0;
99             _path=null;
100             _encodedPath=null;
101             _query=null;
102             if (_parameters!=null)
103                 _parameters.clear();
104             
105             // Scan _uri for host, port, path & query
106
int maxi=uri.length()-1;
107             int mark=0;
108             int state=0;
109             int i=0;
110
111             if (maxi==0 || uri.charAt(0)=='/' && uri.charAt(1)!='/')
112             {
113                 state=3;
114                 _scheme=null;
115                 _host=null;
116                 _port=0;
117             }
118             else
119             {
120                 for (i=0;state<3 && i<=maxi;i++)
121                 {
122                     char c=uri.charAt(i);
123                     switch(state)
124                     {
125                       case 0: // looking for scheme or path
126
if (c==':' &&
127                               uri.charAt(i+1)=='/' &&
128                               uri.charAt(i+2)=='/')
129                           {
130                               // found end of scheme & start of host
131
_scheme=uri.substring(mark,i);
132                               i+=2;
133                               mark=i+1;
134                               state=1;
135                           }
136                           else if (i==0 && c=='/')
137                           {
138                               // Found path
139
state=3;
140                           }
141                           else if (i==0 && c=='*')
142                           {
143                               state=5;
144                               _path="*";
145                               _encodedPath="*";
146                           }
147                           continue;
148                           
149                       case 1: // Get host & look for port or path
150
if (c==':')
151                           {
152                               // found port
153
_host=uri.substring(mark,i);
154                               mark=i+1;
155                               state=2;
156                           }
157                           else if (c=='/')
158                           {
159                               // found path
160
_host=uri.substring(mark,i);
161                               mark=i;
162                               state=3;
163                           }
164                           continue;
165                           
166                       case 2: // Get port & look for path
167
if (c=='/')
168                           {
169                               _port=TypeUtil.parseInt(uri,mark,i-mark,10);
170                               mark=i;
171                               state=3;
172                           }
173                           continue;
174                     }
175                 }
176             }
177             
178             // State 3 - Get path & look for query
179
_query=null;
180             for (i++;i<=maxi;i++)
181             {
182                 char c=uri.charAt(i);
183                 if (c=='?')
184                 {
185                     // Found query
186
_encodedPath=uri.substring(mark,i);
187                     _path=decodePath(_encodedPath);
188
189                     mark=i+1;
190                     state=4;
191                     break;
192                 }
193             }
194
195             // complete last state
196
switch(state)
197             {
198               case 0:
199                   _dirty=false;
200                   _encodedPath=_uri;
201                   _path=decodePath(_encodedPath);
202                   break;
203                   
204               case 1:
205                   _dirty=true;
206                   _encodedPath="/";
207                   _path=_encodedPath;
208                   _host=uri.substring(mark);
209                   break;
210                   
211               case 2:
212                   _dirty=true;
213                   _encodedPath="/";
214                   _path=_encodedPath;
215                   _port=TypeUtil.parseInt(uri,mark,-1,10);
216                   break;
217               case 3:
218                   _dirty=(mark==maxi);
219                   _encodedPath=uri.substring(mark);
220                   _path=decodePath(_encodedPath);
221                   break;
222                   
223               case 4:
224                   _dirty=false;
225                   if (mark<=maxi)
226                       _query=uri.substring(mark);
227                   break;
228                   
229               case 5:
230                   _dirty=false;
231             }
232         
233             if (_query!=null && _query.length()>0)
234             {
235                 if (_parameters==null)
236                     _parameters= new UrlEncoded();
237                 else
238                     _parameters.clear();
239                 _parameters.decode(_query,__CHARSET);
240             }
241             else
242                 _query=null;
243         }
244         catch (Exception JavaDoc e)
245         {
246             LogSupport.ignore(log,e);
247             throw new IllegalArgumentException JavaDoc("Malformed URI '"+uri+
248                                                "' : "+e.toString());
249         }
250     }
251
252     /* ------------------------------------------------------------ */
253     /** Is the URI an absolute URL?
254      * @return True if the URI has a scheme or host
255      */

256     public boolean isAbsolute()
257     {
258         return _scheme!=null || _host!=null;
259     }
260     
261     /* ------------------------------------------------------------ */
262     /** Get the uri scheme.
263      * @return the URI scheme
264      */

265     public String JavaDoc getScheme()
266     {
267         return _scheme;
268     }
269     
270     /* ------------------------------------------------------------ */
271     /** Set the uri scheme.
272      * @param scheme the uri scheme
273      */

274     public void setScheme(String JavaDoc scheme)
275     {
276         _scheme=scheme;
277         _dirty=true;
278     }
279     
280     /* ------------------------------------------------------------ */
281     /** Get the uri host.
282      * @return the URI host
283      */

284     public String JavaDoc getHost()
285     {
286         return _host;
287     }
288     
289     /* ------------------------------------------------------------ */
290     /** Set the uri host.
291      * @param host the uri host
292      */

293     public void setHost(String JavaDoc host)
294     {
295         _host=host;
296         _dirty=true;
297     }
298     
299     /* ------------------------------------------------------------ */
300     /** Get the uri port.
301      * @return the URI port
302      */

303     public int getPort()
304     {
305         return _port;
306     }
307     
308     /* ------------------------------------------------------------ */
309     /** Set the uri port.
310      * A port of 0 implies use the default port.
311      * @param port the uri port
312      */

313     public void setPort(int port)
314     {
315         _port=port;
316         _dirty=true;
317     }
318     
319     /* ------------------------------------------------------------ */
320     /** Get the uri path.
321      * @return the URI path
322      */

323     public String JavaDoc getPath()
324     {
325         return _path;
326     }
327     
328     /* ------------------------------------------------------------ */
329     /** Get the encoded uri path.
330      * @return the URI path
331      */

332     public String JavaDoc getEncodedPath()
333     {
334         return _encodedPath;
335     }
336     
337     /* ------------------------------------------------------------ */
338     /** Set the uri path.
339      * @param path the URI path
340      */

341     public void setPath(String JavaDoc path)
342     {
343         _path=path;
344         _encodedPath=encodePath(_path);
345         _dirty=true;
346     }
347     
348     
349     /* ------------------------------------------------------------ */
350     /** Get the uri query String.
351      * @return the URI query string
352      */

353     public String JavaDoc getQuery()
354     {
355         if (_dirty && _parameters!=null)
356         {
357             _query = _parameters.encode(__CHARSET);
358             if (_query!=null && _query.length()==0)
359                 _query=null;
360         }
361         return _query;
362     }
363     
364     /* ------------------------------------------------------------ */
365     /** Set the uri query String.
366      * @param query the URI query string
367      */

368     public void setQuery(String JavaDoc query)
369     {
370         _query=query;
371         
372         if (_parameters!=null)
373             _parameters.clear();
374         else if (query!=null)
375             _parameters=new UrlEncoded();
376         
377         if (query!=null)
378             _parameters.decode(query,__CHARSET);
379         
380         cleanURI();
381     }
382     
383     /* ------------------------------------------------------------ */
384     /** Get the uri query _parameters names.
385      * @return Unmodifiable set of URI query _parameters names
386      */

387     public Set JavaDoc getParameterNames()
388     {
389         if (_parameters==null)
390             return Collections.EMPTY_SET;
391         return _parameters.keySet();
392     }
393     
394     /* ------------------------------------------------------------ */
395     /** Get the uri query _parameters.
396      * @return the URI query _parameters
397      */

398     public MultiMap getParameters()
399     {
400         if (_parameters==null)
401             _parameters=new UrlEncoded();
402         _dirty=true;
403         return _parameters;
404     }
405     
406     /* ------------------------------------------------------------ */
407     /** Get the uri query _parameters.
408      * @return the URI query _parameters in an unmodifiable map.
409      */

410     public Map JavaDoc getUnmodifiableParameters()
411     {
412         if (_parameters==null)
413             return Collections.EMPTY_MAP;
414         return Collections.unmodifiableMap(_parameters);
415     }
416     
417     /* ------------------------------------------------------------ */
418     /** Add the uri query _parameters to a MultiMap
419      */

420     public void putParametersTo(MultiMap map)
421     {
422         if (_parameters!=null && _parameters.size()>0)
423             map.putAll(_parameters);
424     }
425     
426     /* ------------------------------------------------------------ */
427     /** Clear the URI _parameters.
428      */

429     public void clearParameters()
430     {
431         if (_parameters!=null)
432         {
433             _dirty=true;
434             _parameters.clear();
435         }
436     }
437     
438     /* ------------------------------------------------------------ */
439     /** Add encoded _parameters.
440      * @param encoded A HTTP encoded string of _parameters: e.g.. "a=1&b=2"
441      */

442     public void put(String JavaDoc encoded)
443     {
444         UrlEncoded params = new UrlEncoded(encoded);
445         put(params);
446     }
447     
448     /* ------------------------------------------------------------ */
449     /** Add name value pair to the uri query _parameters.
450      * @param name name of value
451      * @param value The value, which may be a multi valued list or
452      * String array.
453      */

454     public Object JavaDoc put(Object JavaDoc name, Object JavaDoc value)
455     {
456         return getParameters().put(name,value);
457     }
458     
459     /* ------------------------------------------------------------ */
460     /** Add dictionary to the uri query _parameters.
461      */

462     public void put(Map JavaDoc values)
463     {
464         getParameters().putAll(values);
465     }
466
467     /* ------------------------------------------------------------ */
468     /** Get named value
469      */

470     public String JavaDoc get(String JavaDoc name)
471     {
472         if (_parameters==null)
473             return null;
474         return (String JavaDoc)_parameters.get(name);
475     }
476     
477     /* ------------------------------------------------------------ */
478     /** Get named multiple values.
479      * @param name The parameter name
480      * @return Umodifiable list of values or null
481      */

482     public List JavaDoc getValues(String JavaDoc name)
483     {
484         if (_parameters==null)
485             return null;
486         return _parameters.getValues(name);
487     }
488     
489     /* ------------------------------------------------------------ */
490     /** Remove named value
491      */

492     public void remove(String JavaDoc name)
493     {
494         if (_parameters!=null)
495         {
496             _dirty=
497                 _parameters.remove(name)!=null;
498         }
499     }
500     
501     /* ------------------------------------------------------------ */
502     /** @return the URI string encoded.
503      */

504     public String JavaDoc toString()
505     {
506         if (_dirty)
507         {
508             getQuery();
509             cleanURI();
510         }
511         return _uri;
512     }
513
514     /* ------------------------------------------------------------ */
515     private void cleanURI()
516     {
517         StringBuffer JavaDoc buf = new StringBuffer JavaDoc(_uri.length()*2);
518         synchronized(buf)
519         {
520             if (_scheme!=null)
521             {
522                 buf.append(_scheme);
523                 buf.append("://");
524                 buf.append(_host);
525                 if (_port>0)
526                 {
527                     buf.append(':');
528                     buf.append(_port);
529                 }
530             }
531
532             buf.append(_encodedPath);
533             
534             if (_query!=null && _query.length()>0)
535             {
536                 buf.append('?');
537                 buf.append(_query);
538             }
539             _uri=buf.toString();
540             _dirty=false;
541         }
542     }
543     
544                 
545     /* ------------------------------------------------------------ */
546     /** Encode a URI path.
547      * This is the same encoding offered by URLEncoder, except that
548      * the '/' character is not encoded.
549      * @param path The path the encode
550      * @return The encoded path
551      */

552     public static String JavaDoc encodePath(String JavaDoc path)
553     {
554         if (path==null || path.length()==0)
555             return path;
556         
557         StringBuffer JavaDoc buf = encodePath(null,path);
558         return buf==null?path:buf.toString();
559     }
560         
561     /* ------------------------------------------------------------ */
562     /** Encode a URI path.
563      * @param path The path the encode
564      * @param buf StringBuffer to encode path into (or null)
565      * @return The StringBuffer or null if no substitutions required.
566      */

567     public static StringBuffer JavaDoc encodePath(StringBuffer JavaDoc buf, String JavaDoc path)
568     {
569         if (buf==null)
570         {
571         loop:
572             for (int i=0;i<path.length();i++)
573             {
574                 char c=path.charAt(i);
575                 switch(c)
576                 {
577                   case '%':
578                   case '?':
579                   case ';':
580                   case '#':
581                   case ' ':
582                       buf=new StringBuffer JavaDoc(path.length()<<1);
583                       break loop;
584                 }
585             }
586             if (buf==null)
587                 return null;
588         }
589         
590         synchronized(buf)
591         {
592             for (int i=0;i<path.length();i++)
593             {
594                 char c=path.charAt(i);
595                 switch(c)
596                 {
597                   case '%':
598                       buf.append("%25");
599                       continue;
600                   case '?':
601                       buf.append("%3F");
602                       continue;
603                   case ';':
604                       buf.append("%3B");
605                       continue;
606                   case '#':
607                       buf.append("%23");
608                       continue;
609                   case ' ':
610                       buf.append("%20");
611                       continue;
612                   default:
613                       buf.append(c);
614                       continue;
615                 }
616             }
617         }
618
619         return buf;
620     }
621     
622     /* ------------------------------------------------------------ */
623     /** Encode a URI path.
624      * @param path The path the encode
625      * @param buf StringBuffer to encode path into (or null)
626      * @param encode String of characters to encode. % is always encoded.
627      * @return The StringBuffer or null if no substitutions required.
628      */

629     public static StringBuffer JavaDoc encodeString(StringBuffer JavaDoc buf,
630                                             String JavaDoc path,
631                                             String JavaDoc encode)
632     {
633         if (buf==null)
634         {
635         loop:
636             for (int i=0;i<path.length();i++)
637             {
638                 char c=path.charAt(i);
639                 if (c=='%' || encode.indexOf(c)>=0)
640                 {
641                     buf=new StringBuffer JavaDoc(path.length()<<1);
642                     break loop;
643                 }
644             }
645             if (buf==null)
646                 return null;
647         }
648         
649         synchronized(buf)
650         {
651             for (int i=0;i<path.length();i++)
652             {
653                 char c=path.charAt(i);
654                 if (c=='%' || encode.indexOf(c)>=0)
655                 {
656                     buf.append('%');
657                     StringUtil.append(buf,(byte)(0xff&c),16);
658                 }
659                 else
660                     buf.append(c);
661             }
662         }
663
664         return buf;
665     }
666     
667     /* ------------------------------------------------------------ */
668     /* Decode a URI path.
669      * @param path The path the encode
670      * @param buf StringBuffer to encode path into
671      */

672     public static String JavaDoc decodePath(String JavaDoc path)
673     {
674         int len=path.length();
675         byte[] bytes=null;
676         int n=0;
677         boolean noDecode=true;
678         
679         for (int i=0;i<len;i++)
680         {
681             char c = path.charAt(i);
682             
683             byte b = (byte)(0xff & c);
684
685             if (c=='%' && (i+2)<len)
686             {
687                 noDecode=false;
688                 b=(byte)(0xff&TypeUtil.parseInt(path,i+1,2,16));
689                 i+=2;
690             }
691             else if (bytes==null)
692             {
693                 n++;
694                 continue;
695             }
696             
697             if (bytes==null)
698             {
699                 noDecode=false;
700                 bytes=new byte[len];
701                 for (int j=0;j<n;j++)
702                     bytes[j]=(byte)(0xff & path.charAt(j));
703             }
704             
705             bytes[n++]=b;
706         }
707
708         if (noDecode)
709             return path;
710
711         try
712         {
713             return new String JavaDoc(bytes,0,n,__CHARSET);
714         }
715         catch(UnsupportedEncodingException JavaDoc e)
716         {
717             log.warn(LogSupport.EXCEPTION,e);
718             return new String JavaDoc(bytes,0,n);
719         }
720     }
721
722     /* ------------------------------------------------------------ */
723     /** Clone URI.
724      * @return cloned URI
725      */

726     public Object JavaDoc clone()
727     throws CloneNotSupportedException JavaDoc
728     {
729          URI u = (URI)super.clone();
730          if (_parameters!=null)
731              u._parameters=(UrlEncoded)_parameters.clone();
732          _dirty=false;
733          
734          return u;
735     }
736
737
738     /* ------------------------------------------------------------ */
739     /** Add two URI path segments.
740      * Handles null and empty paths, path and query params (eg ?a=b or
741      * ;JSESSIONID=xxx) and avoids duplicate '/'
742      * @param p1 URI path segment
743      * @param p2 URI path segment
744      * @return Legally combined path segments.
745      */

746     public static String JavaDoc addPaths(String JavaDoc p1, String JavaDoc p2)
747     {
748         if (p1==null || p1.length()==0)
749         {
750             if (p2==null || p2.length()==0)
751                 return p1;
752             return p2;
753         }
754         if (p2==null || p2.length()==0)
755             return p1;
756         
757         int split=p1.indexOf(';');
758         if (split<0)
759             split=p1.indexOf('?');
760         if (split==0)
761             return p2+p1;
762         if (split<0)
763             split=p1.length();
764
765         StringBuffer JavaDoc buf = new StringBuffer JavaDoc(p1.length()+p2.length()+2);
766         buf.append(p1);
767         
768         if (buf.charAt(split-1)=='/')
769         {
770             if (p2.startsWith("/"))
771             {
772                 buf.deleteCharAt(split-1);
773                 buf.insert(split-1,p2);
774             }
775             else
776                 buf.insert(split,p2);
777         }
778         else
779         {
780             if (p2.startsWith("/"))
781                 buf.insert(split,p2);
782             else
783             {
784                 buf.insert(split,'/');
785                 buf.insert(split+1,p2);
786             }
787         }
788
789         return buf.toString();
790     }
791     
792     /* ------------------------------------------------------------ */
793     /** Return the parent Path.
794      * Treat a URI like a directory path and return the parent directory.
795      */

796     public static String JavaDoc parentPath(String JavaDoc p)
797     {
798         if (p==null || "/".equals(p))
799             return null;
800         int slash=p.lastIndexOf('/',p.length()-2);
801         if (slash>=0)
802             return p.substring(0,slash+1);
803         return null;
804     }
805     
806     /* ------------------------------------------------------------ */
807     /** Strip parameters from a path.
808      * Return path upto any semicolon parameters.
809      */

810     public static String JavaDoc stripPath(String JavaDoc path)
811     {
812         if (path==null)
813             return null;
814         int semi=path.indexOf(';');
815         if (semi<0)
816             return path;
817         return path.substring(0,semi);
818     }
819     
820     /* ------------------------------------------------------------ */
821     /** Convert a path to a cananonical form.
822      * All instances of "." and ".." are factored out. Null is returned
823      * if the path tries to .. above it's root.
824      * @param path
825      * @return path or null.
826      */

827     public static String JavaDoc canonicalPath(String JavaDoc path)
828     {
829         if (path==null || path.length()==0)
830             return path;
831
832         int end=path.length();
833         int queryIdx=path.indexOf('?');
834         int start = path.lastIndexOf('/', (queryIdx > 0 ? queryIdx : end));
835
836     search:
837         while (end>0)
838         {
839             switch(end-start)
840             {
841               case 2: // possible single dot
842
if (path.charAt(start+1)!='.')
843                       break;
844                   break search;
845               case 3: // possible double dot
846
if (path.charAt(start+1)!='.' || path.charAt(start+2)!='.')
847                       break;
848                   break search;
849             }
850             
851             end=start;
852             start=path.lastIndexOf('/',end-1);
853         }
854
855         // If we have checked the entire string
856
if (start>=end)
857             return path;
858         
859         StringBuffer JavaDoc buf = new StringBuffer JavaDoc(path);
860         int delStart=-1;
861         int delEnd=-1;
862         int skip=0;
863         
864         while (end>0)
865         {
866             switch(end-start)
867             {
868               case 2: // possible single dot
869
if (buf.charAt(start+1)!='.')
870                   {
871                       if (skip>0 && --skip==0)
872                       {
873                           delStart=start>=0?start:0;
874                           if(delStart>0 && delEnd==buf.length() && buf.charAt(delEnd-1)=='.')
875                               delStart++;
876                       }
877                       break;
878                   }
879                   
880                   if(start<0 && buf.length()>2 && buf.charAt(1)=='/' && buf.charAt(2)=='/')
881                       break;
882                   
883                   if(delEnd<0)
884                       delEnd=end;
885                   delStart=start;
886                   if (delStart<0 || delStart==0&&buf.charAt(delStart)=='/')
887                   {
888                       delStart++;
889                       if (delEnd<buf.length() && buf.charAt(delEnd)=='/')
890                           delEnd++;
891                       break;
892                   }
893                   if (end==buf.length())
894                       delStart++;
895                   
896                   end=start--;
897                   while (start>=0 && buf.charAt(start)!='/')
898                       start--;
899                   continue;
900                   
901               case 3: // possible double dot
902
if (buf.charAt(start+1)!='.' || buf.charAt(start+2)!='.')
903                   {
904                       if (skip>0 && --skip==0)
905                       { delStart=start>=0?start:0;
906                           if(delStart>0 && delEnd==buf.length() && buf.charAt(delEnd-1)=='.')
907                               delStart++;
908                       }
909                       break;
910                   }
911                   
912                   delStart=start;
913                   if (delEnd<0)
914                       delEnd=end;
915
916                   skip++;
917                   end=start--;
918                   while (start>=0 && buf.charAt(start)!='/')
919                       start--;
920                   continue;
921
922               default:
923                   if (skip>0 && --skip==0)
924                   {
925                       delStart=start>=0?start:0;
926                       if(delEnd==buf.length() && buf.charAt(delEnd-1)=='.')
927                           delStart++;
928                   }
929             }
930             
931             // Do the delete
932
if (skip<=0 && delStart>=0 && delStart>=0)
933             {
934                 buf.delete(delStart,delEnd);
935                 delStart=delEnd=-1;
936                 if (skip>0)
937                     delEnd=end;
938             }
939             
940             end=start--;
941             while (start>=0 && buf.charAt(start)!='/')
942                 start--;
943         }
944
945         // Too many ..
946
if (skip>0)
947             return null;
948         
949         // Do the delete
950
if (delEnd>=0)
951             buf.delete(delStart,delEnd);
952
953         return buf.toString();
954     }
955
956     /* ------------------------------------------------------------ */
957     /**
958      * @param uri URI
959      * @return True if the uri has a scheme
960      */

961     public static boolean hasScheme(String JavaDoc uri)
962     {
963         for (int i=0;i<uri.length();i++)
964         {
965             char c=uri.charAt(i);
966             if (c==':')
967                 return true;
968             if (!(c>='a'&&c<='z' ||
969                   c>='A'&&c<='Z' ||
970                   (i>0 &&(c>='0'&&c<='9' ||
971                           c=='.' ||
972                           c=='+' ||
973                           c=='-'))
974                   ))
975                 break;
976         }
977         return false;
978     }
979     
980 }
981
982
983
984
Popular Tags