View Javadoc
1   package org.codehaus.mojo.natives.util;
2   
3   import java.io.File;
4   import java.io.IOException;
5   
6   import org.codehaus.plexus.util.StringUtils;
7   
8   public class FileUtil
9   {
10  
11      /**
12       * Returns a relative path for the targetFile relative to the base directory.
13       * 
14       * @param canonicalBase base directory as returned by File.getCanonicalPath()
15       * @param targetFile target file
16       * @return relative path of target file. Returns targetFile if there were no commonalities between the base and the
17       *         target
18       * @author Curt Arnold
19       */
20      public static File getRelativeFile( File workingDirectory, File targetFile )
21      {
22          try
23          {
24              //
25              // remove trailing file separator
26              //
27              String canonicalBase = workingDirectory.getCanonicalFile().getAbsolutePath();
28  
29              if ( canonicalBase.charAt( canonicalBase.length() - 1 ) == File.separatorChar )
30              {
31                  canonicalBase = canonicalBase.substring( 0, canonicalBase.length() - 1 );
32              }
33  
34              //
35              // get canonical name of target and remove trailing separator
36              //
37  
38              String canonicalTarget;
39  
40              if ( System.getProperty( "os.name" ).equals( "OS/400" ) )
41              {
42                  canonicalTarget = targetFile.getPath();
43              }
44              else
45              {
46                  canonicalTarget = targetFile.getCanonicalPath();
47              }
48  
49              if ( canonicalTarget.charAt( canonicalTarget.length() - 1 ) == File.separatorChar )
50              {
51                  canonicalTarget = canonicalTarget.substring( 0, canonicalTarget.length() - 1 );
52              }
53  
54              if ( canonicalTarget.equals( canonicalBase ) )
55              {
56                  return new File( "." );
57              }
58  
59              //
60              // see if the prefixes are the same
61              //
62              if ( canonicalBase.substring( 0, 2 ).equals( "\\\\" ) )
63              {
64                  //
65                  // UNC file name, if target file doesn't also start with same
66                  // server name, don't go there
67                  int endPrefix = canonicalBase.indexOf( '\\', 2 );
68                  String prefix1 = canonicalBase.substring( 0, endPrefix );
69                  String prefix2 = canonicalTarget.substring( 0, endPrefix );
70                  if ( !prefix1.equals( prefix2 ) )
71                  {
72                      return new File( canonicalTarget );
73                  }
74              }
75              else
76              {
77                  if ( canonicalBase.substring( 1, 3 ).equals( ":\\" ) )
78                  {
79                      int endPrefix = 2;
80                      String prefix1 = canonicalBase.substring( 0, endPrefix );
81                      String prefix2 = canonicalTarget.substring( 0, endPrefix );
82                      if ( !prefix1.equals( prefix2 ) )
83                      {
84                          return new File( canonicalTarget );
85                      }
86                  }
87                  else
88                  {
89                      if ( canonicalBase.charAt( 0 ) == '/' )
90                      {
91                          if ( canonicalTarget.charAt( 0 ) != '/' )
92                          {
93                              return new File( canonicalTarget );
94                          }
95                      }
96                  }
97              }
98  
99              char separator = File.separatorChar;
100             int lastSeparator = -1;
101             int minLength = canonicalBase.length();
102 
103             if ( canonicalTarget.length() < minLength )
104             {
105                 minLength = canonicalTarget.length();
106             }
107 
108             int firstDifference = minLength + 1;
109 
110             //
111             // walk to the shorter of the two paths
112             // finding the last separator they have in common
113             for ( int i = 0; i < minLength; i++ )
114             {
115                 if ( canonicalTarget.charAt( i ) == canonicalBase.charAt( i ) )
116                 {
117                     if ( canonicalTarget.charAt( i ) == separator )
118                     {
119                         lastSeparator = i;
120                     }
121                 }
122                 else
123                 {
124                     firstDifference = lastSeparator + 1;
125                     break;
126                 }
127             }
128 
129             StringBuffer relativePath = new StringBuffer( 50 );
130 
131             //
132             // walk from the first difference to the end of the base
133             // adding "../" for each separator encountered
134             //
135             if ( canonicalBase.length() > firstDifference )
136             {
137                 relativePath.append( ".." );
138                 for ( int i = firstDifference; i < canonicalBase.length(); i++ )
139                 {
140                     if ( canonicalBase.charAt( i ) == separator )
141                     {
142                         relativePath.append( separator );
143                         relativePath.append( ".." );
144                     }
145                 }
146             }
147 
148             if ( canonicalTarget.length() > firstDifference )
149             {
150                 //
151                 // append the rest of the target
152                 //
153 
154                 if ( relativePath.length() > 0 )
155                 {
156                     relativePath.append( separator );
157                 }
158 
159                 relativePath.append( canonicalTarget.substring( firstDifference ) );
160             }
161 
162             return new File( relativePath.toString() );
163 
164         }
165         catch ( IOException ex )
166         {
167             // TODO more handling
168         }
169 
170         return targetFile;
171 
172     }
173 
174     public static File[] breakPaths( String paths )
175     {
176         String[] tokens = StringUtils.split( paths, "," );
177 
178         File[] files = new File[tokens.length];
179 
180         for ( int i = 0; i < tokens.length; ++i )
181         {
182             files[i] = new File( tokens[i] );
183         }
184 
185         return files;
186     }
187 
188     /**
189      * @param path String
190      * @param baseDirectory String
191      * @return relative path to a base directory if possible
192      */
193     public static String truncatePath( String path, String baseDirectory )
194     {
195         if ( path.indexOf( baseDirectory ) >= 0 )
196         {
197             path = path.substring( path.indexOf( baseDirectory ) + baseDirectory.length() );
198             if ( path.startsWith( File.separator ) )
199             {
200                 path = path.substring( File.separator.length() );
201             }
202         }
203         return path;
204     }
205 }