1 /* |
|
2 * CDDL HEADER START |
|
3 * |
|
4 * The contents of this file are subject to the terms of the |
|
5 * Common Development and Distribution License (the "License"). |
|
6 * You may not use this file except in compliance with the License. |
|
7 * |
|
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE |
|
9 * or http://www.opensolaris.org/os/licensing. |
|
10 * See the License for the specific language governing permissions |
|
11 * and limitations under the License. |
|
12 * |
|
13 * When distributing Covered Code, include this CDDL HEADER in each |
|
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. |
|
15 * If applicable, add the following below this CDDL HEADER, with the |
|
16 * fields enclosed by brackets "[]" replaced with your own identifying |
|
17 * information: Portions Copyright [yyyy] [name of copyright owner] |
|
18 * |
|
19 * CDDL HEADER END |
|
20 */ |
|
21 |
|
22 /* |
|
23 * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. |
|
24 */ |
|
25 |
|
26 package com.oracle.solaris.vp.panel.common.control; |
|
27 |
|
28 import java.util.*; |
|
29 import com.oracle.solaris.vp.panel.common.ClientContext; |
|
30 import com.oracle.solaris.vp.panel.common.action.*; |
|
31 import com.oracle.solaris.vp.panel.common.model.*; |
|
32 |
|
33 /** |
|
34 * The {@code DefaultControl} class is a {@link Control} that provides a |
|
35 * list-based implementation of {@link #getChildControl}. |
|
36 */ |
|
37 public class DefaultControl<P extends PanelDescriptor> extends Control |
|
38 implements HasPanelDescriptor<P> { |
|
39 |
|
40 // |
|
41 // Instance data |
|
42 // |
|
43 |
|
44 private P descriptor; |
|
45 private ClientContext context; |
|
46 protected List<Control> children = new ArrayList<Control>(); |
|
47 |
|
48 private DefaultStructuredAction resetAction; |
|
49 private DefaultStructuredAction saveAction; |
|
50 |
|
51 // |
|
52 // Constructors |
|
53 // |
|
54 |
|
55 public DefaultControl(String id, String name, ClientContext context) { |
|
56 super(id, name); |
|
57 this.context = context; |
|
58 |
|
59 resetAction = |
|
60 new DefaultStructuredAction(null, context) { |
|
61 @Override |
|
62 public Object workBusy(Object pInput, Object rtInput) |
|
63 throws ActionAbortedException, ActionFailedException, |
|
64 ActionUnauthorizedException { |
|
65 |
|
66 resetAll(); |
|
67 return null; |
|
68 } |
|
69 }; |
|
70 |
|
71 saveAction = |
|
72 new DefaultStructuredAction(null, context) { |
|
73 @Override |
|
74 public Object workBusy(Object pInput, Object rtInput) |
|
75 throws ActionAbortedException, ActionFailedException, |
|
76 ActionUnauthorizedException { |
|
77 |
|
78 saveAll(); |
|
79 return null; |
|
80 } |
|
81 }; |
|
82 } |
|
83 |
|
84 public DefaultControl(String id, String name, P descriptor) { |
|
85 this(id, name, descriptor.getClientContext()); |
|
86 this.descriptor = descriptor; |
|
87 } |
|
88 |
|
89 // |
|
90 // HasPanelDescriptor methods |
|
91 // |
|
92 |
|
93 @Override |
|
94 public P getPanelDescriptor() { |
|
95 return descriptor; |
|
96 } |
|
97 |
|
98 // |
|
99 // Control methods |
|
100 // |
|
101 |
|
102 /** |
|
103 * Calls {@link #ensureChildrenCreated}, then iterates through all {@link |
|
104 * Control}s added via {@link #addChildren addChildren} until it finds one |
|
105 * whose {@link Control#getId getId} method returns a value matching {@code |
|
106 * id}. |
|
107 */ |
|
108 @Override |
|
109 public Control getChildControl(String id) { |
|
110 synchronized (children) { |
|
111 ensureChildrenCreated(); |
|
112 |
|
113 for (Control child : children) { |
|
114 if (child.getId().equals(id)) { |
|
115 return child; |
|
116 } |
|
117 } |
|
118 } |
|
119 |
|
120 return null; |
|
121 } |
|
122 |
|
123 /** |
|
124 * Calls {@link #ensureChildrenCreated}, then returns a list of all child |
|
125 * {@link Control}s that return {@code true} from their {@link #isBrowsable} |
|
126 * methods. |
|
127 * <p/> |
|
128 * Subclasses may wish to override this method to apply different criteria |
|
129 * to the returned list. |
|
130 */ |
|
131 @Override |
|
132 public List<Navigable> getBrowsable() { |
|
133 synchronized (children) { |
|
134 ensureChildrenCreated(); |
|
135 |
|
136 List<Navigable> navigables = new ArrayList<Navigable>(); |
|
137 for (Control child : children) { |
|
138 if (child.isBrowsable()) { |
|
139 navigables.add(child); |
|
140 } |
|
141 } |
|
142 |
|
143 return navigables; |
|
144 } |
|
145 } |
|
146 |
|
147 /** |
|
148 * Gets a {@link DefaultStructuredAction} that invokes {@link #resetAll}, |
|
149 * logging errors. |
|
150 */ |
|
151 @Override |
|
152 public DefaultStructuredAction<?, ?, ?> getResetAction() { |
|
153 return resetAction; |
|
154 } |
|
155 |
|
156 /** |
|
157 * Gets a {@link DefaultStructuredAction} that invokes {@link #saveAll}, |
|
158 * logging errors and prompting for login on {@code |
|
159 * ActionUnauthorizedException}s. |
|
160 */ |
|
161 @Override |
|
162 public DefaultStructuredAction<?, ?, ?> getSaveAction() { |
|
163 return saveAction; |
|
164 } |
|
165 |
|
166 // |
|
167 // DefaultControl methods |
|
168 // |
|
169 |
|
170 public void addChildren(Control... controls) { |
|
171 synchronized (children) { |
|
172 for (Control child : controls) { |
|
173 if (!children.contains(child)) { |
|
174 children.add(child); |
|
175 } |
|
176 } |
|
177 } |
|
178 } |
|
179 |
|
180 /** |
|
181 * Asynchronously closes this instance. |
|
182 */ |
|
183 public void doQuit() { |
|
184 getResetAction().asyncExec( |
|
185 new Runnable() { |
|
186 @Override |
|
187 public void run() { |
|
188 try { |
|
189 getClientContext().closeInstance(true); |
|
190 } catch (ActionException ignore) { |
|
191 } |
|
192 } |
|
193 }); |
|
194 } |
|
195 |
|
196 /** |
|
197 * Asynchronously invokes this {@link Control}'s save action, then closes |
|
198 * this instance. |
|
199 */ |
|
200 public void doSaveAndQuit() { |
|
201 final StructuredAction<?, ?, ?> saveAction = getSaveAction(); |
|
202 saveAction.asyncExec( |
|
203 new Runnable() { |
|
204 @Override |
|
205 public void run() { |
|
206 try { |
|
207 saveAction.invoke(); |
|
208 getClientContext().closeInstance(false); |
|
209 } catch (ActionException ignore) { |
|
210 } |
|
211 } |
|
212 }); |
|
213 } |
|
214 |
|
215 /** |
|
216 * Ensures that any child {@link Control}s that should be available from the |
|
217 * {@link #getChildControl} method have been created. This method is called |
|
218 * from the {@link #getChildControl} and {@link #getBrowsable} methods. |
|
219 * <p/> |
|
220 * This default implementation does nothing. |
|
221 */ |
|
222 protected void ensureChildrenCreated() { |
|
223 } |
|
224 |
|
225 public ClientContext getClientContext() { |
|
226 return descriptor != null ? descriptor.getClientContext() : context; |
|
227 } |
|
228 |
|
229 /** |
|
230 * Convenience method to retrieve a parameter from a given parameter {@code |
|
231 * Map}, or throw a {@link MissingParameterException} if the parameter does |
|
232 * not exist. Intended to be called from within {@link #start}. |
|
233 */ |
|
234 protected String getParameter(Map<String, String> parameters, |
|
235 String parameter) throws MissingParameterException { |
|
236 |
|
237 if (!parameters.containsKey(parameter)) { |
|
238 throw new MissingParameterException(getId(), parameter); |
|
239 } |
|
240 |
|
241 return parameters.get(parameter); |
|
242 } |
|
243 |
|
244 protected void removeChild(int index) { |
|
245 synchronized (children) { |
|
246 children.remove(index); |
|
247 } |
|
248 } |
|
249 } |
|