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