View Javadoc
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  package org.apache.maven.plugins.war.util;
20  
21  import java.io.File;
22  import java.util.Collection;
23  import java.util.HashSet;
24  import java.util.Iterator;
25  import java.util.LinkedHashSet;
26  import java.util.Set;
27  
28  import org.codehaus.plexus.util.DirectoryScanner;
29  
30  /**
31   * Set of file's paths.
32   *
33   * The class extends functionality of a "normal" set of strings by a process of the paths normalization. All paths are
34   * converted to unix form (slashes) and they don't start with starting /.
35   *
36   * @author Piotr Tabor
37   */
38  public class PathSet implements Iterable<String> {
39      private static final String SEPARATOR = "/";
40      private static final char SEPARATOR_CHAR = SEPARATOR.charAt(0);
41      /**
42       * Set of normalized paths
43       */
44      private Set<String> pathsSet = new LinkedHashSet<>();
45  
46      static String normalizeSubPath(String path) {
47          if (path.isEmpty()) {
48              return path;
49          }
50          String cleanPath = path.replaceAll("[\\\\]+", SEPARATOR).replaceAll("[/]+", SEPARATOR);
51          cleanPath = cleanPath.charAt(0) == SEPARATOR_CHAR ? cleanPath.substring(1) : cleanPath;
52          if (cleanPath.isEmpty()) {
53              return cleanPath;
54          }
55          if (cleanPath.charAt(cleanPath.length() - 1) == SEPARATOR_CHAR) {
56              return cleanPath.substring(0, cleanPath.length() - 1);
57          }
58          return cleanPath;
59      }
60  
61      /*-------------------- Business interface ------------------------------*/
62  
63      /**
64       * Creates an empty paths set
65       */
66      public PathSet() {
67          /* Empty default constructor */
68      }
69  
70      /**
71       * Creates paths set and normalizate and adds all 'paths'. The source 'paths' will not be changed
72       *
73       * @param paths to be added
74       */
75      public PathSet(Collection<String> paths) {
76          addAll(paths);
77      }
78  
79      /**
80       * Creates paths set and normalizate and adds all 'paths'. The source 'paths' will not be changed
81       *
82       * @param paths to be added
83       */
84      public PathSet(String[] paths) {
85          addAll(paths);
86      }
87  
88      /**
89       * Normalizes and adds given path to the set.
90       *
91       * @param path to be added
92       */
93      public void add(String path) {
94          pathsSet.add(normalizeSubPath(path));
95      }
96  
97      /**
98       * Normalizes and adds given paths (collection of strings) to the set. The source collection will not be changed
99       *
100      * @param paths - collection of strings to be added
101      * @param prefix added to all given paths
102      */
103     public void addAll(Collection<String> paths, String prefix) {
104         for (String val : paths) {
105             add(prefix + SEPARATOR + val);
106         }
107     }
108 
109     /**
110      * Normalizes and adds given paths to the set. The source collection will not be changed
111      *
112      * @param paths to be added
113      * @param prefix added to all given paths
114      */
115     public void addAll(String[] paths, String prefix) {
116         for (String val : paths) {
117             add(prefix + SEPARATOR + val);
118         }
119     }
120 
121     /**
122      * Adds given paths to the set. The source collection will not be changed
123      *
124      * @param paths to be added
125      * @param prefix added to all given paths
126      */
127     public void addAll(PathSet paths, String prefix) {
128         for (String path : paths) {
129             add(prefix + SEPARATOR + path);
130         }
131     }
132 
133     /**
134      * Normalizes and adds given paths (collection of strings) to the set. The source collection will not be changed
135      *
136      * @param paths - collection of strings to be added
137      */
138     public void addAll(Collection<String> paths) {
139         addAll(paths, "");
140     }
141 
142     /**
143      * Normalizes and adds given paths to the set. The source collection will not be changed
144      *
145      * @param paths to be added
146      */
147     public void addAll(String[] paths) {
148         addAll(paths, "");
149     }
150 
151     /**
152      * Adds given paths to the set. The source collection will not be changed
153      *
154      * @param paths to be added
155      */
156     public void addAll(PathSet paths) {
157         addAll(paths, "");
158     }
159 
160     /**
161      * Checks if the set constains given path. The path is normalized before check.
162      *
163      * @param path we are looking for in the set.
164      * @return information if the set constains the path.
165      */
166     public boolean contains(String path) {
167         return pathsSet.contains(normalizeSubPath(path));
168     }
169 
170     /**
171      * Removes the specified path if it exists.
172      *
173      * @param path the path to remove
174      * @return true if the path was removed, false if it did not existed
175      */
176     boolean remove(String path) {
177         return pathsSet.remove(normalizeSubPath(path));
178     }
179 
180     /**
181      * Returns iterator of normalized paths (strings)
182      *
183      * @return iterator of normalized paths (strings)
184      */
185     @Override
186     public Iterator<String> iterator() {
187         return pathsSet.iterator();
188     }
189 
190     /**
191      * @return {@link #pathsSet}
192      */
193     public Collection<String> paths() {
194         return pathsSet;
195     }
196 
197     /**
198      * Adds given prefix to all paths in the set.
199      *
200      * The prefix should be ended by '/'. The generated paths are normalized.
201      *
202      * @param prefix to be added to all items
203      */
204     public void addPrefix(String prefix) {
205         final Set<String> newSet = new HashSet<>();
206         for (String path : pathsSet) {
207             newSet.add(normalizeSubPath(prefix + path));
208         }
209         pathsSet = newSet;
210     }
211 
212     /**
213      * Returns count of the paths in the set
214      *
215      * @return count of the paths in the set
216      */
217     public int size() {
218         return pathsSet.size();
219     }
220 
221     /**
222      * Adds to the set all files in the given directory
223      *
224      * @param directory that will be searched for file's paths to add
225      * @param prefix to be added to all found files
226      */
227     public void addAllFilesInDirectory(File directory, String prefix) {
228         DirectoryScanner scanner = new DirectoryScanner();
229         scanner.setBasedir(directory);
230         scanner.scan();
231         addAll(scanner.getIncludedFiles(), prefix);
232     }
233 }