1 | // Copyright 2004-2007 Jean-Francois Poilpret |
2 | // |
3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | // you may not use this file except in compliance with the License. |
5 | // You may obtain a copy of the License at |
6 | // |
7 | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | // |
9 | // Unless required by applicable law or agreed to in writing, software |
10 | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | // See the License for the specific language governing permissions and |
13 | // limitations under the License. |
14 | |
15 | package net.sourceforge.hiveboard.main; |
16 | |
17 | import java.awt.BorderLayout; |
18 | import java.util.Map; |
19 | import java.util.Set; |
20 | |
21 | import javax.swing.JDialog; |
22 | import javax.swing.JFrame; |
23 | import javax.swing.JToolBar; |
24 | import javax.swing.RepaintManager; |
25 | import javax.swing.UIManager; |
26 | |
27 | import org.apache.hivemind.internal.ServicePoint; |
28 | import org.flexdock.docking.Dockable; |
29 | import org.flexdock.docking.DockingManager; |
30 | import org.flexdock.perspective.Layout; |
31 | import org.flexdock.perspective.Perspective; |
32 | import org.flexdock.perspective.PerspectiveManager; |
33 | import org.flexdock.plaf.PlafManager; |
34 | import org.jvnet.lafwidget.LafWidget; |
35 | import org.jvnet.substance.SubstanceLookAndFeel; |
36 | |
37 | import net.sourceforge.hiveboard.ServerSettings; |
38 | import net.sourceforge.hiveboard.WhiteBoardUserService; |
39 | import net.sourceforge.hiveboard.command.Quit; |
40 | import net.sourceforge.hiveboard.dialog.LoginPanel; |
41 | import net.sourceforge.hiveboard.docking.ViewHelper; |
42 | import net.sourceforge.hiveboard.drawing.ToolHandler; |
43 | import net.sourceforge.hiveboard.event.EventDispatcher; |
44 | import net.sourceforge.hiveboard.util.ErrorHelper; |
45 | import net.sourceforge.hiveboard.util.ExitManager; |
46 | import net.sourceforge.hivegui.application.FlexdockApplicationInitializer; |
47 | import net.sourceforge.hivegui.application.HiveGuiApplicationMain; |
48 | import net.sourceforge.hivegui.util.ScreenTools; |
49 | import net.sourceforge.hiveremoting.caucho.CauchoProxyConfigurator; |
50 | import net.sourceforge.hiveutils.util.SymmetricEncryptor; |
51 | |
52 | public class HiveBoardInitializer extends FlexdockApplicationInitializer |
53 | { |
54 | static public final String TEST_PERSPECTIVE = "TEST_PERSPECTIVE"; |
55 | |
56 | public HiveBoardInitializer( CauchoProxyConfigurator configurator, |
57 | LoginPrefs prefs, |
58 | WhiteBoardUserService service, |
59 | IdentityHolder holder, |
60 | Map<String, Object> serverSettings, |
61 | EventDispatcher dispatcher, |
62 | ServicePoint imageRepository, |
63 | ServicePoint fullScreenShell, |
64 | ToolHandler toolHandler, |
65 | HiveBoardChannelHooksInitializer hooksInitializer, |
66 | Quit quitListener) |
67 | { |
68 | _configurator = configurator; |
69 | _prefs = prefs; |
70 | _service = service; |
71 | _holder = holder; |
72 | _serverSettings = serverSettings; |
73 | _dispatcher = dispatcher; |
74 | _imageRepository = imageRepository; |
75 | _fullScreenShell = fullScreenShell; |
76 | _toolbar = toolHandler.getToolBar(); |
77 | _hooksInitializer = hooksInitializer; |
78 | _quitListener = quitListener; |
79 | } |
80 | |
81 | private boolean isGuiTest() |
82 | { |
83 | return ((HiveBoardMain) _application).isGuiTest(); |
84 | } |
85 | |
86 | @Override public void initialize(HiveGuiApplicationMain application, String[] args) |
87 | { |
88 | super.initialize(application, args); |
89 | initGUI(); |
90 | } |
91 | |
92 | protected void initGUI() |
93 | { |
94 | // Workaround Sun bug #4711700 with JFileChooser on Windows |
95 | System.setProperty("swing.disableFileChooserSpeedFix", "true"); |
96 | // Workaround Sun bug #5079688 with JFrame/JDialog resize on Windows |
97 | System.setProperty("sun.awt.noerasebackground", "true"); |
98 | // Enable automatic content selection on focus gained for all text fields |
99 | UIManager.put(LafWidget.TEXT_SELECT_ON_FOCUS, Boolean.TRUE); |
100 | // Disable substance watermarks during guitests (because image captures |
101 | // are not reproduceable when using watermarks) |
102 | if (isGuiTest()) |
103 | { |
104 | UIManager.put(SubstanceLookAndFeel.WATERMARK_IGNORE, Boolean.TRUE); |
105 | // Add EDT rule violation checks |
106 | RepaintManager.setCurrentManager( |
107 | new net.sourceforge.hiveboard.util.CheckThreadViolationRepaintManager()); |
108 | } |
109 | |
110 | // Register handler for exceptions thrown from AWT EDT |
111 | ExceptionHandler.register(isGuiTest(), _application); |
112 | |
113 | // Special flexdock look&feel manipulation |
114 | PlafManager.setPreferredTheme("substance"); |
115 | |
116 | // Use also substance LAF decorations for all frames |
117 | JFrame.setDefaultLookAndFeelDecorated(true); |
118 | JDialog.setDefaultLookAndFeelDecorated(true); |
119 | } |
120 | |
121 | // CSOFF: IllegalCatchCheck |
122 | @Override public void startup() |
123 | { |
124 | try |
125 | { |
126 | // First try to login... |
127 | if (!login(true)) |
128 | { |
129 | _startupCancel = true; |
130 | return; |
131 | } |
132 | // Setup exit listener |
133 | _application.addExitListener(_quitListener); |
134 | |
135 | super.startup(); |
136 | } |
137 | catch (RuntimeException e) |
138 | { |
139 | _startupException = e; |
140 | } |
141 | } |
142 | // CSON: IllegalCatchCheck |
143 | |
144 | @Override protected void initMainFrame() |
145 | { |
146 | JFrame frame = _application.getMainFrame(); |
147 | frame.getContentPane().add(_toolbar, BorderLayout.NORTH); |
148 | // Not useful anymore after Jira46 fix in AppFW |
149 | //#### Keep comment until fix is official and retested |
150 | // frame.setPreferredSize(ScreenTools.getMainScreenUsableSize()); |
151 | frame.setSize(ScreenTools.getMainScreenUsableSize()); |
152 | frame.setLocation(ScreenTools.getMainScreenUsableOrigin()); |
153 | frame.setExtendedState(JFrame.MAXIMIZED_BOTH); |
154 | super.initMainFrame(); |
155 | } |
156 | |
157 | protected boolean login(boolean displayLogin) |
158 | { |
159 | // Get user/password from preferences |
160 | //#### Encryptor password should be customizable no? |
161 | SymmetricEncryptor encryptor = new SymmetricEncryptor("MY_STUPID-P@ssW0RD"); |
162 | String user = _prefs.getLogin(); |
163 | String password = encryptor.decrypt(_prefs.getPassword()); |
164 | |
165 | // Display login dialog |
166 | if (displayLogin) |
167 | { |
168 | LoginPanel askLogin = new LoginPanel(user, password); |
169 | if (!_application.showDialog(askLogin)) |
170 | { |
171 | return false; |
172 | } |
173 | user = askLogin.getUserName(); |
174 | password = askLogin.getPassword(); |
175 | } |
176 | |
177 | // Set user credentials for the remote service (through hiveremoting.caucho) |
178 | _configurator.setServiceAuthentication( |
179 | "hiveboard.shared.WhiteBoardUserService", user, password); |
180 | // First call to the server: get self identity and set it to IdentityHolder |
181 | _holder.setIdentity(_service.getSelfAccount()); |
182 | // Second call to the server: get server settings |
183 | initServerSettings(_service.getServerSettings()); |
184 | // Register all necessary channel consumers |
185 | _hooksInitializer.registerHooks(); |
186 | // Early load repositories |
187 | _imageRepository.forceServiceInstantiation(); |
188 | // Early load full screen frame shell |
189 | // NB: in order to remove windows decoration we must let system |
190 | // provide decoration (not substance LAF) before instantiating |
191 | // the frame |
192 | JFrame.setDefaultLookAndFeelDecorated(false); |
193 | _fullScreenShell.forceServiceInstantiation(); |
194 | JFrame.setDefaultLookAndFeelDecorated(true); |
195 | |
196 | // Save last user/password in preferences |
197 | _prefs.setLogin(user); |
198 | _prefs.setPassword(encryptor.encrypt(password)); |
199 | |
200 | return true; |
201 | } |
202 | |
203 | // Make server settings available to everyone through a simple Map service |
204 | protected void initServerSettings(ServerSettings settings) |
205 | { |
206 | _serverSettings.put(ServerSettingsKeys.MAX_BOARD_SIZE, settings.getMaxBoardSize()); |
207 | } |
208 | |
209 | @Override public void ready() |
210 | { |
211 | if (_startupCancel) |
212 | { |
213 | ExitManager.exit(0); |
214 | } |
215 | else if (_startupException != null) |
216 | { |
217 | ErrorHelper.handle(_application, _startupException); |
218 | ExitManager.exit(ErrorCode.UNEXPECTED_PROBLEM); |
219 | } |
220 | else |
221 | { |
222 | _logger.debug("ready()"); |
223 | // Start the event dispatcher |
224 | _dispatcher.start(); |
225 | } |
226 | } |
227 | |
228 | @Override protected String getDefaultPerspectiveId() |
229 | { |
230 | if (isGuiTest()) |
231 | { |
232 | return TEST_PERSPECTIVE; |
233 | } |
234 | else |
235 | { |
236 | return super.getDefaultPerspectiveId(); |
237 | } |
238 | } |
239 | |
240 | @Override public void shutdown() |
241 | { |
242 | closeOpenBoardViews(); |
243 | logout(); |
244 | super.shutdown(); |
245 | // Hide the main frame to avoid any repaint later |
246 | // (ie after HiveGuiApplicationMain.shutdownRegistry()) |
247 | _application.getMainFrame().setVisible(false); |
248 | } |
249 | |
250 | @SuppressWarnings("unchecked") |
251 | protected void closeOpenBoardViews() |
252 | { |
253 | // Close all open boards |
254 | Set<String> ids = DockingManager.getDockableIds(); |
255 | for (String id: ids) |
256 | { |
257 | if (ViewHelper.isOpenBoardAreaView(id)) |
258 | { |
259 | DockingManager.close(DockingManager.getDockable(id)); |
260 | } |
261 | } |
262 | } |
263 | |
264 | // CSOFF: IllegalCatchCheck |
265 | protected void logout() |
266 | { |
267 | // Stop dispatcher |
268 | _dispatcher.stop(); |
269 | |
270 | // Logout |
271 | try |
272 | { |
273 | _service.logout(); |
274 | } |
275 | catch (RuntimeException e) |
276 | { |
277 | _logger.error("logout()", e); |
278 | } |
279 | |
280 | // Wait for dispatcher thread to terminate completely |
281 | _dispatcher.waitForCompletion(); |
282 | } |
283 | // CSON: IllegalCatchCheck |
284 | |
285 | @Override protected void saveLayout() |
286 | { |
287 | // Save docking perspective |
288 | Perspective[] perspectives = PerspectiveManager.getInstance().getPerspectives(); |
289 | for (Perspective p: perspectives) |
290 | { |
291 | Layout layout = p.getLayout(); |
292 | for (Dockable dock: layout.getDockables()) |
293 | { |
294 | String id = dock.getPersistentId(); |
295 | if (ViewHelper.isOpenBoardAreaView(id)) |
296 | { |
297 | layout.remove(id); |
298 | } |
299 | } |
300 | } |
301 | super.saveLayout(); |
302 | } |
303 | |
304 | final private CauchoProxyConfigurator _configurator; |
305 | final private LoginPrefs _prefs; |
306 | final private WhiteBoardUserService _service; |
307 | final private IdentityHolder _holder; |
308 | final private Map<String, Object> _serverSettings; |
309 | final private EventDispatcher _dispatcher; |
310 | final private ServicePoint _imageRepository; |
311 | final private ServicePoint _fullScreenShell; |
312 | final private JToolBar _toolbar; |
313 | final private HiveBoardChannelHooksInitializer _hooksInitializer; |
314 | final private Quit _quitListener; |
315 | private Exception _startupException = null; |
316 | private boolean _startupCancel = false; |
317 | } |