View Javadoc
1   package org.apache.maven.plugins.shade.mojo;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.File;
23  import java.util.ArrayList;
24  import java.util.Collections;
25  import java.util.List;
26  
27  /**
28   *
29   */
30  public final class RelativizePath
31  {
32      private RelativizePath()
33      {
34          //
35      }
36  
37      /**
38       * relativize a pathname. 
39       * @param thing Absolute File of something. (e.g., a parent pom)
40       * @param relativeTo base to relativize it do. (e.g., a pom into which a relative pathname to the 'thing' is to be installed).
41       * @return
42       */
43      static String convertToRelativePath( File thing, File relativeTo )
44      {
45          StringBuilder relativePath;
46  
47          if ( thing.getParentFile().equals( relativeTo.getParentFile() ) )
48          {
49              return thing.getName(); // a very simple relative path.
50          }
51          
52          List<String> thingDirectories = RelativizePath.parentDirs( thing );
53          List<String> relativeToDirectories = RelativizePath.parentDirs( relativeTo );
54      
55          //Get the shortest of the two paths
56          int length = thingDirectories.size() < relativeToDirectories.size() ? thingDirectories.size() : relativeToDirectories.size();
57      
58          int lastCommonRoot = -1; // index of the lowest directory down from the root that the two have in common.
59          int index;
60      
61          //Find common root
62          for ( index = 0; index < length; index++ ) 
63          {
64              if ( thingDirectories.get( index ).equals( relativeToDirectories.get( index ) ) )
65              {
66                  lastCommonRoot = index;
67              }
68              else
69              {
70                  break;
71              }
72          }
73          if ( lastCommonRoot != -1 )
74          { // possible on Windows or other multi-root cases.
75              // Build up the relative path
76              relativePath = new StringBuilder();
77              // add ..'s to get from the base up to the common point
78              for ( index = lastCommonRoot + 1; index < relativeToDirectories.size(); index++ ) 
79              {
80                  relativePath.append( "../" );
81              }
82              
83              // now add down from the common point to the actual 'thing' item. 
84              for ( index = lastCommonRoot + 1; index < thingDirectories.size(); index++ ) 
85              {
86                  relativePath.append(thingDirectories.get(index)).append('/');
87              }
88              relativePath.append( thing.getName() );
89              return relativePath.toString();
90          }
91          return null;
92      }
93  
94      static List<String> parentDirs( File of )
95      {
96          List<String> results = new ArrayList<String>();
97          for ( File p = of.getParentFile() ; p != null ; p = p.getParentFile() )
98          {
99              if ( !"".equals( p.getName() ) )
100             {
101                 results.add( p.getName() );
102             }
103         }
104         
105         Collections.reverse( results );
106         return results;
107     }
108 }