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