KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > hudson > model > RunMap


1 package hudson.model;
2
3 import java.io.File JavaDoc;
4 import java.io.FilenameFilter JavaDoc;
5 import java.io.IOException JavaDoc;
6 import java.util.AbstractMap JavaDoc;
7 import java.util.Collections JavaDoc;
8 import java.util.Comparator JavaDoc;
9 import java.util.Map JavaDoc;
10 import java.util.Set JavaDoc;
11 import java.util.SortedMap JavaDoc;
12 import java.util.TreeMap JavaDoc;
13
14 /**
15  * {@link Map} from build number to {@link Run}.
16  *
17  * <p>
18  * This class is multi-thread safe by using copy-on-write technique,
19  * and it also updates the bi-directional links within {@link Run}
20  * accordingly.
21  *
22  * @author Kohsuke Kawaguchi
23  */

24 public final class RunMap<R extends Run<?,R>> extends AbstractMap JavaDoc<Integer JavaDoc,R> implements SortedMap JavaDoc<Integer JavaDoc,R> {
25     // copy-on-write map
26
private transient volatile SortedMap JavaDoc<Integer JavaDoc,R> builds =
27         new TreeMap JavaDoc<Integer JavaDoc,R>(COMPARATOR);
28
29     /**
30      * Read-only view of this map.
31      */

32     private final SortedMap JavaDoc<Integer JavaDoc,R> view = Collections.unmodifiableSortedMap(this);
33
34     public Set JavaDoc<Entry<Integer JavaDoc,R>> entrySet() {
35         // since the map is copy-on-write, make sure no one modifies it
36
return Collections.unmodifiableSet(builds.entrySet());
37     }
38
39     public synchronized R put(R value) {
40         return put(value.getNumber(),value);
41     }
42
43     public synchronized R put(Integer JavaDoc key, R value) {
44         // copy-on-write update
45
TreeMap JavaDoc<Integer JavaDoc,R> m = new TreeMap JavaDoc<Integer JavaDoc,R>(builds);
46
47         R r = update(m, key, value);
48
49         this.builds = m;
50         return r;
51     }
52
53     public synchronized void putAll(Map JavaDoc<? extends Integer JavaDoc,? extends R> rhs) {
54         // copy-on-write update
55
TreeMap JavaDoc<Integer JavaDoc,R> m = new TreeMap JavaDoc<Integer JavaDoc,R>(builds);
56
57         for (Map.Entry JavaDoc<? extends Integer JavaDoc,? extends R> e : rhs.entrySet())
58             update(m, e.getKey(), e.getValue());
59
60         this.builds = m;
61     }
62
63     private R update(TreeMap JavaDoc<Integer JavaDoc, R> m, Integer JavaDoc key, R value) {
64         // things are bit tricky because this map is order so that the newest one comes first,
65
// yet 'nextBuild' refers to the newer build.
66
R first = m.isEmpty() ? null : m.get(m.firstKey());
67         R r = m.put(key, value);
68         SortedMap JavaDoc<Integer JavaDoc,R> head = m.headMap(key);
69         if(!head.isEmpty()) {
70             R prev = m.get(head.lastKey());
71             value.previousBuild = prev.previousBuild;
72             value.nextBuild = prev;
73             if(value.previousBuild!=null)
74                 value.previousBuild.nextBuild = value;
75             prev.previousBuild=value;
76         } else {
77             value.previousBuild = first;
78             value.nextBuild = null;
79             if(first!=null)
80                 first.nextBuild = value;
81         }
82         return r;
83     }
84
85     public synchronized boolean remove(R run) {
86         if(run.nextBuild!=null)
87             run.nextBuild.previousBuild = run.previousBuild;
88         if(run.previousBuild!=null)
89             run.previousBuild.nextBuild = run.nextBuild;
90
91         // copy-on-write update
92
TreeMap JavaDoc<Integer JavaDoc,R> m = new TreeMap JavaDoc<Integer JavaDoc,R>(builds);
93         R r = m.remove(run.getNumber());
94         this.builds = m;
95
96         return r!=null;
97     }
98
99     public synchronized void reset(TreeMap JavaDoc<Integer JavaDoc,R> builds) {
100         this.builds = new TreeMap JavaDoc<Integer JavaDoc,R>(COMPARATOR);
101         putAll(builds);
102     }
103
104     /**
105      * Gets the read-only view of this map.
106      */

107     public SortedMap JavaDoc<Integer JavaDoc,R> getView() {
108         return view;
109     }
110
111 //
112
// SortedMap delegation
113
//
114
public Comparator JavaDoc<? super Integer JavaDoc> comparator() {
115         return builds.comparator();
116     }
117
118     public SortedMap JavaDoc<Integer JavaDoc, R> subMap(Integer JavaDoc fromKey, Integer JavaDoc toKey) {
119         return builds.subMap(fromKey, toKey);
120     }
121
122     public SortedMap JavaDoc<Integer JavaDoc, R> headMap(Integer JavaDoc toKey) {
123         return builds.headMap(toKey);
124     }
125
126     public SortedMap JavaDoc<Integer JavaDoc, R> tailMap(Integer JavaDoc fromKey) {
127         return builds.tailMap(fromKey);
128     }
129
130     public Integer JavaDoc firstKey() {
131         return builds.firstKey();
132     }
133
134     public Integer JavaDoc lastKey() {
135         return builds.lastKey();
136     }
137
138     public static final Comparator JavaDoc<Comparable JavaDoc> COMPARATOR = new Comparator JavaDoc<Comparable JavaDoc>() {
139         public int compare(Comparable JavaDoc o1, Comparable JavaDoc o2) {
140             return -o1.compareTo(o2);
141         }
142     };
143
144     /**
145      * {@link Run} factory.
146      */

147     public interface Constructor<R extends Run<?,R>> {
148         R create(File JavaDoc dir) throws IOException JavaDoc;
149     }
150
151     /**
152      * Fills in {@link RunMap} by loading build records from the file system.
153      *
154      * @param job
155      * Job that owns this map.
156      * @param cons
157      * Used to create new instance of {@link Run}.
158      */

159     public synchronized void load(Job job, Constructor<R> cons) {
160         TreeMap JavaDoc<Integer JavaDoc,R> builds = new TreeMap JavaDoc<Integer JavaDoc,R>(RunMap.COMPARATOR);
161         File JavaDoc buildDir = job.getBuildDir();
162         buildDir.mkdirs();
163         String JavaDoc[] buildDirs = buildDir.list(new FilenameFilter JavaDoc() {
164             public boolean accept(File JavaDoc dir, String JavaDoc name) {
165                 return new File JavaDoc(dir,name).isDirectory();
166             }
167         });
168
169         for( String JavaDoc build : buildDirs ) {
170             File JavaDoc d = new File JavaDoc(buildDir,build);
171             if(new File JavaDoc(d,"build.xml").exists()) {
172                 // if the build result file isn't in the directory, ignore it.
173
try {
174                     R b = cons.create(d);
175                     builds.put( b.getNumber(), b );
176                 } catch (IOException JavaDoc e) {
177                     e.printStackTrace();
178                 }
179             }
180         }
181
182         reset(builds);
183     }
184 }
185
Popular Tags