Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMazen Faraj2004-08-30 22:25:05 +0000
committerMazen Faraj2004-08-30 22:25:05 +0000
commit266616041676a2aba376dcc353f909cd789ca039 (patch)
tree2adfd0c1f11e690b970eda801bd03b1c6b98f2d4 /org.eclipse.ui.intro
parenta87d8603698ae22b879ee84933ec9f89a85455bb (diff)
downloadeclipse.platform.ua-266616041676a2aba376dcc353f909cd789ca039.tar.gz
eclipse.platform.ua-266616041676a2aba376dcc353f909cd789ca039.tar.xz
eclipse.platform.ua-266616041676a2aba376dcc353f909cd789ca039.zip
Merging 3.0.1 changes
Diffstat (limited to 'org.eclipse.ui.intro')
-rw-r--r--org.eclipse.ui.intro/plugin.xml2
-rw-r--r--org.eclipse.ui.intro/schema/IntroContent.exsd252
-rw-r--r--org.eclipse.ui.intro/schema/introContentFileSpec.html83
-rw-r--r--org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/html/IIntroHTMLConstants.java1
-rw-r--r--org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/html/IntroHTMLGenerator.java2181
-rw-r--r--org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/AbstractIntroContainer.java12
-rw-r--r--org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/AbstractIntroElement.java25
-rw-r--r--org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/AbstractIntroPartImplementation.java2
-rw-r--r--org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/IntroContentProvider.java71
-rw-r--r--org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/IntroModelRoot.java3
-rw-r--r--org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/IntroURL.java8
-rw-r--r--org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/loader/BaseExtensionPointManager.java5
-rw-r--r--org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/loader/ContentProviderManager.java111
-rw-r--r--org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/loader/ModelLoaderUtil.java31
-rw-r--r--org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/viewer/IntroModelContentProvider.java5
-rw-r--r--org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/viewer/IntroModelLabelProvider.java4
-rw-r--r--org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/presentations/BrowserIntroPartImplementation.java30
-rw-r--r--org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/presentations/FormIntroPartImplementation.java5
-rw-r--r--org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/presentations/TextIntroPartImplementation.java4
-rw-r--r--org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/swt/PageContentForm.java18
-rw-r--r--org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/swt/PageForm.java2
-rw-r--r--org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/swt/PageStyleManager.java40
-rw-r--r--org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/swt/PageWidgetFactory.java40
-rw-r--r--org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/util/IntroModelSerializer.java23
-rw-r--r--org.eclipse.ui.intro/src/org/eclipse/ui/intro/config/CustomizableIntroPart.java7
-rw-r--r--org.eclipse.ui.intro/src/org/eclipse/ui/intro/config/IIntroAction.java2
-rw-r--r--org.eclipse.ui.intro/src/org/eclipse/ui/intro/config/IIntroContentProvider.java113
-rw-r--r--org.eclipse.ui.intro/src/org/eclipse/ui/intro/config/IIntroContentProviderSite.java39
28 files changed, 1884 insertions, 1235 deletions
diff --git a/org.eclipse.ui.intro/plugin.xml b/org.eclipse.ui.intro/plugin.xml
index e3d538c1d..2a2565f24 100644
--- a/org.eclipse.ui.intro/plugin.xml
+++ b/org.eclipse.ui.intro/plugin.xml
@@ -3,7 +3,7 @@
<plugin
id="org.eclipse.ui.intro"
name="%plugin_name"
- version="3.0.0"
+ version="3.0.1"
provider-name="%provider_name"
class="org.eclipse.ui.internal.intro.impl.IntroPlugin">
diff --git a/org.eclipse.ui.intro/schema/IntroContent.exsd b/org.eclipse.ui.intro/schema/IntroContent.exsd
index fc0cadc57..593efd7dd 100644
--- a/org.eclipse.ui.intro/schema/IntroContent.exsd
+++ b/org.eclipse.ui.intro/schema/IntroContent.exsd
@@ -53,6 +53,7 @@ The subelements used in a dynamic page are as follows: A &lt;b&gt;group&lt;/b&gt
<element ref="html" minOccurs="0" maxOccurs="unbounded"/>
<element ref="title" minOccurs="0" maxOccurs="1"/>
<element ref="anchor" minOccurs="0" maxOccurs="unbounded"/>
+ <element ref="contentProvider" minOccurs="0" maxOccurs="unbounded"/>
</choice>
<attribute name="url" type="string">
<annotation>
@@ -130,6 +131,7 @@ This seperation of pages can be used when performance is an issue, as the conten
<element ref="include" minOccurs="0" maxOccurs="unbounded"/>
<element ref="html" minOccurs="0" maxOccurs="unbounded"/>
<element ref="anchor" minOccurs="0" maxOccurs="unbounded"/>
+ <element ref="contentProvider" minOccurs="0" maxOccurs="unbounded"/>
</choice>
<attribute name="id" type="string" use="required">
<annotation>
@@ -170,6 +172,63 @@ This seperation of pages can be used when performance is an issue, as the conten
</complexType>
</element>
+ <element name="head">
+ <annotation>
+ <documentation>
+ Direct HTML to include in a page&apos;s HEAD content area. It allows for additional html to be added to the HTML HEAD section. This is useful for adding java srcipts or extra styles sheets.
+This markup is only to be used with an HTML based intro part implementation. It is simply ignored in the case of a UI Forms implementation. A page can have more than one head element. An implementation can have one and only one head element (since it is a shared across all pages).
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="src" type="string" use="required">
+ <annotation>
+ <documentation>
+ relative or absolute URL to a file containing HTML to include directly into the HTML head section.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="title">
+ <annotation>
+ <documentation>
+ a snippet of text that can optionally contain escaped HTML tags. It is only used as a Page Title, and so a given page can have a maximum of one title element.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+ unique identifier of this title.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="style-id" type="string">
+ <annotation>
+ <documentation>
+ A means to classifiy this element into a given category so that a common style may be applied
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="filteredFrom">
+ <annotation>
+ <documentation>
+ an optional attribute that allows for filtering a given element out of a specific implementation. For example, if a group has filteredFrom = swt, it means that this group will not appear as content in the swt implementation.
+ </documentation>
+ </annotation>
+ <simpleType>
+ <restriction base="string">
+ <enumeration value="swt">
+ </enumeration>
+ <enumeration value="html">
+ </enumeration>
+ </restriction>
+ </simpleType>
+ </attribute>
+ </complexType>
+ </element>
+
<element name="link">
<annotation>
<documentation>
@@ -288,54 +347,25 @@ no parameters required&lt;br&gt;
</complexType>
</element>
- <element name="html">
+ <element name="text">
<annotation>
<documentation>
- direct HTML to include in the page either by embedding the entire document, or inlining a snippet of HTML in-place. A fallback image or text must be defined for alternative swt presentation rendering.
-&lt;br&gt;
-Embedding allows for a fully defined html file to be embedded within the dynamic page&apos;s content. An HTML &lt;b&gt;object&lt;/b&gt; element is created that references the html file.
-&lt;br&gt;
-Inclusion allows for including an html snippet directly from a file into the dynamic html page.
+ a snippet of text that can optionally contain escaped HTML tags. It can include b and li tags. It can also contain anchors for urls.
+If multiple paragraphs are needed, then the text can be divided into multiple sections each begining and ending with the p tag.
</documentation>
</annotation>
<complexType>
- <choice>
- <element ref="img"/>
- <element ref="text"/>
- </choice>
- <attribute name="id" type="string" use="required">
- <annotation>
- <documentation>
- unique identifier of this HTML element
- </documentation>
- </annotation>
- </attribute>
- <attribute name="src" type="string" use="required">
- <annotation>
- <documentation>
- relative or absolute URL to a file containing HTML
- </documentation>
- </annotation>
- </attribute>
- <attribute name="type" use="required">
+ <attribute name="id" type="string">
<annotation>
<documentation>
- if &apos;embed&apos;, a valid (full) HTML document will be embedded using HTML &apos;OBJECT&apos; tag. If &apos;inline&apos;, value of &apos;src&apos; will be treated as a snippet of HTML to emit &apos;in-place&apos;. (if type is not specified, this html object is ignored by the intro configuration).
+ unique identifier of this text.
</documentation>
</annotation>
- <simpleType>
- <restriction base="string">
- <enumeration value="inline">
- </enumeration>
- <enumeration value="embed">
- </enumeration>
- </restriction>
- </simpleType>
</attribute>
<attribute name="style-id" type="string">
<annotation>
<documentation>
- A means to classifiy this HTML element into a given category so that a common style may be applied.
+ A means to classifiy this element into a given category so that a common style may be applied
</documentation>
</annotation>
</attribute>
@@ -357,24 +387,38 @@ Inclusion allows for including an html snippet directly from a file into the dyn
</complexType>
</element>
- <element name="title">
+ <element name="img">
<annotation>
<documentation>
- a snippet of text that can optionally contain escaped HTML tags. It is only used as a Page Title, and so a given page can have a maximum of one title element.
+ An image that represents intro content and not presentation (as opposed to decoration images defined in styles).
</documentation>
</annotation>
<complexType>
- <attribute name="id" type="string">
+ <attribute name="id" type="string" use="required">
<annotation>
<documentation>
- unique identifier of this title.
+ unique identifier of this image
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="src" type="string" use="required">
+ <annotation>
+ <documentation>
+ the file to load the image from
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="alt" type="string">
+ <annotation>
+ <documentation>
+ the alternative text to use when the image can not be loaded and as tooltip text for the image.
</documentation>
</annotation>
</attribute>
<attribute name="style-id" type="string">
<annotation>
<documentation>
- A means to classifiy this element into a given category so that a common style may be applied
+ A means to classifiy this image into a given category so that a common style may be applied.
</documentation>
</annotation>
</attribute>
@@ -396,25 +440,54 @@ Inclusion allows for including an html snippet directly from a file into the dyn
</complexType>
</element>
- <element name="text">
+ <element name="html">
<annotation>
<documentation>
- a snippet of text that can optionally contain escaped HTML tags. It can include b and li tags. It can also contain anchors for urls.
-If multiple paragraphs are needed, then the text can be divided into multiple sections each begining and ending with the p tag.
+ direct HTML to include in the page either by embedding the entire document, or inlining a snippet of HTML in-place. A fallback image or text must be defined for alternative swt presentation rendering.
+&lt;br&gt;
+Embedding allows for a fully defined html file to be embedded within the dynamic page&apos;s content. An HTML &lt;b&gt;object&lt;/b&gt; element is created that references the html file.
+&lt;br&gt;
+Inclusion allows for including an html snippet directly from a file into the dynamic html page.
</documentation>
</annotation>
<complexType>
- <attribute name="id" type="string">
+ <choice>
+ <element ref="img"/>
+ <element ref="text"/>
+ </choice>
+ <attribute name="id" type="string" use="required">
<annotation>
<documentation>
- unique identifier of this text.
+ unique identifier of this HTML element
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="src" type="string" use="required">
+ <annotation>
+ <documentation>
+ relative or absolute URL to a file containing HTML
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="type" use="required">
+ <annotation>
+ <documentation>
+ if &apos;embed&apos;, a valid (full) HTML document will be embedded using HTML &apos;OBJECT&apos; tag. If &apos;inline&apos;, value of &apos;src&apos; will be treated as a snippet of HTML to emit &apos;in-place&apos;. (if type is not specified, this html object is ignored by the intro configuration).
</documentation>
</annotation>
+ <simpleType>
+ <restriction base="string">
+ <enumeration value="inline">
+ </enumeration>
+ <enumeration value="embed">
+ </enumeration>
+ </restriction>
+ </simpleType>
</attribute>
<attribute name="style-id" type="string">
<annotation>
<documentation>
- A means to classifiy this element into a given category so that a common style may be applied
+ A means to classifiy this HTML element into a given category so that a common style may be applied.
</documentation>
</annotation>
</attribute>
@@ -467,73 +540,19 @@ If multiple paragraphs are needed, then the text can be divided into multiple se
</complexType>
</element>
- <element name="head">
- <annotation>
- <documentation>
- Direct HTML to include in a page&apos;s HEAD content area. It allows for additional html to be added to the HTML HEAD section. This is useful for adding java srcipts or extra styles sheets.
-This markup is only to be used with an HTML based intro part implementation. It is simply ignored in the case of a UI Forms implementation. A page can have more than one head element. An implementation can have one and only one head element (since it is a shared across all pages).
- </documentation>
- </annotation>
- <complexType>
- <attribute name="src" type="string" use="required">
- <annotation>
- <documentation>
- relative or absolute URL to a file containing HTML to include directly into the HTML head section.
- </documentation>
- </annotation>
- </attribute>
- </complexType>
- </element>
-
- <element name="img">
+ <element name="anchor">
<annotation>
<documentation>
- An image that represents intro content and not presentation (as opposed to decoration images defined in styles).
+ an anchor is the element used to declare extensibility. It is a location in the configurtaion that allows for external contributions. Only anchors are valid target values for the path attribute in an extensionContent
</documentation>
</annotation>
<complexType>
<attribute name="id" type="string" use="required">
<annotation>
<documentation>
- unique identifier of this image
- </documentation>
- </annotation>
- </attribute>
- <attribute name="src" type="string" use="required">
- <annotation>
- <documentation>
- the file to load the image from
- </documentation>
- </annotation>
- </attribute>
- <attribute name="alt" type="string">
- <annotation>
- <documentation>
- the alternative text to use when the image can not be loaded and as tooltip text for the image.
- </documentation>
- </annotation>
- </attribute>
- <attribute name="style-id" type="string">
- <annotation>
- <documentation>
- A means to classifiy this image into a given category so that a common style may be applied.
- </documentation>
- </annotation>
- </attribute>
- <attribute name="filteredFrom">
- <annotation>
- <documentation>
- an optional attribute that allows for filtering a given element out of a specific implementation. For example, if a group has filteredFrom = swt, it means that this group will not appear as content in the swt implementation.
+ unique id to identify this anchor.
</documentation>
</annotation>
- <simpleType>
- <restriction base="string">
- <enumeration value="swt">
- </enumeration>
- <enumeration value="html">
- </enumeration>
- </restriction>
- </simpleType>
</attribute>
</complexType>
</element>
@@ -576,17 +595,36 @@ This markup is only to be used with an HTML based intro part implementation. It
</complexType>
</element>
- <element name="anchor">
+ <element name="contentProvider">
<annotation>
<documentation>
- an anchor is the element used to declare extensibility. It is a location in the configurtaion that allows for external contributions. Only anchors are valid target values for the path attribute in an extensionContent
+ A proxy for an intro content provider, which allows an intro page to dynamically pull data from various sources (e.g., the web, eclipse, etc) and provide content at runtime based on this dynamic data. If the IIntroContentProvider class that is specified in the class attribute can not be loaded, then the contents of the text element will be rendered instead.
+This is a dynamic version of the html intro tag. While the html tag allows for embedding or inlining a static html content into the generated html intro page, the contentProvider tag allows for dynamic creation of that content at runtime.
+Another difference between the tags is that the html tag is only supported for the HTML presentation, while this contentProvider tag is supported for both the HTML and SWT presentations.
</documentation>
</annotation>
<complexType>
- <attribute name="id" type="string">
+ <all>
+ <element ref="text" minOccurs="0" maxOccurs="1"/>
+ </all>
+ <attribute name="id" type="string" use="required">
<annotation>
<documentation>
- unique id to identify this anchor.
+ unique identifier of this HTML element
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="pluginId" type="string">
+ <annotation>
+ <documentation>
+ The id of the plugin that contains the IContentProvider class specified by the class attribute. This is an optional attribute that should be used if the class doesn&apos;t come from the same plugin that defined the markup.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ A class that implements the IContentProvider interface
</documentation>
</annotation>
</attribute>
diff --git a/org.eclipse.ui.intro/schema/introContentFileSpec.html b/org.eclipse.ui.intro/schema/introContentFileSpec.html
index 839c25cb1..eac8b3b8a 100644
--- a/org.eclipse.ui.intro/schema/introContentFileSpec.html
+++ b/org.eclipse.ui.intro/schema/introContentFileSpec.html
@@ -3,7 +3,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
+<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="stylesheet" href="style.css" charset="ISO-8859-1" type="text/css">
@@ -23,20 +23,22 @@ DTD fragments (machine readable <a href="IntroContent.exsd">XML schema</a>).</p>
The introContent element defines the body of the intro content file. The content file is made up of pages, shared groups that can be included in multiple pages, and extensions to anchor points defined in other configurations.</p>
<br><br>
<h2><code>page</code></h2>
-<br><p class=code id=dtd>&lt;!ELEMENT <a name="e.page">page</a> (<a href="#e.group">group</a>* | <a href="#e.link">link</a>* | <a href="#e.text">text</a>* | <a href="#e.head">head</a>* | <a href="#e.img">img</a>* | <a href="#e.include">include</a>* | <a href="#e.html">html</a>* | <a href="#e.title">title</a>? | <a href="#e.anchor">anchor</a>*)&gt;</p>
+<br><p class=code id=dtd>&lt;!ELEMENT <a name="e.page">page</a> (<a href="#e.group">group</a>* | <a href="#e.link">link</a>* | <a href="#e.text">text</a>* | <a href="#e.head">head</a>* | <a href="#e.img">img</a>* | <a href="#e.include">include</a>* | <a href="#e.html">html</a>* | <a href="#e.title">title</a>? | <a href="#e.anchor">anchor</a>*
+| <a href="#e.contentProvider">contentProvider</a>*)&gt;</p>
<p class=code id=dtd>&lt;!ATTLIST page</p>
<p class=code id=dtdAttlist>url&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CDATA #IMPLIED<p class=code id=dtdAttlist>id&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CDATA #REQUIRED<p class=code id=dtdAttlist>style&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CDATA #IMPLIED<p class=code id=dtdAttlist>alt-style&nbsp;&nbsp;&nbsp;&nbsp;CDATA #IMPLIED<p class=code id=dtdAttlist>filteredFrom&nbsp;(swt|html) <p class=code id=dtdAttlist>content&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CDATA #IMPLIED<p class=code id=dtdAttlist>style-id&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CDATA #IMPLIED&gt;</p>
<p></p>
<p class=ConfigMarkup id=elementDesc>
This element is used to describe a page to be displayed. The intro can display both dynamic and static pages.<br>
<br>
-Content for dynamic pages is generated from the subelements of the page, described below. The style or alt-style will be applied depending on the presentation. The styles can be further enhanced by referencing the id or class-id.<br>
+Content for dynamic pages is generated from the sub elements of the page, described below. The style or alt-style will be applied depending on the presentation. The styles can be further enhanced by referencing the id or class-id.<br>
<br>
Static pages allow for the reuse of existing HTML documents within one's introduction, and can be linked to from any static or dynamic page. Static pages are not defined in a page element, they are simply html files that can be linked to by other pages.<br>
<br>
The home page, whose id is specified in the presentation element of the intro config extension point, can have a url indicating that it is a static page. If no url is specified then the home page is assumed to be dynamic. All other pages described using the page element are dynamic.
<br>
- Also note that when the SWT presentation is used and a static page is to be displayed, an external brower is launched and the current page remains visible.<br>
+ Also note that when the SWT presentation is used and a static page is to be displayed, an external
+browser is launched and the current page remains visible.<br>
<br>
The subelements used in a dynamic page are as follows: A <b>group</b> subelement is used to group related content and apply style across the grouped content. A <b>link</b> subelement defines a link which can be used to link to a static or dynamic page and run an intro action/command. A link is normally defined at the page level to navigate between main pages versus links within a page. A <b>text</b> subelement defines textual content at the page level. A <b>head</b> subelement is only applicable for the Web based presentation and allows for additional html to be added to the HTML <b>head</b> section. This is useful for adding java scripts or extra style sheets. An <b>img</b> subelement defines image content for the page level. An <b>include</b> subelement allows for reuse of any element other than a page. An <b>html</b> subelement is only applicable for the Web based presentation and allows for the embedding or inclusion of html into the page's content. Embedding allows for a fully defined html file to be embeded within an HTML <b>object</b> by referencing the html file. Inclusion allows for including an html snippet directly from an html file. A <b>title</b> subelement defines the title of the page. An <b>anchor</b> subelement defines a point where external contributions can be made by an &lt;extensionContent&gt; element.</p>
@@ -45,11 +47,11 @@ The subelements used in a dynamic page are as follows: A <b>group</b> subelement
<li><b>url</b> - The optional relative path to an HTML file. When using the Web based presentation, this HTML file will be displayed instead of any content defined for this page. This attribute is only applicable to the home page, which is identified in the presentation element of the intro config extension point. It is ignored for all other pages.</li>
<li><b>id</b> - A unique name that can be used to identify this page.</li>
<li><b>style</b> - A relative path to a CSS file which is applied to the page only when using the Web based presentation.</li>
-<li><b>alt-style</b> - A relative path to a SWT presentation properies file which is applied to the page only when using the SWT based presentation.</li>
+<li><b>alt-style</b> - A relative path to a SWT presentation properties file which is applied to the page only when using the SWT based presentation.</li>
<li><b>filteredFrom</b> - an optional attribute that allows for filtering a given element out of a specific implementation. For example, if a group has filteredFrom = swt, it means that this group will not appear as content in the swt implementation.</li>
<li><b>content</b> - an optional attribute which can define the location of an introContent.xml file that represents the content of this page. When this attribute is defined, all children and attributes in this page element, except id, are ignored. This is because the content of this page is now assumed to reside in the xml file pointed to by the content file attribute. When resolving to the content of this file, the page with an id that matches the id defined in this page element is chosen.
-This seperation of pages can be used when performance is an issue, as the content of a page is now loaded more lazily.</li>
-<li><b>style-id</b> - A means to classifiy the page into a given category so that a common style may be applied.</li>
+This separation of pages can be used when performance is an issue, as the content of a page is now loaded more lazily.</li>
+<li><b>style-id</b> - A means to classify the page into a given category so that a common style may be applied.</li>
</ul>
<h2><code>group</code></h2>
<br><p class=code id=dtd>&lt;!ELEMENT <a name="e.group">group</a> (<a href="#e.group">group</a>* | <a href="#e.link">link</a>* | <a href="#e.text">text</a>* | <a href="#e.img">img</a>* | <a href="#e.include">include</a>* | <a href="#e.html">html</a>* | <a href="#e.anchor">anchor</a>*)&gt;</p>
@@ -62,7 +64,7 @@ Used to group related content, content that should have similar style applied, o
<ul class=ConfigMarkup id=attlistDesc>
<li><b>id</b> - unique identifier of the group</li>
<li><b>label</b> - a label or heading for this group</li>
-<li><b>style-id</b> - A means to classifiy this group into a given category so that a common style may be applied.</li>
+<li><b>style-id</b> - A means to classify this group into a given category so that a common style may be applied.</li>
<li><b>filteredFrom</b> - an optional attribute that allows for filtering a given element out of a specific implementation. For example, if a group has filteredFrom = swt, it means that this group will not appear as content in the swt implementation.</li>
</ul>
<h2><code>link</code></h2>
@@ -83,7 +85,7 @@ Can link to a static HTML file, an external web site, or can run an Intro URL ac
The predefined actions will be described using this format:
<br>
<p style="margin-left:15px;">
-<b>action name</b> - descripton of action<br>
+<b>action name</b> - description of action<br>
<i>action parameter1</i> - description of parameter<br>
<i>action parameter2 (optional)</i> - description of parameter<br>
<i>action parameter3 (optional) = ("true" | "false") "false"</i> - description of parameter, choice of either true or false and "false" is the default<br>
@@ -107,14 +109,15 @@ no parameters required<br>
<b>runAction</b> - runs the specified action<br>
<i>class</i> - the fully qualified class name of the class that implements one of <code>org.eclipse.ui.intro.config.IIntroAction</code>,
- <code>org.eclipse.jface.actino.IAction</code>, or <code>org.eclipse.ui.IActionDelegate</code><br>
+ <code>org.eclipse.jface.action.IAction</code>, or <code>org.eclipse.ui.IActionDelegate</code><br>
<i>pluginId</i> - The id of the plug-in which contains the class.<br>
<i>standby (optional) = ("true" | "false") "false"</i> - indicate whether to set the intro into standby mode after executing the action<br>
additional parameters - any additional parameters are passed to actions that implement <code>org.eclipse.ui.intro.config.IIntroAction</code><br>
<br>
<b>setStandbyMode</b> - sets the state of the intro part<br>
-<i>standby = ("true" | "false")</i> - true to put the intro part in its partially visible standy mode, and false to make it fully visible<br>
+<i>standby = ("true" | "false")</i> - true to put the intro part in its partially visible
+standby mode, and false to make it fully visible<br>
<br>
<b>showHelp</b> - Open the help system.<br>
@@ -139,7 +142,7 @@ no parameters required<br>
<i>standby (optional) = ("true" | "false") "false"</i> - indicate whether to set the intro into standby mode after showing the page<br>
</p>
<br></li>
-<li><b>style-id</b> - A means to classifiy this link into a given category so that a common style may be applied.</li>
+<li><b>style-id</b> - A means to classify this link into a given category so that a common style may be applied.</li>
<li><b>filteredFrom</b> - an optional attribute that allows for filtering a given element out of a specific implementation. For example, if a group has filteredFrom = swt, it means that this group will not appear as content in the swt implementation.</li>
</ul>
<h2><code>html</code></h2>
@@ -158,7 +161,7 @@ Inclusion allows for including an html snippet directly from a file into the dyn
<li><b>id</b> - unique identifier of this HTML element</li>
<li><b>src</b> - relative or absolute URL to a file containing HTML</li>
<li><b>type</b> - if 'embed', a valid (full) HTML document will be embedded using HTML 'OBJECT' tag. If 'inline', value of 'src' will be treated as a snippet of HTML to emit 'in-place'. (if type is not specified, this html object is ignored by the intro configuration).</li>
-<li><b>style-id</b> - A means to classifiy this HTML element into a given category so that a common style may be applied.</li>
+<li><b>style-id</b> - A means to classify this HTML element into a given category so that a common style may be applied.</li>
<li><b>filteredFrom</b> - an optional attribute that allows for filtering a given element out of a specific implementation. For example, if a group has filteredFrom = swt, it means that this group will not appear as content in the swt implementation.</li>
</ul>
<h2><code>title</code></h2>
@@ -181,11 +184,12 @@ a snippet of text that can optionally contain escaped HTML tags. It is only used
<p></p>
<p class=ConfigMarkup id=elementDesc>
a snippet of text that can optionally contain escaped HTML tags. It can include b and li tags. It can also contain anchors for urls.
-If multiple paragraphs are needed, then the text can be divided into multiple sections each begining and ending with the p tag.</p>
+If multiple paragraphs are needed, then the text can be divided into multiple sections each
+beginning and ending with the p tag.</p>
<br>
<ul class=ConfigMarkup id=attlistDesc>
<li><b>id</b> - unique identifier of this text.</li>
-<li><b>style-id</b> - A means to classifiy this element into a given category so that a common style may be applied</li>
+<li><b>style-id</b> - A means to classify this element into a given category so that a common style may be applied</li>
<li><b>filteredFrom</b> - an optional attribute that allows for filtering a given element out of a specific implementation. For example, if a group has filteredFrom = swt, it means that this group will not appear as content in the swt implementation.</li>
</ul>
<h2><code>include</code></h2>
@@ -207,7 +211,8 @@ expands an element targeted by the given path and optional configId attributes.
<p class=code id=dtdAttlist>src&nbsp;CDATA #REQUIRED&gt;</p>
<p></p>
<p class=ConfigMarkup id=elementDesc>
-Direct HTML to include in a page's HEAD content area. It allows for additional html to be added to the HTML HEAD section. This is useful for adding java srcipts or extra styles sheets.
+Direct HTML to include in a page's HEAD content area. It allows for additional html to be added to the HTML HEAD section. This is useful for adding java
+scripts or extra styles sheets.
This markup is only to be used with an HTML based intro part implementation. It is simply ignored in the case of a UI Forms implementation. A page can have more than one head element. An implementation can have one and only one head element (since it is a shared across all pages).</p>
<br>
<ul class=ConfigMarkup id=attlistDesc>
@@ -225,7 +230,7 @@ An image that represents intro content and not presentation (as opposed to decor
<li><b>id</b> - unique identifier of this image</li>
<li><b>src</b> - the file to load the image from</li>
<li><b>alt</b> - the alternative text to use when the image can not be loaded and as tooltip text for the image.</li>
-<li><b>style-id</b> - A means to classifiy this image into a given category so that a common style may be applied.</li>
+<li><b>style-id</b> - A means to classify this image into a given category so that a common style may be applied.</li>
<li><b>filteredFrom</b> - an optional attribute that allows for filtering a given element out of a specific implementation. For example, if a group has filteredFrom = swt, it means that this group will not appear as content in the swt implementation.</li>
</ul>
<h2><code>extensionContent</code></h2>
@@ -234,25 +239,59 @@ An image that represents intro content and not presentation (as opposed to decor
<p class=code id=dtdAttlist>style&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CDATA #IMPLIED<p class=code id=dtdAttlist>alt-style&nbsp;CDATA #IMPLIED<p class=code id=dtdAttlist>path&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CDATA #REQUIRED&gt;</p>
<p></p>
<p class=ConfigMarkup id=elementDesc>
-The content to be added to the target anchor. Only one extensionContent is allowed in a given configExtension because if this extension could not be resolved (if the config could not be found, or the target anchor element could not be found) then the pages and/or groups in the extension need to be ingnored.</p>
+The content to be added to the target anchor. Only one extensionContent is allowed in a given configExtension because if this extension could not be resolved (if the config could not be found, or the target anchor element could not be found) then the pages and/or groups in the extension need to be
+ignored.</p>
<br>
<ul class=ConfigMarkup id=attlistDesc>
<li><b>style</b> - A relative path to a CSS file which is applied to the page only when using the Web based presentation.</li>
-<li><b>alt-style</b> - A relative path to a SWT presentation properies file which is applied to the page only when using the SWT based presentation.</li>
+<li><b>alt-style</b> - A relative path to a SWT presentation properties file which is applied to the page only when using the SWT based presentation.</li>
<li><b>path</b> - the path that uniquely represents the path to an anchor. (e.g. page/group1/group2/anchorId) within the target configuration to be extended. It can only be an anchor which can be in any page or group, including shared groups at configuration level</li>
</ul>
<h2><code>anchor</code></h2>
<br><p class=code id=dtd>&lt;!ELEMENT <a name="e.anchor">anchor</a> EMPTY&gt;</p>
<p class=code id=dtd>&lt;!ATTLIST anchor</p>
-<p class=code id=dtdAttlist>id&nbsp;CDATA #IMPLIED&gt;</p>
+<p class=code id=dtdAttlist>id&nbsp;CDATA #REQUIRED&gt;</p>
<p></p>
<p class=ConfigMarkup id=elementDesc>
-an anchor is the element used to declare extensibility. It is a location in the configurtaion that allows for external contributions. Only anchors are valid target values for the path attribute in an extensionContent</p>
+an anchor is the element used to declare extensibility. It is a location in the
+configuration that allows for external contributions. Only anchors are valid target values for the path attribute in an extensionContent</p>
<br>
<ul class=ConfigMarkup id=attlistDesc>
<li><b>id</b> - unique id to identify this anchor.</li>
</ul>
+&nbsp;<h2 id="dtd"><code>contentProvider</code></h2>
+<p class="code" id="dtd">&nbsp;</p>
+<p class="code" id="dtd">&lt;!ELEMENT <a name="e.contentProvider">contentProvider</a>
+(<a href="#e.text">text</a>)&gt;</p>
+<p class="code" id="dtd">&lt;!ATTLIST contentProvider</p>
+<p class="code" id="dtdAttlist">id&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CDATA #REQUIRED </p>
+<p class="code" id="dtdAttlist">pluginId&nbsp;CDATA #IMPLIED </p>
+<p class="code" id="dtdAttlist">class&nbsp;&nbsp;&nbsp;&nbsp;CDATA #REQUIRED&gt;</p>
+<p>&nbsp;</p>
+<p class="ConfigMarkup" id="elementDesc">A proxy for an intro content provider,
+which allows an intro page to dynamically pull data from various sources (e.g.,
+the web, eclipse, etc) and provide content at runtime based on this dynamic
+data. If the IIntroContentProvider class that is specified in the class
+attribute can not be loaded, then the contents of the text element will be
+rendered instead. This is a dynamic version of the html intro tag. While the
+html tag allows for embedding or inlining a static html content into the
+generated html intro page, the contentProvider tag allows for dynamic creation
+of that content at runtime. Another difference between the tags is that the html
+tag is only supported for the HTML presentation, while this contentProvider tag
+is supported for both the HTML and SWT presentations.</p>
+<p><br>
+&nbsp;</p>
+<ul class="ConfigMarkup" id="attlistDesc">
+ <li><b>id</b> - unique identifier of this HTML element </li>
+ <li><b>pluginId</b> - The id of the plug-in that contains the IContentProvider
+ class specified by the class attribute. This is an optional attribute that
+ should be used if the class doesn't come from the same plug-in that defined
+ the markup. </li>
+ <li><b>class</b> - A class that implements the IContentProvider interface </li>
+</ul>
+<p>
<br><br>
+</p>
<p class=note id=copyright>
</p>
@@ -267,4 +306,4 @@ this distribution, and is available at
</body>
-</html>
+</html> \ No newline at end of file
diff --git a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/html/IIntroHTMLConstants.java b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/html/IIntroHTMLConstants.java
index 0639c4749..4bd9ed877 100644
--- a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/html/IIntroHTMLConstants.java
+++ b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/html/IIntroHTMLConstants.java
@@ -62,6 +62,7 @@ public interface IIntroHTMLConstants {
String DIV_ID_PRESENTATION_HEADER = "presentation-header"; //$NON-NLS-1$
String DIV_ID_PAGE = "page"; //$NON-NLS-1$
String DIV_CLASS_INLINE_HTML = "inline-html"; //$NON-NLS-1$
+ String DIV_CLASS_PROVIDED_CONTENT = "provided-content"; //$NON-NLS-1$
String ANCHOR_CLASS_LINK = "link"; //$NON-NLS-1$
String IMAGE_SRC_BLANK = "icons/blank.gif"; //$NON-NLS-1$
diff --git a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/html/IntroHTMLGenerator.java b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/html/IntroHTMLGenerator.java
index c10fd5432..30bb25a14 100644
--- a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/html/IntroHTMLGenerator.java
+++ b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/html/IntroHTMLGenerator.java
@@ -1,1051 +1,1166 @@
/*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
+ * Copyright (c) 2004 IBM Corporation and others. All rights reserved. This
+ * program and the accompanying materials are made available under the terms of
+ * the Common Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/cpl-v10.html
*
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
+ * Contributors: IBM Corporation - initial API and implementation
+ ******************************************************************************/
package org.eclipse.ui.internal.intro.impl.html;
+
import java.io.*;
import java.net.*;
+
import org.eclipse.ui.internal.intro.impl.*;
import org.eclipse.ui.internal.intro.impl.model.*;
+import org.eclipse.ui.internal.intro.impl.model.loader.*;
import org.eclipse.ui.internal.intro.impl.util.*;
+import org.eclipse.ui.intro.config.*;
+
public class IntroHTMLGenerator {
- private AbstractIntroPage introPage;
-
- /**
- * Generates the HTML code that will be presented in the browser widget for
- * the provided intro page.
- *
- * @param page
- * the page to generate HTML for
- * @param title
- * the title of the intro presentation, or null
- */
- public HTMLElement generateHTMLforPage(AbstractIntroPage page) {
- if (page == null)
- return null;
- this.introPage = page;
- // generate and add the appropriate encoding to the top of the document
- // generateEncoding();
- // create the main HTML element, and all of its contents
- return generateHTMLElement();
- }
- private HTMLElement generateEncoding() {
- HTMLElement encoding = new HTMLElement(""); //$NON-NLS-1$
- // TODO: figure out how to handle locale based encoding
- // As far as the HTML generator is concerned, this is probably as
- // simple as asking the model for the information
- return encoding;
- }
- /**
- * Generates the HTML element and its content:
- *
- * <pre>
- *
- * &lt;HTML&gt;
- * &lt;HEAD&gt;
- * head content
- * &lt;/HEAD&gt;
- * &lt;BODY&gt;
- * body content
- * &lt;/BODY&gt;
- * &lt;/HTML&gt;
- *
- * </pre>
- *
- * @return the html HTMLElement
- */
- private HTMLElement generateHTMLElement() {
- // this is the outermost element, so it has no indent
- int indentLevel = 0;
- HTMLElement html = new FormattedHTMLElement(
- IIntroHTMLConstants.ELEMENT_HTML, indentLevel, true);
- HTMLElement head = generateHeadElement(indentLevel + 1);
- HTMLElement body = generateBodyElement(indentLevel + 1);
- html.addContent(head);
- html.addContent(body);
- return html;
- }
- /**
- * Generates the HEAD element and its content:
- *
- * <pre>
- *
- * &lt;HEAD&gt;
- * &lt;BASE href=&quot;base_plugin_location&gt;
- * &lt;style type=&quot;text/css&quot;&gt;HTML, IMG { border: 0px; } &lt;/style&gt;
- * &lt;TITLE&gt;page title &lt;/TITLE&gt;
- * &lt;LINK href=&quot;style sheet&quot;&gt;
- * additional head content, if specified
- * &lt;/HEAD&gt;
- *
- * </pre>
- *
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return the head HTMLElement
- */
- private HTMLElement generateHeadElement(int indentLevel) {
- HTMLElement head = new FormattedHTMLElement(
- IIntroHTMLConstants.ELEMENT_HEAD, indentLevel, true);
- // add the title
- head.addContent(generateTitleElement(null, indentLevel + 1));
- // create the BASE element
- String basePath = HTMLUtil.getResolvedBundleLocation(introPage
- .getBundle());
- HTMLElement base = generateBaseElement(indentLevel + 1, basePath);
- if (base != null)
- head.addContent(base);
- // create the HTML style block
- head.addContent(generateStyleElement(indentLevel + 1));
- // add the presentation style
- String style = IntroPlugin.getDefault().getIntroModelRoot()
- .getPresentation().getImplementationStyle();
- if (style != null)
- head.addContent(generateLinkElement(style, indentLevel + 1));
- //TODO: Should introPage.getStyles() return the main page style as
- // well?
- style = introPage.getStyle();
- if (style != null)
- head.addContent(generateLinkElement(style, indentLevel + 1));
- // add the page's inherited style(s)
- String[] pageStyles = introPage.getStyles();
- for (int i = 0; i < pageStyles.length; i++) {
- style = pageStyles[i];
- if (style != null)
- head.addContent(generateLinkElement(style, indentLevel + 1));
- }
- // if there is additional head conent specified in an external file,
- // include it. Additional head content can be specified at the
- // implementation level (which would apply to ALL pages) and at the
- // page level (which would apply only to that particular page).
- // For the implementation's head contribution:
- StringBuffer content = null;
- IntroHead introHead = IntroPlugin.getDefault().getIntroModelRoot()
- .getPresentation().getHead();
- if (introHead != null) {
- content = readFromFile(introHead.getSrc());
- if (content != null)
- head.addContent(content);
- }
- // For the page's head contribution:
- // TODO: there should only be one of these at the page level, not a
- // collection..
- IntroHead[] htmlHeads = introPage.getHTMLHeads();
- for (int i = 0; i < htmlHeads.length; i++) {
- introHead = htmlHeads[i];
- if (introHead != null) {
- content = readFromFile(introHead.getSrc());
- if (content != null)
- head.addContent(content);
- }
- }
- return head;
- }
- /**
- * Generates the BODY element and its content:
- *
- * <pre>
- *
- * &lt;BODY&gt;
- * &lt;DIV id=&quot;pageId&quot; class=&quot;pageClass&quot;&gt;
- * page content
- * &lt;/DIV&gt;
- * &lt;/BODY&gt;
- *
- * </pre>
- *
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return the body HTMLElement
- */
- private HTMLElement generateBodyElement(int indentLevel) {
- HTMLElement body = new FormattedHTMLElement(
- IIntroHTMLConstants.ELEMENT_BODY, indentLevel, true);
- // Create the div that contains the page content
- String pageId = (introPage.getId() != null)
- ? introPage.getId()
- : IIntroHTMLConstants.DIV_ID_PAGE;
- HTMLElement pageContentDiv = generateDivElement(pageId, indentLevel + 1);
- if (introPage.getStyleId() != null)
- pageContentDiv.addAttribute(IIntroHTMLConstants.ATTRIBUTE_CLASS,
- introPage.getStyleId());
- // Add any children of the page, in the order they are defined
- AbstractIntroElement[] children = introPage.getChildren();
- for (int i = 0; i < children.length; i++) {
- AbstractIntroElement child = children[i];
- // use indentLevel + 2 here, since this element is contained within
- // the pageContentDiv
- HTMLElement childElement = generateIntroElement(child,
- indentLevel + 2);
- if (childElement != null)
- pageContentDiv.addContent(childElement);
- }
- body.addContent(pageContentDiv);
- return body;
- }
- /**
- * Given an IntroElement, generate the appropriate HTMLElement
- *
- * @param element
- * the IntroElement
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return an HTMLElement
- */
- private HTMLElement generateIntroElement(AbstractIntroElement element,
- int indentLevel) {
- if (element == null)
- return null;
- // check to see if this element should be filtered from the HTML
- // presentation
- if(filteredFromPresentation(element))
- return null;
- switch (element.getType()) {
- case AbstractIntroElement.GROUP :
- return generateIntroDiv((IntroGroup) element, indentLevel);
- case AbstractIntroElement.LINK :
- return generateIntroLink((IntroLink) element, indentLevel);
- case AbstractIntroElement.HTML :
- return generateIntroHTML((IntroHTML) element, indentLevel);
- case AbstractIntroElement.IMAGE :
- return generateIntroImage((IntroImage) element, indentLevel);
- case AbstractIntroElement.TEXT :
- return generateIntroText((IntroText) element, indentLevel);
- case AbstractIntroElement.PAGE_TITLE :
- return generateIntroTitle((IntroPageTitle) element, indentLevel);
- default :
- return null;
- }
- }
- /**
- * Create a div element and its content from an IntroDiv:
- *
- * <pre>
- *
- * &lt;div id=&quot;attrvalue&quot;&gt;
- * &lt;h4&gt;&lt;span class=&quot;div-label&quot;&gt;attrvalue&lt;/span&gt;&lt;h4&gt;
- * any defined divs, links, html, images, text, includes
- * &lt;/div&gt;
- *
- * </pre>
- *
- * @param element
- * the IntroDiv
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return a div HTMLElement
- */
- private HTMLElement generateIntroDiv(IntroGroup element, int indentLevel) {
- // Create the outer div element
- HTMLElement divElement = generateDivElement(element.getId(),
- indentLevel);
- // if a div class was specified, add it
- if (element.getStyleId() != null)
- divElement.addAttribute(IIntroHTMLConstants.ATTRIBUTE_CLASS,
- element.getStyleId());
- // Create the div label, if specified
- if (element.getLabel() != null) {
- HTMLElement divLabel = generateTextElement(
- IIntroHTMLConstants.ELEMENT_H4, null,
- IIntroHTMLConstants.SPAN_CLASS_DIV_LABEL, element
- .getLabel(), indentLevel + 1);
- divElement.addContent(divLabel);
- }
- // Add any children of the div, in the order they are defined
- AbstractIntroElement[] children = element.getChildren();
- for (int i = 0; i < children.length; i++) {
- AbstractIntroElement child = children[i];
- HTMLElement childElement = generateIntroElement(child,
- indentLevel + 1);
- if (childElement != null)
- divElement.addContent(childElement);
- }
- return divElement;
- }
- /**
- * Generates an anchor (link) element and its content from an IntroLink:
- *
- * <pre>
- *
- * &lt;A id=linkId class=&quot;link&quot; href=linkHref&gt;
- * &lt;IMG src=&quot;blank.gif&quot;&gt;
- * &lt;SPAN class=&quot;link-label&quot;&gt;linkLabel &lt;/SPAN&gt;
- * &lt;P&gt;&lt;SPAN&gt;text&lt;/SPAN&gt;&lt;/P&gt;
- * &lt;/A&gt;
- *
- * </pre>
- *
- * @param element
- * the IntroLink
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return an anchor (&lt;A&gt;) HTMLElement
- */
- private HTMLElement generateIntroLink(IntroLink element, int indentLevel) {
- HTMLElement anchor = generateAnchorElement(element, indentLevel);
- // add <IMG src="blank.gif">
- String blankImageURL = IntroModelRoot.getPluginLocation(
- IIntroHTMLConstants.IMAGE_SRC_BLANK, IIntroConstants.PLUGIN_ID);
- if (blankImageURL != null) {
- anchor.addContent(generateImageElement(blankImageURL, null,
- IIntroHTMLConstants.IMAGE_CLASS_BG, indentLevel + 1));
- }
- // add link image, if one is specified
- if(element.getImg() != null) {
- HTMLElement img = generateIntroElement(element.getImg(), indentLevel + 1);
- if(img != null)
- anchor.addContent(img);
- }
- // add <SPAN class="link-label">linkLabel</SPAN>
- if (element.getLabel() != null) {
- HTMLElement label = generateSpanElement(
- IIntroHTMLConstants.SPAN_CLASS_LINK_LABEL, indentLevel + 1);
- label.addContent(element.getLabel());
- anchor.addContent(label);
- }
- IntroText linkText = element.getIntroText();
- if (linkText != null && linkText.getText() != null) {
- HTMLElement text = generateIntroElement(
- linkText, indentLevel + 1);
- if(text != null)
- anchor.addContent(text);
- }
- return anchor;
- }
- /**
- * Generate the appropriate HTML from an IntroHTML. If the IntroHTML type is
- * "inline", then the content from the referenced file is emitted as-is into
- * a div element. If the type is "embed", an OBJECT html element is created
- * whose <code>data</code> attribute is equal to the IntroHTML's
- * <code>src</code> value
- *
- * @param element
- * the IntroHTML
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return an HTMLElement
- */
- private HTMLElement generateIntroHTML(IntroHTML element, int indentLevel) {
- if (element.isInlined())
- return generateInlineIntroHTML(element, indentLevel);
- else
- return generateEmbeddedIntroHTML(element, indentLevel);
- }
- /**
- * Generate an image element from an IntroImage:
- *
- * <pre>
- *
- * &lt;IMG src=imageSrc id=imageId&gt;
- *
- * </pre>
- *
- * @param element
- * the IntroImage
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return an img HTMLElement
- */
- private HTMLElement generateIntroImage(IntroImage element, int indentLevel) {
- HTMLElement imageElement = generateImageElement(element.getSrc(),
- element.getAlt(), element.getStyleId(), indentLevel);
- if (element.getId() != null)
- imageElement.addAttribute(IIntroHTMLConstants.ATTRIBUTE_ID, element
- .getId());
- return imageElement;
- }
- /**
- * Generate a paragraph (&lt;P&gt;) element from an IntroText. The paragraph
- * element will contain a span element that will contain the actual text.
- * Providing the span element provides additional flexibility for CSS
- * designers.
- *
- * <pre>
- *
- * &lt;P&gt;&lt;SPAN&gt;spanContent&lt;/SPAN&gt;&lt;/P&gt;
- *
- * </pre>
- *
- * @param element
- * the IntroText
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return a paragraph HTMLElement
- */
- private HTMLElement generateIntroText(IntroText element, int indentLevel) {
- String spanClass = (element.getStyleId() != null) ? element
- .getStyleId() : IIntroHTMLConstants.SPAN_CLASS_TEXT;
- HTMLElement textElement = generateTextElement(
- IIntroHTMLConstants.ELEMENT_PARAGRAPH, element.getId(),
- spanClass, element.getText(), indentLevel);
- return textElement;
- }
- /**
- * @param element
- * @param indentLevel
- * @return
- */
- private HTMLElement generateIntroTitle(IntroPageTitle element,
- int indentLevel) {
- HTMLElement titleElement = generateHeaderDiv(element.getId(), element
- .getStyleId(), IIntroHTMLConstants.ELEMENT_H1, element
- .getTitle(), indentLevel);
- return titleElement;
- }
- /**
- * Generate "inline" content from an IntroHTML. The content from the file
- * referenced by the IntroHTML's <code>src</code> attribute is emitted
- * as-is into a div element:
- *
- * <pre>
- *
- * &lt;div id=&quot;attrvalue&quot; class=&quot;attrvalue2&quot;&gt;
- * content from file specified in src attribute
- * &lt;/div&gt;
- *
- * </pre>
- *
- * @param element
- * the IntroHTML
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return a div HTMLElement, or null if there was a problem reading from
- * the file
- */
- private HTMLElement generateInlineIntroHTML(IntroHTML element,
- int indentLevel) {
- StringBuffer content = readFromFile(element.getSrc());
- if (content != null && content.length() > 0) {
- // Create the outer div element
- String divClass = (element.getStyleId() != null) ? element
- .getStyleId() : IIntroHTMLConstants.DIV_CLASS_INLINE_HTML;
- HTMLElement divElement = generateDivElement(element.getId(),
- divClass, indentLevel);
- // add the content of the specified file into the div element
- divElement.addContent(content);
- return divElement;
- }
- return null;
- }
- /**
- * Generate "embedded" content from an IntroHTML. An OBJECT html element is
- * created whose <code>data</code> attribute is equal to the IntroHTML's
- * <code>src</code> value.
- *
- * <pre>
- *
- * &lt;OBJECT type=&quot;text/html&quot; data=&quot;attrvalue&quot;&gt;
- * alternative text in case the object can not be rendered
- * &lt;/OBJECT&gt;
- *
- * </pre>
- *
- * @param element
- * the IntroHTML
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return an object HTMLElement
- */
- private HTMLElement generateEmbeddedIntroHTML(IntroHTML element,
- int indentLevel) {
- HTMLElement objectElement = new FormattedHTMLElement(
- IIntroHTMLConstants.ELEMENT_OBJECT, indentLevel, true);
- objectElement.addAttribute(IIntroHTMLConstants.ATTRIBUTE_TYPE,
- IIntroHTMLConstants.OBJECT_TYPE);
- if (element.getId() != null)
- objectElement.addAttribute(IIntroHTMLConstants.ATTRIBUTE_ID,
- element.getId());
- if (element.getSrc() != null)
- objectElement.addAttribute(IIntroHTMLConstants.ATTRIBUTE_DATA,
- element.getSrc());
- if (element.getStyleId() != null)
- objectElement.addAttribute(IIntroHTMLConstants.ATTRIBUTE_CLASS,
- element.getStyleId());
- // The alternative content is added in case the browser can not render
- // the specified content
- IntroText htmlText = element.getIntroText();
- if (htmlText != null && htmlText.getText() != null) {
- String textClass = (htmlText.getStyleId() != null) ? htmlText
- .getStyleId() : IIntroHTMLConstants.SPAN_CLASS_TEXT;
- HTMLElement text = generateTextElement(
- IIntroHTMLConstants.ELEMENT_PARAGRAPH, htmlText.getId(),
- textClass, element.getText(), indentLevel);
- if (text != null)
- objectElement.addContent(text);
- }
- if (element.getIntroImage() != null) {
- HTMLElement img = generateIntroImage(element.getIntroImage(),
- indentLevel);
- if (img != null)
- objectElement.addContent(img);
- }
- return objectElement;
- }
- /**
- * Generates the BASE element for the head of the html document. Each
- * document can have only one base element
- *
- * <pre>
- * &lt;BASE href=baseURL&gt;
- * </pre>
- *
- * @param indentLevel
- * @param baseURL
- * @return
- */
- private HTMLElement generateBaseElement(int indentLevel, String baseURL) {
- HTMLElement base = new FormattedHTMLElement(
- IIntroHTMLConstants.ELEMENT_BASE, indentLevel, true, false);
- if (baseURL != null)
- base.addAttribute(IIntroHTMLConstants.ATTRIBUTE_HREF, baseURL);
- return base;
- }
- /**
- * Generates the style element that goes into HEAD:
- *
- * <pre>
- *
- * &lt;style type=&quot;text/css&quot;&gt;HTML, IMG { border: 0px; } &lt;/style&gt;
- *
- * </pre>
- *
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return the style HTMLElement
- */
- private HTMLElement generateStyleElement(int indentLevel) {
- HTMLElement style = new FormattedHTMLElement(
- IIntroHTMLConstants.ELEMENT_STYLE, indentLevel, false);
- style.addAttribute(IIntroHTMLConstants.ATTRIBUTE_TYPE,
- IIntroHTMLConstants.LINK_STYLE);
- style.addContent(IIntroHTMLConstants.STYLE_HTML);
- return style;
- }
- /**
- * Generates the title element and its content:
- *
- * <pre>
- *
- * &lt;TITLE&gt;intro title&lt;/TITLE&gt;
- *
- * </pre>
- *
- * @param title
- * the title of this intro page
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return the title HTMLElement
- */
- private HTMLElement generateTitleElement(String title, int indentLevel) {
- HTMLElement titleElement = new FormattedHTMLElement(
- IIntroHTMLConstants.ELEMENT_TITLE, indentLevel, false);
- if (title != null)
- titleElement.addContent(title);
- return titleElement;
- }
- /**
- * Generates a link element that refers to a cascading style sheet (CSS):
- *
- * <pre>
- *
- * &lt;LINK rel=&quot;stylesheet&quot; style=&quot;text/css&quot; href=&quot;style sheet&quot;&gt;
- *
- * </pre>
- *
- * @param href
- * the value of the href attribute for this link element
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return a link HTMLElement
- */
- private HTMLElement generateLinkElement(String href, int indentLevel) {
- HTMLElement link = new FormattedHTMLElement(
- IIntroHTMLConstants.ELEMENT_LINK, indentLevel, true, false);
- link.addAttribute(IIntroHTMLConstants.ATTRIBUTE_RELATIONSHIP,
- IIntroHTMLConstants.LINK_REL);
- link.addAttribute(IIntroHTMLConstants.ATTRIBUTE_STYLE,
- IIntroHTMLConstants.LINK_STYLE);
- if (href != null)
- link.addAttribute(IIntroHTMLConstants.ATTRIBUTE_HREF, href);
- return link;
- }
- /**
- * Generate an anchor element:
- *
- * <pre>
- *
- * &lt;A id=linkId class=linkClass href=linkHref&gt; &lt;/A&gt;
- *
- * </pre>
- *
- * @param link
- * the IntroLink element that contains the value for the id and
- * href attributes
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return an anchor (&lt;A&gt;) HTMLElement
- */
- private HTMLElement generateAnchorElement(IntroLink link, int indentLevel) {
- HTMLElement anchor = new FormattedHTMLElement(
- IIntroHTMLConstants.ELEMENT_ANCHOR, indentLevel, true);
- if (link.getId() != null)
- anchor.addAttribute(IIntroHTMLConstants.ATTRIBUTE_ID, link.getId());
- if (link.getUrl() != null)
- anchor.addAttribute(IIntroHTMLConstants.ATTRIBUTE_HREF, link
- .getUrl());
- if (link.getStyleId() != null)
- anchor.addAttribute(IIntroHTMLConstants.ATTRIBUTE_CLASS, link
- .getStyleId());
- else
- anchor.addAttribute(IIntroHTMLConstants.ATTRIBUTE_CLASS,
- IIntroHTMLConstants.ANCHOR_CLASS_LINK);
- return anchor;
- }
- /**
- * Generates a div block that contains a header and span element:
- *
- * <pre>
- *
- * &lt;DIV id=divId&gt;
- * &lt;H&gt;&lt;SPAN&gt;spanContent &lt;/SPAN&gt; &lt;/H&gt;
- * &lt;/DIV&gt;
- *
- * </pre>
- *
- * @param divId
- * the id of the div to create
- * @param divClass
- * the class of the div
- * @param headerType
- * what type of header to create (e.g., H1, H2, etc)
- * @param spanContent
- * the span content
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return a div HTMLElement that contains a header
- */
- private HTMLElement generateHeaderDiv(String divId, String divClass,
- String headerType, String spanContent, int indentLevel) {
- // create the text element: <P><SPAN>spanContent</SPAN></P>
- HTMLElement text = generateTextElement(headerType, null, null,
- spanContent, indentLevel + 1);
- // create the containing div element
- HTMLElement div = generateDivElement(divId, divClass, indentLevel);
- div.addContent(text);
- return div;
- }
- /**
- * Generates a span element inside a text element, where the text element
- * can be a P (paragraph), or any of the H (Header) elements. Providing the
- * span element provides additional flexibility for CSS designers.
- *
- * <pre>
- *
- * &lt;P&gt;&lt;SPAN&gt;spanContent&lt;/SPAN&gt;&lt;/P&gt;
- *
- * </pre>
- *
- * @param type
- * the type of text element to create (e.g., P, H1, H2, etc)
- * @param spanID
- * the id of the span element, or null
- * @param spanClass
- * the class of the span element, or null
- * @param spanContent
- * the span content
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return a text HTMLElement that contains a span element
- */
- private HTMLElement generateTextElement(String type, String spanID,
- String spanClass, String spanContent, int indentLevel) {
- // Create the span: <SPAN>spanContent</SPAN>
- HTMLElement span = new HTMLElement(IIntroHTMLConstants.ELEMENT_SPAN);
- if (spanID != null)
- span.addAttribute(IIntroHTMLConstants.ATTRIBUTE_ID, spanID);
- if (spanClass != null)
- span.addAttribute(IIntroHTMLConstants.ATTRIBUTE_CLASS, spanClass);
- if (spanContent != null)
- span.addContent(spanContent);
- // Create the enclosing text element: <P><SPAN>spanContent</SPAN></P>
- HTMLElement text = new FormattedHTMLElement(type, indentLevel, false);
- text.addContent(span);
- return text;
- }
- /**
- * Generates a DIV element with the provided indent, id, and class.
- *
- * @param divId
- * value for the div's id attribute
- * @param divClass
- * value for the div's class attribute
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return a div HTMLElement
- */
- private HTMLElement generateDivElement(String divId, String divClass,
- int indentLevel) {
- HTMLElement div = generateDivElement(divId, indentLevel);
- div.addAttribute(IIntroHTMLConstants.ATTRIBUTE_CLASS, divClass);
- return div;
- }
- /**
- * Generates a DIV element with the provided indent and id.
- *
- * @param divId
- * value for the div's id attribute
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return a div HTMLElement
- */
- private HTMLElement generateDivElement(String divId, int indentLevel) {
- HTMLElement div = new FormattedHTMLElement(
- IIntroHTMLConstants.ELEMENT_DIV, indentLevel, true);
- if (divId != null)
- div.addAttribute(IIntroHTMLConstants.ATTRIBUTE_ID, divId);
- return div;
- }
- /**
- * Generates an IMG element:
- *
- * <pre>
- *
- * &lt;IMG src=imageSrc alt=altText&gt;
- *
- * </pre>
- *
- * @param imageSrc
- * the value to be supplied to the src attribute
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return an img HTMLElement
- */
- private HTMLElement generateImageElement(String imageSrc, String altText,
- String imageClass, int indentLevel) {
- HTMLElement image = new FormattedHTMLElement(
- IIntroHTMLConstants.ELEMENT_IMG, indentLevel, true, false);
- image.addAttribute(IIntroHTMLConstants.ATTRIBUTE_SRC, imageSrc);
- if (altText == null)
- altText = ""; //$NON-NLS-1$
- image.addAttribute(IIntroHTMLConstants.ATTRIBUTE_ALT, altText);
- if(imageClass != null)
- image.addAttribute(IIntroHTMLConstants.ATTRIBUTE_CLASS, imageClass);
- return image;
- }
- /**
- * Generate a span element
- *
- * <pre>
- *
- * &lt;SPAN class=spanClass&gt; &lt;/SPAN&gt;
- *
- * </pre>
- *
- * @param spanClass
- * the value to be supplied to the class attribute
- * @param indentLevel
- * the number of indents to insert before the element when it is
- * printed
- * @return a span HTMLElement
- */
- private HTMLElement generateSpanElement(String spanClass, int indentLevel) {
- HTMLElement span = new FormattedHTMLElement(
- IIntroHTMLConstants.ELEMENT_SPAN, indentLevel, false);
- span.addAttribute(IIntroHTMLConstants.ATTRIBUTE_CLASS, spanClass);
- return span;
- }
-
+
+ private AbstractIntroPage introPage;
+ private IIntroContentProviderSite providerSite;
+
+ /**
+ * Generates the HTML code that will be presented in the browser widget for
+ * the provided intro page.
+ *
+ * @param page
+ * the page to generate HTML for
+ * @param presentation
+ * the presentation associated with this page.
+ */
+ public HTMLElement generateHTMLforPage(AbstractIntroPage page,
+ IIntroContentProviderSite providerSite) {
+ if (page == null)
+ return null;
+ this.introPage = page;
+ this.providerSite = providerSite;
+
+ // generate and add the appropriate encoding to the top of the document
+ // generateEncoding();
+ // create the main HTML element, and all of its contents.
+ return generateHTMLElement();
+ }
+
+ private HTMLElement generateEncoding() {
+ HTMLElement encoding = new HTMLElement(""); //$NON-NLS-1$
+ // TODO: figure out how to handle locale based encoding
+ // As far as the HTML generator is concerned, this is probably as
+ // simple as asking the model for the information
+ return encoding;
+ }
+
+ /**
+ * Generates the HTML element and its content:
+ *
+ * <pre>
+ *
+ * &lt;HTML&gt;
+ * &lt;HEAD&gt;
+ * head content
+ * &lt;/HEAD&gt;
+ * &lt;BODY&gt;
+ * body content
+ * &lt;/BODY&gt;
+ * &lt;/HTML&gt;
+ *
+ * </pre>
+ *
+ * @return the html HTMLElement
+ */
+ private HTMLElement generateHTMLElement() {
+ // this is the outermost element, so it has no indent
+ int indentLevel = 0;
+ HTMLElement html = new FormattedHTMLElement(
+ IIntroHTMLConstants.ELEMENT_HTML, indentLevel, true);
+ HTMLElement head = generateHeadElement(indentLevel + 1);
+ HTMLElement body = generateBodyElement(indentLevel + 1);
+ html.addContent(head);
+ html.addContent(body);
+ return html;
+ }
+
+ /**
+ * Generates the HEAD element and its content:
+ *
+ * <pre>
+ *
+ *
+ * &lt;HEAD&gt;
+ * &lt;BASE href=&quot;base_plugin_location&gt;
+ * &lt;style type=&quot;text/css&quot;&gt;HTML, IMG { border: 0px; } &lt;/style&gt;
+ * &lt;TITLE&gt;page title &lt;/TITLE&gt;
+ * &lt;LINK href=&quot;style sheet&quot;&gt;
+ * additional head content, if specified
+ * &lt;/HEAD&gt;
+ *
+ *
+ * </pre>
+ *
+ * @param indentLevel
+ * the number of indents to insert before the element when it is
+ * printed
+ * @return the head HTMLElement
+ */
+ private HTMLElement generateHeadElement(int indentLevel) {
+ HTMLElement head = new FormattedHTMLElement(
+ IIntroHTMLConstants.ELEMENT_HEAD, indentLevel, true);
+ // add the title
+ head.addContent(generateTitleElement(null, indentLevel + 1));
+ // create the BASE element
+ String basePath = HTMLUtil.getResolvedBundleLocation(introPage
+ .getBundle());
+ HTMLElement base = generateBaseElement(indentLevel + 1, basePath);
+ if (base != null)
+ head.addContent(base);
+ // create the HTML style block
+ head.addContent(generateStyleElement(indentLevel + 1));
+ // add the presentation style
+ String style = IntroPlugin.getDefault().getIntroModelRoot()
+ .getPresentation().getImplementationStyle();
+ if (style != null)
+ head.addContent(generateLinkElement(style, indentLevel + 1));
+ //TODO: Should introPage.getStyles() return the main page style as
+ // well?
+ style = introPage.getStyle();
+ if (style != null)
+ head.addContent(generateLinkElement(style, indentLevel + 1));
+ // add the page's inherited style(s)
+ String[] pageStyles = introPage.getStyles();
+ for (int i = 0; i < pageStyles.length; i++) {
+ style = pageStyles[i];
+ if (style != null)
+ head.addContent(generateLinkElement(style, indentLevel + 1));
+ }
+ // if there is additional head conent specified in an external file,
+ // include it. Additional head content can be specified at the
+ // implementation level (which would apply to ALL pages) and at the
+ // page level (which would apply only to that particular page).
+ // For the implementation's head contribution:
+ StringBuffer content = null;
+ IntroHead introHead = IntroPlugin.getDefault().getIntroModelRoot()
+ .getPresentation().getHead();
+ if (introHead != null) {
+ content = readFromFile(introHead.getSrc());
+ if (content != null)
+ head.addContent(content);
+ }
+ // For the page's head contribution:
+ // TODO: there should only be one of these at the page level, not a
+ // collection..
+ IntroHead[] htmlHeads = introPage.getHTMLHeads();
+ for (int i = 0; i < htmlHeads.length; i++) {
+ introHead = htmlHeads[i];
+ if (introHead != null) {
+ content = readFromFile(introHead.getSrc());
+ if (content != null)
+ head.addContent(content);
+ }
+ }
+ return head;
+ }
+
+ /**
+ * Generates the BODY element and its content:
+ *
+ * <pre>
+ *
+ *
+ * &lt;BODY&gt;
+ * &lt;DIV id=&quot;pageId&quot; class=&quot;pageClass&quot;&gt;
+ * page content
+ * &lt;/DIV&gt;
+ * &lt;/BODY&gt;
+ *
+ *
+ * </pre>
+ *
+ * @param indentLevel
+ * the number of indents to insert before the element when it is
+ * printed
+ * @return the body HTMLElement
+ */
+ private HTMLElement generateBodyElement(int indentLevel) {
+ HTMLElement body = new FormattedHTMLElement(
+ IIntroHTMLConstants.ELEMENT_BODY, indentLevel, true);
+ // Create the div that contains the page content
+ String pageId = (introPage.getId() != null) ? introPage.getId()
+ : IIntroHTMLConstants.DIV_ID_PAGE;
+ HTMLElement pageContentDiv = generateDivElement(pageId, indentLevel + 1);
+ if (introPage.getStyleId() != null)
+ pageContentDiv.addAttribute(IIntroHTMLConstants.ATTRIBUTE_CLASS,
+ introPage.getStyleId());
+ // Add any children of the page, in the order they are defined
+ AbstractIntroElement[] children = introPage.getChildren();
+ for (int i = 0; i < children.length; i++) {
+ AbstractIntroElement child = children[i];
+ // use indentLevel + 2 here, since this element is contained within
+ // the pageContentDiv
+ HTMLElement childElement = generateIntroElement(child,
+ indentLevel + 2);
+ if (childElement != null)
+ pageContentDiv.addContent(childElement);
+ }
+ body.addContent(pageContentDiv);
+ return body;
+ }
+
+ /**
+ * Given an IntroElement, generate the appropriate HTMLElement
+ *
+ * @param element
+ * the IntroElement
+ * @param indentLevel
+ * the number of indents to insert before the element when it is
+ * printed
+ * @return an HTMLElement
+ */
+ private HTMLElement generateIntroElement(AbstractIntroElement element,
+ int indentLevel) {
+ if (element == null)
+ return null;
+ // check to see if this element should be filtered from the HTML
+ // presentation
+ if (filteredFromPresentation(element))
+ return null;
+ switch (element.getType()) {
+ case AbstractIntroElement.GROUP:
+ return generateIntroDiv((IntroGroup) element, indentLevel);
+ case AbstractIntroElement.LINK:
+ return generateIntroLink((IntroLink) element, indentLevel);
+ case AbstractIntroElement.HTML:
+ return generateIntroHTML((IntroHTML) element, indentLevel);
+ case AbstractIntroElement.CONTENT_PROVIDER:
+ return generateIntroContent((IntroContentProvider) element,
+ indentLevel);
+ case AbstractIntroElement.IMAGE:
+ return generateIntroImage((IntroImage) element, indentLevel);
+ case AbstractIntroElement.TEXT:
+ return generateIntroText((IntroText) element, indentLevel);
+ case AbstractIntroElement.PAGE_TITLE:
+ return generateIntroTitle((IntroPageTitle) element, indentLevel);
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * Create a div element and its content from an IntroDiv:
+ *
+ * <pre>
+ *
+ *
+ * &lt;div id=&quot;attrvalue&quot;&gt;
+ * &lt;h4&gt;&lt;span class=&quot;div-label&quot;&gt;attrvalue&lt;/span&gt;&lt;h4&gt;
+ * any defined divs, links, html, images, text, includes
+ * &lt;/div&gt;
+ *
+ *
+ * </pre>
+ *
+ * @param element
+ * the IntroDiv
+ * @param indentLevel
+ * the number of indents to insert before the element when it is
+ * printed
+ * @return a div HTMLElement
+ */
+ private HTMLElement generateIntroDiv(IntroGroup element, int indentLevel) {
+ // Create the outer div element
+ HTMLElement divElement = generateDivElement(element.getId(),
+ indentLevel);
+ // if a div class was specified, add it
+ if (element.getStyleId() != null)
+ divElement.addAttribute(IIntroHTMLConstants.ATTRIBUTE_CLASS,
+ element.getStyleId());
+ // Create the div label, if specified
+ if (element.getLabel() != null) {
+ HTMLElement divLabel = generateTextElement(
+ IIntroHTMLConstants.ELEMENT_H4, null,
+ IIntroHTMLConstants.SPAN_CLASS_DIV_LABEL, element
+ .getLabel(), indentLevel + 1);
+ divElement.addContent(divLabel);
+ }
+ // Add any children of the div, in the order they are defined
+ AbstractIntroElement[] children = element.getChildren();
+ for (int i = 0; i < children.length; i++) {
+ AbstractIntroElement child = children[i];
+ HTMLElement childElement = generateIntroElement(child,
+ indentLevel + 1);
+ if (childElement != null)
+ divElement.addContent(childElement);
+ }
+ return divElement;
+ }
+
+ /**
+ * Generates an anchor (link) element and its content from an IntroLink:
+ *
+ * <pre>
+ *
+ *
+ * &lt;A id=linkId class=&quot;link&quot; href=linkHref&gt;
+ * &lt;IMG src=&quot;blank.gif&quot;&gt;
+ * &lt;SPAN class=&quot;link-label&quot;&gt;linkLabel &lt;/SPAN&gt;
+ * &lt;P&gt;&lt;SPAN&gt;text&lt;/SPAN&gt;&lt;/P&gt;
+ * &lt;/A&gt;
+ *
+ *
+ * </pre>
+ *
+ * @param element
+ * the IntroLink
+ * @param indentLevel
+ * the number of indents to insert before the element when it is
+ * printed
+ * @return an anchor (&lt;A&gt;) HTMLElement
+ */
+ private HTMLElement generateIntroLink(IntroLink element, int indentLevel) {
+ HTMLElement anchor = generateAnchorElement(element, indentLevel);
+ // add <IMG src="blank.gif">
+ String blankImageURL = IntroModelRoot.getPluginLocation(
+ IIntroHTMLConstants.IMAGE_SRC_BLANK, IIntroConstants.PLUGIN_ID);
+ if (blankImageURL != null) {
+ anchor.addContent(generateImageElement(blankImageURL, null,
+ IIntroHTMLConstants.IMAGE_CLASS_BG, indentLevel + 1));
+ }
+ // add link image, if one is specified
+ if (element.getImg() != null) {
+ HTMLElement img = generateIntroElement(element.getImg(),
+ indentLevel + 1);
+ if (img != null)
+ anchor.addContent(img);
+ }
+ // add <SPAN class="link-label">linkLabel</SPAN>
+ if (element.getLabel() != null) {
+ HTMLElement label = generateSpanElement(
+ IIntroHTMLConstants.SPAN_CLASS_LINK_LABEL, indentLevel + 1);
+ label.addContent(element.getLabel());
+ anchor.addContent(label);
+ }
+ IntroText linkText = element.getIntroText();
+ if (linkText != null && linkText.getText() != null) {
+ HTMLElement text = generateIntroElement(linkText, indentLevel + 1);
+ if (text != null)
+ anchor.addContent(text);
+ }
+ return anchor;
+ }
+
+ /**
+ * Generate the appropriate HTML from an IntroHTML. If the IntroHTML type is
+ * "inline", then the content from the referenced file is emitted as-is into
+ * a div element. If the type is "embed", an OBJECT html element is created
+ * whose <code>data</code> attribute is equal to the IntroHTML's
+ * <code>src</code> value
+ *
+ * @param element
+ * the IntroHTML
+ * @param indentLevel
+ * the number of indents to insert before the element when it is
+ * printed
+ * @return an HTMLElement
+ */
+ private HTMLElement generateIntroHTML(IntroHTML element, int indentLevel) {
+ if (element.isInlined())
+ return generateInlineIntroHTML(element, indentLevel);
+ else
+ return generateEmbeddedIntroHTML(element, indentLevel);
+ }
+
+ /**
+ * Generate an image element from an IntroImage:
+ *
+ * <pre>
+ *
+ *
+ * &lt;IMG src=imageSrc id=imageId&gt;
+ *
+ *
+ * </pre>
+ *
+ * @param element
+ * the IntroImage
+ * @param indentLevel
+ * the number of indents to insert before the element when it is
+ * printed
+ * @return an img HTMLElement
+ */
+ private HTMLElement generateIntroImage(IntroImage element, int indentLevel) {
+ HTMLElement imageElement = generateImageElement(element.getSrc(),
+ element.getAlt(), element.getStyleId(), indentLevel);
+ if (element.getId() != null)
+ imageElement.addAttribute(IIntroHTMLConstants.ATTRIBUTE_ID, element
+ .getId());
+ return imageElement;
+ }
+
+ /**
+ * Generate a paragraph (&lt;P&gt;) element from an IntroText. The paragraph
+ * element will contain a span element that will contain the actual text.
+ * Providing the span element provides additional flexibility for CSS
+ * designers.
+ *
+ * <pre>
+ *
+ *
+ * &lt;P&gt;&lt;SPAN&gt;spanContent&lt;/SPAN&gt;&lt;/P&gt;
+ *
+ *
+ * </pre>
+ *
+ * @param element
+ * the IntroText
+ * @param indentLevel
+ * the number of indents to insert before the element when it is
+ * printed
+ * @return a paragraph HTMLElement
+ */
+ private HTMLElement generateIntroText(IntroText element, int indentLevel) {
+ String spanClass = (element.getStyleId() != null) ? element
+ .getStyleId() : IIntroHTMLConstants.SPAN_CLASS_TEXT;
+ HTMLElement textElement = generateTextElement(
+ IIntroHTMLConstants.ELEMENT_PARAGRAPH, element.getId(),
+ spanClass, element.getText(), indentLevel);
+ return textElement;
+ }
+
+ /**
+ * @param element
+ * @param indentLevel
+ * @return
+ */
+ private HTMLElement generateIntroTitle(IntroPageTitle element,
+ int indentLevel) {
+ HTMLElement titleElement = generateHeaderDiv(element.getId(), element
+ .getStyleId(), IIntroHTMLConstants.ELEMENT_H1, element
+ .getTitle(), indentLevel);
+ return titleElement;
+ }
+
+ /**
+ * Generate "inline" content from an IntroHTML. The content from the file
+ * referenced by the IntroHTML's <code>src</code> attribute is emitted
+ * as-is into a div element:
+ *
+ * <pre>
+ *
+ *
+ * &lt;div id=&quot;attrvalue&quot; class=&quot;attrvalue2&quot;&gt;
+ * content from file specified in src attribute
+ * &lt;/div&gt;
+ *
+ *
+ * </pre>
+ *
+ * @param element
+ * the IntroHTML
+ * @param indentLevel
+ * the number of indents to insert before the element when it is
+ * printed
+ * @return a div HTMLElement, or null if there was a problem reading from
+ * the file
+ */
+ private HTMLElement generateInlineIntroHTML(IntroHTML element,
+ int indentLevel) {
+ StringBuffer content = readFromFile(element.getSrc());
+ if (content != null && content.length() > 0) {
+ // Create the outer div element
+ String divClass = (element.getStyleId() != null) ? element
+ .getStyleId() : IIntroHTMLConstants.DIV_CLASS_INLINE_HTML;
+ HTMLElement divElement = generateDivElement(element.getId(),
+ divClass, indentLevel);
+ // add the content of the specified file into the div element
+ divElement.addContent(content);
+ return divElement;
+ }
+ return null;
+ }
+
+ /**
+ * Includes HTML content that is created by an IIntroContentProvider
+ * implementation.
+ *
+ * @param element
+ * @param indentLevel
+ * @return
+ */
+ private HTMLElement generateIntroContent(IntroContentProvider element,
+ int indentLevel) {
+ // create a new div to wrap the content
+ HTMLElement divElement = generateDivElement(element.getId(),
+ IIntroHTMLConstants.DIV_CLASS_PROVIDED_CONTENT, indentLevel);
+
+ // If we've already loaded the content provider for this element,
+ // retrieve it, otherwise load the class
+ IIntroContentProvider providerClass = ContentProviderManager.getInst()
+ .getContentProvider(element);
+ if (providerClass == null)
+ // content provider never created before, create it.
+ providerClass = ContentProviderManager.getInst()
+ .createContentProvider(element, providerSite);
+
+ if (providerClass != null) {
+ StringWriter stringWriter = new StringWriter();
+ PrintWriter pw = new PrintWriter(stringWriter);
+ // create the specialized content
+ providerClass.createContent(element.getId(), pw);
+ // add the content of the specified file into the div element
+ stringWriter.flush();
+ divElement.addContent(stringWriter.toString());
+ pw.close();
+ } else {
+ // we couldn't load the content provider, so add any alternate
+ // text content if there is any
+ IntroText htmlText = element.getIntroText();
+ if (htmlText != null && htmlText.getText() != null) {
+ String textClass = (htmlText.getStyleId() != null) ? htmlText
+ .getStyleId() : IIntroHTMLConstants.SPAN_CLASS_TEXT;
+ HTMLElement text = generateTextElement(
+ IIntroHTMLConstants.ELEMENT_PARAGRAPH,
+ htmlText.getId(), textClass, element.getText(),
+ indentLevel);
+ if (text != null)
+ divElement.addContent(text);
+ }
+ }
+ return divElement;
+ }
+
+ /**
+ * Generate "embedded" content from an IntroHTML. An OBJECT html element is
+ * created whose <code>data</code> attribute is equal to the IntroHTML's
+ * <code>src</code> value.
+ *
+ * <pre>
+ *
+ * &lt;OBJECT type=&quot;text/html&quot; data=&quot;attrvalue&quot;&gt;
+ * alternative text in case the object can not be rendered
+ * &lt;/OBJECT&gt;
+ *
+ * </pre>
+ *
+ * @param element
+ * the IntroHTML
+ * @param indentLevel
+ * the number of indents to insert before the element when it is
+ * printed
+ * @return an object HTMLElement
+ */
+ private HTMLElement generateEmbeddedIntroHTML(IntroHTML element,
+ int indentLevel) {
+ HTMLElement objectElement = new FormattedHTMLElement(
+ IIntroHTMLConstants.ELEMENT_OBJECT, indentLevel, true);
+ objectElement.addAttribute(IIntroHTMLConstants.ATTRIBUTE_TYPE,
+ IIntroHTMLConstants.OBJECT_TYPE);
+ if (element.getId() != null)
+ objectElement.addAttribute(IIntroHTMLConstants.ATTRIBUTE_ID,
+ element.getId());
+ if (element.getSrc() != null)
+ objectElement.addAttribute(IIntroHTMLConstants.ATTRIBUTE_DATA,
+ element.getSrc());
+ if (element.getStyleId() != null)
+ objectElement.addAttribute(IIntroHTMLConstants.ATTRIBUTE_CLASS,
+ element.getStyleId());
+ // The alternative content is added in case the browser can not render
+ // the specified content
+ IntroText htmlText = element.getIntroText();
+ if (htmlText != null && htmlText.getText() != null) {
+ String textClass = (htmlText.getStyleId() != null) ? htmlText
+ .getStyleId() : IIntroHTMLConstants.SPAN_CLASS_TEXT;
+ HTMLElement text = generateTextElement(
+ IIntroHTMLConstants.ELEMENT_PARAGRAPH, htmlText.getId(),
+ textClass, element.getText(), indentLevel);
+ if (text != null)
+ objectElement.addContent(text);
+ }
+ if (element.getIntroImage() != null) {
+ HTMLElement img = generateIntroImage(element.getIntroImage(),
+ indentLevel);
+ if (img != null)
+ objectElement.addContent(img);
+ }
+ return objectElement;
+ }
+
+ /**
+ * Generates the BASE element for the head of the html document. Each
+ * document can have only one base element
+ *
+ * <pre>
+ *
+ * &lt;BASE href=baseURL&gt;
+ *
+ * </pre>
+ *
+ * @param indentLevel
+ * @param baseURL
+ * @return
+ */
+ private HTMLElement generateBaseElement(int indentLevel, String baseURL) {
+ HTMLElement base = new FormattedHTMLElement(
+ IIntroHTMLConstants.ELEMENT_BASE, indentLevel, true, false);
+ if (baseURL != null)
+ base.addAttribute(IIntroHTMLConstants.ATTRIBUTE_HREF, baseURL);
+ return base;
+ }
+
+ /**
+ * Generates the style element that goes into HEAD:
+ *
+ * <pre>
+ *
+ * &lt;style type=&quot;text/css&quot;&gt;HTML, IMG { border: 0px; } &lt;/style&gt;
+ * </pre>
+ *
+ * @param indentLevel
+ * the number of indents to insert before the element when it is
+ * printed
+ * @return the style HTMLElement
+ */
+ private HTMLElement generateStyleElement(int indentLevel) {
+ HTMLElement style = new FormattedHTMLElement(
+ IIntroHTMLConstants.ELEMENT_STYLE, indentLevel, false);
+ style.addAttribute(IIntroHTMLConstants.ATTRIBUTE_TYPE,
+ IIntroHTMLConstants.LINK_STYLE);
+ style.addContent(IIntroHTMLConstants.STYLE_HTML);
+ return style;
+ }
+
+ /**
+ * Generates the title element and its content:
+ *
+ * <pre>
+ *
+ *
+ * &lt;TITLE&gt;intro title&lt;/TITLE&gt;
+ *
+ *
+ * </pre>
+ *
+ * @param title
+ * the title of this intro page
+ * @param indentLevel
+ * the number of indents to insert before the element when it is
+ * printed
+ * @return the title HTMLElement
+ */
+ private HTMLElement generateTitleElement(String title, int indentLevel) {
+ HTMLElement titleElement = new FormattedHTMLElement(
+ IIntroHTMLConstants.ELEMENT_TITLE, indentLevel, false);
+ if (title != null)
+ titleElement.addContent(title);
+ return titleElement;
+ }
+
+ /**
+ * Generates a link element that refers to a cascading style sheet (CSS):
+ *
+ * <pre>
+ *
+ *
+ * &lt;LINK rel=&quot;stylesheet&quot; style=&quot;text/css&quot; href=&quot;style sheet&quot;&gt;
+ *
+ *
+ * </pre>
+ *
+ * @param href
+ * the value of the href attribute for this link element
+ * @param indentLevel
+ * the number of indents to insert before the element when it is
+ * printed
+ * @return a link HTMLElement
+ */
+ private HTMLElement generateLinkElement(String href, int indentLevel) {
+ HTMLElement link = new FormattedHTMLElement(
+ IIntroHTMLConstants.ELEMENT_LINK, indentLevel, true, false);
+ link.addAttribute(IIntroHTMLConstants.ATTRIBUTE_RELATIONSHIP,
+ IIntroHTMLConstants.LINK_REL);
+ link.addAttribute(IIntroHTMLConstants.ATTRIBUTE_STYLE,
+ IIntroHTMLConstants.LINK_STYLE);
+ if (href != null)
+ link.addAttribute(IIntroHTMLConstants.ATTRIBUTE_HREF, href);
+ return link;
+ }
+
+ /**
+ * Generate an anchor element:
+ *
+ * <pre>
+ *
+ *
+ * &lt;A id=linkId class=linkClass href=linkHref&gt; &lt;/A&gt;
+ *
+ *
+ * </pre>
+ *
+ * @param link
+ * the IntroLink element that contains the value for the id and
+ * href attributes
+ * @param indentLevel
+ * the number of indents to insert before the element when it is
+ * printed
+ * @return an anchor (&lt;A&gt;) HTMLElement
+ */
+ private HTMLElement generateAnchorElement(IntroLink link, int indentLevel) {
+ HTMLElement anchor = new FormattedHTMLElement(
+ IIntroHTMLConstants.ELEMENT_ANCHOR, indentLevel, true);
+ if (link.getId() != null)
+ anchor.addAttribute(IIntroHTMLConstants.ATTRIBUTE_ID, link.getId());
+ if (link.getUrl() != null)
+ anchor.addAttribute(IIntroHTMLConstants.ATTRIBUTE_HREF, link
+ .getUrl());
+ if (link.getStyleId() != null)
+ anchor.addAttribute(IIntroHTMLConstants.ATTRIBUTE_CLASS, link
+ .getStyleId());
+ else
+ anchor.addAttribute(IIntroHTMLConstants.ATTRIBUTE_CLASS,
+ IIntroHTMLConstants.ANCHOR_CLASS_LINK);
+ return anchor;
+ }
+
+ /**
+ * Generates a div block that contains a header and span element:
+ *
+ * <pre>
+ *
+ *
+ * &lt;DIV id=divId&gt;
+ * &lt;H&gt;&lt;SPAN&gt;spanContent &lt;/SPAN&gt; &lt;/H&gt;
+ * &lt;/DIV&gt;
+ *
+ *
+ * </pre>
+ *
+ * @param divId
+ * the id of the div to create
+ * @param divClass
+ * the class of the div
+ * @param headerType
+ * what type of header to create (e.g., H1, H2, etc)
+ * @param spanContent
+ * the span content
+ * @param indentLevel
+ * the number of indents to insert before the element when it is
+ * printed
+ * @return a div HTMLElement that contains a header
+ */
+ private HTMLElement generateHeaderDiv(String divId, String divClass,
+ String headerType, String spanContent, int indentLevel) {
+ // create the text element: <P><SPAN>spanContent</SPAN></P>
+ HTMLElement text = generateTextElement(headerType, null, null,
+ spanContent, indentLevel + 1);
+ // create the containing div element
+ HTMLElement div = generateDivElement(divId, divClass, indentLevel);
+ div.addContent(text);
+ return div;
+ }
+
+ /**
+ * Generates a span element inside a text element, where the text element
+ * can be a P (paragraph), or any of the H (Header) elements. Providing the
+ * span element provides additional flexibility for CSS designers.
+ *
+ * <pre>
+ *
+ * &lt;P&gt;&lt;SPAN&gt;spanContent&lt;/SPAN&gt;&lt;/P&gt;
+ *
+ * </pre>
+ *
+ * @param type
+ * the type of text element to create (e.g., P, H1, H2, etc)
+ * @param spanID
+ * the id of the span element, or null
+ * @param spanClass
+ * the class of the span element, or null
+ * @param spanContent
+ * the span content
+ * @param indentLevel
+ * the number of indents to insert before the element when it is
+ * printed
+ * @return a text HTMLElement that contains a span element
+ */
+ private HTMLElement generateTextElement(String type, String spanID,
+ String spanClass, String spanContent, int indentLevel) {
+ // Create the span: <SPAN>spanContent</SPAN>
+ HTMLElement span = new HTMLElement(IIntroHTMLConstants.ELEMENT_SPAN);
+ if (spanID != null)
+ span.addAttribute(IIntroHTMLConstants.ATTRIBUTE_ID, spanID);
+ if (spanClass != null)
+ span.addAttribute(IIntroHTMLConstants.ATTRIBUTE_CLASS, spanClass);
+ if (spanContent != null)
+ span.addContent(spanContent);
+ // Create the enclosing text element: <P><SPAN>spanContent</SPAN></P>
+ HTMLElement text = new FormattedHTMLElement(type, indentLevel, false);
+ text.addContent(span);
+ return text;
+ }
+
+ /**
+ * Generates a DIV element with the provided indent, id, and class.
+ *
+ * @param divId
+ * value for the div's id attribute
+ * @param divClass
+ * value for the div's class attribute
+ * @param indentLevel
+ * the number of indents to insert before the element when it is
+ * printed
+ * @return a div HTMLElement
+ */
+ private HTMLElement generateDivElement(String divId, String divClass,
+ int indentLevel) {
+ HTMLElement div = generateDivElement(divId, indentLevel);
+ div.addAttribute(IIntroHTMLConstants.ATTRIBUTE_CLASS, divClass);
+ return div;
+ }
+
+ /**
+ * Generates a DIV element with the provided indent and id.
+ *
+ * @param divId
+ * value for the div's id attribute
+ * @param indentLevel
+ * the number of indents to insert before the element when it is
+ * printed
+ * @return a div HTMLElement
+ */
+ private HTMLElement generateDivElement(String divId, int indentLevel) {
+ HTMLElement div = new FormattedHTMLElement(
+ IIntroHTMLConstants.ELEMENT_DIV, indentLevel, true);
+ if (divId != null)
+ div.addAttribute(IIntroHTMLConstants.ATTRIBUTE_ID, divId);
+ return div;
+ }
+
+ /**
+ * Generates an IMG element:
+ *
+ * <pre>
+ *
+ *
+ * &lt;IMG src=imageSrc alt=altText&gt;
+ *
+ *
+ * </pre>
+ *
+ * @param imageSrc
+ * the value to be supplied to the src attribute
+ * @param indentLevel
+ * the number of indents to insert before the element when it is
+ * printed
+ * @return an img HTMLElement
+ */
+ private HTMLElement generateImageElement(String imageSrc, String altText,
+ String imageClass, int indentLevel) {
+ HTMLElement image = new FormattedHTMLElement(
+ IIntroHTMLConstants.ELEMENT_IMG, indentLevel, true, false);
+ image.addAttribute(IIntroHTMLConstants.ATTRIBUTE_SRC, imageSrc);
+ if (altText == null)
+ altText = ""; //$NON-NLS-1$
+ image.addAttribute(IIntroHTMLConstants.ATTRIBUTE_ALT, altText);
+ if (imageClass != null)
+ image.addAttribute(IIntroHTMLConstants.ATTRIBUTE_CLASS, imageClass);
+ return image;
+ }
+
+ /**
+ * Generate a span element
+ *
+ * <pre>
+ *
+ *
+ * &lt;SPAN class=spanClass&gt; &lt;/SPAN&gt;
+ *
+ *
+ * </pre>
+ *
+ * @param spanClass
+ * the value to be supplied to the class attribute
+ * @param indentLevel
+ * the number of indents to insert before the element when it is
+ * printed
+ * @return a span HTMLElement
+ */
+ private HTMLElement generateSpanElement(String spanClass, int indentLevel) {
+ HTMLElement span = new FormattedHTMLElement(
+ IIntroHTMLConstants.ELEMENT_SPAN, indentLevel, false);
+ span.addAttribute(IIntroHTMLConstants.ATTRIBUTE_CLASS, spanClass);
+ return span;
+ }
+
private boolean filteredFromPresentation(AbstractIntroElement element) {
if (element.isOfType(AbstractIntroElement.BASE_ELEMENT))
return ((AbstractBaseIntroElement) element).isFiltered();
else
return false;
}
+
+
+ /**
+ * Reads the content of the file referred to by the <code>src</code>
+ * parameter and returns the content in the form of a StringBuffer. If the
+ * file read contains substitution segments of the form $plugin:plugin_id$
+ * then this method will make the proper substitution (the segment will be
+ * replaced with the absolute path to the plugin with id plugin_id).
+ *
+ * @param src -
+ * the file that contains the target conent
+ * @return a StringBuffer containing the content in the file, or null
+ */
+ private StringBuffer readFromFile(String src) {
+ if (src == null)
+ return null;
+ InputStream stream = null;
+ StringBuffer content = new StringBuffer();
+ BufferedReader reader = null;
+ try {
+ URL url = new URL(src);
+ stream = url.openStream();
+ //TODO: Do we need to worry about the encoding here? e.g.:
+ //reader = new BufferedReader(new InputStreamReader(stream,
+ // ResourcesPlugin.getEncoding()));
+ reader = new BufferedReader(new InputStreamReader(stream));
+ while (true) {
+ int character = reader.read();
+ if (character == -1) // EOF
+ break; // done reading file
+
+ else if (character == PluginIdParser.SUBSTITUTION_BEGIN) { // possible
+ // substitution
+ PluginIdParser parser = new PluginIdParser(character,
+ reader);
+ // If a valid plugin id was found in the proper format, text
+ // will be the absolute path to that plugin. Otherwise, text
+ // will simply be all characters read up to (but not
+ // including)
+ // the next dollar sign that follows the one just found.
+ String text = parser.parsePluginId();
+ if (text != null)
+ content.append(text);
+ } else {
+ // make sure character is in char range before making cast
+ if (character > 0x00 && character < 0xffff)
+ content.append((char) character);
+ else
+ content.append(character);
+ }
+ }
+ } catch (Exception exception) {
+ Log.error("Error reading from file", exception); //$NON-NLS-1$
+ } finally {
+ try {
+ if (reader != null)
+ reader.close();
+ if (stream != null)
+ stream.close();
+ } catch (IOException e) {
+ Log.error("Error closing input stream", e); //$NON-NLS-1$
+ return null;
+ }
+ }
+ return content;
+ }
+
+ /**
+ * A helper class to help identify substitution strings in a content file. A
+ * properly formatted substitution string is of the form:
+ * <code>$plugin:plugin_id$</code> where plugin_id is the valid id of an
+ * installed plugin. The substitution string will be replaced with the
+ * absolute path to the plugin.
+ *
+ * An example usage of the string substution: The html file
+ * <code>inline.html</code> is included in your intro via the html inline
+ * mechanism . This file needs to reference a resource that is located in
+ * another plugin. The following might be found in inline.html: <code>
+ * <a href="$plugin:test.plugin$html/test.html">link to file</a>
+ * </code>
+ * When this file is read in, the relevant section will be replaced as
+ * follows: <code>
+ * <a href="file:/install_path/plugins/test.plugin/html/test.html">link to file</a>
+ * </code>
+ *
+ */
+ private static class PluginIdParser {
+ private BufferedReader reader;
+ private static final char SUBSTITUTION_BEGIN = '$';
+ private static final char SUBSTITUTION_END = '$';
+ // tokenContent will contain all characters read by the parser, starting
+ // with and including the initial $ token.
+ private StringBuffer tokenContent;
+ // pluginId will contain the content between the "$plugin:" segment
+ // and the closing "$" token
+ private StringBuffer pluginId;
+
+ protected PluginIdParser(char tokenBegin, BufferedReader bufferedreader) {
+ reader = bufferedreader;
+ tokenContent = new StringBuffer(tokenBegin);
+ pluginId = new StringBuffer();
+ }
+
+ protected PluginIdParser(int tokenBegin, BufferedReader bufferedreader) {
+ reader = bufferedreader;
+ tokenContent = new StringBuffer();
+ pluginId = new StringBuffer();
+ // make sure tokenBegin is in char range before making cast
+ if (tokenBegin > 0x00 && tokenBegin < 0xffff)
+ tokenContent.append((char) tokenBegin);
+ }
+
+ /**
+ * This method should be called after the initial substitution
+ * identifier has been read in (the substition string begins and ends
+ * with the "$" character). A properly formatted substitution string is
+ * of the form:</code> "$plugin:plugin_id$</code>- the initial "$" is
+ * immediately followed by the "plugin:" segment - the <code>plugin_id
+ * </code> refers to a valid, installed plugin - the substitution string
+ * is terminated by a closing "$" If the above conditions are not met,
+ * no substitution occurs. If the above conditions are met, the content
+ * between (and including) the opening and closing "$" characters will
+ * be replaced by the absolute path to the plugin
+ *
+ * @return
+ */
+ protected String parsePluginId() {
+ if (reader == null || tokenContent == null || pluginId == null)
+ return null;
+
+ try {
+ // Mark the current position of the reader so we can roll
+ // back to this point if the proper "plugin:" segment is not
+ // found.
+ // Use 1024 as our readAheadLimit
+ reader.mark(0x400);
+ if (findValidPluginSegment()) {
+ String pluginPath = getPluginPath();
+ if (pluginPath == null) {
+ // Didn't find a valid plugin id.
+ // return tokenContent, which contains all characters
+ // read up to (not including) the last $. (if the
+ // last $ is part of a subsequent "$plugin:" segment
+ // it can still be processed properly)
+ return tokenContent.toString();
+ } else {
+ return pluginPath;
+ }
+ } else {
+ // The "plugin:" segment was not found. Reset the reader
+ // so we can continue reading character by character.
+ reader.reset();
+ return tokenContent.toString();
+ }
+
+ } catch (IOException exception) {
+ Log.error("Error reading from file", exception); //$NON-NLS-1$
+ return tokenContent.toString();
+ }
+ }
+
+ /**
+ * This method should be called after an initial substitution character
+ * has been found (that is, after a $). It looks at the subsequent
+ * characters in the input stream to determine if they match the
+ * expected <code>plugin:</code> segment of the substitution string.
+ * If the expected characters are found, they will be appended to the
+ * tokenContent StringBuffer and the method will return true. If they
+ * are not found, false is returned and the caller should reset the
+ * BufferedReader to the position it was in before this method was
+ * called.
+ *
+ * Resetting the reader ensures that the characters read in this method
+ * can be re-examined in case one of them happens to be the beginning of
+ * a valid substitution segment.
+ *
+ * @return true if the next characters match <code>plugin:</code>,
+ * and false otherwise.
+ */
+ private boolean findValidPluginSegment() {
+ final char[] PLUGIN_SEGMENT = { 'p', 'l', 'u', 'g', 'i', 'n', ':' };
+ char[] streamContent = new char[PLUGIN_SEGMENT.length];
+ try {
+ int peek = reader.read(streamContent, 0, PLUGIN_SEGMENT.length);
+ if ((peek == PLUGIN_SEGMENT.length)
+ && (HTMLUtil.equalCharArrayContent(streamContent,
+ PLUGIN_SEGMENT))) {
+ // we have found the "$plugin:" segment
+ tokenContent.append(streamContent);
+ return true;
+ }
+ // The "plugin:" segment did not immediately follow the initial
+ // $.
+ return false;
+ } catch (IOException exception) {
+ Log.error("Error reading from file", exception); //$NON-NLS-1$
+ return false;
+ }
+ }
+
+ /**
+ * This method continues to read from the input stream until either the
+ * end of the file is reached, or until a character is found that
+ * indicates the end of the substitution. If the SUBSTITUTION_END
+ * character is found, the method looks up the plugin id that has been
+ * built up to see if it is a valid id. If so, return the absolute path
+ * to that plugin. If not, return null.
+ *
+ * This method assumes that the reader is positioned just after a valid
+ * <code>plugin:</code> segment in a substitution string.
+ *
+ * @return absolute path of the plugin id, if valid. null otherwise
+ */
+ private String getPluginPath() {
+ try {
+ while (true) {
+ int nextChar = reader.read();
+
+ if (nextChar == -1) {
+ // reached EOF while looking for closing $
+ return null;
+ } else if (nextChar == SUBSTITUTION_END) { // end of plugin
+ // id
+ // look up the plugin id. If it is a valid id
+ // return the absolute path to this plugin.
+ // otherwise return null.
+ String path = HTMLUtil
+ .getResolvedBundleLocation(pluginId.toString());
+
+ // If the plugin id was not valid, reset reader to the
+ // previous mark. The mark should be at the character
+ // just before the last dollar sign.
+ if (path == null)
+ reader.reset();
+
+ return path;
+ } else { // we have a regular character
+ // mark the most recent non-dollar char in case we don't
+ // find a valid plugin id and have to roll back
+ // Use 1024 as our readAheadLimit
+ reader.mark(0x400);
+ // Add this character to the pluginId and tokenContent
+ // String.
+ // make sure we have a valid character before performing
+ // cast
+ if (nextChar > 0x00 && nextChar < 0xffff) {
+ tokenContent.append((char) nextChar);
+ // only include non-whitespace characters in plugin
+ // id
+ if (!Character.isWhitespace((char) nextChar))
+ pluginId.append((char) nextChar);
+ } else {
+ tokenContent.append(nextChar);
+ pluginId.append(nextChar);
+ }
+ }
+ }
+ } catch (IOException exception) {
+ Log.error("Error reading from file", exception); //$NON-NLS-1$
+ return null;
+ }
+ }
+ }
+
-
- /**
- * Reads the content of the file referred to by the <code>src</code>
- * parameter and returns the content in the form of a StringBuffer.
- * If the file read contains substitution segments of the form
- * $plugin:plugin_id$ then this method will make the proper
- * substitution (the segment will be replaced with the absolute
- * path to the plugin with id plugin_id).
- *
- * @param src -
- * the file that contains the target conent
- * @return a StringBuffer containing the content in the file, or null
- */
- private StringBuffer readFromFile(String src) {
- if (src == null)
- return null;
- InputStream stream = null;
- StringBuffer content = new StringBuffer();
- BufferedReader reader = null;
- try {
- URL url = new URL(src);
- stream = url.openStream();
- //TODO: Do we need to worry about the encoding here? e.g.:
- //reader = new BufferedReader(new InputStreamReader(stream,
- // ResourcesPlugin.getEncoding()));
- reader = new BufferedReader(new InputStreamReader(stream));
- while (true) {
- int character = reader.read();
- if (character == -1) // EOF
- break; // done reading file
-
- else if(character == PluginIdParser.SUBSTITUTION_BEGIN) { // possible substitution
- PluginIdParser parser = new PluginIdParser(character, reader);
- // If a valid plugin id was found in the proper format, text
- // will be the absolute path to that plugin. Otherwise, text
- // will simply be all characters read up to (but not including)
- // the next dollar sign that follows the one just found.
- String text = parser.parsePluginId();
- if(text != null)
- content.append(text);
- }
- else {
- // make sure character is in char range before making cast
- if(character > 0x00 && character < 0xffff)
- content.append((char)character);
- else content.append(character);
- }
- }
- } catch (Exception exception) {
- Log.error("Error reading from file", exception); //$NON-NLS-1$
- } finally {
- try {
- if (reader != null)
- reader.close();
- if (stream != null)
- stream.close();
- } catch (IOException e) {
- Log.error("Error closing input stream", e); //$NON-NLS-1$
- return null;
- }
- }
- return content;
- }
-
- /**
- * A helper class to help identify substitution strings in a content file.
- * A properly formatted substitution string is of the form:
- * <code>$plugin:plugin_id$</code>
- * where plugin_id is the valid id of an installed plugin. The substitution
- * string will be replaced with the absolute path to the plugin.
- *
- * An example usage of the string substution:
- * The html file <code>inline.html</code> is included in your intro via
- * the html inline mechanism . This file needs to reference a resource that
- * is located in another plugin. The following might be found in inline.html:
- * <code>
- * <a href="$plugin:test.plugin$html/test.html">link to file</a>
- * </code>
- * When this file is read in, the relevant section will be replaced as follows:
- * <code>
- * <a href="file:/install_path/plugins/test.plugin/html/test.html">link to file</a>
- * </code>
- *
- */
- private static class PluginIdParser {
- private BufferedReader reader;
- private static final char SUBSTITUTION_BEGIN = '$';
- private static final char SUBSTITUTION_END = '$';
- // tokenContent will contain all characters read by the parser, starting
- // with and including the initial $ token.
- private StringBuffer tokenContent;
- // pluginId will contain the content between the "$plugin:" segment
- // and the closing "$" token
- private StringBuffer pluginId;
-
- protected PluginIdParser(char tokenBegin, BufferedReader bufferedreader){
- reader = bufferedreader;
- tokenContent = new StringBuffer(tokenBegin);
- pluginId = new StringBuffer();
- }
-
- protected PluginIdParser(int tokenBegin, BufferedReader bufferedreader){
- reader = bufferedreader;
- tokenContent = new StringBuffer();
- pluginId = new StringBuffer();
- // make sure tokenBegin is in char range before making cast
- if(tokenBegin > 0x00 && tokenBegin < 0xffff)
- tokenContent.append((char)tokenBegin);
- }
-
- /**
- * This method should be called after the initial substitution identifier
- * has been read in (the substition string begins and ends with the "$"
- * character).
- * A properly formatted substitution string is of the form:
- * </code>"$plugin:plugin_id$</code>
- * - the initial "$" is immediately followed by the "plugin:" segment
- * - the <code>plugin_id</code> refers to a valid, installed plugin
- * - the substitution string is terminated by a closing "$"
- * If the above conditions are not met, no substitution occurs.
- * If the above conditions are met, the content between (and including)
- * the opening and closing "$" characters will be replaced by the
- * absolute path to the plugin
- * @return
- */
- protected String parsePluginId() {
- if(reader == null || tokenContent == null || pluginId == null)
- return null;
-
- try {
- // Mark the current position of the reader so we can roll
- // back to this point if the proper "plugin:" segment is not found.
- // Use 1024 as our readAheadLimit
- reader.mark(0x400);
- if(findValidPluginSegment()){
- String pluginPath = getPluginPath();
- if(pluginPath == null){
- // Didn't find a valid plugin id.
- // return tokenContent, which contains all characters
- // read up to (not including) the last $. (if the
- // last $ is part of a subsequent "$plugin:" segment
- // it can still be processed properly)
- return tokenContent.toString();
- }
- else {
- return pluginPath;
- }
- }
- else {
- // The "plugin:" segment was not found. Reset the reader
- // so we can continue reading character by character.
- reader.reset();
- return tokenContent.toString();
- }
-
- } catch (IOException exception){
- Log.error("Error reading from file", exception); //$NON-NLS-1$
- return tokenContent.toString();
- }
- }
-
- /**
- * This method should be called after an initial substitution character
- * has been found (that is, after a $). It looks at the subsequent
- * characters in the input stream to determine if they match the
- * expected <code>plugin:</code> segment of the substitution string.
- * If the expected characters are found, they will be appended to the
- * tokenContent StringBuffer and the method will return true. If they
- * are not found, false is returned and the caller should reset the
- * BufferedReader to the position it was in before this method was called.
- *
- * Resetting the reader ensures that the characters read in this method
- * can be re-examined in case one of them happens to be the beginning of
- * a valid substitution segment.
- *
- * @return true if the next characters match <code>plugin:</code>, and
- * false otherwise.
- */
- private boolean findValidPluginSegment(){
- final char[] PLUGIN_SEGMENT = {'p', 'l', 'u', 'g', 'i', 'n', ':' };
- char[] streamContent = new char[PLUGIN_SEGMENT.length];
- try {
- int peek = reader.read(streamContent, 0, PLUGIN_SEGMENT.length);
- if ((peek == PLUGIN_SEGMENT.length)
- && (HTMLUtil.equalCharArrayContent(streamContent, PLUGIN_SEGMENT))){
- // we have found the "$plugin:" segment
- tokenContent.append(streamContent);
- return true;
- }
- // The "plugin:" segment did not immediately follow the initial $.
- return false;
- } catch (IOException exception){
- Log.error("Error reading from file", exception); //$NON-NLS-1$
- return false;
- }
- }
- /**
- * This method continues to read from the input stream until
- * either the end of the file is reached, or until a character
- * is found that indicates the end of the substitution. If the
- * SUBSTITUTION_END character is found, the method looks up the
- * plugin id that has been built up to see if it is a valid
- * id. If so, return the absolute path to that plugin. If not,
- * return null.
- *
- * This method assumes that the reader is positioned just
- * after a valid <code>plugin:</code> segment in a substitution
- * string.
- *
- * @return absolute path of the plugin id, if valid. null otherwise
- */
- private String getPluginPath(){
- try {
- while(true) {
- int nextChar = reader.read();
-
- if(nextChar == -1) {
- // reached EOF while looking for closing $
- return null;
- }
- else if(nextChar == SUBSTITUTION_END) { // end of plugin id
- // look up the plugin id. If it is a valid id
- // return the absolute path to this plugin.
- // otherwise return null.
- String path = HTMLUtil.getResolvedBundleLocation(
- pluginId.toString());
-
- // If the plugin id was not valid, reset reader to the
- // previous mark. The mark should be at the character
- // just before the last dollar sign.
- if(path == null)
- reader.reset();
-
- return path;
- }
- else { // we have a regular character
- // mark the most recent non-dollar char in case we don't
- // find a valid plugin id and have to roll back
- // Use 1024 as our readAheadLimit
- reader.mark(0x400);
- // Add this character to the pluginId and tokenContent String.
- // make sure we have a valid character before performing cast
- if(nextChar > 0x00 && nextChar < 0xffff) {
- tokenContent.append((char)nextChar);
- // only include non-whitespace characters in plugin id
- if(!Character.isWhitespace((char)nextChar))
- pluginId.append((char)nextChar);
- }
- else {
- tokenContent.append(nextChar);
- pluginId.append(nextChar);
- }
- }
- }
- } catch (IOException exception){
- Log.error("Error reading from file", exception); //$NON-NLS-1$
- return null;
- }
- }
- }
} \ No newline at end of file
diff --git a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/AbstractIntroContainer.java b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/AbstractIntroContainer.java
index 991b7c306..bfb49dd22 100644
--- a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/AbstractIntroContainer.java
+++ b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/AbstractIntroContainer.java
@@ -168,10 +168,16 @@ public abstract class AbstractIntroContainer extends AbstractBaseIntroElement {
case AbstractIntroElement.PAGE_TITLE:
src = new IntroPageTitle[size];
break;
+ case AbstractIntroElement.ANCHOR:
+ src = new IntroAnchor[size];
+ break;
+ case AbstractIntroElement.CONTENT_PROVIDER:
+ src = new IntroContentProvider[size];
+ break;
default:
// now handle left over abstract types. Vector is not homogenous.
- src = src = new AbstractIntroElement[size];
+ src = new AbstractIntroElement[size];
break;
}
if (src == null)
@@ -205,7 +211,6 @@ public abstract class AbstractIntroContainer extends AbstractBaseIntroElement {
loaded = true;
// free DOM model for memory performance.
element = null;
-
}
/**
@@ -275,6 +280,9 @@ public abstract class AbstractIntroContainer extends AbstractBaseIntroElement {
else if (childElement.getNodeName().equalsIgnoreCase(
IntroAnchor.TAG_ANCHOR))
child = new IntroAnchor(childElement, bundle);
+ else if (childElement.getNodeName().equalsIgnoreCase(
+ IntroContentProvider.TAG_CONTENT_PROVIDER))
+ child = new IntroContentProvider(childElement, bundle);
return child;
}
diff --git a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/AbstractIntroElement.java b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/AbstractIntroElement.java
index dad31699d..b14830d72 100644
--- a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/AbstractIntroElement.java
+++ b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/AbstractIntroElement.java
@@ -85,11 +85,6 @@ public abstract class AbstractIntroElement implements Cloneable {
public static final int LINK = 1 << 6;
/**
- * Type constant which identifies the AbstractText element.
- */
- public static final int ABSTRACT_TEXT = HTML | LINK;
-
- /**
* Type constant which identifies the IntroImage element.
*/
public static final int IMAGE = 1 << 7;
@@ -124,6 +119,15 @@ public abstract class AbstractIntroElement implements Cloneable {
*/
public static final int ANCHOR = 1 << 13;
+ /**
+ * Type constant which identifies the IntroContentProvider element.
+ */
+ public static final int CONTENT_PROVIDER = 1 << 14;
+
+ /**
+ * Type constant which identifies the AbstractText element.
+ */
+ public static final int ABSTRACT_TEXT = HTML | LINK | CONTENT_PROVIDER;
/**
* Type constant which identifies the AbstractCommonIntroElement element.
@@ -284,7 +288,7 @@ public abstract class AbstractIntroElement implements Cloneable {
/**
- * Returns whether the element is among the specified element types.An
+ * Returns whether the element is among the specified element types. An
* example of an element mask is as follows:
* <p>
* <code>
@@ -330,11 +334,10 @@ public abstract class AbstractIntroElement implements Cloneable {
}
/**
- * Shallow copy. Note, not all parents are cloned. One parent has many
- * children. The design of cloning this model assumes that when a container
- * is cloned, all its children must be cloned and reparented to it, hence
- * one clone of this container object. This is why we have a shallow copy
- * here.
+ * Shallow copy. The design of cloning this model assumes that when a
+ * container is cloned, all its children must be cloned and reparented to
+ * it, hence one clone of this container object. This is why we have a
+ * shallow copy here.
*/
public Object clone() throws CloneNotSupportedException {
return super.clone();
diff --git a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/AbstractIntroPartImplementation.java b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/AbstractIntroPartImplementation.java
index 5c226a413..474628ffe 100644
--- a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/AbstractIntroPartImplementation.java
+++ b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/AbstractIntroPartImplementation.java
@@ -245,6 +245,8 @@ public abstract class AbstractIntroPartImplementation {
*/
protected abstract void updateNavigationActionsState();
+
+
public abstract boolean navigateBackward();
public abstract boolean navigateForward();
diff --git a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/IntroContentProvider.java b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/IntroContentProvider.java
new file mode 100644
index 000000000..e47f9f27f
--- /dev/null
+++ b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/IntroContentProvider.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.ui.internal.intro.impl.model;
+
+import org.osgi.framework.*;
+import org.w3c.dom.*;
+
+/**
+ * An intro content provider element. This element allows intro page to
+ * dynamically pull data from various sources (e.g., the web, eclipse, etc) and
+ * provide content based on this dynamic data. The element's class must
+ * implement the IIntroContentProvider interface. The pluginId attribute can be
+ * used if the class doesn't come from the plugin that defined the markup. The
+ * text content should be used only if we fail to load the class. <br>
+ *
+ * REVISIT: model class has access to style-id attribute but it is not used in
+ * the schema.
+ */
+public class IntroContentProvider extends AbstractTextElement {
+ protected static final String TAG_CONTENT_PROVIDER = "contentProvider"; //$NON-NLS-1$
+
+ private static final String ATT_PLUGIN_ID = "pluginId"; //$NON-NLS-1$
+ private static final String ATT_CLASS = "class"; //$NON-NLS-1$
+
+ private String contentProvider;
+ private String pluginId;
+
+
+ public IntroContentProvider(Element element, Bundle bundle) {
+ super(element, bundle);
+ contentProvider = getAttribute(element, ATT_CLASS);
+ pluginId = getAttribute(element, ATT_PLUGIN_ID);
+ }
+
+ /**
+ * Returns the content provider, which should implement
+ * IIntroContentProvider
+ *
+ * @return Returns the contentProvider.
+ */
+ public String getClassName() {
+ return contentProvider;
+ }
+
+ /**
+ * Returns the id of the plugin that contains the content provider class
+ *
+ * @return Returns the pluginId.
+ */
+ public String getPluginId() {
+ return pluginId;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.internal.intro.impl.model.AbstractIntroElement#getType()
+ */
+ public int getType() {
+ return AbstractIntroElement.CONTENT_PROVIDER;
+ }
+} \ No newline at end of file
diff --git a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/IntroModelRoot.java b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/IntroModelRoot.java
index 3a622d3de..28c20d3ee 100644
--- a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/IntroModelRoot.java
+++ b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/IntroModelRoot.java
@@ -424,7 +424,8 @@ public class IntroModelRoot extends AbstractIntroContainer {
}
/**
- * @return Returns the standby Page.
+ * @return Returns the standby Page. May return null if standby page is not
+ * defined.
*/
public IntroHomePage getStandbyPage() {
return standbyPage;
diff --git a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/IntroURL.java b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/IntroURL.java
index 340d845b7..4e815489c 100644
--- a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/IntroURL.java
+++ b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/IntroURL.java
@@ -160,7 +160,7 @@ public class IntroURL implements IIntroURL {
/**
* Sets the into part to standby, and shows the passed standby part, with
- * the given input.
+ * the given input. Forces the Intro view to open, if not yet created.
*
* @param partId
* @param input
@@ -189,7 +189,8 @@ public class IntroURL implements IIntroURL {
}
/**
- * Set the Workbench Intro Part state.
+ * Set the Workbench Intro Part state. Forces the Intro view to open, if not
+ * yet created.
*
* @param state
*/
@@ -294,8 +295,7 @@ public class IntroURL implements IIntroURL {
}
/**
- * Display an Intro Page. Take a flag to enable to disable redrawing.
- * Default is setting redraw to of.
+ * Display an Intro Page.
* <p>
* REVISIT: revisit picking first page.
*/
diff --git a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/loader/BaseExtensionPointManager.java b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/loader/BaseExtensionPointManager.java
index b38aa3c4b..7a4d6b2ac 100644
--- a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/loader/BaseExtensionPointManager.java
+++ b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/loader/BaseExtensionPointManager.java
@@ -20,7 +20,6 @@ import org.eclipse.ui.internal.intro.impl.util.*;
/**
* Base class for handling Intro Extensions.
*/
-
public class BaseExtensionPointManager {
// the config extension id
@@ -51,12 +50,12 @@ public class BaseExtensionPointManager {
registry = Platform.getExtensionRegistry();
}
- protected IntroModelRoot loadModel(String attrributeName,
+ protected IntroModelRoot loadModel(String attributeName,
String attributeValue) {
// get all Config extension point contributions. There could be more
// than one config contribution, but there should only be one that maps
// to the cached intro part id.
- IConfigurationElement introConfig = getIntroConfig(attrributeName,
+ IConfigurationElement introConfig = getIntroConfig(attributeName,
attributeValue);
// load model with the config elements of the correct contribution. If
diff --git a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/loader/ContentProviderManager.java b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/loader/ContentProviderManager.java
new file mode 100644
index 000000000..a598aa589
--- /dev/null
+++ b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/loader/ContentProviderManager.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.ui.internal.intro.impl.model.loader;
+
+import java.util.*;
+
+import org.eclipse.ui.internal.intro.impl.model.*;
+import org.eclipse.ui.internal.intro.impl.util.*;
+import org.eclipse.ui.intro.config.*;
+
+/**
+ * Class for handling/caching all the loaded Intro Content providers, from all
+ * loaded models. <br>
+ * For now, content provider model classes are used as keys in the hashtable,
+ * and their corresponding classes as values.
+ *
+ */
+
+public class ContentProviderManager {
+
+ // singleton instance. Can be retrieved from here or from the Intro Plugin.
+ private static ContentProviderManager inst = new ContentProviderManager();
+
+
+ // Holds all created content providers, to prevent the need to recreate the
+ // class on each navigation. Key is the contentProvider model class, value
+ // is the actual Intro content provider instance.
+ private Hashtable contentProviders = new Hashtable();
+
+ /*
+ * Prevent creation.
+ */
+ protected ContentProviderManager() {
+ }
+
+ /**
+ * @return Returns the inst.
+ */
+ public static ContentProviderManager getInst() {
+ return inst;
+ }
+
+ /**
+ * Retrieve an existing content provider class, or null if never created
+ * before.
+ *
+ * @param provider
+ * @return
+ */
+ public IIntroContentProvider getContentProvider(
+ IntroContentProvider provider) {
+ // safe to cast since we know the object class in table.
+ IIntroContentProvider providerClass = (IIntroContentProvider) contentProviders
+ .get(provider);
+ return providerClass;
+ }
+
+ /**
+ * Tries to create an intro content provider class. may return null if
+ * creation fails. This will be logged.
+ *
+ * @param provider
+ * @param site
+ * @return
+ */
+ public IIntroContentProvider createContentProvider(
+ IntroContentProvider provider, IIntroContentProviderSite site) {
+
+ // the content provider has never been created before. Create and cache
+ // one.
+ String pluginId = (provider.getPluginId() != null) ? provider
+ .getPluginId() : provider.getBundle().getSymbolicName();
+ Object aClass = (IIntroContentProvider) ModelLoaderUtil
+ .createClassInstance(pluginId, provider.getClassName());
+ IIntroContentProvider providerClass = null;
+ if (aClass != null && aClass instanceof IIntroContentProvider) {
+ providerClass = ((IIntroContentProvider) aClass);
+ providerClass.init(site);
+ contentProviders.put(provider, providerClass);
+ } else
+ Log.info("Failed to create Intro model content provider: " //$NON-NLS-1$
+ + provider.getClassName());
+ return providerClass;
+ }
+
+
+
+ public void clear() {
+ for (Iterator it = contentProviders.values().iterator(); it.hasNext();) {
+ Object provider = it.next();
+ if (provider instanceof IIntroContentProvider) {
+ ((IIntroContentProvider) provider).dispose();
+ }
+ }
+ contentProviders.clear();
+ Log.info("Cleared Intro model content providers"); //$NON-NLS-1$
+ }
+
+
+}
+
+
diff --git a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/loader/ModelLoaderUtil.java b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/loader/ModelLoaderUtil.java
index b495905e3..cd6108202 100644
--- a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/loader/ModelLoaderUtil.java
+++ b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/loader/ModelLoaderUtil.java
@@ -13,6 +13,7 @@ package org.eclipse.ui.internal.intro.impl.model.loader;
import java.util.*;
import org.eclipse.core.runtime.*;
+import org.eclipse.ui.internal.intro.impl.model.*;
import org.eclipse.ui.internal.intro.impl.util.*;
import org.osgi.framework.*;
import org.w3c.dom.*;
@@ -260,13 +261,35 @@ public class ModelLoaderUtil {
aObject = aClass.newInstance();
return aObject;
} catch (Exception e) {
- Log
- .error(
- "Intro Could not instantiate: " + className + " in " + pluginId, //$NON-NLS-1$ //$NON-NLS-2$
- e);
+ Log.error("Intro Could not instantiate: " + className + " in " //$NON-NLS-1$ //$NON-NLS-2$
+ + pluginId, e);
return null;
}
}
+
+ /**
+ * Creates a key for the given element. Returns null if any id is null along
+ * the path.
+ *
+ * @param element
+ * @return
+ */
+ public static StringBuffer createPathToElementKey(
+ AbstractIntroIdElement element) {
+ if (element.getId() == null)
+ return null;
+ StringBuffer buffer = new StringBuffer(element.getId());
+ AbstractBaseIntroElement parent = (AbstractBaseIntroElement) element
+ .getParent();
+ while (parent != null
+ && !parent.isOfType(AbstractIntroElement.MODEL_ROOT)) {
+ if (parent.getId() == null)
+ return null;
+ buffer.insert(0, parent.getId() + "."); //$NON-NLS-1$
+ parent = (AbstractBaseIntroElement) parent.getParent();
+ }
+ return buffer;
+ }
} \ No newline at end of file
diff --git a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/viewer/IntroModelContentProvider.java b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/viewer/IntroModelContentProvider.java
index 450ab9cb2..dd31b6bce 100644
--- a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/viewer/IntroModelContentProvider.java
+++ b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/viewer/IntroModelContentProvider.java
@@ -13,6 +13,7 @@ package org.eclipse.ui.internal.intro.impl.model.viewer;
import org.eclipse.jface.viewers.*;
import org.eclipse.ui.internal.intro.impl.model.*;
+import org.eclipse.ui.intro.config.*;
public class IntroModelContentProvider implements ITreeContentProvider {
@@ -61,7 +62,7 @@ public class IntroModelContentProvider implements ITreeContentProvider {
}
/**
- * @see IContentProvider#dispose()
+ * @see IIntroContentProvider#dispose()
*/
public void dispose() {
}
@@ -69,7 +70,7 @@ public class IntroModelContentProvider implements ITreeContentProvider {
/*
* (non-Javadoc)
*
- * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer,
+ * @see org.eclipse.jface.viewers.IIntroContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer,
* java.lang.Object, java.lang.Object)
*/
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
diff --git a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/viewer/IntroModelLabelProvider.java b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/viewer/IntroModelLabelProvider.java
index 498aa937b..ff09134c9 100644
--- a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/viewer/IntroModelLabelProvider.java
+++ b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/model/viewer/IntroModelLabelProvider.java
@@ -94,6 +94,10 @@ public class IntroModelLabelProvider extends LabelProvider {
+ ((IntroPartPresentation) introElement)
.getImplementationKind();
break;
+ case AbstractIntroElement.CONTENT_PROVIDER:
+ label = "CONTENT PROVIDER: " //$NON-NLS-1$
+ + ((IntroContentProvider) introElement).getClassName();
+ break;
case AbstractIntroElement.CONTAINER_EXTENSION:
label = "Unresolved ConfigExtension: " //$NON-NLS-1$
+ ((IntroExtensionContent) introElement).getPath();
diff --git a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/presentations/BrowserIntroPartImplementation.java b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/presentations/BrowserIntroPartImplementation.java
index 16c5f0fda..085067be0 100644
--- a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/presentations/BrowserIntroPartImplementation.java
+++ b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/presentations/BrowserIntroPartImplementation.java
@@ -19,9 +19,11 @@ import org.eclipse.ui.internal.intro.impl.*;
import org.eclipse.ui.internal.intro.impl.html.*;
import org.eclipse.ui.internal.intro.impl.model.*;
import org.eclipse.ui.internal.intro.impl.util.*;
+import org.eclipse.ui.intro.config.*;
public class BrowserIntroPartImplementation extends
- AbstractIntroPartImplementation implements IPropertyListener {
+ AbstractIntroPartImplementation implements IPropertyListener,
+ IIntroContentProviderSite {
// the browser widget that will display the intro content
@@ -145,7 +147,7 @@ public class BrowserIntroPartImplementation extends
*/
private boolean generateDynamicContentForPage(AbstractIntroPage page) {
- HTMLElement html = getHTMLGenerator().generateHTMLforPage(page);
+ HTMLElement html = getHTMLGenerator().generateHTMLforPage(page, this);
if (html == null) {
// there was an error generating the html. log an error
@@ -213,7 +215,7 @@ public class BrowserIntroPartImplementation extends
standbyPage = homePage;
if (standby) {
- generateDynamicContentForPage(getModel().getStandbyPage());
+ generateDynamicContentForPage(standbyPage);
} else {
// REVISIT: If cached page is the standby page and we are not
// initially in standby mode, it means standby was forced on
@@ -239,7 +241,8 @@ public class BrowserIntroPartImplementation extends
if (pageId == null || pageId.equals("")) //$NON-NLS-1$
// page ID was not set properly. exit.
return;
- generateDynamicContentForPage(getModel().getCurrentPage());
+ // update the presentation's content based on the model changes
+ updateContent();
}
}
@@ -252,6 +255,22 @@ public class BrowserIntroPartImplementation extends
}
/**
+ * Regenerate the dynamic content for the current page
+ */
+ protected void updateContent() {
+ generateDynamicContentForPage(getModel().getCurrentPage());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.internal.intro.impl.model.AbstractIntroPartImplementation#reflow()
+ */
+ public void reflow(IIntroContentProvider provider, boolean incremental) {
+ updateContent();
+ }
+
+ /**
* Override parent behavior to handle the case when we have a static page.
* This can happen in both the static intro case, or in the dynamic when the
* last visited page is the dynamic browser is an http: page, and not an
@@ -377,7 +396,8 @@ public class BrowserIntroPartImplementation extends
if (getModel().isDynamic()) {
// null generator first.
htmlGenerator = null;
- // Add this presentation as a listener to mode only in dynamic case.
+ // Add this presentation as a listener to model only in dynamic
+ // case.
getModel().addPropertyListener(this);
getModel().firePropertyChange(
IntroModelRoot.CURRENT_PAGE_PROPERTY_ID);
diff --git a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/presentations/FormIntroPartImplementation.java b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/presentations/FormIntroPartImplementation.java
index 427183a10..29bbc479d 100644
--- a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/presentations/FormIntroPartImplementation.java
+++ b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/presentations/FormIntroPartImplementation.java
@@ -73,7 +73,6 @@ public class FormIntroPartImplementation extends
}
public void createPartControl(Composite container) {
-
if (getModel().isDynamic())
dynamicCreatePartControl(container);
else {
@@ -281,7 +280,7 @@ public class FormIntroPartImplementation extends
boolean pageisCached = showExistingPage(pageToShow);
if (!pageisCached) {
- // page has not been show before.
+ // page has not been shown before.
// load style manager here to test for navigation.
PageStyleManager styleManager = new PageStyleManager(pageToShow,
sharedStyleManager.getProperties());
@@ -477,4 +476,6 @@ public class FormIntroPartImplementation extends
welcomeLink.setToolTipText(homePage.getUrl());
}
}
+
+
} \ No newline at end of file
diff --git a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/presentations/TextIntroPartImplementation.java b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/presentations/TextIntroPartImplementation.java
index 5690dd159..11d0139d5 100644
--- a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/presentations/TextIntroPartImplementation.java
+++ b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/presentations/TextIntroPartImplementation.java
@@ -16,6 +16,7 @@ import org.eclipse.swt.widgets.*;
import org.eclipse.ui.internal.intro.impl.*;
import org.eclipse.ui.internal.intro.impl.model.*;
import org.eclipse.ui.internal.intro.impl.util.*;
+import org.eclipse.ui.intro.config.*;
/**
* This is an Text based implementation of an Intro Part. It simply walks the
@@ -76,5 +77,6 @@ public class TextIntroPartImplementation extends
return false;
}
-
+ public void reflow(IIntroContentProvider provider, boolean incremental) {
+ }
} \ No newline at end of file
diff --git a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/swt/PageContentForm.java b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/swt/PageContentForm.java
index 8193d4d17..896da8d17 100644
--- a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/swt/PageContentForm.java
+++ b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/swt/PageContentForm.java
@@ -15,16 +15,20 @@ import org.eclipse.swt.widgets.*;
import org.eclipse.ui.forms.widgets.*;
import org.eclipse.ui.internal.intro.impl.*;
import org.eclipse.ui.internal.intro.impl.model.*;
+import org.eclipse.ui.intro.config.*;
/**
* A Composite that represents the content of an Intro Page. It is swapped in
* the categories page book in the PageForm class.
*/
-public class PageContentForm implements IIntroConstants {
+public class PageContentForm implements IIntroConstants,
+ IIntroContentProviderSite {
private FormToolkit toolkit;
private IntroModelRoot model;
private PageStyleManager styleManager;
+ // composite to control reflow.
+ private Composite contentComposite;
// the page we are modeling here.
private AbstractIntroPage page;
@@ -90,6 +94,7 @@ public class PageContentForm implements IIntroConstants {
private void createPageChildren(AbstractIntroPage page, Composite parent) {
// setup page composite/layout
PageWidgetFactory factory = new PageWidgetFactory(toolkit, styleManager);
+ factory.setContentProviderSite(this);
Composite pageComposite = createPageTableComposite(factory, parent);
// now add all children
AbstractIntroElement[] children = page.getChildren();
@@ -128,4 +133,15 @@ public class PageContentForm implements IIntroConstants {
return client;
}
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.intro.config.IIntroContentProviderSite#reflow(org.eclipse.ui.intro.config.IIntroContentProvider,
+ * boolean)
+ */
+ public void reflow(IIntroContentProvider provider, boolean incremental) {
+ contentComposite.layout(true);
+ }
+
} \ No newline at end of file
diff --git a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/swt/PageForm.java b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/swt/PageForm.java
index 81e85a5f4..a98e925b7 100644
--- a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/swt/PageForm.java
+++ b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/swt/PageForm.java
@@ -22,7 +22,7 @@ import org.eclipse.ui.internal.intro.impl.util.*;
/**
* A Form that represents an Intro Page. It is swapped in the main page book in
* the FormIntroPartImplementation class. It has a page book for swapping in
- * categories of Intro Pages.
+ * categories (content) of Intro Pages.
*/
public class PageForm implements IIntroConstants {
diff --git a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/swt/PageStyleManager.java b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/swt/PageStyleManager.java
index b84bb532f..3b6c7fac7 100644
--- a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/swt/PageStyleManager.java
+++ b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/swt/PageStyleManager.java
@@ -14,6 +14,7 @@ import org.eclipse.jface.resource.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.ui.forms.widgets.*;
import org.eclipse.ui.internal.intro.impl.model.*;
+import org.eclipse.ui.internal.intro.impl.model.loader.*;
import org.eclipse.ui.internal.intro.impl.util.*;
import org.osgi.framework.*;
@@ -176,7 +177,7 @@ public class PageStyleManager extends SharedStyleManager {
private int getIntProperty(AbstractBaseIntroElement element,
String qualifier, int defaultValue) {
- StringBuffer buff = createPathToElementKey(element);
+ StringBuffer buff = ModelLoaderUtil.createPathToElementKey(element);
if (buff == null)
return defaultValue;
String key = buff.append(qualifier).toString();
@@ -209,7 +210,7 @@ public class PageStyleManager extends SharedStyleManager {
* @return
*/
public String getDescription(IntroGroup group) {
- StringBuffer buff = createPathToElementKey(group);
+ StringBuffer buff = ModelLoaderUtil.createPathToElementKey(group);
if (buff == null)
return null;
String key = buff.append(".description-id").toString(); //$NON-NLS-1$
@@ -327,7 +328,7 @@ public class PageStyleManager extends SharedStyleManager {
String key = page.getId() + ".show-link-description"; //$NON-NLS-1$
String value = getProperty(key);
if (value == null) {
- key = ".show-link-description";
+ key = ".show-link-description"; //$NON-NLS-1$
value = getProperty(key);
}
if (value == null)
@@ -339,7 +340,7 @@ public class PageStyleManager extends SharedStyleManager {
String key = page.getId() + ".show-home-page-navigation"; //$NON-NLS-1$
String value = getProperty(key);
if (value == null) {
- key = ".show-home-page-navigation";
+ key = ".show-home-page-navigation"; //$NON-NLS-1$
value = getProperty(key);
}
if (value == null)
@@ -349,7 +350,7 @@ public class PageStyleManager extends SharedStyleManager {
public Color getColor(FormToolkit toolkit, AbstractBaseIntroElement element) {
- StringBuffer buff = createPathToElementKey(element);
+ StringBuffer buff = ModelLoaderUtil.createPathToElementKey(element);
if (buff == null)
return null;
String key = buff.append(".font.fg").toString(); //$NON-NLS-1$
@@ -358,7 +359,7 @@ public class PageStyleManager extends SharedStyleManager {
public boolean isBold(IntroText text) {
String value = null;
- StringBuffer buff = createPathToElementKey(text);
+ StringBuffer buff = ModelLoaderUtil.createPathToElementKey(text);
if (buff != null) {
String key = buff.append(".font.bold").toString(); //$NON-NLS-1$
value = getProperty(key);
@@ -411,7 +412,7 @@ public class PageStyleManager extends SharedStyleManager {
String qualifier) {
StringBuffer buff = null;
if (link != null) {
- buff = createPathToElementKey(link);
+ buff = ModelLoaderUtil.createPathToElementKey(link);
if (buff == null)
return ""; //$NON-NLS-1$
} else {
@@ -425,7 +426,8 @@ public class PageStyleManager extends SharedStyleManager {
public Image getImage(IntroImage introImage) {
String imageLocation = introImage.getSrcAsIs();
- String key = createPathToElementKey(introImage).toString();
+ String key = ModelLoaderUtil.createPathToElementKey(introImage)
+ .toString();
if (ImageUtil.hasImage(key))
return ImageUtil.getImage(key);
// key not already registered.
@@ -434,28 +436,6 @@ public class PageStyleManager extends SharedStyleManager {
return image;
}
- /**
- * Creates a key for the given element. Returns null if any id is null along
- * the path.
- *
- * @param element
- * @return
- */
- private StringBuffer createPathToElementKey(AbstractIntroIdElement element) {
- if (element.getId() == null)
- return null;
- StringBuffer buffer = new StringBuffer(element.getId());
- AbstractBaseIntroElement parent = (AbstractBaseIntroElement) element
- .getParent();
- while (parent != null
- && !parent.isOfType(AbstractIntroElement.MODEL_ROOT)) {
- if (parent.getId() == null)
- return null;
- buffer.insert(0, parent.getId() + "."); //$NON-NLS-1$
- parent = (AbstractBaseIntroElement) parent.getParent();
- }
- return buffer;
- }
}
diff --git a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/swt/PageWidgetFactory.java b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/swt/PageWidgetFactory.java
index eeb1b746e..ff74ef983 100644
--- a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/swt/PageWidgetFactory.java
+++ b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/swt/PageWidgetFactory.java
@@ -16,7 +16,9 @@ import org.eclipse.ui.forms.events.*;
import org.eclipse.ui.forms.widgets.*;
import org.eclipse.ui.internal.intro.impl.*;
import org.eclipse.ui.internal.intro.impl.model.*;
+import org.eclipse.ui.internal.intro.impl.model.loader.*;
import org.eclipse.ui.internal.intro.impl.util.*;
+import org.eclipse.ui.intro.config.*;
/**
* Factory to create all UI forms widgets for the Forms intro presentation.
@@ -51,6 +53,7 @@ public class PageWidgetFactory {
protected FormToolkit toolkit;
protected PageStyleManager styleManager;
+ protected IIntroContentProviderSite site;
/*
@@ -62,6 +65,9 @@ public class PageWidgetFactory {
this.styleManager = styleManager;
}
+ public void setContentProviderSite(IIntroContentProviderSite site) {
+ this.site = site;
+ }
public void createIntroElement(Composite parent,
AbstractIntroElement element) {
@@ -128,6 +134,11 @@ public class PageWidgetFactory {
if (c != null)
updateLayoutData(c, element);
break;
+ case AbstractIntroElement.CONTENT_PROVIDER:
+ IntroContentProvider provider = (IntroContentProvider) element;
+ c = createContentProvider(parent, provider);
+ updateLayoutData(c, element);
+ break;
default:
break;
}
@@ -228,7 +239,7 @@ public class PageWidgetFactory {
ImageHyperlink imageLink = toolkit.createImageHyperlink(parent,
SWT.WRAP | SWT.CENTER);
imageLink.setImage(linkImage);
- imageLink.setHoverImage(styleManager.getImage(link, "hover-icon",
+ imageLink.setHoverImage(styleManager.getImage(link, "hover-icon", //$NON-NLS-1$
null));
TableWrapData td = new TableWrapData();
td.grabHorizontal = true;
@@ -308,6 +319,33 @@ public class PageWidgetFactory {
}
+ protected Control createContentProvider(Composite parent,
+ IntroContentProvider provider) {
+ // If we've already loaded the content provider for this element,
+ // retrieve it, otherwise load the class.
+ // Create parent composite to hold daynamic content, and set layout
+ // accordingly.
+ Composite container = toolkit.createComposite(parent);
+ TableWrapLayout layout = new TableWrapLayout();
+ layout.topMargin = 0;
+ layout.bottomMargin = 0;
+ layout.leftMargin = 0;
+ layout.rightMargin = 0;
+ container.setLayout(layout);
+
+ IIntroContentProvider providerClass = ContentProviderManager.getInst()
+ .getContentProvider(provider);
+ if (providerClass == null)
+ // content provider never created before, create it.
+ providerClass = ContentProviderManager.getInst()
+ .createContentProvider(provider, site);
+
+ if (providerClass != null) {
+ providerClass.createContent(provider.getId(), container, toolkit);
+ }
+ return container;
+ }
+
private void colorControl(Control elementControl,
AbstractBaseIntroElement element) {
Color fg = styleManager.getColor(toolkit, element);
diff --git a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/util/IntroModelSerializer.java b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/util/IntroModelSerializer.java
index e34bbe444..6681f8d00 100644
--- a/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/util/IntroModelSerializer.java
+++ b/org.eclipse.ui.intro/src/org/eclipse/ui/internal/intro/impl/util/IntroModelSerializer.java
@@ -145,6 +145,10 @@ public class IntroModelSerializer {
case AbstractIntroElement.ANCHOR:
printAnchor(text, (IntroAnchor) children[i], indent);
break;
+ case AbstractIntroElement.CONTENT_PROVIDER:
+ printContentProvidor(text, (IntroContentProvider) children[i],
+ indent);
+ break;
}
}
@@ -220,6 +224,17 @@ public class IntroModelSerializer {
text.append(indent + "ANCHOR: id = " + anchor.getId()); //$NON-NLS-1$
}
+ private void printContentProvidor(StringBuffer text,
+ IntroContentProvider provider, String indent) {
+ text.append(indent + "CONTENT PROVIDER: id = " + provider.getId()); //$NON-NLS-1$
+ indent = indent + "\t\t"; //$NON-NLS-1$
+ text.append(indent + "class = " + provider.getClassName()); //$NON-NLS-1$
+ text.append(indent + "pluginId = " + provider.getPluginId()); //$NON-NLS-1$
+ if (provider.getIntroText() != null)
+ printText(text, provider.getIntroText(), indent + "\t\t"); //$NON-NLS-1$
+
+ }
+
/**
* Appends a given page's categories to the Text buffer.
*
@@ -292,6 +307,14 @@ public class IntroModelSerializer {
+ firstPage
.getChildrenOfType(AbstractIntroElement.ABSTRACT_PAGE).length);
text
+ .append("\n\t\t\tAnchors: " //$NON-NLS-1$
+ + firstPage
+ .getChildrenOfType(AbstractIntroElement.ANCHOR).length);
+ text
+ .append("\n\t\t\tContent providers: " //$NON-NLS-1$
+ + firstPage
+ .getChildrenOfType(AbstractIntroElement.CONTENT_PROVIDER).length);
+ text
.append("\n\t\t\tElements with Text child(AbstractTextElemets): " //$NON-NLS-1$
+ firstPage
.getChildrenOfType(AbstractIntroElement.ABSTRACT_TEXT).length);
diff --git a/org.eclipse.ui.intro/src/org/eclipse/ui/intro/config/CustomizableIntroPart.java b/org.eclipse.ui.intro/src/org/eclipse/ui/intro/config/CustomizableIntroPart.java
index 76e73d222..ffdae7ded 100644
--- a/org.eclipse.ui.intro/src/org/eclipse/ui/intro/config/CustomizableIntroPart.java
+++ b/org.eclipse.ui.intro/src/org/eclipse/ui/intro/config/CustomizableIntroPart.java
@@ -286,7 +286,7 @@ public final class CustomizableIntroPart extends IntroPart implements
}
private Control getStandbyControl() {
- // the Containet top control may have only one child if the stanndby
+ // the Container top control may have only one child if the standby
// part is not created yet. This happens if the intro never goes into
// standby. Doing this for performance.
if (standbyPart != null)
@@ -313,6 +313,7 @@ public final class CustomizableIntroPart extends IntroPart implements
standbyPart.dispose();
// clear all loaded models since we are disposing of the Intro Part.
IntroPlugin.getDefault().getExtensionPointManager().clear();
+ ContentProviderManager.getInst().clear();
// clean platform adapter.
Platform.getAdapterManager().unregisterAdapters(factory,
CustomizableIntroPart.class);
@@ -394,8 +395,9 @@ public final class CustomizableIntroPart extends IntroPart implements
public void run() {
String currentPageId = model.getCurrentPageId();
- // clear model
+ // clear model, including content providers.
ExtensionPointManager.getInst().clear();
+ ContentProviderManager.getInst().clear();
// refresh to new model.
model = ExtensionPointManager.getInst().getCurrentModel();
// reuse existing presentation, since we just nulled it.
@@ -409,7 +411,6 @@ public final class CustomizableIntroPart extends IntroPart implements
});
}
-
}
diff --git a/org.eclipse.ui.intro/src/org/eclipse/ui/intro/config/IIntroAction.java b/org.eclipse.ui.intro/src/org/eclipse/ui/intro/config/IIntroAction.java
index 3000d7014..e76a1a086 100644
--- a/org.eclipse.ui.intro/src/org/eclipse/ui/intro/config/IIntroAction.java
+++ b/org.eclipse.ui.intro/src/org/eclipse/ui/intro/config/IIntroAction.java
@@ -33,6 +33,6 @@ public interface IIntroAction {
* @param site
* @param params
*/
- void run(IIntroSite site, Properties params);
+ public void run(IIntroSite site, Properties params);
} \ No newline at end of file
diff --git a/org.eclipse.ui.intro/src/org/eclipse/ui/intro/config/IIntroContentProvider.java b/org.eclipse.ui.intro/src/org/eclipse/ui/intro/config/IIntroContentProvider.java
new file mode 100644
index 000000000..8c231d25a
--- /dev/null
+++ b/org.eclipse.ui.intro/src/org/eclipse/ui/intro/config/IIntroContentProvider.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ui.intro.config;
+
+import java.io.*;
+
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.forms.widgets.*;
+
+/**
+ * A content provider for dynamic intro content. It is initialized with the
+ * content provider site because a typical content provider would need to update
+ * its contents dynamically at runtime. And so, the site can be informed of a
+ * need to redraw its content through a call to its reflow method.
+ * <p>
+ * The life cycle of an IIntroContentProvider is as follows:
+ * <ul>
+ * <li>a content provider is defined in the Intro content markup file (ie:
+ * introContent.xml file) as follows:
+ *
+ * <p>
+ * &lt;contentProvider id=&quot;roles&quot;
+ * class=&quot;x.y.z.ContentProvider&quot;&gt; <br>
+ * &lt;text&gt;Some alternate text for dynamic content&lt;/text&gt; <br>
+ * &lt;/contentProvider&gt;
+ * </p>
+ *
+ * This defines the content provider as part of the intro content for that page.
+ * </li>
+ * <li>the content provider class is created when the page that contains this
+ * provider is loaded. It is only created once in the life cycle of an open
+ * Intro view, ie: the class instance is cached and only disposed of when the
+ * intro view is closed.
+ * <li>init() is called to initialize the instance of the class on load of the
+ * page. This is where the provider site can be cached for later reuse.</li>
+ * <li>createContent() is then called to give the content provider a chance to
+ * generate the dynamic content. This is when the dynamic content can be cached
+ * for later reuse when the same page is shown again.</li>
+ * <li>it is important to note that there is a difference between when the
+ * createContent() is called in the case of SWT and HTML presentations. The HTML
+ * presentation is dynamic html generated on the fly each time an Intro page
+ * needs to be displayed. SWT presentation on the other hand, is based on SWT
+ * forms widgets, and for performance, each page is only created once and cached
+ * in a pageBook for re-use. With this in mind, createContent() is called every
+ * time a page is shown in the case of HTML presentation. Whereas it is only
+ * called once in the case of the SWT presentation. This is why createContent()
+ * should not be used as a means of refreshing content. Content should only be
+ * created once during this method call, and cached for later re-use. If a
+ * refresh is needed, then reflow() should be called on the contentProviderSite
+ * when the appropriate event happens.
+ * <li>finally, when the intro view is closed, dispose will be called on the
+ * content provider to give it a chance to dispose of any resources.</li>
+ *
+ * @since 3.0.1
+ */
+public interface IIntroContentProvider {
+ /**
+ * Initializes the content provider. An IIntroContentProviderSite is passed,
+ * which will be called on to recompute or layout the content when the
+ * content becomes stale.
+ *
+ * @param site
+ * the site of this IIntroContentProvider
+ */
+ public void init(IIntroContentProviderSite site);
+
+
+ /**
+ * Creates HTML content in the provided PrintWriter. This content will be
+ * included in the generated HTML page when embedded HTML widget is used to
+ * render intro content.
+ *
+ * @param id
+ * the unique identifier of the content element. The same content
+ * provider class can be reused for several elements and the id
+ * can be used to tell them apart.
+ * @param out
+ * the output print writer to generate HTML content into
+ */
+ public void createContent(String id, PrintWriter out);
+
+ /**
+ * Creates SWT content in the provided Composite. This method is called when
+ * Eclipse Forms are used to render intro content.
+ *
+ * @param id
+ * the unique identifier of the content element
+ * @param parent
+ * the parent composite that should be used when creating SWT
+ * widgets
+ * @param toolkit
+ * the form toolkit that should be used when creating new widgets
+ */
+ public void createContent(String id, Composite parent, FormToolkit toolkit);
+
+
+ /**
+ * Dispose of the ContentProvider. This will only be called when the Intro
+ * view is closed. In other words, the content provider will not be disposed
+ * of until the last possible minute. This gives the implementor the chance
+ * to cache content and avoid regenerating content on every page switch.
+ */
+ public void dispose();
+
+} \ No newline at end of file
diff --git a/org.eclipse.ui.intro/src/org/eclipse/ui/intro/config/IIntroContentProviderSite.java b/org.eclipse.ui.intro/src/org/eclipse/ui/intro/config/IIntroContentProviderSite.java
new file mode 100644
index 000000000..21864118d
--- /dev/null
+++ b/org.eclipse.ui.intro/src/org/eclipse/ui/intro/config/IIntroContentProviderSite.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ui.intro.config;
+
+/**
+ * An interface between a content provider and its parent container. A content
+ * provider is responsible for creating dynamic intro content, while the content
+ * provider site is responsible for reflowing the new content in the intro part.
+ * An intro content provider site may have more than one content provider. The
+ * id of the content provider can be used to distinguish the source of the
+ * reflow.
+ * <p>
+ * This interface is not intended to be implemented or extended by clients.
+ *
+ * @since 3.0.1
+ */
+public interface IIntroContentProviderSite {
+ /**
+ * This method will be called when the IIntroContentProvider is notified
+ * that its content has become stale. For an HTML presentation, the whole
+ * page should be regenerated. An SWT presentation should cause the page's
+ * layout to be updated.
+ *
+ * @param provider the content provider that requests a reflow
+ * @param incremental if <code>true</code>, an attempt should be made
+ * to incrementally reflow the page. Otherwise, the page should
+ * be recreated from scratch. This is just a hint and the implementation
+ * of the interface can ignore it.
+ */
+ public void reflow(IIntroContentProvider provider, boolean incremental);
+} \ No newline at end of file

Back to the top