View Javadoc
1   /*
2    * (C) Copyright 2006-2014 Nuxeo SA (http://nuxeo.com/) and contributors.
3    *
4    * All rights reserved. This program and the accompanying materials
5    * are made available under the terms of the GNU Lesser General Public License
6    * (LGPL) version 2.1 which accompanies this distribution, and is available at
7    * http://www.gnu.org/licenses/lgpl-2.1.html
8    *
9    * This library is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12   * Lesser General Public License for more details.
13   *
14   * Contributors:
15   *     bstefanescu, jcarsique
16   */
17  package org.nuxeo.build.ant;
18  
19  import java.io.File;
20  import java.util.ArrayList;
21  import java.util.HashMap;
22  import java.util.Iterator;
23  import java.util.List;
24  import java.util.Map;
25  import java.util.regex.Matcher;
26  import java.util.regex.Pattern;
27  
28  import org.apache.tools.ant.BuildException;
29  import org.apache.tools.ant.Project;
30  import org.apache.tools.ant.Task;
31  
32  /**
33   * Remove duplicate jars (with different versions) and preserve only the latest
34   * version. The pattern to detect duplicates is: (.*)-([0-9]+.*).jar. The
35   * versions are compared and the lower versions are removed.
36   */
37  public class RemoveDuplicateTask extends Task {
38  
39      static final Pattern PATTERN = Pattern.compile("-([0-9]+.*)\\.jar");
40  
41      protected File dir;
42  
43      public void setDir(File dir) {
44          this.dir = dir;
45      }
46  
47      @Override
48      public void execute() throws BuildException {
49          if (dir == null) {
50              throw new BuildException("dir attribute is required");
51          }
52          String[] names = dir.list();
53          if (names == null) {
54              return;
55          }
56          Map<String, List<Entry>> map = new HashMap<>();
57          for (String name : names) {
58              Matcher m = PATTERN.matcher(name);
59              if (m.find()) {
60                  String key = name.substring(0, m.start());
61                  String v = m.group(1);
62                  Entry entry = new Entry(new File(dir, name), Version.parse(v));
63                  List<Entry> list = map.get(key);
64                  if (list == null) {
65                      list = new ArrayList<>();
66                      map.put(key, list);
67                  }
68                  list.add(entry);
69              }
70          }
71          for (List<Entry> list : map.values()) {
72              removeAllButLatest(list);
73          }
74      }
75  
76      public static Entry getLatest(List<Entry> list) {
77          if (list.isEmpty()) {
78              return null;
79          }
80          Iterator<Entry> it = list.iterator();
81          if (!it.hasNext()) {
82              return null;
83          }
84          Entry latest = it.next();
85          while (it.hasNext()) {
86              Entry p = it.next();
87              if (p.version.greaterThan(latest.version)) {
88                  latest = p;
89              }
90          }
91          return latest;
92      }
93  
94      public void removeAllButLatest(List<Entry> list) {
95          Entry latest = getLatest(list);
96          StringBuilder buf = new StringBuilder();
97          for (Entry p : list) {
98              if (p != latest) {
99                  buf.append(p.file.getName()).append(" ");
100                 p.file.delete();
101             }
102         }
103         if (buf.length() > 0) {
104             log("removed duplicates: " + buf.toString() + "; preserved: "
105                     + latest.file.getName(), Project.MSG_INFO);
106         }
107     }
108 
109     static class Entry {
110         protected File file;
111 
112         protected Version version;
113 
114         Entry(File file, Version version) {
115             this.file = file;
116             this.version = version;
117         }
118     }
119 
120 }