File D:\maven-qcr-plugin-testsunitaires\qcr4java\jenkins-master\target\site\qc\core\src\main\java\hudson\model\ListView.java.html

1 /*
2 * The MIT License
3 *
4 * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi,
5 * Erik Ramfelt, Seiji Sogabe, Martin Eigenbrodt, Alan Harder
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 */
25 package hudson.model;
26
27 import hudson.Extension;
28 import hudson.Util;
29 import hudson.model.Descriptor.FormException;
30 import hudson.util.CaseInsensitiveComparator;
31 import hudson.util.DescribableList;
32 import hudson.util.FormValidation;
33 import hudson.util.HttpResponses;
34 import hudson.views.ListViewColumn;
35 import hudson.views.ViewJobFilter;
36 import org.kohsuke.stapler.DataBoundConstructor;
37 import org.kohsuke.stapler.HttpResponse;
38 import org.kohsuke.stapler.QueryParameter;
39 import org.kohsuke.stapler.StaplerRequest;
40 import org.kohsuke.stapler.StaplerResponse;
41 import org.kohsuke.stapler.interceptor.RequirePOST;
42
43 import javax.annotation.concurrent.GuardedBy;
44 import javax.servlet.ServletException;
45 import java.io.IOException;
46 import java.util.ArrayList;
47 import java.util.LinkedHashSet;
48 import java.util.List;
49 import java.util.SortedSet;
50 import java.util.TreeSet;
51 import java.util.regex.Pattern;
52 import java.util.regex.PatternSyntaxException;
53
54 /**
55 * Displays {@link Job}s in a flat list view.
56 *
57 * @author Kohsuke Kawaguchi
58 */
59 public class ListView extends View implements Saveable {
60
61 /**
62 * List of job names. This is what gets serialized.
63 */
64 @GuardedBy("this")
65 /*package*/ final SortedSet<String> jobNames = new TreeSet<String>(CaseInsensitiveComparator.INSTANCE);
66
67 private DescribableList<ViewJobFilter, Descriptor<ViewJobFilter>> jobFilters;
68
69 private DescribableList<ListViewColumn, Descriptor<ListViewColumn>> columns;
70
71 /**
72 * Include regex string.
73 */
74 private String includeRegex;
75
76 /**
77 * Compiled include pattern from the includeRegex string.
78 */
79 private transient Pattern includePattern;
80
81 /**
82 * Filter by enabled/disabled status of jobs.
83 * Null for no filter, true for enabled-only, false for disabled-only.
84 */
85 private Boolean statusFilter;
86
87 @DataBoundConstructor
88 public ListView(String name) {
89 super(name);
90 initColumns();
91 initJobFilters();
92 }
93
94 public ListView(String name, ViewGroup owner) {
95 this(name);
96 this.owner = owner;
97 }
98
99 private Object readResolve() {
100 if(includeRegex!=null)
101 includePattern = Pattern.compile(includeRegex);
102 initColumns();
103 initJobFilters();
104 return this;
105 }
106
107 protected void initColumns() {
108 if (columns == null)
109 columns = new DescribableList<ListViewColumn, Descriptor<ListViewColumn>>(this,ListViewColumn.createDefaultInitialColumnList());
110 }
111
112 protected void initJobFilters() {
113 if (jobFilters == null)
114 jobFilters = new DescribableList<ViewJobFilter, Descriptor<ViewJobFilter>>(this);
115 }
116
117 /**
118 * Used to determine if we want to display the Add button.
119 */
120 public boolean hasJobFilterExtensions() {
121 return !ViewJobFilter.all().isEmpty();
122 }
123
124 public DescribableList<ViewJobFilter, Descriptor<ViewJobFilter>> getJobFilters() {
125 return jobFilters;
126 }
127
128 public DescribableList<ListViewColumn, Descriptor<ListViewColumn>> getColumns() {
129 return columns;
130 }
131
132 /**
133 * Returns a read-only view of all {@link Job}s in this view.
134 *
135 * <p>
136 * This method returns a separate copy each time to avoid
137 * concurrent modification issue.
138 */
139 public List<TopLevelItem> getItems() {
140 SortedSet<String> names;
141
142 synchronized (this) {
143 names = new TreeSet<String>(jobNames);
144 }
145
146 if (includePattern != null) {
147 for (Item item : getOwnerItemGroup().getItems()) {
148 String itemName = item.getName();
149 if (includePattern.matcher(itemName).matches()) {
150 names.add(itemName);
151 }
152 }
153 }
154
155 Boolean statusFilter = this.statusFilter; // capture the value to isolate us from concurrent update
156 List<TopLevelItem> items = new ArrayList<TopLevelItem>(names.size());
157 for (TopLevelItem item : getOwnerItemGroup().getItems()) {
158 if (!names.contains(item.getName())) continue;
159 // Add if no status filter or filter matches enabled/disabled status:
160 if(statusFilter == null || !(item instanceof AbstractProject)
161 || ((AbstractProject)item).isDisabled() ^ statusFilter)
162 items.add(item);
163 }
164
165 // check the filters
166 Iterable<ViewJobFilter> jobFilters = getJobFilters();
167 List<TopLevelItem> allItems = new ArrayList<TopLevelItem>(getOwnerItemGroup().getItems());
168 for (ViewJobFilter jobFilter: jobFilters) {
169 items = jobFilter.filter(items, allItems, this);
170 }
171 // for sanity, trim off duplicates
172 items = new ArrayList<TopLevelItem>(new LinkedHashSet<TopLevelItem>(items));
173
174 return items;
175 }
176
177 public synchronized boolean contains(TopLevelItem item) {
178 return jobNames.contains(item.getName());
179 }
180
181 /**
182 * Adds the given item to this view.
183 *
184 * @since 1.389
185 */
186 public void add(TopLevelItem item) throws IOException {
187 synchronized (this) {
188 jobNames.add(item.getName());
189 }
190 save();
191 }
192
193 public String getIncludeRegex() {
194 return includeRegex;
195 }
196
197 /**
198 * Filter by enabled/disabled status of jobs.
199 * Null for no filter, true for enabled-only, false for disabled-only.
200 */
201 public Boolean getStatusFilter() {
202 return statusFilter;
203 }
204
205 public Item doCreateItem(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException {
206 ItemGroup<? extends TopLevelItem> ig = getOwnerItemGroup();
207 if (ig instanceof ModifiableItemGroup) {
208 TopLevelItem item = ((ModifiableItemGroup<? extends TopLevelItem>)ig).doCreateItem(req, rsp);
209 if(item!=null) {
210 synchronized (this) {
211 jobNames.add(item.getName());
212 }
213 owner.save();
214 }
215 return item;
216 }
217 return null;
218 }
219
220 @RequirePOST
221 public HttpResponse doAddJobToView(@QueryParameter String name) throws IOException, ServletException {
222 checkPermission(View.CONFIGURE);
223 if(name==null)
224 throw new Failure("Query parameter 'name' is required");
225
226 if (getOwnerItemGroup().getItem(name) == null)
227 throw new Failure("Query parameter 'name' does not correspond to a known item");
228
229 if (jobNames.add(name))
230 owner.save();
231
232 return HttpResponses.ok();
233 }
234
235 @RequirePOST
236 public HttpResponse doRemoveJobFromView(@QueryParameter String name) throws IOException, ServletException {
237 checkPermission(View.CONFIGURE);
238 if(name==null)
239 throw new Failure("Query parameter 'name' is required");
240
241 if (jobNames.remove(name))
242 owner.save();
243
244 return HttpResponses.ok();
245 }
246
247 @Override
248 public synchronized void onJobRenamed(Item item, String oldName, String newName) {
249 if(jobNames.remove(oldName) && newName!=null)
250 jobNames.add(newName);
251 }
252
253 /**
254 * Handles the configuration submission.
255 *
256 * Load view-specific properties here.
257 */
258 @Override
259 protected void submit(StaplerRequest req) throws ServletException, FormException, IOException {
260 synchronized (this) {
261 jobNames.clear();
262 for (TopLevelItem item : getOwnerItemGroup().getItems()) {
263 if(req.getParameter(item.getName())!=null)
264 jobNames.add(item.getName());
265 }
266 }
267
268 if (req.getParameter("useincluderegex") != null) {
269 includeRegex = Util.nullify(req.getParameter("includeRegex"));
270 if (includeRegex == null)
271 includePattern = null;
272 else
273 includePattern = Pattern.compile(includeRegex);
274 } else {
275 includeRegex = null;
276 includePattern = null;
277 }
278
279 if (columns == null) {
280 columns = new DescribableList<ListViewColumn,Descriptor<ListViewColumn>>(this);
281 }
282 columns.rebuildHetero(req, req.getSubmittedForm(), ListViewColumn.all(), "columns");
283
284 if (jobFilters == null) {
285 jobFilters = new DescribableList<ViewJobFilter,Descriptor<ViewJobFilter>>(this);
286 }
287 jobFilters.rebuildHetero(req, req.getSubmittedForm(), ViewJobFilter.all(), "jobFilters");
288
289 String filter = Util.fixEmpty(req.getParameter("statusFilter"));
290 statusFilter = filter != null ? "1".equals(filter) : null;
291 }
292
293 @Extension
294 public static class DescriptorImpl extends ViewDescriptor {
295 public String getDisplayName() {
296 return Messages.ListView_DisplayName();
297 }
298
299 /**
300 * Checks if the include regular expression is valid.
301 */
302 public FormValidation doCheckIncludeRegex( @QueryParameter String value ) throws IOException, ServletException, InterruptedException {
303 String v = Util.fixEmpty(value);
304 if (v != null) {
305 try {
306 Pattern.compile(v);
307 } catch (PatternSyntaxException pse) {
308 return FormValidation.error(pse.getMessage());
309 }
310 }
311 return FormValidation.ok();
312 }
313 }
314
315 /**
316 * @deprecated as of 1.391
317 * Use {@link ListViewColumn#createDefaultInitialColumnList()}
318 */
319 public static List<ListViewColumn> getDefaultColumns() {
320 return ListViewColumn.createDefaultInitialColumnList();
321 }
322 }
323