1   package org.apache.maven.wagon;
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  import java.io.File;
23  import java.util.StringTokenizer;
24  
25  
26  
27  
28  
29  
30  
31  public final class PathUtils
32  {
33      private PathUtils()
34      {
35      }
36  
37      
38  
39  
40  
41  
42  
43      public static String dirname( final String path )
44      {
45          final int i = path.lastIndexOf( "/" );
46  
47          return ( ( i >= 0 ) ? path.substring( 0, i ) : "" );
48      }
49  
50      
51  
52  
53  
54  
55      public static String filename( final String path )
56      {
57          final int i = path.lastIndexOf( "/" );
58          return ( ( i >= 0 ) ? path.substring( i + 1 ) : path );
59      }
60  
61      public static String[] dirnames( final String path )
62      {
63          final String dirname = PathUtils.dirname( path );
64          return split( dirname, "/", -1 );
65  
66      }
67  
68      private static String[] split( final String str, final String separator, final int max )
69      {
70          final StringTokenizer tok;
71  
72          if ( separator == null )
73          {
74              
75              
76              tok = new StringTokenizer( str );
77          }
78          else
79          {
80              tok = new StringTokenizer( str, separator );
81          }
82  
83          int listSize = tok.countTokens();
84  
85          if ( max > 0 && listSize > max )
86          {
87              listSize = max;
88          }
89  
90          final String[] list = new String[listSize];
91  
92          int i = 0;
93  
94          int lastTokenBegin;
95          int lastTokenEnd = 0;
96  
97          while ( tok.hasMoreTokens() )
98          {
99              if ( max > 0 && i == listSize - 1 )
100             {
101                 
102                 
103                 
104                 final String endToken = tok.nextToken();
105 
106                 lastTokenBegin = str.indexOf( endToken, lastTokenEnd );
107 
108                 list[i] = str.substring( lastTokenBegin );
109 
110                 break;
111 
112             }
113             else
114             {
115                 list[i] = tok.nextToken();
116 
117                 lastTokenBegin = str.indexOf( list[i], lastTokenEnd );
118 
119                 lastTokenEnd = lastTokenBegin + list[i].length();
120             }
121 
122             i++;
123         }
124         return list;
125     }
126 
127     
128 
129 
130 
131 
132 
133 
134     public static String host( final String url )
135     {
136         if ( url == null || url.length() == 0 )
137         {
138             return "localhost";
139         }
140         String authorization = authorization( url );
141         int index = authorization.indexOf( '@' );
142         String host = ( index >= 0 ) ? authorization.substring( index + 1 ) : authorization;
143         
144         
145         return ( ( host.charAt( 0 ) == '[' ) && ( host.charAt( host.length() - 1 ) == ']' ) )
146                         ? host.substring( 1, host.length() - 1 )
147                         : host;
148     }
149 
150     
151 
152 
153     static String authorization( final String url )
154     {
155         if ( url == null )
156         {
157             return "localhost";
158         }
159 
160         String protocol = PathUtils.protocol( url );
161 
162         if ( protocol == null || protocol.equalsIgnoreCase( "file" ) )
163         {
164             return "localhost";
165         }
166 
167         String host = url;
168         if ( protocol.equalsIgnoreCase( "scm" ) )
169         {
170             
171             host = host.substring( host.indexOf( ":", 4 ) + 1 ).trim();
172         }
173 
174         protocol = PathUtils.protocol( host );
175 
176         if ( protocol.equalsIgnoreCase( "file" ) )
177         {
178             return "localhost";
179         }
180 
181         
182         host = host.substring( host.indexOf( ":" ) + 1 ).trim();
183         if ( host.startsWith( "//" ) )
184         {
185             host = host.substring( 2 );
186         }
187 
188         int pos = host.indexOf( "/" );
189 
190         if ( pos > 0 )
191         {
192             host = host.substring( 0, pos );
193         }
194 
195         pos = host.indexOf( '@' );
196 
197         pos = ( pos > 0 ) ? endOfHostPosition( host, pos ) : endOfHostPosition( host, 0 );
198 
199         if ( pos > 0 )
200         {
201             host = host.substring( 0, pos );
202         }
203         return host;
204     }
205 
206     private static int endOfHostPosition( String host, int pos )
207     {
208         
209         
210         int endOfIPv6Pos = host.indexOf( ']', pos );
211         return ( endOfIPv6Pos > 0 ) ? endOfIPv6Pos + 1 : host.indexOf( ":", pos );
212     }
213 
214     
215 
216 
217 
218 
219 
220 
221 
222 
223 
224     public static String protocol( final String url )
225     {
226         final int pos = url.indexOf( ":" );
227 
228         if ( pos == -1 )
229         {
230             return "";
231         }
232         return url.substring( 0, pos ).trim();
233     }
234 
235     
236 
237 
238 
239     public static int port( String url )
240     {
241 
242         final String protocol = PathUtils.protocol( url );
243 
244         if ( protocol == null || protocol.equalsIgnoreCase( "file" ) )
245         {
246             return WagonConstants.UNKNOWN_PORT;
247         }
248 
249         final String authorization = PathUtils.authorization( url );
250 
251         if ( authorization == null )
252         {
253             return WagonConstants.UNKNOWN_PORT;
254         }
255 
256         if ( protocol.equalsIgnoreCase( "scm" ) )
257         {
258             
259             url = url.substring( url.indexOf( ":", 4 ) + 1 ).trim();
260         }
261 
262         if ( url.regionMatches( true, 0, "file:", 0, 5 ) || url.regionMatches( true, 0, "local:", 0, 6 ) )
263         {
264             return WagonConstants.UNKNOWN_PORT;
265         }
266 
267         
268         url = url.substring( url.indexOf( ":" ) + 1 ).trim();
269         if ( url.startsWith( "//" ) )
270         {
271             url = url.substring( 2 );
272         }
273 
274         int start = authorization.length();
275 
276         if ( url.length() > start && url.charAt( start ) == ':' )
277         {
278             int end = url.indexOf( '/', start );
279 
280             if ( end == start + 1 )
281             {
282                 
283                 return WagonConstants.UNKNOWN_PORT;
284             }
285 
286             if ( end == -1 )
287             {
288                 end = url.length();
289             }
290 
291             return Integer.parseInt( url.substring( start + 1, end ) );
292         }
293         else
294         {
295             return WagonConstants.UNKNOWN_PORT;
296         }
297 
298     }
299 
300     
301 
302 
303 
304 
305 
306 
307     public static String basedir( String url )
308     {
309         String protocol = PathUtils.protocol( url );
310 
311         String retValue = null;
312 
313         if ( protocol.equalsIgnoreCase( "scm" ) )
314         {
315             
316             if ( url.regionMatches( true, 0, "scm:svn:", 0, 8 ) )
317             {
318                 url = url.substring( url.indexOf( ":", 4 ) + 1 );
319                 protocol = PathUtils.protocol( url );
320             }
321         }
322 
323         if ( protocol.equalsIgnoreCase( "file" ) )
324         {
325             retValue = url.substring( protocol.length() + 1 );
326             retValue = decode( retValue );
327             
328             if ( retValue.startsWith( "//" ) )
329             {
330                 retValue = retValue.substring( 2 );
331 
332                 if ( retValue.length() >= 2 && ( retValue.charAt( 1 ) == '|' || retValue.charAt( 1 ) == ':' ) )
333                 {
334                     
335                     retValue = retValue.charAt( 0 ) + ":" + retValue.substring( 2 );
336                 }
337                 else
338                 {
339                     
340                     int index = retValue.indexOf( "/" );
341                     if ( index >= 0 )
342                     {
343                         retValue = retValue.substring( index + 1 );
344                     }
345 
346                     
347                     if ( retValue.length() >= 2 && ( retValue.charAt( 1 ) == '|' || retValue.charAt( 1 ) == ':' ) )
348                     {
349                         retValue = retValue.charAt( 0 ) + ":" + retValue.substring( 2 );
350                     }
351                     else if ( index >= 0 )
352                     {
353                         
354                         retValue = "/" + retValue;
355                     }
356                 }
357             }
358 
359             
360             if ( retValue.length() >= 2 && retValue.charAt( 1 ) == '|' )
361             {
362                 retValue = retValue.charAt( 0 ) + ":" + retValue.substring( 2 );
363             }
364         }
365         else
366         {
367             final String authorization = PathUtils.authorization( url );
368 
369             final int port = PathUtils.port( url );
370 
371             int pos = 0;
372 
373             if ( protocol.equalsIgnoreCase( "scm" ) )
374             {
375                 pos = url.indexOf( ":", 4 ) + 1;
376                 pos = url.indexOf( ":", pos ) + 1;
377             }
378             else
379             {
380                 int index = url.indexOf( "://" );
381                 if ( index != -1 )
382                 {
383                     pos = index + 3;
384                 }
385             }
386 
387             pos += authorization.length();
388 
389             if ( port != WagonConstants.UNKNOWN_PORT )
390             {
391                 pos = pos + Integer.toString( port ).length() + 1;
392             }
393 
394             if ( url.length() > pos )
395             {
396                 retValue = url.substring( pos );
397                 if ( retValue.startsWith( ":" ) )
398                 {
399                     
400                     retValue = retValue.substring( 1 );
401                 }
402 
403                 
404                 retValue = retValue.replace( ':', '/' );
405             }
406         }
407 
408         if ( retValue == null )
409         {
410             retValue = "/";
411         }
412         return retValue.trim();
413     }
414 
415     
416 
417 
418 
419 
420 
421 
422     private static String decode( String url )
423     {
424         String decoded = url;
425         if ( url != null )
426         {
427             int pos = -1;
428             while ( ( pos = decoded.indexOf( '%', pos + 1 ) ) >= 0 )
429             {
430                 if ( pos + 2 < decoded.length() )
431                 {
432                     String hexStr = decoded.substring( pos + 1, pos + 3 );
433                     char ch = (char) Integer.parseInt( hexStr, 16 );
434                     decoded = decoded.substring( 0, pos ) + ch + decoded.substring( pos + 3 );
435                 }
436             }
437         }
438         return decoded;
439     }
440 
441     public static String user( String url )
442     {
443         String host = authorization( url );
444         int index = host.indexOf( '@' );
445         if ( index > 0 )
446         {
447             String userInfo = host.substring( 0, index );
448             index = userInfo.indexOf( ':' );
449             if ( index > 0 )
450             {
451                 return userInfo.substring( 0, index );
452             }
453             else if ( index < 0 )
454             {
455                 return userInfo;
456             }
457         }
458         return null;
459     }
460 
461     public static String password( String url )
462     {
463         String host = authorization( url );
464         int index = host.indexOf( '@' );
465         if ( index > 0 )
466         {
467             String userInfo = host.substring( 0, index );
468             index = userInfo.indexOf( ':' );
469             if ( index >= 0 )
470             {
471                 return userInfo.substring( index + 1 );
472             }
473         }
474         return null;
475     }
476 
477     
478     public static String toRelative( File basedir, String absolutePath )
479     {
480         String relative;
481 
482         absolutePath = absolutePath.replace( '\\', '/' );
483         String basedirPath = basedir.getAbsolutePath().replace( '\\', '/' );
484 
485         if ( absolutePath.startsWith( basedirPath ) )
486         {
487             relative = absolutePath.substring( basedirPath.length() );
488             if ( relative.startsWith( "/" ) )
489             {
490                 relative = relative.substring( 1 );
491             }
492             if ( relative.length() <= 0 )
493             {
494                 relative = ".";
495             }
496         }
497         else
498         {
499             relative = absolutePath;
500         }
501 
502         return relative;
503     }
504 }