KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > intro > impl > model > IntroURL


1 /*******************************************************************************
2  * Copyright (c) 2004 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11
12 package org.eclipse.ui.internal.intro.impl.model;
13
14 import java.io.*;
15 import java.net.*;
16 import java.util.*;
17
18 import org.eclipse.jface.action.*;
19 import org.eclipse.swt.custom.*;
20 import org.eclipse.swt.widgets.*;
21 import org.eclipse.ui.*;
22 import org.eclipse.ui.help.*;
23 import org.eclipse.ui.internal.intro.impl.*;
24 import org.eclipse.ui.internal.intro.impl.model.loader.*;
25 import org.eclipse.ui.internal.intro.impl.parts.*;
26 import org.eclipse.ui.internal.intro.impl.util.*;
27 import org.eclipse.ui.intro.*;
28 import org.eclipse.ui.intro.config.*;
29
30 /**
31  * An intro url. An intro URL is a valid http url, with org.eclipse.ui.intro as
32  * a host. This class holds all logic to execute Intro URL commands, ie: an
33  * Intro URL knows how to execute itself.
34  */

35 public class IntroURL implements IIntroURL {
36
37
38     /**
39      * Intro URL constants.
40      */

41     public static final String JavaDoc INTRO_PROTOCOL = "http"; //$NON-NLS-1$
42
public static final String JavaDoc INTRO_HOST_ID = "org.eclipse.ui.intro"; //$NON-NLS-1$
43

44     /**
45      * Constants that represent Intro URL actions.
46      */

47     public static final String JavaDoc SET_STANDBY_MODE = "setStandbyMode"; //$NON-NLS-1$
48
public static final String JavaDoc SHOW_STANDBY = "showStandby"; //$NON-NLS-1$
49
public static final String JavaDoc CLOSE = "close"; //$NON-NLS-1$
50
public static final String JavaDoc SHOW_HELP_TOPIC = "showHelpTopic"; //$NON-NLS-1$
51
public static final String JavaDoc SHOW_HELP = "showHelp"; //$NON-NLS-1$
52
public static final String JavaDoc OPEN_BROWSER = "openBrowser"; //$NON-NLS-1$
53
public static final String JavaDoc RUN_ACTION = "runAction"; //$NON-NLS-1$
54
public static final String JavaDoc SHOW_PAGE = "showPage"; //$NON-NLS-1$
55
public static final String JavaDoc SHOW_MESSAGE = "showMessage"; //$NON-NLS-1$
56
public static final String JavaDoc NAVIGATE = "navigate"; //$NON-NLS-1$
57

58     /**
59      * Constants that represent valid action keys.
60      */

61     public static final String JavaDoc KEY_ID = "id"; //$NON-NLS-1$
62
public static final String JavaDoc KEY_PLUGIN_ID = "pluginId"; //$NON-NLS-1$
63
public static final String JavaDoc KEY_CLASS = "class"; //$NON-NLS-1$
64
public static final String JavaDoc KEY_STANDBY = "standby"; //$NON-NLS-1$
65
public static final String JavaDoc KEY_PART_ID = "partId"; //$NON-NLS-1$
66
public static final String JavaDoc KEY_INPUT = "input"; //$NON-NLS-1$
67
public static final String JavaDoc KEY_MESSAGE = "message"; //$NON-NLS-1$
68
public static final String JavaDoc KEY_URL = "url"; //$NON-NLS-1$
69
public static final String JavaDoc KEY_DIRECTION = "direction"; //$NON-NLS-1$
70

71
72     public static final String JavaDoc VALUE_BACKWARD = "backward"; //$NON-NLS-1$
73
public static final String JavaDoc VALUE_FORWARD = "forward"; //$NON-NLS-1$
74
public static final String JavaDoc VALUE_HOME = "home"; //$NON-NLS-1$
75

76     private String JavaDoc action = null;
77     private Properties parameters = null;
78
79     /**
80      * Prevent creation. Must be created through an IntroURLParser. This
81      * constructor assumed we have a valid intro url.
82      *
83      * @param url
84      */

85     IntroURL(String JavaDoc action, Properties parameters) {
86         this.action = action;
87         this.parameters = parameters;
88     }
89
90     /**
91      * Executes whatever valid Intro action is embedded in this Intro URL.
92      *
93      */

94     public boolean execute() {
95         final boolean[] result = new boolean[1];
96         Display display = Display.getCurrent();
97         BusyIndicator.showWhile(display, new Runnable JavaDoc() {
98
99             public void run() {
100                 result[0] = doExecute();
101             }
102         });
103         return result[0];
104     }
105
106     private boolean doExecute() {
107
108         // check for all supported Intro actions first.
109
if (action.equals(CLOSE))
110             return closeIntro();
111
112         else if (action.equals(SET_STANDBY_MODE))
113             // Sets the state of the intro part. Does not care about passing
114
// input to the part.
115
return setStandbyState(getParameter(KEY_STANDBY));
116
117         else if (action.equals(SHOW_STANDBY))
118             return handleStandbyState(getParameter(KEY_PART_ID),
119                     getParameter(KEY_INPUT));
120
121         else if (action.equals(SHOW_HELP))
122             // display the full Help System.
123
return showHelp();
124
125         else if (action.equals(SHOW_HELP_TOPIC))
126             // display a Help System Topic.
127
return showHelpTopic(getParameter(KEY_ID));
128
129         else if (action.equals(OPEN_BROWSER))
130             // display url in external browser
131
return openBrowser(getParameter(KEY_URL),
132                     getParameter(KEY_PLUGIN_ID));
133
134         else if (action.equals(RUN_ACTION))
135             // run an Intro action. Get the pluginId and the class keys. Pass
136
// the parameters and the standby state.
137
return runAction(getParameter(KEY_PLUGIN_ID),
138                     getParameter(KEY_CLASS), parameters,
139                     getParameter(KEY_STANDBY));
140
141         else if (action.equals(SHOW_PAGE))
142             // display an Intro Page.
143
return showPage(getParameter(KEY_ID), getParameter(KEY_STANDBY));
144
145         else if (action.equals(SHOW_MESSAGE))
146             return showMessage(getParameter(KEY_MESSAGE));
147
148         else if (action.equals(NAVIGATE))
149             return navigate(getParameter(KEY_DIRECTION));
150
151         else
152             return handleCustomAction();
153     }
154
155
156     private boolean closeIntro() {
157         // Relies on Workbench.
158
return IntroPlugin.closeIntro();
159     }
160
161     /**
162      * Sets the into part to standby, and shows the passed standby part, with
163      * the given input.
164      *
165      * @param partId
166      * @param input
167      */

168     private boolean handleStandbyState(String JavaDoc partId, String JavaDoc input) {
169         // set intro to standby mode. we know we have a customizable part.
170
CustomizableIntroPart introPart = (CustomizableIntroPart) IntroPlugin
171                 .getIntro();
172         if (introPart == null)
173             introPart = (CustomizableIntroPart) IntroPlugin.showIntro(true);
174         // store the flag to indicate that standbypart is needed.
175
introPart.getControl().setData(IIntroConstants.SHOW_STANDBY_PART,
176                 "true"); //$NON-NLS-1$
177
IntroPlugin.setIntroStandby(true);
178         StandbyPart standbyPart = (StandbyPart) introPart
179                 .getAdapter(StandbyPart.class);
180
181         boolean success = standbyPart.showContentPart(partId, input);
182         if (success)
183             return true;
184
185         // we do not have a valid partId or we failed to instantiate part or
186
// create the part content, show empty part and signal failure.
187
standbyPart.setTopControl(IIntroConstants.EMPTY_STANDBY_CONTENT_PART);
188         return false;
189     }
190
191     /**
192      * Set the Workbench Intro Part state.
193      *
194      * @param state
195      */

196     private boolean setStandbyState(String JavaDoc state) {
197         if (state == null)
198             return false;
199         boolean standby = state.equals("true") ? true : false; //$NON-NLS-1$
200
IIntroPart introPart = IntroPlugin.showIntro(standby);
201         if (introPart == null)
202             return false;
203         else
204             return true;
205     }
206
207
208     /**
209      * Run an action
210      */

211     private boolean runAction(String JavaDoc pluginId, String JavaDoc className,
212             Properties parameters, String JavaDoc standbyState) {
213
214         Object JavaDoc actionObject = ModelLoaderUtil.createClassInstance(pluginId,
215                 className);
216         try {
217             if (actionObject instanceof IIntroAction) {
218                 IIntroAction introAction = (IIntroAction) actionObject;
219                 IIntroSite site = IntroPlugin.getDefault().getIntroModelRoot()
220                         .getPresentation().getIntroPart().getIntroSite();
221                 introAction.run(site, parameters);
222             } else if (actionObject instanceof IAction) {
223                 IAction action = (IAction) actionObject;
224                 action.run();
225
226             } else if (actionObject instanceof IActionDelegate) {
227                 final IActionDelegate delegate = (IActionDelegate) actionObject;
228                 if (delegate instanceof IWorkbenchWindowActionDelegate)
229                     ((IWorkbenchWindowActionDelegate) delegate).init(PlatformUI
230                             .getWorkbench().getActiveWorkbenchWindow());
231                 Action proxy = new Action(this.action) {
232
233                     public void run() {
234                         delegate.run(this);
235                     }
236                 };
237                 proxy.run();
238             } else
239                 // we could not create the class.
240
return false;
241             // ran action successfully. Now set intro intro standby if needed.
242
if (standbyState == null)
243                 return true;
244             else
245                 return setStandbyState(standbyState);
246         } catch (Exception JavaDoc e) {
247             Log.error("Could not run action: " + className, e); //$NON-NLS-1$
248
return false;
249         }
250     }
251
252     /**
253      * Open a help topic.
254      */

255     private boolean showHelpTopic(String JavaDoc href) {
256         // WorkbenchHelp takes care of error handling.
257
WorkbenchHelp.displayHelpResource(href);
258         return true;
259     }
260
261     /**
262      * Open the help system.
263      */

264     private boolean showHelp() {
265         WorkbenchHelp.displayHelp();
266         return true;
267     }
268
269     /**
270      * Launch external browser
271      */

272     private boolean openBrowser(String JavaDoc url, String JavaDoc pluginId) {
273         // no need to decode url because we will create another url from this
274
// url anyway. Resolve the url just in case we are trying to load a
275
// plugin relative file.
276
url = IntroModelRoot.resolveURL(url, pluginId);
277         return Util.openBrowser(url);
278     }
279
280     private boolean showMessage(String JavaDoc message) {
281         if (message == null)
282             return false;
283         else {
284             try {
285                 message = URLDecoder.decode(message, "UTF-8"); //$NON-NLS-1$
286
DialogUtil.displayInfoMessage(null, message);
287                 return true;
288             } catch (UnsupportedEncodingException e) {
289                 DialogUtil.displayInfoMessage(null, "IntroURL.failedToDecode", //$NON-NLS-1$
290
new Object JavaDoc[] { message });
291                 return false;
292             }
293         }
294     }
295
296     /**
297      * Display an Intro Page. Take a flag to enable to disable redrawing.
298      * Default is setting redraw to of.
299      * <p>
300      * REVISIT: revisit picking first page.
301      */

302     private boolean showPage(String JavaDoc pageId, String JavaDoc standbyState) {
303         // set the current page id in the model. This will triger appropriate
304
// listener event to the UI. If setting the page in the model fails (ie:
305
// the page was not found in the current model, look for it in loaded
306
// models. return false if failed.
307
// avoid flicker.
308
CustomizableIntroPart currentIntroPart = (CustomizableIntroPart) IntroPlugin
309                 .getIntro();
310         currentIntroPart.getControl().setRedraw(false);
311
312         IntroModelRoot modelRoot = IntroPlugin.getDefault().getIntroModelRoot();
313         boolean success = modelRoot.setCurrentPageId(pageId);
314         if (!success)
315             success = includePageToShow(modelRoot, pageId);
316
317         // we turned drawing off. Turn it on again.
318
currentIntroPart.getControl().setRedraw(true);
319
320         if (success) {
321             // found page
322
modelRoot.getPresentation().updateHistory(pageId);
323             // ran action successfully. Now set intro intro standby if needed.
324
if (standbyState == null)
325                 return true;
326             else
327                 return setStandbyState(standbyState);
328         } else
329             // could not find referenced page.
330
return false;
331     }
332
333     /**
334      * Finds the target page and includes it in passed model.
335      *
336      * @param pageId
337      * @return
338      */

339     private boolean includePageToShow(IntroModelRoot model, String JavaDoc pageId) {
340         AbstractIntroPage page = findPageToShow(pageId);
341         if (page == null) {
342             Log.error("Failed to clone Intro page.", null); //$NON-NLS-1$
343
return false;
344         }
345         // now clone the target page because original model should be kept
346
// intact. Resolve target page first to resolve its includes
347
// properly. Insert presentation shared style at the top of the shared
348
// styles list because once reparented, the shared style is lost.
349
// Finally, add clone page to current model.
350
page.getChildren();
351         // current kind.
352
String JavaDoc currentPresentationKind = model.getPresentation()
353                 .getImplementationKind();
354         // load shared style corresponding to same presentation kind from target
355
// model.
356
IntroPartPresentation targetPresentation = ((IntroModelRoot) page
357                 .getParent()).getPresentation();
358         String JavaDoc targetSharedStyle = targetPresentation
359                 .getSharedStyle(currentPresentationKind);
360         // clone.
361
AbstractIntroPage clonedPage = null;
362         try {
363             clonedPage = (AbstractIntroPage) page.clone();
364         } catch (CloneNotSupportedException JavaDoc ex) {
365             // should never be here.
366
Log.error("Failed to clone Intro model node.", ex); //$NON-NLS-1$
367
return false;
368         }
369         // reparent cloned target to current model.
370
clonedPage.setParent(model);
371         // REVISIT: SWT presentation does not support multiple shared
372
// styles.
373
if (targetSharedStyle != null)
374             // add target model shared style.
375
clonedPage.insertStyle(targetSharedStyle, 0);
376         model.children.add(clonedPage);
377         return model.setCurrentPageId(clonedPage.getId());
378     }
379
380
381     /**
382      * Searches all loaded models for the first page with the given id.
383      *
384      * @param pageId
385      * @return
386      */

387     private AbstractIntroPage findPageToShow(String JavaDoc pageId) {
388         // get all cached models.
389
Hashtable models = ExtensionPointManager.getInst().getIntroModels();
390         Enumeration values = models.elements();
391         while (values.hasMoreElements()) {
392             IntroModelRoot model = (IntroModelRoot) values.nextElement();
393             AbstractIntroPage page = (AbstractIntroPage) model.findChild(
394                     pageId, AbstractIntroElement.ABSTRACT_PAGE);
395             if (page != null)
396                 return page;
397         }
398         // could not find page in any model.
399
return null;
400     }
401
402     /**
403      * Navigate foward in the presentation, whichever one it is.
404      *
405      * @return
406      */

407     private boolean navigate(String JavaDoc direction) {
408         // set intro to standby mode. we know we have a customizable part.
409
CustomizableIntroPart introPart = (CustomizableIntroPart) IntroPlugin
410                 .getIntro();
411         if (introPart == null)
412             // intro is closed. Do nothing.
413
return false;
414
415         IntroPartPresentation presentation = (IntroPartPresentation) introPart
416                 .getAdapter(IntroPartPresentation.class);
417
418         if (direction.equalsIgnoreCase(VALUE_BACKWARD))
419             return presentation.navigateBackward();
420         else if (direction.equalsIgnoreCase(VALUE_FORWARD))
421             return presentation.navigateForward();
422         else if (direction.equalsIgnoreCase(VALUE_HOME))
423             return presentation.navigateHome();
424         return false;
425     }
426
427
428     /**
429      * @return Returns the action imbedded in this URL.
430      */

431     public String JavaDoc getAction() {
432         return action;
433     }
434
435     /**
436      * Return a parameter defined in the Intro URL. Returns null if the
437      * parameter is not defined.
438      *
439      * @param parameterId
440      * @return
441      */

442     public String JavaDoc getParameter(String JavaDoc parameterId) {
443         return parameters.getProperty(parameterId);
444     }
445
446     private boolean handleCustomAction() {
447         IntroURLAction command = ExtensionPointManager.getInst()
448                 .getSharedConfigExtensionsManager().getCommand(action);
449         if (command == null) {
450             DialogUtil.displayInfoMessage(null, "IntroURL.badCommand", //$NON-NLS-1$
451
new Object JavaDoc[] { action });
452             return false;
453         }
454
455         // custom command. execute it.
456
StringBuffer JavaDoc url = new StringBuffer JavaDoc();
457         url.append("http://org.eclipse.ui.intro/"); //$NON-NLS-1$
458
url.append(command.getReplaceValue().trim());
459         if (command.getReplaceValue().indexOf("?") == -1) //$NON-NLS-1$
460
// command does not have parameters.
461
url.append("?"); //$NON-NLS-1$
462
else
463             // command already has parameters.
464
url.append("&"); //$NON-NLS-1$
465
url.append(retrieveInitialQuery());
466         IIntroURL introURL = IntroURLFactory.createIntroURL(url.toString());
467         if (introURL != null)
468             return introURL.execute();
469         else
470             return false;
471     }
472
473
474     /**
475      * Recreate the initial query passed to this URL.
476      *
477      * @return
478      */

479     private String JavaDoc retrieveInitialQuery() {
480         StringBuffer JavaDoc query = new StringBuffer JavaDoc();
481         Enumeration keys = parameters.keys();
482         while (keys.hasMoreElements()) {
483             String JavaDoc key = (String JavaDoc) keys.nextElement();
484             query.append(key);
485             query.append("="); //$NON-NLS-1$
486
query.append(parameters.get(key));
487             if (keys.hasMoreElements())
488                 query.append("&"); //$NON-NLS-1$
489
}
490         return query.toString();
491     }
492
493 }
494
495
Popular Tags