View Javadoc

1   package org.apache.maven.plugin.reactor;
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.Iterator;
24  import java.util.LinkedList;
25  
26  /**
27   * Calculates relative paths
28   * @author <a href="mailto:dfabulich@apache.org">Dan Fabulich</a>
29   *
30   */
31  class RelativePather {
32      /**
33       * Calculates a relative path
34       * @param context the "current" context directory
35       * @param dest the directory to be described by a relative path
36       * @return a relative path from the context directory to the dest directory
37       */
38      public static String getRelativePath(File context, File dest) {
39          LinkedList contextChunks = getPathChunks(context);
40          LinkedList destChunks = getPathChunks(dest);
41          if (!contextChunks.getFirst().equals(destChunks.getFirst())) throw new DifferentRootsException("Roots differ");
42          int count = 0;
43          Iterator contextChunker = contextChunks.iterator();
44          Iterator destChunker = destChunks.iterator();
45          String contextChunk = (String) contextChunker.next();
46          String destChunk = (String) destChunker.next();
47          boolean pathsDiffer = false;
48          while (true) {
49              count++;
50              if (!contextChunker.hasNext()) break;
51              if (!destChunker.hasNext()) break;
52              contextChunk = (String) contextChunker.next();
53              destChunk = (String) destChunker.next();
54              if (!contextChunk.equals(destChunk)) {
55                  pathsDiffer = true;
56                  break;
57              }
58          }
59          
60          // the paths agree for the first N chunks
61          
62          StringBuffer relativePath = new StringBuffer();
63          
64          if (count < contextChunks.size()) {
65              int dotDotCount = contextChunks.size() - count;
66              for (int i = 0; i < dotDotCount; i++) {
67                  relativePath.append("..");
68                  // omit trailing slash
69                  if (i < dotDotCount -1) {
70                      relativePath.append(File.separatorChar);
71                  }
72              }
73          }
74          if (pathsDiffer) {
75              if (relativePath.length() > 0) {
76                  relativePath.append(File.separatorChar);
77              }
78              relativePath.append(destChunk);
79          }
80          while (destChunker.hasNext()) {
81              if (relativePath.length() > 0) {
82                  relativePath.append(File.separatorChar);
83              }
84              relativePath.append(destChunker.next());
85          }
86          
87          return relativePath.toString();
88      }
89      
90      private static LinkedList getPathChunks(File f) {
91          LinkedList l = new LinkedList();
92          while (f.getParentFile() != null) {
93              l.addFirst(f.getName());
94              f = f.getParentFile();
95          }
96          l.addFirst(f.getAbsolutePath());
97          return l;
98      }
99      
100     static class DifferentRootsException extends RuntimeException {
101         private static final long serialVersionUID = 1L;
102 
103         public DifferentRootsException() {
104             super();
105         }
106 
107         public DifferentRootsException(String message, Throwable cause) {
108             super(message, cause);
109         }
110 
111         public DifferentRootsException(String message) {
112             super(message);
113         }
114 
115         public DifferentRootsException(Throwable cause) {
116             super(cause);
117         }
118         
119     }
120 }