KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2004, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-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.util.ArrayList JavaDoc;
15 import java.util.Map JavaDoc;
16 import java.util.StringTokenizer JavaDoc;
17 import java.util.Vector JavaDoc;
18
19 import org.eclipse.core.runtime.IConfigurationElement;
20 import org.eclipse.core.runtime.IRegistryChangeEvent;
21 import org.eclipse.core.runtime.Platform;
22 import org.eclipse.swt.SWTError;
23 import org.eclipse.swt.widgets.Composite;
24 import org.eclipse.ui.IMemento;
25 import org.eclipse.ui.internal.intro.impl.model.loader.ModelLoaderUtil;
26 import org.eclipse.ui.internal.intro.impl.model.util.ModelUtil;
27 import org.eclipse.ui.internal.intro.impl.presentations.BrowserIntroPartImplementation;
28 import org.eclipse.ui.internal.intro.impl.presentations.FormIntroPartImplementation;
29 import org.eclipse.ui.internal.intro.impl.presentations.TextIntroPartImplementation;
30 import org.eclipse.ui.internal.intro.impl.util.Log;
31 import org.eclipse.ui.internal.intro.impl.util.StringUtil;
32 import org.eclipse.ui.intro.IIntroPart;
33
34 /**
35  * This class models the presentation element contributed to a config extension point. The
36  * Presentation class delegates UI creation to the actual Implementation class, and passes the
37  * IntroPart along to this implementation class. Also, dynamic awarness is honored here.
38  * <p>
39  * Rules:
40  * <ul>
41  * <li>There is no model class for the "implementation" markup element. This presentation class
42  * inherits information from the implementation class that is picked (based on OS, ...).</li>
43  * <li>ID attribute of this model class is the id of the picked implementation element.</li>
44  * <li>Style attribute in this model class is the style of the picked implementation element.</li>
45  * <li>HTMLHeadContent in this model class is the HEAD element under the picked implementation
46  * element, only if the implementation element is a Browser implmenetation.</li>
47  * <li>The UI model class, AbstractIntroPartImplementation, that represents the IntroPart
48  * implementation is cached here for quick access. It is used by intro url actions for manipulation
49  * of UI.<br>
50  * INTRO:This really should be in a UI model class.
51  * <ul>
52  */

53 public class IntroPartPresentation extends AbstractIntroElement {
54
55     protected static final String JavaDoc TAG_PRESENTATION = "presentation"; //$NON-NLS-1$
56
private static final String JavaDoc TAG_IMPLEMENTATION = "implementation"; //$NON-NLS-1$
57

58     private static final String JavaDoc ATT_KIND = "kind"; //$NON-NLS-1$
59
private static final String JavaDoc ATT_STYLE = "style"; //$NON-NLS-1$
60
private static final String JavaDoc ATT_OS = "os"; //$NON-NLS-1$
61
private static final String JavaDoc ATT_WS = "ws"; //$NON-NLS-1$
62
protected static final String JavaDoc ATT_HOME_PAGE_ID = "home-page-id"; //$NON-NLS-1$
63
protected static final String JavaDoc ATT_STANDBY_PAGE_ID = "standby-page-id"; //$NON-NLS-1$
64

65     public static final String JavaDoc BROWSER_IMPL_KIND = "html"; //$NON-NLS-1$
66
public static final String JavaDoc FORMS_IMPL_KIND = "swt"; //$NON-NLS-1$
67
// this implementation kind if not public api. Only used internally for
68
// debugging.
69
private static final String JavaDoc TEXT_IMPL_KIND = "text"; //$NON-NLS-1$
70

71
72     // private String title;
73
private String JavaDoc [] implementationStyles;
74     private String JavaDoc implementationKind;
75     private String JavaDoc homePageId;
76     private String JavaDoc standbyPageId;
77
78     // The Head contributions to this preentation (inherited from child
79
// implementation).
80
private IntroHead head;
81
82     private AbstractIntroPartImplementation implementation;
83
84     private IntroLaunchBarElement launchBar;
85
86     // CustomizableIntroPart and memento instances. Passed to the Implementation
87
// classes.
88
private IIntroPart introPart;
89     private IMemento memento;
90
91     /**
92      *
93      */

94     IntroPartPresentation(IConfigurationElement element) {
95         super(element);
96         homePageId = element.getAttribute(ATT_HOME_PAGE_ID);
97         standbyPageId = element.getAttribute(ATT_STANDBY_PAGE_ID);
98     }
99
100     private void updatePresentationAttributes(IConfigurationElement element) {
101         if (element != null) {
102             // reset (ie: inherit) type and style to be implementation type and
103
// style. Then handle HEAD content for the case of HTML Browser.
104
String JavaDoc value = element.getAttribute(ATT_STYLE);
105             if (value!=null) {
106                 IntroModelRoot root = getModelRoot();
107                 ArrayList JavaDoc list = new ArrayList JavaDoc();
108                 StringTokenizer JavaDoc stok = new StringTokenizer JavaDoc(value, ","); //$NON-NLS-1$
109
for (;stok.hasMoreTokens();) {
110                     String JavaDoc oneStyle = stok.nextToken().trim();
111                     if (root!=null)
112                         oneStyle = root.resolveVariables(oneStyle);
113                     list.add(oneStyle);
114                 }
115                 implementationStyles = (String JavaDoc[])list.toArray(new String JavaDoc[list.size()]);
116             }
117             implementationKind = element.getAttribute(ATT_KIND);
118             // get Head contribution, regardless of implementation class.
119
// Implementation class is created lazily by UI.
120
head = getHead(element);
121             // Resolve.
122
if (implementationStyles!=null) {
123                 for (int i=0; i<implementationStyles.length; i++) {
124                     implementationStyles[i] = ModelUtil.resolveURL(implementationStyles[i], element);
125                 }
126             }
127         }
128     }
129
130     /**
131      * Returns the styles associated with the Presentation. May be null if no shared presentation
132      * style is needed, or in the case of static HTML OOBE.
133      *
134      * @return Returns the array of styles or null if not defined.
135      */

136     public String JavaDoc[] getImplementationStyles() {
137         return implementationStyles;
138     }
139
140     /**
141      * Returns the type attribute of the implementation picked by this presentation.
142      *
143      * @return Returns the implementationKind.
144      */

145     public String JavaDoc getImplementationKind() {
146         return implementationKind;
147     }
148
149     public AbstractIntroPartImplementation getIntroPartImplementation() {
150         return implementation;
151     }
152
153
154     /**
155      * Returns the model class for the Head element under an implementation. Returns null if there
156      * is no head contribution.
157      *
158      * @param element
159      * @return
160      */

161     private IntroHead getHead(IConfigurationElement element) {
162         try {
163             // There should only be one head element. Since elements where
164
// obtained by name, no point validating name.
165
IConfigurationElement[] headElements = element.getChildren(IntroHead.TAG_HEAD);
166             if (headElements.length == 0)
167                 // no contributions. done.
168
return null;
169             IntroHead head = new IntroHead(headElements[0]);
170             head.setParent(this);
171             return head;
172         } catch (Exception JavaDoc e) {
173             Log.error(e.getMessage(), e);
174             return null;
175         }
176     }
177
178     /**
179      * Returns the launch bar element if defined in this presentation, or <code>null</code>
180      * otherwise.
181      *
182      * @since 3.1
183      * @return
184      */

185
186     public IntroLaunchBarElement getLaunchBarElement() {
187         if (launchBar != null)
188             return launchBar;
189         IConfigurationElement[] children = getCfgElement().getChildren("launchBar"); //$NON-NLS-1$
190
if (children.length > 0) {
191             launchBar = new IntroLaunchBarElement(children[0]);
192             launchBar.setParent(this);
193             if (children.length > 1)
194                 Log
195                         .warning("Mutiple Intro Launch bars defined when only one is allowed. Only first one was loaded. "); //$NON-NLS-1$
196
}
197         return launchBar;
198     }
199
200     /**
201      * @param introPart
202      */

203     public void init(IIntroPart introPart, IMemento memento) {
204         // REVISIT: Called when the actual UI needs to be created. Incomplete
205
// separation of model / UI. Will change later. should not get here if
206
// there is no valid implementation.
207
this.introPart = introPart;
208         this.memento = memento;
209     }
210
211     /**
212      * Creates the UI based on the implementation class.
213      *
214      * @see org.eclipse.ui.IWorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
215      */

216     public void createPartControl(Composite parent) {
217         Vector JavaDoc validImplementations = getValidImplementationElements(getCfgElement());
218         IConfigurationElement implementationElement = null;
219         for (int i = 0; i < validImplementations.size(); i++) {
220             implementationElement = (IConfigurationElement) validImplementations.elementAt(i);
221             // you want to pass primed model.
222
updatePresentationAttributes(implementationElement);
223             try {
224                 implementation = createIntroPartImplementation(getImplementationKind());
225                 if (implementation == null)
226                     // failed to create executable.
227
continue;
228
229                 implementation.init(introPart, memento);
230                 implementation.createPartControl(parent);
231                 IntroModelRoot model = getModelRoot();
232                 if (model != null && model.getConfigurer() != null) {
233                     IntroTheme theme = model.getTheme();
234                     Map JavaDoc properties = theme!=null?theme.getProperties():null;
235                     model.getConfigurer().init(introPart.getIntroSite(), properties);
236                 }
237                 if (Log.logInfo)
238                     Log.info("Loading Intro UI implementation from: " //$NON-NLS-1$
239
+ ModelLoaderUtil.getLogString(implementationElement, "kind")); //$NON-NLS-1$
240
break;
241             } catch (SWTError e) {
242                 Log.warning("Failed to create Intro UI implementation from: " //$NON-NLS-1$
243
+ ModelLoaderUtil.getLogString(implementationElement, "kind") + e.getMessage()); //$NON-NLS-1$
244
implementation = null;
245                 implementationElement = null;
246             } catch (Exception JavaDoc e) {
247                 Log.error("Failed to create Intro UI implementation from: " //$NON-NLS-1$
248
+ ModelLoaderUtil.getLogString(implementationElement, "kind"), e); //$NON-NLS-1$
249
implementation = null;
250                 implementationElement = null;
251             }
252         }
253
254         if (implementationElement == null) {
255             // worst case scenario. We failed in all cases.
256
implementation = new FormIntroPartImplementation();
257             try {
258                 implementation.init(introPart, memento);
259                 // simply set the presentation kind since all other attributes
260
// will be null.
261
implementationKind = FORMS_IMPL_KIND;
262             } catch (Exception JavaDoc e) {
263                 // should never be here.
264
Log.error(e.getMessage(), e);
265                 return;
266             }
267             implementation.createPartControl(parent);
268             Log.warning("Loaded UI Forms implementation as a default UI implementation."); //$NON-NLS-1$
269
}
270     }
271
272     /**
273      * Retruns a list of valid implementation elements of the config. Choose correct implementation
274      * element based on os atrributes. Rules: get current OS, choose first contributrion, with os
275      * that matches OS. Otherwise, choose first contribution with no os. Returns null if no valid
276      * implementation is found.
277      */

278     private Vector JavaDoc getValidImplementationElements(IConfigurationElement configElement) {
279
280         Vector JavaDoc validList = new Vector JavaDoc();
281
282         // There can be more than one implementation contribution. Add each
283
// valid one. First start with OS, then WS then no OS.
284
IConfigurationElement[] implementationElements = configElement.getChildren(TAG_IMPLEMENTATION);
285         // IConfigurationElement implementationElement = null;
286

287         if (implementationElements.length == 0)
288             // no contributions. done.
289
return validList;
290
291         String JavaDoc currentOS = Platform.getOS();
292         String JavaDoc currentWS = Platform.getWS();
293
294         // first loop through all to find one with matching OS, with or
295
// without WS.
296
for (int i = 0; i < implementationElements.length; i++) {
297             String JavaDoc os = implementationElements[i].getAttribute(ATT_OS);
298             if (os == null)
299                 // no os, no match.
300
continue;
301
302             if (listValueHasValue(os, currentOS)) {
303                 // found implementation with correct OS. Now try if WS
304
// matches.
305
String JavaDoc ws = implementationElements[i].getAttribute(ATT_WS);
306                 if (ws == null) {
307                     // good OS, and they do not care about WS. we have a
308
// match.
309
validList.add(implementationElements[i]);
310                 } else {
311                     // good OS, and we have WS.
312
if (listValueHasValue(ws, currentWS))
313                         validList.add(implementationElements[i]);
314                 }
315             }
316         }
317
318         // now loop through all to find one with no OS defined, but with a
319
// matching WS.
320
for (int i = 0; i < implementationElements.length; i++) {
321             String JavaDoc os = implementationElements[i].getAttribute(ATT_OS);
322             if (os == null) {
323                 // found implementation with no OS. Now try if WS
324
// matches.
325
String JavaDoc ws = implementationElements[i].getAttribute(ATT_WS);
326                 if (ws == null) {
327                     // no OS, and they do not care about WS. we have a
328
// match.
329
validList.add(implementationElements[i]);
330                 } else {
331                     // no OS, and we have WS.
332
if (listValueHasValue(ws, currentWS))
333                         validList.add(implementationElements[i]);
334                 }
335
336             }
337         }
338
339         return validList;
340
341     }
342
343     /**
344      * Util method that searches for the given value in a comma separated list of values. The list
345      * is retrieved as an attribute value of OS, WS.
346      *
347      */

348     private boolean listValueHasValue(String JavaDoc stringValue, String JavaDoc value) {
349         String JavaDoc[] attributeValues = StringUtil.split(stringValue, ","); //$NON-NLS-1$
350
for (int i = 0; i < attributeValues.length; i++) {
351             if (attributeValues[i].equalsIgnoreCase(value))
352                 return true;
353         }
354         return false;
355     }
356
357     /**
358      * Util method to load shared style from given kind.
359      */

360     public String JavaDoc getSharedStyle(String JavaDoc kind) {
361         // There can be more than one implementation contribution.
362
IConfigurationElement[] implementationElements = getCfgElement().getChildren(TAG_IMPLEMENTATION);
363         // IConfigurationElement implementationElement = null;
364

365         if (implementationElements.length == 0)
366             // no implementations. done.
367
return null;
368
369         // loop through all to find one with matching kind.
370
for (int i = 0; i < implementationElements.length; i++) {
371             String JavaDoc aKind = implementationElements[i].getAttribute(ATT_KIND);
372             if (aKind.equals(kind)) {
373                 // found implementation with matching kind.
374
String JavaDoc style = implementationElements[i].getAttribute(ATT_STYLE);
375                 return ModelUtil.resolveURL(style, getCfgElement());
376             }
377         }
378         return null;
379     }
380
381
382     /**
383      * Creates the actual implementation class. Returns null on failure.
384      *
385      */

386     private AbstractIntroPartImplementation createIntroPartImplementation(String JavaDoc implementationType) {
387         // quick exits
388
if (implementationType == null)
389             return null;
390         if (!implementationType.equals(BROWSER_IMPL_KIND) && !implementationType.equals(FORMS_IMPL_KIND)
391                 && !implementationType.equals(TEXT_IMPL_KIND))
392             return null;
393
394         AbstractIntroPartImplementation implementation = null;
395         try {
396             if (implementationType.equals(BROWSER_IMPL_KIND))
397                 implementation = new BrowserIntroPartImplementation();
398             else if (implementationType.equals(FORMS_IMPL_KIND))
399                 implementation = new FormIntroPartImplementation();
400             else
401                 implementation = new TextIntroPartImplementation();
402         } catch (Exception JavaDoc e) {
403             Log.error("Could not instantiate implementation " //$NON-NLS-1$
404
+ implementationType, e);
405         }
406         return implementation;
407     }
408
409     /**
410      * Returns the the Customizable Intro Part. may return null if init() has not been called yet on
411      * the presentation.
412      *
413      * @return Returns the introPart.
414      */

415     public IIntroPart getIntroPart() {
416         return introPart;
417     }
418
419     /**
420      * Save the current state of the intro. Delegate to the implementation to do the work, as
421      * different implementations may have different requirements.
422      *
423      * @param memento
424      * the memento in which to store state information
425      */

426     public void saveState(IMemento memento) {
427         if (implementation != null)
428             implementation.saveState(memento);
429     }
430
431
432     public void setFocus() {
433         if (implementation != null)
434             implementation.setFocus();
435     }
436
437     public void standbyStateChanged(boolean standby, boolean isStandbyPartNeeded) {
438         if (implementation != null)
439             implementation.standbyStateChanged(standby, isStandbyPartNeeded);
440     }
441
442     public void updateHistory(AbstractIntroPage page) {
443         if (implementation != null)
444             implementation.updateHistory(page);
445     }
446
447
448
449     public boolean navigateForward() {
450         if (implementation != null)
451             return implementation.navigateForward();
452         return false;
453     }
454
455     public boolean navigateBackward() {
456         if (implementation != null)
457             return implementation.navigateBackward();
458         return false;
459     }
460
461     public boolean navigateHome() {
462         if (implementation != null)
463             return implementation.navigateHome();
464         return false;
465     }
466
467
468     /**
469      * Called when the IntroPart is disposed. Forwards the call to the implementation class.
470      */

471     public void dispose() {
472         if (implementation != null)
473             implementation.dispose();
474     }
475
476     /**
477      * Support dynamic awarness. Clear cached models first, then update UI by delegating to
478      * implementation.
479      *
480      * @see org.eclipse.core.runtime.IRegistryChangeListener#registryChanged(org.eclipse.core.runtime.IRegistryChangeEvent)
481      */

482     public void registryChanged(IRegistryChangeEvent event) {
483         if (implementation != null)
484             implementation.registryChanged(event);
485     }
486
487     /**
488      * @return Returns the homePageId.
489      */

490     public String JavaDoc getHomePageId() {
491         return homePageId;
492     }
493
494     /**
495      * @return Returns the homePageId.
496      */

497     public String JavaDoc getStandbyPageId() {
498         return standbyPageId;
499     }
500
501     /*
502      * (non-Javadoc)
503      *
504      * @see org.eclipse.ui.internal.intro.impl.model.IntroElement#getType()
505      */

506     public int getType() {
507         return AbstractIntroElement.PRESENTATION;
508     }
509
510     /**
511      * @return Returns the HTML head conttent to be added to each dynamic html page in this
512      * presentation..
513      */

514     public IntroHead getHead() {
515         return head;
516     }
517
518
519
520
521 }
522
Popular Tags