Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Austin2011-03-02 16:06:00 -0500
committerChris Austin2011-03-02 16:06:00 -0500
commitf80d928f29a67bfad5d8779e0d916627e5c035d7 (patch)
tree3eae5c4a5e0e05a8062c9bdaeffca2bad7056034
parent6954a216bfa05fb8ce639426c60a2c5d211e1512 (diff)
downloadeclipse.platform.ua-f80d928f29a67bfad5d8779e0d916627e5c035d7.tar.gz
eclipse.platform.ua-f80d928f29a67bfad5d8779e0d916627e5c035d7.tar.xz
eclipse.platform.ua-f80d928f29a67bfad5d8779e0d916627e5c035d7.zip
Bug 319907 - [Help] Promote main help servlets to public API
-rw-r--r--org.eclipse.help.webapp/META-INF/MANIFEST.MF2
-rw-r--r--org.eclipse.help.webapp/plugin.xml85
-rw-r--r--org.eclipse.help.webapp/schema/validatedServlet.exsd129
-rw-r--r--org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/WebappResources.properties7
-rw-r--r--org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/data/SearchData.java17
-rw-r--r--org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/parser/ContextParser.java85
-rw-r--r--org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/parser/ExtensionParser.java77
-rw-r--r--org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/parser/IndexFragmentParser.java55
-rw-r--r--org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/parser/IndexParser.java60
-rw-r--r--org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/parser/ParseElement.java123
-rw-r--r--org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/parser/ResultParser.java99
-rw-r--r--org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/parser/SearchParser.java84
-rw-r--r--org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/parser/TocFragmentParser.java94
-rw-r--r--org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/parser/TocParser.java58
-rw-r--r--org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/AboutService.java42
-rw-r--r--org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/AdvancedSearchService.java135
-rw-r--r--org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/ContentService.java89
-rw-r--r--org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/ContextService.java109
-rw-r--r--org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/ControlService.java35
-rw-r--r--org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/ExtensionService.java97
-rw-r--r--org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/IndexFragmentService.java112
-rw-r--r--org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/IndexService.java99
-rw-r--r--org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/LiveHelpService.java34
-rw-r--r--org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/NavService.java68
-rw-r--r--org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/SearchService.java102
-rw-r--r--org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/SearchStateService.java118
-rw-r--r--org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/TocFragmentService.java117
-rw-r--r--org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/TocService.java98
-rw-r--r--org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/ContextServlet.java50
-rw-r--r--org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/ExtensionServlet.java12
-rw-r--r--org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/IndexFragmentServlet.java13
-rw-r--r--org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/IndexServlet.java13
-rw-r--r--org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/SearchServlet.java62
-rw-r--r--org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/ServletPrintWriter.java81
-rw-r--r--org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/TocFragmentServlet.java13
-rw-r--r--org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/TocServlet.java11
-rw-r--r--org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/ValidatorServlet.java274
-rw-r--r--org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/utils/JSonHelper.java56
-rw-r--r--org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/utils/SearchXMLGenerator.java117
-rw-r--r--org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/utils/Utils.java95
-rw-r--r--org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/utils/XMLHelper.java41
-rw-r--r--org.eclipse.ua.tests/data/help/jsp/server.js45
-rw-r--r--org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/AllHelpTests.java4
-rw-r--r--org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/remote/ContextServletTest.java7
-rw-r--r--org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/remote/IndexServletTest.java3
-rwxr-xr-xorg.eclipse.ua.tests/help/org/eclipse/ua/tests/help/remote/SearchServletTest.java7
-rw-r--r--org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/remote/TocServletTest.java3
-rw-r--r--org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/AdvancedSearchServiceTest.java69
-rw-r--r--org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/AllWebappServiceTests.java41
-rw-r--r--org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/ContentServiceTest.java60
-rw-r--r--org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/ContextServiceTest.java55
-rw-r--r--org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/ExtensionServiceTest.java161
-rw-r--r--org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/IndexFragmentServiceTest.java82
-rw-r--r--org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/IndexServiceTest.java60
-rw-r--r--org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/SchemaValidator.java55
-rw-r--r--org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/SearchServiceTest.java69
-rw-r--r--org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/ServicesTestUtils.java41
-rw-r--r--org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/TocFragmentServiceTest.java169
-rw-r--r--org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/TocServiceTest.java68
-rw-r--r--org.eclipse.ua.tests/plugin.xml6
-rw-r--r--org.eclipse.ua.tests/service/schema/xml/advancedsearch.xsd34
-rw-r--r--org.eclipse.ua.tests/service/schema/xml/context.xsd22
-rw-r--r--org.eclipse.ua.tests/service/schema/xml/extension.xsd31
-rw-r--r--org.eclipse.ua.tests/service/schema/xml/index.xsd68
-rw-r--r--org.eclipse.ua.tests/service/schema/xml/indexfragment.xsd28
-rw-r--r--org.eclipse.ua.tests/service/schema/xml/search.xsd25
-rw-r--r--org.eclipse.ua.tests/service/schema/xml/toc.xsd169
-rw-r--r--org.eclipse.ua.tests/service/schema/xml/tocfragment.xsd65
68 files changed, 4373 insertions, 142 deletions
diff --git a/org.eclipse.help.webapp/META-INF/MANIFEST.MF b/org.eclipse.help.webapp/META-INF/MANIFEST.MF
index 4394f30d6..4654fcdf1 100644
--- a/org.eclipse.help.webapp/META-INF/MANIFEST.MF
+++ b/org.eclipse.help.webapp/META-INF/MANIFEST.MF
@@ -14,7 +14,9 @@ Require-Bundle: org.eclipse.help.base;bundle-version="[3.5.0,4.0.0)",
org.eclipse.core.expressions;bundle-version="3.4.200"
Export-Package: org.eclipse.help.internal.webapp;x-friends:="org.eclipse.ua.tests",
org.eclipse.help.internal.webapp.data;x-friends:="org.eclipse.ua.tests",
+ org.eclipse.help.internal.webapp.service;x-friends:="org.eclipse.ua.tests",
org.eclipse.help.internal.webapp.servlet;x-friends:="org.eclipse.ua.tests,org.eclipse.ua.tests.doc",
+ org.eclipse.help.internal.webapp.utils;x-friends:="org.eclipse.ua.tests",
org.eclipse.help.webapp
Bundle-RequiredExecutionEnvironment: J2SE-1.4
Import-Package: com.ibm.icu.text;version="3.8.0",
diff --git a/org.eclipse.help.webapp/plugin.xml b/org.eclipse.help.webapp/plugin.xml
index 9346a84ce..b9be17994 100644
--- a/org.eclipse.help.webapp/plugin.xml
+++ b/org.eclipse.help.webapp/plugin.xml
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.0"?> <!--
- Copyright (c) 2005, 2010 IBM Corporation and others.
+ Copyright (c) 2005, 2011 IBM Corporation and others.
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
which accompanies this distribution, and is available at
http://www.eclipse.org/legal/epl-v10.html
-
+
Contributors:
IBM Corporation - initial API and implementation
-->
@@ -15,6 +15,7 @@
<extension-point id="view" name="View" schema="schema/view.exsd"/>
<extension-point id="frame" name="Webapp Frame" schema="schema/frame.exsd"/>
<extension-point id="toolbarButton" name="Toolbar Button" schema="schema/toolbarButton.exsd"/>
+ <extension-point id="validatedServlet" name="Validated Servlet" schema="schema/validatedServlet.exsd"/>
<extension
point="org.eclipse.equinox.http.registry.httpcontexts">
<httpcontext
@@ -140,6 +141,11 @@
<serviceSelector
filter="(other.info=org.eclipse.help)">
</serviceSelector>
+ <servlet
+ alias="/vs"
+ class="org.eclipse.help.internal.webapp.servlet.ValidatorServlet"
+ httpcontextId="help">
+ </servlet>
</extension>
<extension
id="org.eclipse.help.webapp.remoteStatusProducer"
@@ -149,4 +155,79 @@
producer="org.eclipse.help.internal.webapp.StatusProducer">
</contentProducer>
</extension>
+ <extension
+ point="org.eclipse.help.webapp.validatedServlet">
+ <servlet
+ alias="/service/control"
+ class="org.eclipse.help.internal.webapp.service.ControlService">
+ </servlet>
+ <servlet
+ alias="/service/content"
+ class="org.eclipse.help.internal.webapp.service.ContentService">
+ </servlet>
+ <servlet
+ alias="/service/topic"
+ class="org.eclipse.help.internal.webapp.service.ContentService">
+ </servlet>
+ <servlet
+ alias="/service/nftopic"
+ class="org.eclipse.help.internal.webapp.service.ContentService">
+ </servlet>
+ <servlet
+ alias="/service/ntopic"
+ class="org.eclipse.help.internal.webapp.service.ContentService">
+ </servlet>
+ <servlet
+ alias="/service/rtopic"
+ class="org.eclipse.help.internal.webapp.service.ContentService">
+ </servlet>
+ <servlet
+ alias="/service/nav"
+ class="org.eclipse.help.internal.webapp.service.NavService">
+ </servlet>
+ <servlet
+ alias="/service/livehelp"
+ class="org.eclipse.help.internal.webapp.service.LiveHelpService">
+ </servlet>
+ <servlet
+ alias="/service/toc"
+ class="org.eclipse.help.internal.webapp.service.TocService">
+ </servlet>
+ <servlet
+ alias="/service/tocfragment"
+ class="org.eclipse.help.internal.webapp.service.TocFragmentService">
+ </servlet>
+ <servlet
+ alias="/service/index"
+ class="org.eclipse.help.internal.webapp.service.IndexService">
+ </servlet>
+ <servlet
+ alias="/service/indexfragment"
+ class="org.eclipse.help.internal.webapp.service.IndexFragmentService">
+ </servlet>
+ <servlet
+ alias="/service/advancedsearch"
+ class="org.eclipse.help.internal.webapp.service.AdvancedSearchService">
+ </servlet>
+ <servlet
+ alias="/service/search"
+ class="org.eclipse.help.internal.webapp.service.SearchService">
+ </servlet>
+ <servlet
+ alias="/service/context"
+ class="org.eclipse.help.internal.webapp.service.ContextService">
+ </servlet>
+ <servlet
+ alias="/service/extension"
+ class="org.eclipse.help.internal.webapp.service.ExtensionService">
+ </servlet>
+ <servlet
+ alias="/service/about.html"
+ class="org.eclipse.help.internal.webapp.service.AboutService">
+ </servlet>
+ <servlet
+ alias="/service/state"
+ class="org.eclipse.help.internal.webapp.service.SearchStateService">
+ </servlet>
+ </extension>
</plugin>
diff --git a/org.eclipse.help.webapp/schema/validatedServlet.exsd b/org.eclipse.help.webapp/schema/validatedServlet.exsd
new file mode 100644
index 000000000..5cd63c97c
--- /dev/null
+++ b/org.eclipse.help.webapp/schema/validatedServlet.exsd
@@ -0,0 +1,129 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.help.webapp" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.help.webapp" id="validatedServlet" name="Validated Servlet"/>
+ </appInfo>
+ <documentation>
+ This extension points implements a webapp security validator around a servlet. All calls to the servlet are checked for known malicious threats before returning to the client. Important: All context paths to servlet validator resources must start with /vs. For example: http://host:port/help/vs/service/toc
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appInfo>
+ <meta.element />
+ </appInfo>
+ </annotation>
+ <complexType>
+ <sequence minOccurs="0" maxOccurs="unbounded">
+ <element ref="servlet"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="servlet">
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="javax.servlet.http.HttpServlet:"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="alias" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ 3.7
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ Here is an example where a servlet &apos;ControlService&apos; will be called and validated with the URL:
+(path)/vs/service/control
+
+&lt;extension
+ point=&quot;org.eclipse.help.webapp.validatedServlet&quot;&gt;
+ &lt;servlet
+ alias=&quot;/service/control&quot;
+ class=&quot;org.eclipse.help.internal.webapp.service.ControlService&quot;&gt;
+ &lt;/servlet&gt;
+&lt;/extension&gt;
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiinfo"/>
+ </appInfo>
+ <documentation>
+ The supplied servlet class must extend the class &lt;samp&gt;javax.servlet.http.HttpServlet&lt;/samp&gt;. The servlet class should function no differently then general servlets.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ A supplied implementation of this point can be found in &lt;samp&gt;org.eclipse.help.webapp&lt;/samp&gt; for any of the services in org.eclipse.help.internal.webapp.services.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+ Copyright (c) 2011 IBM Corporation and others.&lt;br&gt;
+All rights reserved. This program and the accompanying materials are made
+available under the terms of the Eclipse Public License v1.0 which accompanies
+this distribution, and is available at &lt;a href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/WebappResources.properties b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/WebappResources.properties
index b8de2576a..ef9db7c25 100644
--- a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/WebappResources.properties
+++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/WebappResources.properties
@@ -212,3 +212,10 @@ Uncategorized=Uncategorized
criterionClosed=Criterion closed
criterionOpen=Criterion open
Criteria=Criteria
+
+# Validator Servlet
+cantCreateServlet=Unable to create servlet: {0}
+
+# Service API
+StatusServlet_PARAM_MISSING=The "{0}" parameter is missing from the request.
+
diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/data/SearchData.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/data/SearchData.java
index 7dd59274f..f7a1c123f 100644
--- a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/data/SearchData.java
+++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/data/SearchData.java
@@ -100,8 +100,16 @@ public class SearchData extends ActivitiesData {
}
// try loading search results or get the indexing progress info.
- if (isSearchRequest() && !isScopeRequest()) {
+ readSearchResults();
+ }
+ public void readSearchResults() {
+
+ // try loading search results or get the indexing progress info.
+ if (isSearchRequest() && !isScopeRequest()) {
+
+ altList.clear();
+
AbstractSearchProcessor processors[] = SearchManager.getSearchProcessors();
for (int p=0;p<processors.length;p++)
{
@@ -156,13 +164,10 @@ public class SearchData extends ActivitiesData {
}
if (reset)
hits = SearchManager.convertResultsToHits(results);
-
-
}
}
}
-
/**
* Returns true when there is a search request
*
@@ -230,6 +235,10 @@ public class SearchData extends ActivitiesData {
public int getResultsCount() {
return hits.length;
}
+
+ public SearchHit[] getResults() {
+ return hits;
+ }
public String getSelectedTopicId() {
return selectedTopicId;
diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/parser/ContextParser.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/parser/ContextParser.java
new file mode 100644
index 000000000..7b4ac5c2e
--- /dev/null
+++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/parser/ContextParser.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.help.internal.webapp.parser;
+
+import java.util.Properties;
+
+import org.eclipse.help.internal.webapp.utils.JSonHelper;
+import org.eclipse.help.internal.webapp.utils.XMLHelper;
+import org.xml.sax.Attributes;
+
+public class ContextParser extends ResultParser {
+
+ private ParseElement element = null;
+ private String currentTag;
+
+ public ContextParser() {
+ super(JSonHelper.TITLE);
+ }
+
+ public void startElement(String uri, String lname, String name, Attributes attrs) {
+
+ currentTag = name;
+ if (name.equalsIgnoreCase(XMLHelper.ELEMENT_DESCRIPTION))
+ return;
+
+ Properties properties = new Properties();
+ properties.put(JSonHelper.PROPERTY_NAME, name);
+ for (int i = 0; i < attrs.getLength(); i++) {
+ String qname = attrs.getQName(i);
+ String val = attrs.getValue(i);
+ properties.put(qname, val);
+ }
+
+ ParseElement elem = new ParseElement(properties, element);
+ if (element != null)
+ element.addChild(elem);
+ else
+ items.add(elem);
+
+ element = elem;
+
+ }
+
+ public void characters(char[] ch, int start, int length) {
+
+ if (element != null
+ && currentTag.equalsIgnoreCase(
+ XMLHelper.ELEMENT_DESCRIPTION)) {
+
+ Properties properties = element.getProps();
+ if (properties != null) {
+
+ String content = new String(ch, start, length);
+
+ String existing = (String) properties.get(currentTag);
+ if (existing == null)
+ existing = ""; //$NON-NLS-1$
+
+ content = content.replaceAll("[\\n\\t]", "").trim(); //$NON-NLS-1$ //$NON-NLS-2$
+
+ properties.put(currentTag, existing + content);
+ element.updateParseElement(properties);
+ }
+ }
+ }
+
+ public void endElement(String uri, String lname, String name) {
+
+ if (name.equalsIgnoreCase(XMLHelper.ELEMENT_DESCRIPTION))
+ return;
+
+ if (element != null) {
+ element = element.getParent();
+ }
+ }
+
+}
diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/parser/ExtensionParser.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/parser/ExtensionParser.java
new file mode 100644
index 000000000..12a2e9a0a
--- /dev/null
+++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/parser/ExtensionParser.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.help.internal.webapp.parser;
+
+import java.util.Properties;
+
+import org.eclipse.help.internal.webapp.utils.JSonHelper;
+import org.xml.sax.Attributes;
+
+public class ExtensionParser extends ResultParser {
+
+ private ParseElement element = null;
+ private String currentTag;
+
+ public ExtensionParser() {
+ super(JSonHelper.TITLE);
+ }
+
+ public void startElement(String uri, String lname, String name, Attributes attrs) {
+
+ currentTag = name;
+
+ Properties properties = new Properties();
+ properties.put(JSonHelper.PROPERTY_NAME, name);
+ for (int i = 0; i < attrs.getLength(); i++) {
+ String qname = attrs.getQName(i);
+ String val = attrs.getValue(i);
+ properties.put(qname, val);
+ }
+
+ ParseElement elem = new ParseElement(properties, element);
+ if (element != null)
+ element.addChild(elem);
+ else
+ items.add(elem);
+
+ element = elem;
+
+ }
+
+ public void characters(char[] ch, int start, int length) {
+
+ if (element != null) {
+
+ Properties properties = element.getProps();
+ if (properties != null) {
+
+ String content = new String(ch, start, length);
+
+ String existing = (String) properties.get(currentTag);
+ if (existing == null)
+ existing = ""; //$NON-NLS-1$
+
+ content = content.replaceAll("[\\n\\t]", "").trim(); //$NON-NLS-1$ //$NON-NLS-2$
+
+ properties.put(currentTag, existing + content);
+ element.updateParseElement(properties);
+ }
+ }
+ }
+
+ public void endElement(String uri, String lname, String name) {
+
+ if (element != null) {
+ element = element.getParent();
+ }
+ }
+
+}
diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/parser/IndexFragmentParser.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/parser/IndexFragmentParser.java
new file mode 100644
index 000000000..efc9f42bd
--- /dev/null
+++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/parser/IndexFragmentParser.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.help.internal.webapp.parser;
+
+import java.util.Properties;
+
+import org.eclipse.help.internal.webapp.utils.JSonHelper;
+import org.eclipse.help.internal.webapp.utils.XMLHelper;
+import org.xml.sax.Attributes;
+
+public class IndexFragmentParser extends ResultParser{
+
+ private ParseElement element = null;
+
+ public IndexFragmentParser() {
+ super(JSonHelper.TITLE);
+ }
+
+ public void startElement(String uri, String lname, String name, Attributes attrs) {
+ if (name.equalsIgnoreCase(XMLHelper.ELEMENT_NODE))
+ {
+ Properties properties = new Properties();
+ properties.put(JSonHelper.PROPERTY_NAME, JSonHelper.INDEX);
+ for (int i = 0; i < attrs.getLength(); i++) {
+ String qname = attrs.getQName(i);
+ String val = attrs.getValue(i);
+ properties.put(qname, val);
+ }
+
+ ParseElement elem = new ParseElement(properties, element);
+ if (element != null)
+ element.addChild(elem);
+ else
+ items.add(elem);
+
+ element = elem;
+ }
+
+ }
+
+ public void endElement(String uri, String lname, String name) {
+ if (element != null
+ && name.equalsIgnoreCase(XMLHelper.ELEMENT_NODE)) {
+ element = element.getParent();
+ }
+ }
+}
diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/parser/IndexParser.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/parser/IndexParser.java
new file mode 100644
index 000000000..980867f16
--- /dev/null
+++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/parser/IndexParser.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.help.internal.webapp.parser;
+
+import java.util.Properties;
+
+import org.eclipse.help.internal.webapp.utils.JSonHelper;
+import org.eclipse.help.internal.webapp.utils.XMLHelper;
+import org.xml.sax.Attributes;
+
+public class IndexParser extends ResultParser {
+
+ private ParseElement element = null;
+
+ public IndexParser() {
+ super(JSonHelper.TITLE);
+ }
+
+ public void startElement(String uri, String lname, String name, Attributes attrs) {
+ if (name.equalsIgnoreCase(XMLHelper.ELEMENT_INDEX_CONTRIBUTIONS)
+ || name.equalsIgnoreCase(XMLHelper.ELEMENT_INDEX))
+ return;
+
+ Properties properties = new Properties();
+ properties.put(JSonHelper.PROPERTY_NAME, name);
+ for (int i = 0; i < attrs.getLength(); i++) {
+ String qname = attrs.getQName(i);
+ String val = attrs.getValue(i);
+ properties.put(qname, val);
+ }
+
+ ParseElement elem = new ParseElement(properties, element);
+ if (element != null)
+ element.addChild(elem);
+ else
+ items.add(elem);
+
+ element = elem;
+
+ }
+
+ public void endElement(String uri, String lname, String name) {
+ if (name.equalsIgnoreCase(XMLHelper.ELEMENT_INDEX_CONTRIBUTIONS)
+ || name.equalsIgnoreCase(XMLHelper.ELEMENT_INDEX))
+ return;
+
+ if (element != null) {
+ element = element.getParent();
+ }
+ }
+
+}
diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/parser/ParseElement.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/parser/ParseElement.java
new file mode 100644
index 000000000..50438b475
--- /dev/null
+++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/parser/ParseElement.java
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.help.internal.webapp.parser;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Properties;
+
+import org.eclipse.help.internal.webapp.utils.JSonHelper;
+
+public class ParseElement {
+
+ private Properties props;
+ private ArrayList children = new ArrayList();
+ private ParseElement parent;
+
+ public ParseElement(Properties props, ParseElement parent) {
+ this.props = props;
+ this.parent = parent;
+ }
+
+ public ParseElement(Properties props) {
+ this(props, null);
+ }
+
+ public void updateParseElement(Properties props) {
+ this.props = props;
+ }
+
+ public Properties getProps() {
+ return props;
+ }
+
+ public ParseElement getParent() {
+ return parent;
+ }
+
+ public String getProperty(String key) {
+ return (props != null) ? props.getProperty(key) : ""; //$NON-NLS-1$
+ }
+
+ public String toString() {
+ return (props != null) ? props.toString() : ""; //$NON-NLS-1$
+ }
+
+ public void addChild(ParseElement elem) {
+ children.add(elem);
+ }
+
+ public int getChildrenCount() {
+ return children.size();
+ }
+
+ public String toJSON(int level) {
+
+ StringBuffer buff = new StringBuffer();
+
+ String space = JSonHelper.SPACE;
+ for (int s = 0; s < level; s++) {
+ space += JSonHelper.SPACE;
+ }
+
+ buff.append(JSonHelper.NEWLINE + space);
+ buff.append(JSonHelper.BEGIN_BRACE);
+
+ if (props != null) {
+ Enumeration enumObj = props.keys();
+ while (enumObj.hasMoreElements()) {
+
+ String key = (String) enumObj.nextElement();
+ String val = props.getProperty(key);
+
+ buff.append(JSonHelper.NEWLINE + space + JSonHelper.SPACE);
+ buff.append(key);
+ buff.append(JSonHelper.COLON);
+ buff.append(JSonHelper.getQuotes(val));
+ buff.append(JSonHelper.COMMA);
+ }
+ }
+
+ if (children.size() <= 0) {
+ int len = buff.length();
+ char ch = buff.charAt(len - 1);
+ if (ch == ',') {
+ buff.deleteCharAt(len - 1);
+ buff.append(JSonHelper.NEWLINE + space);
+ }
+
+ } else {
+
+ buff.append(JSonHelper.NEWLINE + space + JSonHelper.SPACE);
+ buff.append(JSonHelper.CHILDREN);
+ buff.append(JSonHelper.COLON);
+ buff.append(JSonHelper.BEGIN_BRACKET);
+
+ for (int i = 0; i < children.size(); i++) {
+
+ if (i > 0)
+ buff.append(JSonHelper.COMMA);
+
+ ParseElement element = (ParseElement) children.get(i);
+ buff.append(element.toJSON(level + 2));
+ }
+
+ buff.append(JSonHelper.NEWLINE + space + JSonHelper.SPACE);
+
+ buff.append(JSonHelper.END_BRACKET);
+ buff.append(JSonHelper.NEWLINE + space);
+ }
+
+ buff.append(JSonHelper.END_BRACE);
+
+ return buff.toString();
+ }
+}
diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/parser/ResultParser.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/parser/ResultParser.java
new file mode 100644
index 000000000..945d71d0f
--- /dev/null
+++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/parser/ResultParser.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.help.internal.webapp.parser;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.eclipse.help.internal.webapp.utils.JSonHelper;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+public class ResultParser extends DefaultHandler {
+
+ private String label = ""; //$NON-NLS-1$
+ protected ArrayList items = new ArrayList(); //parser populates the items arrayList withe parsed data.
+
+ public ResultParser(String label) {
+ this.label = label;
+ }
+
+ public void parse(URL tocURL)
+ throws ParserConfigurationException, SAXException, IOException
+ {
+ parse(tocURL.openStream());
+ }
+
+ public void parse(InputStream in)
+ throws ParserConfigurationException, SAXException, IOException
+ {
+ SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
+ parser.parse(in, this);
+ }
+
+ public ArrayList getItems()
+ {
+ return items;
+ }
+
+ public String toString()
+ {
+ return items.toString();
+ }
+
+ public String toJSON() {
+
+ StringBuffer buf = new StringBuffer();
+
+ buf.append(JSonHelper.BEGIN_BRACE);
+ buf.append(JSonHelper.NEWLINE + JSonHelper.SPACE);
+
+ buf.append(JSonHelper.IDENTIFIER);
+ buf.append(JSonHelper.COLON);
+ buf.append(JSonHelper.getQuotes(JSonHelper.ID));
+ buf.append(JSonHelper.COMMA);
+
+ buf.append(JSonHelper.NEWLINE + JSonHelper.SPACE);
+ buf.append(JSonHelper.LABEL);
+ buf.append(JSonHelper.COLON);
+ buf.append(JSonHelper.getQuotes(label));
+ buf.append(JSonHelper.COMMA);
+
+ buf.append(JSonHelper.NEWLINE + JSonHelper.SPACE);
+ buf.append(JSonHelper.ITEMS);
+ buf.append(JSonHelper.COLON);
+ buf.append(JSonHelper.BEGIN_BRACKET);
+
+ for (int i = 0; i < items.size(); i++) {
+
+ if (i > 0)
+ buf.append(JSonHelper.COMMA);
+
+ ParseElement element = (ParseElement) items.get(i);
+ buf.append(element.toJSON(1));
+ }
+
+ if (items.size() > 0)
+ buf.append(JSonHelper.NEWLINE + JSonHelper.SPACE);
+
+ buf.append(JSonHelper.END_BRACKET);
+ buf.append(JSonHelper.NEWLINE);
+ buf.append(JSonHelper.END_BRACE);
+
+ return buf.toString();
+ }
+}
diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/parser/SearchParser.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/parser/SearchParser.java
new file mode 100644
index 000000000..f152f474f
--- /dev/null
+++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/parser/SearchParser.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.help.internal.webapp.parser;
+
+import java.util.Properties;
+
+import org.eclipse.help.internal.webapp.utils.JSonHelper;
+import org.eclipse.help.internal.webapp.utils.XMLHelper;
+import org.xml.sax.Attributes;
+
+public class SearchParser extends ResultParser {
+
+// private ParseElement element;
+ private Properties properties;
+ private String currentTag;
+
+ public SearchParser() {
+ super(JSonHelper.LABEL);
+ }
+
+ public void startElement(String uri,
+ String lname, String name, Attributes attrs) {
+
+ currentTag = name;
+ if (name.equalsIgnoreCase(XMLHelper.ELEMENT_HIT)) {
+
+ properties = new Properties();
+ properties.put(JSonHelper.PROPERTY_NAME, name);
+ for (int i = 0; i < attrs.getLength(); i++) {
+ String qname = attrs.getQName(i);
+ String val = attrs.getValue(i);
+ properties.put(qname, val);
+ }
+
+ String id = "" + items.size(); //$NON-NLS-1$
+ properties.put(JSonHelper.ID, id);
+
+ } else if (name.equalsIgnoreCase(XMLHelper.ELEMENT_CATEGORY)) {
+ for (int i = 0; i < attrs.getLength(); i++) {
+ String qname = attrs.getQName(i);
+ String val = attrs.getValue(i);
+ if (qname.equalsIgnoreCase(XMLHelper.ATTR_HREF))
+ qname = XMLHelper.CATEGORY_HREF;
+ properties.put(qname, val);
+ }
+ }
+ }
+
+ public void characters(char[] ch, int start, int length) {
+
+ if (currentTag.equalsIgnoreCase(XMLHelper.ELEMENT_HIT)
+ || currentTag.equalsIgnoreCase(XMLHelper.ELEMENT_HITS))
+ return;
+
+ if (properties != null)
+ {
+ String content = new String(ch, start, length);
+
+ String existing = (String) properties.get(currentTag);
+ if (existing == null)
+ existing = ""; //$NON-NLS-1$
+
+ content = content.replaceAll("[\\n\\t]", "").trim(); //$NON-NLS-1$ //$NON-NLS-2$
+
+ properties.put(currentTag, existing + content);
+ }
+ }
+
+ public void endElement(String uri, String lname, String name) {
+
+ if (name.equalsIgnoreCase(XMLHelper.ELEMENT_HIT)) {
+ ParseElement element = new ParseElement(properties);
+ items.add(element);
+ }
+ }
+}
diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/parser/TocFragmentParser.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/parser/TocFragmentParser.java
new file mode 100644
index 000000000..cd2b5c607
--- /dev/null
+++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/parser/TocFragmentParser.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.help.internal.webapp.parser;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Properties;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.eclipse.help.internal.webapp.utils.JSonHelper;
+import org.eclipse.help.internal.webapp.utils.XMLHelper;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+public class TocFragmentParser extends ResultParser {
+
+ private Properties properties;
+ private String parentId = ""; //$NON-NLS-1$
+ private int tagLevel = -1;
+ private int level = 0;
+
+ public TocFragmentParser() {
+ super(JSonHelper.TITLE);
+ }
+
+ public void parse(URL tocURL, int level)
+ throws ParserConfigurationException, SAXException, IOException
+ {
+ parse(tocURL.openStream(), level);
+ }
+
+ public void parse(InputStream in, int level)
+ throws ParserConfigurationException, SAXException, IOException
+ {
+ this.level = level;
+ super.parse(in);
+ }
+
+ public void startElement(String uri,
+ String lname, String name, Attributes attrs) {
+
+ if (name.equalsIgnoreCase(XMLHelper.ELEMENT_NODE))
+ {
+ tagLevel++;
+
+ if (tagLevel == level) {
+ properties = new Properties();
+ properties.put(JSonHelper.PROPERTY_NAME, JSonHelper.TOPIC);
+ for (int i = 0; i < attrs.getLength(); i++) {
+ String qname = attrs.getQName(i);
+ String val = attrs.getValue(i);
+ if (qname.equals(XMLHelper.ATTR_ID)) {
+ if (parentId.length() > 0)
+ val = parentId + '$' + val;
+ }
+ properties.put(qname, val);
+ }
+ } else if (parentId.length() <= 0) {
+ for (int i = 0; i < attrs.getLength(); i++) {
+ if (attrs.getQName(i).equals(XMLHelper.ATTR_ID))
+ parentId = attrs.getValue(i);
+ }
+ }
+ }
+ }
+
+ public void endElement(String uri, String lname, String name) {
+
+ if (name.equalsIgnoreCase(XMLHelper.ELEMENT_NODE))
+ {
+ if (tagLevel == level && properties != null ) {
+
+ properties.setProperty("type", "toc"); //$NON-NLS-1$ //$NON-NLS-2$
+
+ ParseElement element = new ParseElement(properties);
+ items.add(element);
+
+ properties = null;
+ }
+
+ tagLevel--;
+ }
+ }
+}
diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/parser/TocParser.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/parser/TocParser.java
new file mode 100644
index 000000000..e7a452932
--- /dev/null
+++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/parser/TocParser.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.help.internal.webapp.parser;
+
+import java.util.Properties;
+
+import org.eclipse.help.internal.webapp.utils.JSonHelper;
+import org.eclipse.help.internal.webapp.utils.XMLHelper;
+import org.xml.sax.Attributes;
+
+public class TocParser extends ResultParser {
+
+ private ParseElement element = null;
+
+ public TocParser() {
+ super(JSonHelper.LABEL);
+ }
+
+ public void startElement(String uri, String lname, String name, Attributes attrs) {
+ if (name.equalsIgnoreCase(XMLHelper.ELEMENT_TOC_CONTRIBUTIONS))
+ return;
+
+ Properties properties = new Properties();
+ properties.put(JSonHelper.PROPERTY_NAME, name);
+ for (int i = 0; i < attrs.getLength(); i++) {
+ String qname = attrs.getQName(i);
+ String val = attrs.getValue(i);
+ properties.put(qname, val);
+ }
+
+ ParseElement elem = new ParseElement(properties, element);
+ if (element != null)
+ element.addChild(elem);
+ else
+ items.add(elem);
+
+ element = elem;
+
+ }
+
+ public void endElement(String uri, String lname, String name) {
+ if (name.equalsIgnoreCase(XMLHelper.ELEMENT_TOC_CONTRIBUTIONS))
+ return;
+
+ if (element != null) {
+ element = element.getParent();
+ }
+ }
+
+}
diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/AboutService.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/AboutService.java
new file mode 100644
index 000000000..7365b1c80
--- /dev/null
+++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/AboutService.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.help.internal.webapp.service;
+
+import org.eclipse.help.internal.webapp.servlet.AboutServlet;
+
+/**
+ * Generates an html page having informations about either <code>User-Agent</code>,
+ * Help system <code>preferences</code> or the available plug-ins in Help system
+ * like Provider, Plugin name, Version and PluginId.
+ *
+ * <p>Extends the {@link org.eclipse.help.internal.webapp.servlet.AboutServlet}
+ * servlet.
+ *
+ * @param show - (Optional) specifying either <code>agent</code>
+ * to view the request's <code>User-Agent</code> info, else
+ * <code>preferences</code> to view the Help system preferences.
+ * Do not specify any value to show the available plugins in
+ * Help web application.
+ * @param sortColumn - (Optional) specifying the column number over
+ * which displayed output needs to be sorted. Applicable only if
+ * <code>show</code> parameter is <code>null</code>.
+ *
+ * @return Html page having informations about either <code>User-Agent</code>,
+ * <code>preferences</code> or the available plug-ins.
+ *
+ * @version $Version$
+ *
+ **/
+public class AboutService extends AboutServlet {
+
+ private static final long serialVersionUID = 1L;
+
+}
diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/AdvancedSearchService.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/AdvancedSearchService.java
new file mode 100644
index 000000000..3bce8e348
--- /dev/null
+++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/AdvancedSearchService.java
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.help.internal.webapp.service;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.help.internal.search.SearchHit;
+import org.eclipse.help.internal.search.SearchProgressMonitor;
+import org.eclipse.help.internal.webapp.data.SearchData;
+import org.eclipse.help.internal.webapp.data.UrlUtil;
+import org.eclipse.help.internal.webapp.parser.SearchParser;
+import org.eclipse.help.internal.webapp.utils.Utils;
+import org.eclipse.help.internal.webapp.utils.SearchXMLGenerator;
+
+/**
+ * Returns the search hits in <code>xml</code> or <code>json</code>
+ * form for the query provided in the <code>searchWord</code> parameter.
+ *
+ * <p>This servlet is called on infocenters by client workbenches
+ * configured for remote help in order to retrieve search hits
+ * from the remote help server.
+ *
+ * <p>Internally reads {@link org.eclipse.help.internal.webapp.data.SearchData}.
+ *
+ * @param searchWord - specifies the search keyword
+ * @param quickSearch - (optional) specifies if it is a quick search. Scopes
+ * is just the selected toc or topic
+ * @param quickSearchType - (optional) specifies <code>QuickSearchTopic</code> for topic
+ * quick search
+ * @param scope - (optional) specifies search scope values
+ * @param workingSet - (optional) specifies the working set for scoped search
+ * @param maxHits - (optional) specifies the number of hits to return, default value is 500
+ * @param fieldSearch - (optional) specifies if field only search should be performed;
+ * if set to false, default field "contents" and all other fields will be searched
+ * @param lang - (optional) specifies the locale
+ * @param returnType - (Optional) specifies the return type of the servlet.
+ * Accepts either <code>xml</code> (default) or
+ * <code>json</code>
+ *
+ * @return The search hits, either as <code>xml</code> (default) or
+ * <code>json</code>
+ *
+ * @version $Version$
+ *
+ **/
+public class AdvancedSearchService extends HttpServlet {
+
+ private static final long serialVersionUID = 1L;
+ public static final String XID = "xid"; //$NON-NLS-1$
+
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+
+ req.setCharacterEncoding("UTF-8"); //$NON-NLS-1$
+ // Set standard HTTP/1.1 no-cache headers.
+ resp.setHeader("Cache-Control", //$NON-NLS-1$
+ "no-store, no-cache, must-revalidate"); //$NON-NLS-1$
+
+ resp.setContentType("application/xml; charset=UTF-8"); //$NON-NLS-1$
+
+ ServletContext context = req.getSession().getServletContext();
+ SearchData searchData = new SearchData(context, req, resp);
+
+ String noCat = req.getParameter(Utils.NO_CATEGORY);
+ boolean boolIsCategory = (noCat == null
+ || !noCat.equalsIgnoreCase("true")); //$NON-NLS-1$
+
+ String locale = UrlUtil.getLocale(req, resp);
+ SearchProgressMonitor pm = SearchProgressMonitor
+ .getProgressMonitor(locale);
+ while (!pm.isDone()) {
+ try {
+ Thread.sleep(500); // Sleep for 0.5 sec
+ } catch(InterruptedException ex) {}
+ }
+
+ // Load search results
+ searchData.readSearchResults();
+ SearchHit[] hits = searchData.getResults();
+
+ String response = SearchXMLGenerator.serialize(hits, boolIsCategory);
+
+ String returnType = req.getParameter(Utils.RETURN_TYPE);
+ boolean boolIsJSON = (returnType != null
+ && returnType.equalsIgnoreCase(Utils.JSON));
+
+ // If JSON output is required
+ if (boolIsJSON) {
+ resp.setContentType("text/plain"); //$NON-NLS-1$
+ response = getJSONResponse(response);
+ }
+
+ resp.getWriter().write(response);
+ }
+
+ protected String getJSONResponse(String response)
+ throws IOException {
+ SearchParser searchParser = new SearchParser();
+
+ InputStream is = null;
+ try {
+ if (response != null) {
+ is = new ByteArrayInputStream(response.getBytes("UTF-8")); //$NON-NLS-1$
+ searchParser.parse(is);
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ if (is != null)
+ is.close();
+
+ // Call after the catch.
+ // An empty JSON is created if any Exception is thrown
+ // Else returns the complete JSON
+ return searchParser.toJSON();
+ }
+}
diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/ContentService.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/ContentService.java
new file mode 100644
index 000000000..e1873a68b
--- /dev/null
+++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/ContentService.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.help.internal.webapp.service;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.net.URL;
+import java.net.URLConnection;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.help.internal.webapp.utils.Utils;
+
+/**
+ * Returns an HTML page for the selected topic passed as request path info.
+ *
+ * <p>Passes the request to {@link org.eclipse.help.internal.webapp.servlet.ContentServlet}
+ * servlet.
+ *
+ * @param lang - (optional) specifies the locale
+ *
+ * @return An html page for the selected topic
+ *
+ * @version $Version$
+ *
+ **/
+public class ContentService extends HttpServlet {
+
+ private static final long serialVersionUID = 1L;
+
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+ req.setCharacterEncoding("UTF-8"); //$NON-NLS-1$
+
+ String baseURL = req.getRequestURL().toString();
+ String contentURL = baseURL.replaceFirst(Utils.SERVICE_CONTEXT, ""); //$NON-NLS-1$
+ String query = req.getQueryString();
+ if (query != null)
+ contentURL += '?' + query;
+
+ URL url = new URL(contentURL);
+ URLConnection con = url.openConnection();
+ con.setAllowUserInteraction(false);
+ con.setDoInput(true);
+ con.connect();
+
+ String contentType;
+ ServletContext context = getServletContext();
+ String pathInfo = req.getPathInfo();
+ String mimeType = context.getMimeType(pathInfo);
+ if (mimeType != null && !mimeType.equals("application/xhtml+xml")) { //$NON-NLS-1$
+ contentType = mimeType;
+ } else {
+ contentType = con.getContentType();
+ }
+ resp.setContentType(contentType);
+
+ InputStream is = con.getInputStream();
+ OutputStream out = resp.getOutputStream();
+ if (!contentType.equals("application/xhtml+xml") //$NON-NLS-1$
+ && !contentType.equals("text/html") //$NON-NLS-1$
+ && !con.getContentType().equals("text/html")) { //$NON-NLS-1$
+ Utils.transferContent(is, out);
+ out.flush();
+ } else {
+ String response = Utils.convertStreamToString(url.openStream());
+ response = Utils.updateResponse(response);
+ PrintWriter writer = new PrintWriter(new OutputStreamWriter(out, "UTF-8")); //$NON-NLS-1$
+ writer.write(response);
+ writer.close();
+ }
+ }
+
+}
diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/ContextService.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/ContextService.java
new file mode 100644
index 000000000..82147869e
--- /dev/null
+++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/ContextService.java
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.help.internal.webapp.service;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.help.internal.webapp.parser.ContextParser;
+import org.eclipse.help.internal.webapp.servlet.ContextServlet;
+import org.eclipse.help.internal.webapp.utils.Utils;
+
+/**
+ * Returns a context help entry with the id specified in the
+ * <code>id</code> parameter in <code>xml</code> or <code>json</code> form.
+ *
+ * <p>This servlet is called on infocenters by client workbenches
+ * configured for remote help in order to retrieve context help
+ * stored on the remote help server.
+ *
+ * <p>Extends the {@link org.eclipse.help.internal.webapp.servlet.ContextServlet}
+ * servlet.
+ *
+ * @param id - A <code>String</code> specifying the context id
+ * for the context help entry
+ * @param lang - (optional) A <code>String</code> specifying the locale
+ * @param returnType - (Optional) A <code>String</code> specifying the
+ * return type of the servlet. Accepts either
+ * <code>xml</code> (default) or <code>json</code>
+ *
+ * @return A context help entry with the id specified, either as
+ * <code>xml</code> (default) or <code>json</code>
+ *
+ * @exception 400 Error - If context <code>id</code> parameter is missing
+ * @exception 404 Error - If wrong context <code>id</code> parameter
+ *
+ * @version $Version$
+ *
+ **/
+public class ContextService extends ContextServlet {
+
+ private static final long serialVersionUID = 1L;
+
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+
+ req.setCharacterEncoding("UTF-8"); //$NON-NLS-1$
+ // Set standard HTTP/1.1 no-cache headers.
+ resp.setHeader("Cache-Control", //$NON-NLS-1$
+ "no-store, no-cache, must-revalidate"); //$NON-NLS-1$
+
+ String response = processRequest(req, resp);
+ if ("400".equals(response)) { //$NON-NLS-1$
+ resp.sendError(400); // bad request; missing parameter
+ return;
+ } else if ("404".equals(response)) { //$NON-NLS-1$
+ resp.sendError(404); // Wrong context id; not found
+ return;
+ }
+
+ String returnType = req.getParameter(Utils.RETURN_TYPE);
+ boolean boolIsJSON = (returnType != null
+ && returnType.equalsIgnoreCase(Utils.JSON));
+
+ // If JSON output is required
+ if (boolIsJSON) {
+ resp.setContentType("text/plain"); //$NON-NLS-1$
+ response = getJSONResponse(response);
+ }
+
+ resp.getWriter().write(response);
+ }
+
+ protected String getJSONResponse(String response)
+ throws IOException {
+ ContextParser searchParser = new ContextParser();
+ InputStream is = null;
+ try {
+ if (response != null) {
+ is = new ByteArrayInputStream(response.getBytes("UTF-8")); //$NON-NLS-1$
+ searchParser.parse(is);
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ if (is != null)
+ is.close();
+
+ // Call after the catch.
+ // An empty JSON is created if any Exception is thrown
+ // Else returns the complete JSON
+ return searchParser.toJSON();
+ }
+
+}
diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/ControlService.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/ControlService.java
new file mode 100644
index 000000000..df9409560
--- /dev/null
+++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/ControlService.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.help.internal.webapp.service;
+
+import org.eclipse.help.internal.webapp.servlet.ControlServlet;
+
+/**
+ * Controls Eclipse help application from standalone application. This
+ * service do not allow remote clients to control Eclipse help application.
+ *
+ * <p>Extends the {@link org.eclipse.help.internal.webapp.servlet.ControlServlet}
+ * servlet.
+ *
+ * @param command - specifies the control command. Accepts the following parameters:
+ * displayHelp | displayHelpWindow | shutdown
+ * | install | update | enable | disable | uninstall
+ * | search | listFeatures | addSite | removeSite
+ * | apply
+ *
+ * @version $Version$
+ *
+ **/
+public class ControlService extends ControlServlet {
+
+ private static final long serialVersionUID = 1L;
+
+}
diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/ExtensionService.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/ExtensionService.java
new file mode 100644
index 000000000..292e987a5
--- /dev/null
+++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/ExtensionService.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.help.internal.webapp.service;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.help.internal.webapp.parser.ExtensionParser;
+import org.eclipse.help.internal.webapp.servlet.ExtensionServlet;
+import org.eclipse.help.internal.webapp.utils.Utils;
+
+/**
+ * Returns all topic extensions available on this host in <code>xml</code>
+ * or <code>json</code> form.
+ *
+ * <p>This servlet is called on infocenters by client workbenches
+ * configured for remote help in order to gather all the pieces of
+ * a document.
+ *
+ * <p>Extends the {@link org.eclipse.help.internal.webapp.servlet.ExtensionServlet}
+ * servlet.
+ *
+ * @param lang - (optional) specifying the locale
+ * @param returnType - (Optional) specifying the return type of the servlet.
+ * Accepts either <code>xml</code> (default) or
+ * <code>json</code>
+ *
+ * @return All topic extensions available on this host, either as
+ * <code>xml</code> (default) or <code>json</code>
+ *
+ * @version $Version$
+ *
+ **/
+public class ExtensionService extends ExtensionServlet {
+
+ private static final long serialVersionUID = 1L;
+
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+
+ req.setCharacterEncoding("UTF-8"); //$NON-NLS-1$
+ // Set standard HTTP/1.1 no-cache headers.
+ resp.setHeader("Cache-Control", //$NON-NLS-1$
+ "no-store, no-cache, must-revalidate"); //$NON-NLS-1$
+ resp.setContentType("application/xml; charset=UTF-8"); //$NON-NLS-1$
+
+ String response = processRequest(req, resp);
+ String returnType = req.getParameter(Utils.RETURN_TYPE);
+ boolean boolIsJSON = (returnType != null
+ && returnType.equalsIgnoreCase(Utils.JSON));
+
+ // If JSON output is required
+ if (boolIsJSON) {
+ resp.setContentType("text/plain"); //$NON-NLS-1$
+ response = getJSONResponse(response);
+ }
+
+ resp.getWriter().write(response);
+ }
+
+ protected String getJSONResponse(String response)
+ throws IOException {
+ ExtensionParser searchParser = new ExtensionParser();
+ InputStream is = null;
+ try {
+ if (response != null) {
+ is = new ByteArrayInputStream(response.getBytes("UTF-8")); //$NON-NLS-1$
+ searchParser.parse(is);
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ if (is != null)
+ is.close();
+
+ // Call after the catch.
+ // An empty JSON is created if any Exception is thrown
+ // Else returns the complete JSON
+ return searchParser.toJSON();
+ }
+
+}
diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/IndexFragmentService.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/IndexFragmentService.java
new file mode 100644
index 000000000..1fae9c881
--- /dev/null
+++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/IndexFragmentService.java
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.help.internal.webapp.service;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.help.internal.webapp.parser.IndexFragmentParser;
+import org.eclipse.help.internal.webapp.servlet.IndexFragmentServlet;
+import org.eclipse.help.internal.webapp.utils.Utils;
+
+/**
+ * Returns <code>xml</code> or <code>json</code> representing selected parts
+ * of the index.
+ *
+ * <p>This servlet is called on infocenters by client workbenches
+ * configured for remote help in order to gather selected parts of the index.
+ *
+ * <p>Extends the {@link org.eclipse.help.internal.webapp.servlet.IndexFragmentServlet}
+ * servlet.
+ *
+ * @param start - (optional) represents the part of the index to
+ * start reading from
+ * @param size - (optional) indicates the number of entries to read,
+ * no size parameter or a negative size parameter
+ * indicates that all entries which match the start
+ * letters should be displayed
+ * @param mode - (optional) specifies either <code>next</code> or
+ * <code>previous</code>
+ * @param entry - (optional) represents the starting point relative
+ * to the start
+ * @param showAll - (optional) specifies either <code>on</code> or
+ * <code>off</code> to set filter enablement of
+ * activity support
+ * @param showconfirm - (optional) specifies <code>true</code> or
+ * <code>false</code> to show/hide all confirm dialog
+ * @param lang - (optional) specifies the locale
+ * @param returnType - (Optional) specifies the return type of the servlet.
+ * Accepts either <code>xml</code> (default) or
+ * <code>json</code>
+ *
+ * @return Selected parts of the index, either as <code>xml</code>
+ * (default) or <code>json</code>
+ *
+ * @version $Version$
+ *
+ **/
+public class IndexFragmentService extends IndexFragmentServlet {
+
+ private static final long serialVersionUID = 1L;
+
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+
+ req.setCharacterEncoding("UTF-8"); //$NON-NLS-1$
+ // Set standard HTTP/1.1 no-cache headers.
+ resp.setHeader("Cache-Control", //$NON-NLS-1$
+ "no-store, no-cache, must-revalidate"); //$NON-NLS-1$
+ resp.setContentType("application/xml; charset=UTF-8"); //$NON-NLS-1$
+
+ String response = processRequest(req, resp);
+
+ String returnType = req.getParameter(Utils.RETURN_TYPE);
+ boolean boolIsJSON = (returnType != null
+ && returnType.equalsIgnoreCase(Utils.JSON));
+
+ // If JSON output is required
+ if (boolIsJSON) {
+ resp.setContentType("text/plain"); //$NON-NLS-1$
+ response = getJSONResponse(response);
+ }
+
+ resp.getWriter().write(response);
+ }
+
+ protected String getJSONResponse(String response)
+ throws IOException {
+ IndexFragmentParser indexParser = new IndexFragmentParser();
+ InputStream is = null;
+ try {
+ if (response != null) {
+ is = new ByteArrayInputStream(response.getBytes("UTF-8")); //$NON-NLS-1$
+ indexParser.parse(is);
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ if (is != null)
+ is.close();
+
+ // Call after the catch.
+ // An empty JSON is created if any Exception is thrown
+ // Else returns the complete JSON
+ return indexParser.toJSON();
+ }
+
+}
diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/IndexService.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/IndexService.java
new file mode 100644
index 000000000..6c52ef6d7
--- /dev/null
+++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/IndexService.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.help.internal.webapp.service;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.help.internal.webapp.parser.IndexParser;
+import org.eclipse.help.internal.webapp.servlet.IndexServlet;
+import org.eclipse.help.internal.webapp.utils.Utils;
+
+/**
+ * Returns all available keyword index data in <code>xml</code>
+ * or <code>json</code> form. The data is sent as one large index
+ * contribution that includes all merged contributions from the system.
+ *
+ * <p>This servlet is called on infocenters by client workbenches
+ * configured for remote help in order to gather all the index keywords
+ * and assemble them into a complete index.
+ *
+ * <p>Extends the {@link org.eclipse.help.internal.webapp.servlet.IndexServlet}
+ * servlet.
+ *
+ * @param lang - (optional) specifies the locale
+ * @param returnType - (Optional) specifies the return type of the servlet.
+ * Accepts either <code>xml</code> (default) or
+ * <code>json</code>
+ *
+ * @return All available keyword index data, either as <code>xml</code>
+ * (default) or <code>json</code>
+ *
+ * @version $Version$
+ *
+ **/
+public class IndexService extends IndexServlet {
+
+ private static final long serialVersionUID = 1L;
+
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+
+ req.setCharacterEncoding("UTF-8"); //$NON-NLS-1$
+ // Set standard HTTP/1.1 no-cache headers.
+ resp.setHeader("Cache-Control", //$NON-NLS-1$
+ "no-store, no-cache, must-revalidate"); //$NON-NLS-1$
+ resp.setContentType("application/xml; charset=UTF-8"); //$NON-NLS-1$
+
+ String response = processRequest(req, resp);
+
+ String returnType = req.getParameter(Utils.RETURN_TYPE);
+ boolean boolIsJSON = (returnType != null
+ && returnType.equalsIgnoreCase(Utils.JSON));
+
+ // If JSON output is required
+ if (boolIsJSON) {
+ resp.setContentType("text/plain"); //$NON-NLS-1$
+ response = getJSONResponse(response);
+ }
+
+ resp.getWriter().write(response);
+ }
+
+ protected String getJSONResponse(String response)
+ throws IOException {
+ IndexParser indexParser = new IndexParser();
+ InputStream is = null;
+ try {
+ if (response != null) {
+ is = new ByteArrayInputStream(response.getBytes("UTF-8")); //$NON-NLS-1$
+ indexParser.parse(is);
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ if (is != null)
+ is.close();
+
+ // Call after the catch.
+ // An empty JSON is created if any Exception is thrown
+ // Else returns the complete JSON
+ return indexParser.toJSON();
+ }
+
+}
diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/LiveHelpService.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/LiveHelpService.java
new file mode 100644
index 000000000..94f0fa679
--- /dev/null
+++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/LiveHelpService.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.help.internal.webapp.service;
+
+import org.eclipse.help.internal.webapp.servlet.LiveHelpServlet;
+
+/**
+ * Handles the live help action requests with the specified
+ * <code>pluginID</code>, <code>class</code> and respective <code>args</code>.
+ *
+ * <p>Extends the {@link org.eclipse.help.internal.webapp.servlet.LiveHelpServlet}
+ * servlet.
+ *
+ * @param pluginID - specifying the plugin id
+ * @param class - specifying the class
+ * @param arg - (Optional) specifying the arguments for the
+ * live help extension
+ *
+ * @version $Version$
+ *
+ **/
+public class LiveHelpService extends LiveHelpServlet {
+
+ private static final long serialVersionUID = 1L;
+
+}
diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/NavService.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/NavService.java
new file mode 100644
index 000000000..a6ac5eb46
--- /dev/null
+++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/NavService.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.help.internal.webapp.service;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.net.URL;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.help.internal.webapp.utils.Utils;
+
+/**
+ * Generates navigation HTML page where topic is not present in the table
+ * of contents for the selected toc passed as request path info. Displays
+ * links to the direct child topics.
+ *
+ * <p>This servlet is called on infocenters by client workbenches
+ * configured for remote help in order to generate the navigation pages.
+ *
+ * <p>Passes the request to {@link org.eclipse.help.internal.webapp.servlet.NavServlet}
+ * servlet.
+ *
+ * @return An html page having the links to the direct child topics for
+ * the selected toc
+ *
+ * @version $Version$
+ *
+ **/
+public class NavService extends HttpServlet {
+
+ private static final long serialVersionUID = 1L;
+
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+
+ req.setCharacterEncoding("UTF-8"); //$NON-NLS-1$
+ resp.setContentType("text/html; charset=UTF-8"); //$NON-NLS-1$
+
+ String baseURL = req.getRequestURL().toString();
+ String navURL = baseURL.replaceFirst(Utils.SERVICE_CONTEXT, ""); //$NON-NLS-1$
+ String query = req.getQueryString();
+ if (query != null)
+ navURL += '?' + query;
+ URL url = new URL(navURL);
+ String response = Utils.convertStreamToString(url.openStream());
+ response = Utils.updateResponse(response);
+
+ OutputStream out = resp.getOutputStream();
+ PrintWriter writer = new PrintWriter(new OutputStreamWriter(out, "UTF-8")); //$NON-NLS-1$
+ writer.write(response);
+ writer.close();
+ }
+
+}
diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/SearchService.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/SearchService.java
new file mode 100644
index 000000000..4c304e34c
--- /dev/null
+++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/SearchService.java
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.help.internal.webapp.service;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.help.internal.webapp.parser.SearchParser;
+import org.eclipse.help.internal.webapp.servlet.SearchServlet;
+import org.eclipse.help.internal.webapp.utils.Utils;
+
+/**
+ * Returns the search hits in <code>xml</code> or <code>json</code>
+ * form for the query provided in the <code>phrase</code> parameter.
+ *
+ * <p>This servlet is called on infocenters by client workbenches
+ * configured for remote help in order to retrieve search hits
+ * from the remote help server.
+ *
+ * <p>Extends the {@link org.eclipse.help.internal.webapp.servlet.SearchServlet}
+ * servlet.
+ *
+ * @param phrase - specifies the search keyword
+ * @param lang - (optional) specifies the locale
+ * @param returnType - (Optional) specifies the return type of the servlet.
+ * Accepts either <code>xml</code> (default) or
+ * <code>json</code>
+ *
+ * @return The search hits, either as <code>xml</code> (default) or
+ * <code>json</code>
+ *
+ * @version $Version$
+ *
+ **/
+public class SearchService extends SearchServlet {
+
+ private static final long serialVersionUID = 1L;
+
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+
+ req.setCharacterEncoding("UTF-8"); //$NON-NLS-1$
+ // Set standard HTTP/1.1 no-cache headers.
+ resp.setHeader("Cache-Control", //$NON-NLS-1$
+ "no-store, no-cache, must-revalidate"); //$NON-NLS-1$
+
+ String response = processRequest(req, resp);
+ if ("".equals(response)) { //$NON-NLS-1$
+ resp.sendError(400); // bad request; missing parameter
+ return;
+ }
+
+ String returnType = req.getParameter(Utils.RETURN_TYPE);
+ boolean boolIsJSON = (returnType != null
+ && returnType.equalsIgnoreCase(Utils.JSON));
+
+ // If JSON output is required
+ if (boolIsJSON) {
+ resp.setContentType("text/plain"); //$NON-NLS-1$
+ response = getJSONResponse(response);
+ }
+
+ resp.getWriter().write(response);
+ }
+
+ protected String getJSONResponse(String response)
+ throws IOException {
+ SearchParser searchParser = new SearchParser();
+ InputStream is = null;
+ try {
+ if (response != null) {
+ is = new ByteArrayInputStream(response.getBytes("UTF-8")); //$NON-NLS-1$
+ searchParser.parse(is);
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ if (is != null)
+ is.close();
+
+ // Call after the catch.
+ // An empty JSON is created if any Exception is thrown
+ // Else returns the complete JSON
+ return searchParser.toJSON();
+ }
+
+}
diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/SearchStateService.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/SearchStateService.java
new file mode 100644
index 000000000..6183516a7
--- /dev/null
+++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/SearchStateService.java
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.help.internal.webapp.service;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.help.internal.search.SearchProgressMonitor;
+import org.eclipse.help.internal.webapp.data.UrlUtil;
+import org.eclipse.help.internal.webapp.utils.Utils;
+
+/**
+ * Returns <code>xml</code> or <code>String</code> representing search progress monitor
+ *
+ * @param lang - (optional) specifies the locale
+ * @param returnType - (Optional) specifies the return type of the servlet.
+ * Accepts either <code>xml</code> (default) or
+ * <code>json</code>
+ *
+ * @return Search progress monitor state, either as <code>xml</code>
+ * or <code>String</code> (default)
+ *
+ * @version $Version$
+ *
+ **/
+public class SearchStateService extends HttpServlet {
+
+ private static final long serialVersionUID = 1L;
+ private final static String STATE = "state"; //$NON-NLS-1$
+ private final static String PERCENT = "percent"; //$NON-NLS-1$
+
+ public void init() throws ServletException {
+ }
+
+ /**
+ * Called by the server (via the <code>service</code> method) to allow a
+ * Servlet to handle a GET request.
+ */
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+
+ process(req,resp);
+ }
+
+ /**
+ *
+ * Called by the server (via the <code>service</code> method) to allow a
+ * Servlet to handle a POST request.
+ *
+ * Handle the search requests,
+ *
+ */
+ protected void doPost(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+ process(req, resp);
+ }
+
+
+ /**
+ * Processes all requests to the servlet.
+ *
+ */
+ private void process(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+
+ resp.setHeader("Cache-Control", "no-store, no-cache, must-revalidate"); //$NON-NLS-1$ //$NON-NLS-2$
+ resp.setCharacterEncoding("UTF-8"); //$NON-NLS-1$
+
+ int indexCompletion = 0;
+ String locale = UrlUtil.getLocale(req, resp);
+ SearchProgressMonitor pm = SearchProgressMonitor
+ .getProgressMonitor(locale);
+ if (pm.isDone()) {
+ indexCompletion = 100;
+ } else {
+ indexCompletion = pm.getPercentage();
+ if (indexCompletion >= 100) {
+ // 38573 We do not have results, so index cannot be 100
+ indexCompletion = 100 - 1;
+ }
+ }
+
+ String returnType = req.getParameter(Utils.RETURN_TYPE);
+ boolean isXML = Utils.XML.equalsIgnoreCase(returnType);
+ if (isXML) {
+ resp.setContentType("application/xml"); //$NON-NLS-1$
+ resp.getWriter().write(toXML(indexCompletion));
+ } else {
+ resp.setContentType("text/plain"); //$NON-NLS-1$
+ resp.getWriter().write(toString(indexCompletion));
+ }
+ resp.getWriter().flush();
+ }
+
+ public static String toXML(int percent) {
+ String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; //$NON-NLS-1$
+ xml += '<'+STATE+">\n"; //$NON-NLS-1$
+ xml += " <"+PERCENT+'>'+percent+"</"+PERCENT+">\n"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ xml += "</"+STATE+">"; //$NON-NLS-1$ //$NON-NLS-2$
+ return xml;
+ }
+
+ public static String toString(int percent) {
+ return "Percent:" + percent; //$NON-NLS-1$
+ }
+}
diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/TocFragmentService.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/TocFragmentService.java
new file mode 100644
index 000000000..31befb0c2
--- /dev/null
+++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/TocFragmentService.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.help.internal.webapp.service;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.help.internal.webapp.parser.TocFragmentParser;
+import org.eclipse.help.internal.webapp.servlet.TocFragmentServlet;
+import org.eclipse.help.internal.webapp.utils.Utils;
+
+/**
+ * Returns <code>xml</code> or <code>json</code> representing selected parts
+ * of one or more TOCs depending on the parameters.
+ *
+ * <p>This servlet is called on infocenters by client workbenches
+ * configured for remote help in order to gather selected parts of the TOCs.
+ *
+ * <p>Extends the {@link org.eclipse.help.internal.webapp.servlet.TocFragmentServlet}
+ * servlet.
+ *
+ * @param topic - (optional)
+ * @param toc - (optional) specifies the toc id value in xml node
+ * @param expandPath - (optional)
+ * @param anchor - (optional)
+ * @param path - (optional) specifies initial root path
+ * @param href - (optional) specifies
+ * @param errorSuppress - (optional) (default) false
+ * @param lang - (optional) specifies the locale
+ * @param returnType - (Optional) specifies the return type of the servlet.
+ * Accepts either <code>xml</code> (default) or
+ * <code>json</code>
+ *
+ * @return The selected parts of one or more TOCs, either as <code>xml</code>
+ * (default) or <code>json</code>
+ *
+ * @version $Version$
+ *
+ **/
+public class TocFragmentService extends TocFragmentServlet {
+
+ private static final long serialVersionUID = 1L;
+
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+
+ req.setCharacterEncoding("UTF-8"); //$NON-NLS-1$
+ // Set standard HTTP/1.1 no-cache headers.
+ resp.setHeader("Cache-Control", //$NON-NLS-1$
+ "no-store, no-cache, must-revalidate"); //$NON-NLS-1$
+ resp.setContentType("application/xml; charset=UTF-8"); //$NON-NLS-1$
+
+ String response = processRequest(req, resp);
+
+ String returnType = req.getParameter(Utils.RETURN_TYPE);
+ boolean boolIsJSON = (returnType != null
+ && returnType.equalsIgnoreCase(Utils.JSON));
+
+ // If JSON output is required
+ if (boolIsJSON) {
+ resp.setContentType("text/plain"); //$NON-NLS-1$
+ String toc = req.getParameter("toc"); //$NON-NLS-1$
+ String path = req.getParameter("path"); //$NON-NLS-1$
+ response = getJSONResponse(toc, path, response);
+ }
+
+ resp.getWriter().write(response);
+ }
+
+ protected String getJSONResponse(String toc, String path, String xmlResource)
+ throws IOException {
+ TocFragmentParser tocParser = new TocFragmentParser();
+ InputStream is = null;
+ try {
+ if (xmlResource != null) {
+ is = new ByteArrayInputStream(xmlResource.getBytes("UTF-8")); //$NON-NLS-1$
+
+ int level = 0;
+ if (toc != null && toc.length() > 0) {
+ level++;
+
+
+ if (path != null && path.length() > 0) {
+ String[] pathIdxs = path.split("_"); //$NON-NLS-1$
+ level += pathIdxs.length;
+ }
+ }
+
+ tocParser.parse(is, level);
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ if (is != null)
+ is.close();
+
+ // Call after the catch.
+ // An empty JSON is created if any Exception is thrown
+ // Else returns the complete JSON
+ return tocParser.toJSON();
+ }
+}
diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/TocService.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/TocService.java
new file mode 100644
index 000000000..67f87b60e
--- /dev/null
+++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/service/TocService.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.help.internal.webapp.service;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.help.internal.webapp.parser.TocParser;
+import org.eclipse.help.internal.webapp.servlet.TocServlet;
+import org.eclipse.help.internal.webapp.utils.Utils;
+
+/**
+ * Returns <code>xml</code> or <code>json</code> representing all toc contributions
+ * available on this host
+ *
+ * <p>This servlet is called on infocenters by client workbenches
+ * configured for remote help in order to gather all the toc fragments and assemble
+ * them into a complete toc.
+ *
+ * <p>Extends the {@link org.eclipse.help.internal.webapp.servlet.TocServlet}
+ * servlet.
+ *
+ * @param lang - (optional) specifies the locale
+ * @param returnType - (Optional) specifies the return type of the servlet.
+ * Accepts either <code>xml</code> (default) or
+ * <code>json</code>
+ *
+ * @return Toc contributions available on the host, either as <code>xml</code>
+ * (default) or <code>json</code>
+ *
+ * @version $Version$
+ *
+ **/
+public class TocService extends TocServlet {
+
+ private static final long serialVersionUID = 1L;
+
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+
+ req.setCharacterEncoding("UTF-8"); //$NON-NLS-1$
+ // Set standard HTTP/1.1 no-cache headers.
+ resp.setHeader("Cache-Control", //$NON-NLS-1$
+ "no-store, no-cache, must-revalidate"); //$NON-NLS-1$
+ resp.setContentType("application/xml; charset=UTF-8"); //$NON-NLS-1$
+
+ String response = processRequest(req, resp);
+
+ String returnType = req.getParameter(Utils.RETURN_TYPE);
+ boolean boolIsJSON = (returnType != null
+ && returnType.equalsIgnoreCase(Utils.JSON));
+
+ // If JSON output is required
+ if (boolIsJSON) {
+ resp.setContentType("text/plain"); //$NON-NLS-1$
+ response = getJSONResponse(response);
+ }
+
+ resp.getWriter().write(response);
+ }
+
+ protected String getJSONResponse(String response)
+ throws IOException {
+ TocParser tocParser = new TocParser();
+ InputStream is = null;
+ try {
+ if (response != null) {
+ is = new ByteArrayInputStream(response.getBytes("UTF-8")); //$NON-NLS-1$
+ tocParser.parse(is);
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ if (is != null)
+ is.close();
+
+ // Call after the catch.
+ // An empty JSON is created if any Exception is thrown
+ // Else returns the complete JSON
+ return tocParser.toJSON();
+ }
+
+}
diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/ContextServlet.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/ContextServlet.java
index 8025ee8c7..b3c28c40a 100644
--- a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/ContextServlet.java
+++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/ContextServlet.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -11,7 +11,6 @@
package org.eclipse.help.internal.webapp.servlet;
import java.io.IOException;
-import java.io.Writer;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
@@ -40,6 +39,17 @@ public class ContextServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
+ String response = processRequest(req, resp);
+ if ("400".equals(response)) //$NON-NLS-1$
+ resp.sendError(400); // bad request; missing parameter
+ else if ("404".equals(response)) //$NON-NLS-1$
+ resp.sendError(404); // Wrong context id; not found
+ else
+ resp.getWriter().write(response);
+ }
+
+ protected String processRequest(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
BaseHelpSystem.checkMode();
String locale = UrlUtil.getLocale(req, resp);
req.setCharacterEncoding("UTF-8"); //$NON-NLS-1$
@@ -48,15 +58,13 @@ public class ContextServlet extends HttpServlet {
if (id != null) {
IContext context = getContext(locale, id);
if (context != null) {
- serialize(context, resp.getWriter());
+ return serialize(context);
}
- else {
- resp.sendError(404);
- }
- }
- else {
- resp.sendError(400); // bad request; missing parameter
+ // Wrong context id; not found
+ return "404"; //$NON-NLS-1$
}
+ // bad request; missing parameter
+ return "400"; //$NON-NLS-1$
}
protected IContext getContext(String locale, String id) {
@@ -64,32 +72,34 @@ public class ContextServlet extends HttpServlet {
return context;
}
- private void serialize(IContext context, Writer out) throws IOException {
- out.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); //$NON-NLS-1$
- out.write('<' + Context.NAME );
+ private String serialize(IContext context) throws IOException {
+ StringBuffer buff = new StringBuffer();
+ buff.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); //$NON-NLS-1$
+ buff.append('<' + Context.NAME );
if (context instanceof IContext2) {
String title = ((IContext2)context).getTitle();
if (title != null && title.length() > 0) {
- out.write(" title=\"" + title + "\""); //$NON-NLS-1$ //$NON-NLS-2$
+ buff.append(" title=\"" + title + "\""); //$NON-NLS-1$ //$NON-NLS-2$
}
}
- out.write(">\n"); //$NON-NLS-1$
+ buff.append(">\n"); //$NON-NLS-1$
String description = context.getText();
if (description != null) {
- out.write(" <description>" + UrlUtil.htmlEncode(description) + "</description>\n"); //$NON-NLS-1$ //$NON-NLS-2$
+ buff.append(" <description>" + UrlUtil.htmlEncode(description) + "</description>\n"); //$NON-NLS-1$ //$NON-NLS-2$
}
IHelpResource[] topics = context.getRelatedTopics();
for (int i=0;i<topics.length;++i) {
- out.write(" <" + Topic.NAME); //$NON-NLS-1$
+ buff.append(" <" + Topic.NAME); //$NON-NLS-1$
if (topics[i].getLabel() != null) {
- out.write("\n " + Topic.ATTRIBUTE_LABEL + "=\"" + topics[i].getLabel() + '"'); //$NON-NLS-1$ //$NON-NLS-2$
+ buff.append("\n " + Topic.ATTRIBUTE_LABEL + "=\"" + topics[i].getLabel() + '"'); //$NON-NLS-1$ //$NON-NLS-2$
}
if (topics[i].getHref() != null) {
- out.write("\n " + Topic.ATTRIBUTE_HREF + "=\"" + topics[i].getHref() + '"'); //$NON-NLS-1$ //$NON-NLS-2$
+ buff.append("\n " + Topic.ATTRIBUTE_HREF + "=\"" + topics[i].getHref() + '"'); //$NON-NLS-1$ //$NON-NLS-2$
}
- out.write(">\n </topic>"); //$NON-NLS-1$
+ buff.append("> </" + Topic.NAME + ">\n"); //$NON-NLS-1$ //$NON-NLS-2$
}
- out.write("</" + Context.NAME + ">\n"); //$NON-NLS-1$ //$NON-NLS-2$
+ buff.append("</" + Context.NAME + ">\n"); //$NON-NLS-1$ //$NON-NLS-2$
+ return buff.toString();
}
}
diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/ExtensionServlet.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/ExtensionServlet.java
index d58e92930..52628b2c1 100644
--- a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/ExtensionServlet.java
+++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/ExtensionServlet.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 IBM Corporation and others.
+ * Copyright (c) 2007, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -39,9 +39,15 @@ public class ExtensionServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
+ // set the character-set to UTF-8 before calling resp.getWriter()
+ resp.setContentType("application/xml; charset=UTF-8"); //$NON-NLS-1$
+ resp.getWriter().write(processRequest(req, resp));
+ }
+
+ protected String processRequest(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
String locale = UrlUtil.getLocale(req, resp);
req.setCharacterEncoding("UTF-8"); //$NON-NLS-1$
- resp.setContentType("application/xml; charset=UTF-8"); //$NON-NLS-1$
if (responseByLocale == null) {
responseByLocale = new WeakHashMap();
@@ -57,7 +63,7 @@ public class ExtensionServlet extends HttpServlet {
}
responseByLocale.put(locale, response);
}
- resp.getWriter().write(response);
+ return response;
}
private String serialize(ContentExtension[] extensions) throws TransformerException {
diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/IndexFragmentServlet.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/IndexFragmentServlet.java
index ee29e3b7f..db713a824 100644
--- a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/IndexFragmentServlet.java
+++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/IndexFragmentServlet.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2010 IBM Corporation and others.
+ * Copyright (c) 2007, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -68,6 +68,13 @@ public class IndexFragmentServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
+ // set the character-set to UTF-8 before calling resp.getWriter()
+ resp.setContentType("application/xml; charset=UTF-8"); //$NON-NLS-1$
+ resp.getWriter().write(processRequest(req, resp));
+ }
+
+ protected String processRequest(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
String locale = UrlUtil.getLocale(req, resp);
startParameter = req.getParameter("start"); //$NON-NLS-1$
if (startParameter != null) {
@@ -100,7 +107,6 @@ public class IndexFragmentServlet extends HttpServlet {
}
req.setCharacterEncoding("UTF-8"); //$NON-NLS-1$
- resp.setContentType("application/xml; charset=UTF-8"); //$NON-NLS-1$
// Cache suppression required because the set of in scope
// topics could change between requests
@@ -112,7 +118,8 @@ public class IndexFragmentServlet extends HttpServlet {
Serializer serializer = new Serializer(locale, scope);
String response = serializer.generateIndexXml();
locale2Response.put(locale, response);
- resp.getWriter().write(response);
+
+ return response;
}
/*
diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/IndexServlet.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/IndexServlet.java
index 3da5a4926..7ecc0d291 100644
--- a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/IndexServlet.java
+++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/IndexServlet.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -44,10 +44,16 @@ public class IndexServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
+ // set the character-set to UTF-8 before calling resp.getWriter()
+ resp.setContentType("application/xml; charset=UTF-8"); //$NON-NLS-1$
+ resp.getWriter().write(processRequest(req, resp));
+ }
+
+ protected String processRequest(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
BaseHelpSystem.checkMode();
String locale = UrlUtil.getLocale(req, resp);
req.setCharacterEncoding("UTF-8"); //$NON-NLS-1$
- resp.setContentType("application/xml; charset=UTF-8"); //$NON-NLS-1$
if (responseByLocale == null) {
responseByLocale = new WeakHashMap();
@@ -63,7 +69,8 @@ public class IndexServlet extends HttpServlet {
}
responseByLocale.put(locale, response);
}
- resp.getWriter().write(response);
+
+ return (response != null) ? response : ""; //$NON-NLS-1$
}
public String serialize(IndexContribution[] contributions, String locale) throws TransformerException {
diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/SearchServlet.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/SearchServlet.java
index 118f03d40..fe9d253ca 100644
--- a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/SearchServlet.java
+++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/SearchServlet.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -14,7 +14,6 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
-import java.util.Iterator;
import java.util.List;
import javax.servlet.ServletException;
@@ -27,10 +26,10 @@ import org.eclipse.help.internal.base.BaseHelpSystem;
import org.eclipse.help.internal.search.ISearchHitCollector;
import org.eclipse.help.internal.search.ISearchQuery;
import org.eclipse.help.internal.search.QueryTooComplexException;
-import org.eclipse.help.internal.search.SearchHit;
import org.eclipse.help.internal.search.SearchQuery;
import org.eclipse.help.internal.util.URLCoder;
import org.eclipse.help.internal.webapp.data.UrlUtil;
+import org.eclipse.help.internal.webapp.utils.SearchXMLGenerator;
/*
* Returns the search hits for the query provided in the phrase parameter.
@@ -61,65 +60,34 @@ public class SearchServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
+ String response = processRequest(req, resp);
+ if ("".equals(response)) //$NON-NLS-1$
+ resp.sendError(400); // bad request; missing parameter
+ else
+ resp.getWriter().write(response);
+ }
+
+ protected String processRequest(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
BaseHelpSystem.checkMode();
HitCollector collector = new HitCollector();
String locale = UrlUtil.getLocale(req, resp);
req.setCharacterEncoding("UTF-8"); //$NON-NLS-1$
resp.setContentType("application/xml; charset=UTF-8"); //$NON-NLS-1$
- String phrase = req.getParameter(PARAMETER_PHRASE);
+ String phrase = req.getParameter(PARAMETER_PHRASE);
if (phrase != null) {
phrase = URLCoder.decode(phrase);
ISearchQuery query = new SearchQuery(phrase, false, Collections.EMPTY_LIST, locale);
collector.results.clear();
BaseHelpSystem.getSearchManager().search(query, collector, new NullProgressMonitor());
if (searchException == null) {
- String response = serialize(collector.results);
- resp.getWriter().write(response);
- return;
+ return serialize(collector.results);
}
}
-
- resp.sendError(400); // bad request; missing parameter
-
+ return ""; //$NON-NLS-1$
}
public static String serialize(Collection results) {
- StringBuffer buf = new StringBuffer();
- buf.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); //$NON-NLS-1$
- buf.append("<searchHits>\n"); //$NON-NLS-1$
- Iterator iter = results.iterator();
- while (iter.hasNext()) {
- SearchHit hit = (SearchHit)iter.next();
- serialize(hit, buf, " "); //$NON-NLS-1$
- }
- buf.append("</searchHits>\n"); //$NON-NLS-1$
- return buf.toString();
- }
-
- private static void serialize(SearchHit hit, StringBuffer buf, String indent) {
- buf.append(indent + "<hit"); //$NON-NLS-1$
- if (hit.getHref() != null) {
- buf.append('\n' + indent + " href=\"" + XMLGenerator.xmlEscape(hit.getHref()) + '"'); //$NON-NLS-1$
- }
- if (hit.getLabel() != null) {
- buf.append('\n' + indent + " label=\"" + XMLGenerator.xmlEscape(hit.getLabel()) + '"'); //$NON-NLS-1$
- }
- if (hit.isPotentialHit()) {
- buf.append('\n' + indent + " isPotentialHit=\"true\""); //$NON-NLS-1$
- }
- buf.append('\n' + indent + " score=\"" + hit.getScore() + '"'); //$NON-NLS-1$
- buf.append(">\n"); //$NON-NLS-1$
-
- String summary = hit.getSummary();
- if (summary != null) {
- serialize(summary, buf, indent + " "); //$NON-NLS-1$
- }
- buf.append(indent + "</hit>\n"); //$NON-NLS-1$
- }
-
- private static void serialize(String summary, StringBuffer buf, String indent) {
- buf.append(indent + "<summary>"); //$NON-NLS-1$
- buf.append(XMLGenerator.xmlEscape(summary));
- buf.append("</summary>\n"); //$NON-NLS-1$
+ return SearchXMLGenerator.serialize(results);
}
}
diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/ServletPrintWriter.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/ServletPrintWriter.java
new file mode 100644
index 000000000..e0a6db4f7
--- /dev/null
+++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/ServletPrintWriter.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.help.internal.webapp.servlet;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintWriter;
+
+public class ServletPrintWriter extends PrintWriter{
+
+ private StringBuffer buffer;
+
+ public ServletPrintWriter() {
+ super(new ByteArrayOutputStream());
+ buffer = new StringBuffer();
+ }
+
+ /**
+ * Writes a single character.
+ * @param c int specifying a character to be written.
+ */
+ public void write(int c) {
+ synchronized (lock) {
+ buffer.append((char)(c));
+ }
+ }
+
+ /**
+ * Writes A Portion of an array of characters.
+ * @param buf Array of characters
+ * @param off Offset from which to start writing characters
+ * @param len Number of characters to write
+ */
+ public void write(char buf[], int off, int len) {
+ synchronized (lock) {
+ buffer.append(buf, off, len);
+ }
+ }
+
+ /**
+ * Writes an array of characters. This method cannot be inherited from the
+ * Writer class because it must suppress I/O exceptions.
+ * @param buf Array of characters to be written
+ */
+ public void write(char buf[]) {
+ write(buf, 0, buf.length);
+ }
+
+ /**
+ * Writes a portion of a string.
+ * @param s A String
+ * @param off Offset from which to start writing characters
+ * @param len Number of characters to write
+ */
+ public void write(String s, int off, int len) {
+ synchronized (lock) {
+ buffer.append(s.toCharArray(), off, off+len);
+ }
+ }
+
+ /**
+ * Writes a string. This method cannot be inherited from the Writer class
+ * because it must suppress I/O exceptions.
+ * @param s String to be written
+ */
+ public void write(String s) {
+ write(s, 0, s.length());
+ }
+
+ public String toString()
+ {
+ return buffer.toString();
+ }
+}
diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/TocFragmentServlet.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/TocFragmentServlet.java
index 4b601329c..78ed6e640 100644
--- a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/TocFragmentServlet.java
+++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/TocFragmentServlet.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2010 IBM Corporation and others.
+ * Copyright (c) 2006, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -46,9 +46,15 @@ public class TocFragmentServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
+ // set the character-set to UTF-8 before calling resp.getWriter()
+ resp.setContentType("application/xml; charset=UTF-8"); //$NON-NLS-1$
+ resp.getWriter().write(processRequest(req, resp));
+ }
+
+ protected String processRequest(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
String locale = UrlUtil.getLocale(req, resp);
req.setCharacterEncoding("UTF-8"); //$NON-NLS-1$
- resp.setContentType("application/xml; charset=UTF-8"); //$NON-NLS-1$
resp.setHeader("Cache-Control","no-cache"); //$NON-NLS-1$//$NON-NLS-2$
resp.setHeader("Pragma","no-cache"); //$NON-NLS-1$ //$NON-NLS-2$
resp.setDateHeader ("Expires", 0); //$NON-NLS-1$
@@ -60,7 +66,8 @@ public class TocFragmentServlet extends HttpServlet {
Serializer serializer = new Serializer(data, req.getLocale(), scope);
String response = serializer.generateTreeXml();
locale2Response.put(locale, response);
- resp.getWriter().write(response);
+
+ return response;
}
private void readParameters(HttpServletRequest req) {
diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/TocServlet.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/TocServlet.java
index 80dbdf607..5421cdbc8 100644
--- a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/TocServlet.java
+++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/TocServlet.java
@@ -45,10 +45,16 @@ public class TocServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
+ // set the character-set to UTF-8 before calling resp.getWriter()
+ resp.setContentType("application/xml; charset=UTF-8"); //$NON-NLS-1$
+ resp.getWriter().write(processRequest(req, resp));
+ }
+
+ protected String processRequest(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
BaseHelpSystem.checkMode();
String locale = UrlUtil.getLocale(req, resp);
req.setCharacterEncoding("UTF-8"); //$NON-NLS-1$
- resp.setContentType("application/xml; charset=UTF-8"); //$NON-NLS-1$
if (clearCache){
responseByLocale = new WeakHashMap();
@@ -69,7 +75,8 @@ public class TocServlet extends HttpServlet {
}
responseByLocale.put(locale, response);
}
- resp.getWriter().write(response);
+
+ return (response != null) ? response : ""; //$NON-NLS-1$
}
protected String serialize(TocContribution[] contributions, String locale) throws TransformerException {
diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/ValidatorServlet.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/ValidatorServlet.java
new file mode 100644
index 000000000..30be71fce
--- /dev/null
+++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/servlet/ValidatorServlet.java
@@ -0,0 +1,274 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.help.internal.webapp.servlet;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.help.internal.webapp.HelpWebappPlugin;
+import org.eclipse.help.internal.webapp.WebappResources;
+import org.eclipse.help.internal.webapp.data.UrlUtil;
+import org.eclipse.help.internal.webapp.utils.Utils;
+
+/*
+ * Class is responsible for implementing security protection. All servlets
+ * who use the org.eclipse.help.webapp.validatedServlet extension point will
+ * will be processed for security failures by this class.
+ *
+ * Any URL that starts with <path>/vs<etc> will be redirected here for further
+ * processing. If the validatedServlet extension point has an alias that
+ * matches the URL passed here, it will finish the processing and return
+ * results here for validation. If there are no malicious threats detected,
+ * this class will return the output to the client.
+ *
+ */
+public class ValidatorServlet extends HttpServlet {
+
+ private static final long serialVersionUID = -3783758607845176051L;
+ private Hashtable servletTable = new Hashtable();
+
+ protected void process(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+
+ String baseURL = req.getRequestURL().toString();
+ baseURL = baseURL.substring(0, baseURL.indexOf(req.getServletPath()));
+
+ Locale locale = UrlUtil.getLocaleObj(req,resp);
+
+ String service = req.getRequestURL().toString().substring(
+ (baseURL).length()+("/vs".length())); //$NON-NLS-1$
+
+ try {
+ HttpServletResponseAdv response = new HttpServletResponseAdv(resp);
+
+ HttpServlet servlet = getServlet(service);
+ ServletConfig config = getServletConfig();
+ servlet.init(config);
+ servlet.service(req, response);
+
+ if (isSecure(req, response))
+ response.commitOutput();
+
+ } catch(Exception ex) {
+
+ String errorMsg = WebappResources.getString("cantCreateServlet", //$NON-NLS-1$
+ locale, service);
+ HelpWebappPlugin.logError(errorMsg, ex);
+
+ PrintWriter writer = resp.getWriter();
+ writer.println(errorMsg);
+ ex.printStackTrace(writer);
+
+ resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ }
+ }
+
+ private HttpServlet getServlet(String name)
+ throws CoreException {
+
+ HttpServlet servlet = (HttpServlet)servletTable.get(name);
+
+ if (servlet == null) {
+
+ IConfigurationElement[] configs =
+ Platform.getExtensionRegistry().getConfigurationElementsFor(HelpWebappPlugin.PLUGIN_ID+".validatedServlet"); //$NON-NLS-1$
+
+ for (int c=0; c < configs.length; c++) {
+
+ String alias = configs[c].getAttribute("alias"); //$NON-NLS-1$
+ if (alias != null) {
+
+ if (isMatch(alias, name)) {
+ servlet = (HttpServlet)configs[c].createExecutableExtension("class"); //$NON-NLS-1$
+ servletTable.put(name, servlet);
+ break;
+ }
+ }
+ }
+ }
+
+ return servlet;
+ }
+
+ private boolean isMatch(String alias, String name) {
+
+ int index = name.indexOf(alias);
+ if (index == 0) {
+ int offset = alias.length();
+ if (name.length() == offset)
+ return true;
+ char ch = name.charAt(offset);
+ if (ch == '/' || ch == '?')
+ return true;
+ }
+ return false;
+ }
+
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+ process(req, resp);
+ }
+
+ protected void doPost(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+ process(req, resp);
+ }
+
+ public boolean isSecure(HttpServletRequest req,HttpServletResponseAdv resp)
+ throws SecurityException {
+
+ Enumeration names = req.getParameterNames();
+ List values = new ArrayList();
+ List scripts = new ArrayList();
+
+ while (names.hasMoreElements()) {
+
+ String name = (String)names.nextElement();
+ String val = req.getParameter(name);
+ values.add(val);
+ if (replaceAll(val, '+', "").indexOf("<script")>-1) //$NON-NLS-1$ //$NON-NLS-2$
+ scripts.add(val);
+ }
+
+ if (resp.getWriter() != null) {
+
+ String data = resp.getString();
+ for (int s=0; s < scripts.size(); s++)
+ if (data.indexOf((String)scripts.get(s)) > -1)
+ throw new SecurityException("Potential cross-site scripting detected."); //$NON-NLS-1$
+ }
+
+ return true;
+ }
+
+ public void isScript(List params,OutputStream out) {
+
+// ByteArrayOutputStream bOut = new ByteArrayOutputStream(out);
+ }
+
+
+ public String replaceAll(String str, char remove, String add) {
+
+ StringBuffer buffer = new StringBuffer();
+ for (int s=0; s < str.length(); s++) {
+
+ char ch = str.charAt(s);
+ if (ch == remove)
+ buffer.append(add);
+ else
+ buffer.append(ch);
+ }
+ return buffer.toString();
+ }
+
+ private class HttpServletResponseAdv extends HttpServletResponseWrapper {
+
+ private HttpServletResponse response;
+ private ByteArrayOutputStream out;
+ private ServletPrintWriter writer;
+ private SecureServletOutputStream stream;
+
+ public HttpServletResponseAdv(HttpServletResponse response) {
+ super(response);
+ out = new ByteArrayOutputStream();
+ this.response = response;
+ }
+
+ public PrintWriter getWriter() {
+
+ if (writer == null && stream == null)
+ writer = new ServletPrintWriter();
+ return writer;
+ }
+
+ public ServletOutputStream getOutputStream() {
+
+ if (stream == null && writer == null)
+ stream = new SecureServletOutputStream(out);
+ return stream;
+ }
+
+ public void commitOutput() throws IOException {
+
+ OutputStream os = response.getOutputStream();
+ InputStream is = getInputStream();
+
+ Utils.transferContent(is, os);
+
+ os.flush();
+ }
+
+ public InputStream getInputStream() {
+
+ if (stream != null) {
+
+ try {
+ out.flush();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return new ByteArrayInputStream(out.toByteArray());
+ }
+ if (writer != null) {
+
+ try {
+ return new ByteArrayInputStream(writer.toString().getBytes(getCharacterEncoding()));
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+ }
+ return null;
+ }
+
+ public String getString() {
+
+ if (writer != null)
+ return writer.toString();
+
+ return null;
+ }
+ }
+
+
+ private class SecureServletOutputStream extends ServletOutputStream {
+
+ private OutputStream out;
+
+ public SecureServletOutputStream(OutputStream out) {
+ this.out = out;
+ }
+
+ public void write(int b) throws IOException {
+ out.write(b);
+ }
+ }
+}
diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/utils/JSonHelper.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/utils/JSonHelper.java
new file mode 100644
index 000000000..f3f6a65b8
--- /dev/null
+++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/utils/JSonHelper.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.help.internal.webapp.utils;
+
+public final class JSonHelper {
+
+ //JSON Characters
+ public static final String BEGIN_BRACE = "{"; //$NON-NLS-1$
+ public static final String END_BRACE = "}"; //$NON-NLS-1$
+ public static final String QUOTE = "\'"; //$NON-NLS-1$
+ public static final String COLON = ":"; //$NON-NLS-1$
+ public static final String BEGIN_BRACKET = "["; //$NON-NLS-1$
+ public static final String END_BRACKET = "]"; //$NON-NLS-1$
+ public static final String COMMA = ","; //$NON-NLS-1$
+ public static final String NEWLINE = "\n"; //$NON-NLS-1$
+ public static final String SPACE = " "; //$NON-NLS-1$
+
+ //JSON items
+ public static final String LABEL = "label"; //$NON-NLS-1$
+ public static final String IDENTIFIER = "identifier"; //$NON-NLS-1$
+ public static final String URL = "url"; //$NON-NLS-1$
+ public static final String PROVIDER = "provider"; //$NON-NLS-1$
+ public static final String ITEMS = "items"; //$NON-NLS-1$
+ public static final String NAME = "name"; //$NON-NLS-1$
+ public static final String TITLE = "title"; //$NON-NLS-1$
+ public static final String ID = "id"; //$NON-NLS-1$
+ public static final String HREF = "href"; //$NON-NLS-1$
+ public static final String TYPE = "type"; //$NON-NLS-1$
+ public static final String CHECKED = "checked"; //$NON-NLS-1$
+ public static final String CHILDREN = "children"; //$NON-NLS-1$
+ public static final String REFERENCE = "_reference"; //$NON-NLS-1$
+ public static final String IS_LEAF = "is_leaf"; //$NON-NLS-1$
+ public static final String IS_SELECTED = "is_selected"; //$NON-NLS-1$
+ public static final String IS_HIGHLIGHTED = "is_highlighted"; //$NON-NLS-1$
+ public static final String TOC = "toc"; //$NON-NLS-1$
+ public static final String PATH = "path"; //$NON-NLS-1$
+ public static final String CATEGORY = "category"; //$NON-NLS-1$
+ public static final String DESCRIPTION = "description"; //$NON-NLS-1$
+ public static final String CATEGORY_HREF = CATEGORY+"_"+HREF; //$NON-NLS-1$
+ public static final String PROPERTY_NAME = "propertyName"; //$NON-NLS-1$
+ public static final String INDEX = "Index"; //$NON-NLS-1$
+ public static final String TOPIC = "Topic"; //$NON-NLS-1$
+
+ public static String getQuotes(String str){
+ return ((str != null)?QUOTE + str + QUOTE:""); //$NON-NLS-1$
+ }
+
+}
diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/utils/SearchXMLGenerator.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/utils/SearchXMLGenerator.java
new file mode 100644
index 000000000..cd86bc65e
--- /dev/null
+++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/utils/SearchXMLGenerator.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.help.internal.webapp.utils;
+
+import java.util.Collection;
+
+import org.eclipse.help.HelpSystem;
+import org.eclipse.help.IHelpResource;
+import org.eclipse.help.IToc;
+import org.eclipse.help.ITopic;
+import org.eclipse.help.internal.search.SearchHit;
+import org.eclipse.help.internal.webapp.data.UrlUtil;
+import org.eclipse.help.internal.webapp.servlet.XMLGenerator;
+
+public class SearchXMLGenerator {
+
+ public static String serialize(Collection results) {
+ return serialize((results != null) ? results.toArray() : null, false);
+ }
+
+ public static String serialize(Object[] hits, boolean boolIsCategory) {
+ StringBuffer buf = new StringBuffer();
+ buf.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); //$NON-NLS-1$
+ buf.append("<searchHits>\n"); //$NON-NLS-1$
+
+ if (hits != null) {
+ for (int i = 0; i < hits.length; i++) {
+ SearchHit hit = (SearchHit) hits[i];
+ serialize(hit, buf, " ", boolIsCategory); //$NON-NLS-1$
+ }
+ }
+
+ buf.append("</searchHits>\n"); //$NON-NLS-1$
+
+ return buf.toString();
+ }
+
+ private static void serialize(SearchHit hit, StringBuffer buf,
+ String indent, boolean boolIsCategory) {
+ buf.append(indent + "<hit"); //$NON-NLS-1$
+ if (hit.getHref() != null) {
+ buf.append('\n' + indent + " href=\"" + XMLGenerator.xmlEscape(hit.getHref()) + '"'); //$NON-NLS-1$
+ }
+ if (hit.getLabel() != null) {
+ buf.append('\n' + indent + " label=\"" + XMLGenerator.xmlEscape(hit.getLabel()) + '"'); //$NON-NLS-1$
+ }
+ if (hit.isPotentialHit()) {
+ buf.append('\n' + indent + " isPotentialHit=\"true\""); //$NON-NLS-1$
+ }
+ buf.append('\n' + indent + " score=\"" + hit.getScore() + '"'); //$NON-NLS-1$
+ buf.append(">\n"); //$NON-NLS-1$
+
+ // get Category
+ if (boolIsCategory) {
+ IHelpResource categoryResource = hit.getCategory();
+ if (categoryResource != null) {
+ serializeCategory(categoryResource, buf, indent + " "); //$NON-NLS-1$
+ }
+ }
+
+ // get Summary/Description
+ String summary = hit.getSummary();
+ if (summary != null) {
+ serialize(summary, buf, indent + " "); //$NON-NLS-1$
+ }
+ buf.append(indent + "</hit>\n"); //$NON-NLS-1$
+ }
+
+ private static void serialize(String summary, StringBuffer buf, String indent) {
+ buf.append(indent + "<summary>"); //$NON-NLS-1$
+ buf.append(XMLGenerator.xmlEscape(summary));
+ buf.append("</summary>\n"); //$NON-NLS-1$
+ }
+
+ private static void serializeCategory(IHelpResource categoryResource,
+ StringBuffer buf, String indent) {
+ String category = categoryResource.getLabel();
+ if (category == null) return;
+
+ buf.append(indent + "<category"); //$NON-NLS-1$
+
+ String catHref = getCategoryHref(categoryResource);
+ if (catHref != null) {
+ buf.append('\n' + indent + " href=\"" //$NON-NLS-1$
+ + XMLGenerator.xmlEscape(catHref) + '"');
+ }
+
+ buf.append(">\n"); //$NON-NLS-1$
+ buf.append(XMLGenerator.xmlEscape(category));
+
+ buf.append("</category>\n"); //$NON-NLS-1$
+ }
+
+ private static String getCategoryHref(IHelpResource categoryResource) {
+ String tocHref = categoryResource.getHref();
+ IToc[] tocs = HelpSystem.getTocs();
+ for (int j=0;j<tocs.length;++j) {
+ if (tocHref.equals(tocs[j].getHref())) {
+ ITopic topic = tocs[j].getTopic(null);
+ String topicHref = topic.getHref();
+ if (topicHref != null) {
+ return UrlUtil.getHelpURL(topicHref);
+ }
+ return "../nav/" + j; //$NON-NLS-1$
+ }
+ }
+ return null;
+ }
+}
diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/utils/Utils.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/utils/Utils.java
new file mode 100644
index 000000000..f07d767ed
--- /dev/null
+++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/utils/Utils.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.help.internal.webapp.utils;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.StringWriter;
+import java.io.Writer;
+
+public class Utils {
+
+ public static final String SERVICE_CONTEXT = "/vs/service"; //$NON-NLS-1$
+
+ public static final String RETURN_TYPE = "returnType"; //$NON-NLS-1$
+ public static final String NO_CATEGORY = "noCategory"; //$NON-NLS-1$
+
+ // returnType values: xml (default) | json
+ public static final String XML = "xml"; //$NON-NLS-1$
+ public static final String JSON = "json"; //$NON-NLS-1$
+
+ public static String convertStreamToString(InputStream is)
+ throws IOException {
+ if (is != null) {
+ Writer writer = new StringWriter();
+ char[] buffer = new char[1024];
+ try {
+ Reader reader = new BufferedReader(
+ new InputStreamReader(is, "UTF-8")); //$NON-NLS-1$
+ int n;
+ while ((n = reader.read(buffer)) != -1) {
+ writer.write(buffer, 0, n);
+ }
+ } finally {
+ is.close();
+ }
+ return writer.toString();
+ } else {
+ return ""; //$NON-NLS-1$
+ }
+ }
+
+ public static void transferContent(InputStream inputStream, OutputStream out)
+ throws IOException {
+ try {
+ // Prepare the input stream for reading
+ BufferedInputStream dataStream = new BufferedInputStream(
+ inputStream);
+
+ // Create a fixed sized buffer for reading.
+ // We could create one with the size of available data...
+ byte[] buffer = new byte[4096];
+ int len = 0;
+ while (true) {
+ len = dataStream.read(buffer); // Read file into the byte array
+ if (len == -1)
+ break;
+ out.write(buffer, 0, len);
+ }
+ } catch (Exception e) {
+ }
+ }
+
+ public static String updateResponse(String response) {
+ response = removeString(response, "advanced/synchWithToc.js"); //$NON-NLS-1$
+ response = removeString(response, "index.jsp"); //$NON-NLS-1$
+ return response;
+ }
+
+ private static String removeString(String response, String remove) {
+ StringBuffer buff = new StringBuffer(response);
+ int index = buff.indexOf(remove);
+ if (index > -1) {
+ int start = buff.lastIndexOf("<script", index); //$NON-NLS-1$
+ int end = buff.indexOf("</script>", index); //$NON-NLS-1$
+ if (start > -1 && end > -1 && start < end) {
+ buff.delete(start, end + "</script>".length()); //$NON-NLS-1$
+ }
+ }
+ return buff.toString();
+ }
+
+}
diff --git a/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/utils/XMLHelper.java b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/utils/XMLHelper.java
new file mode 100644
index 000000000..614b701d5
--- /dev/null
+++ b/org.eclipse.help.webapp/src/org/eclipse/help/internal/webapp/utils/XMLHelper.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.help.internal.webapp.utils;
+
+public final class XMLHelper {
+
+ public static final String SESSION_URL = "helpURL"; //$NON-NLS-1$
+
+ public static final String URL36_PREFIX = "/advanced"; //$NON-NLS-1$
+ public static final String TOC_URL = "/tocfragment"; //$NON-NLS-1$
+ public static final String SEARCH_URL = "/search"; //$NON-NLS-1$
+
+ public static final String ATTR_TITLE = "title"; //$NON-NLS-1$
+ public static final String ATTR_ID = "id"; //$NON-NLS-1$
+ public static final String ATTR_HREF = "href"; //$NON-NLS-1$
+ public static final String ATTR_IMAGE = "image"; //$NON-NLS-1$
+ public static final String ATTR_LABEL = "label"; //$NON-NLS-1$
+ public static final String ATTR_SCORE = "score"; //$NON-NLS-1$
+ public static final String ATTR_LOCALE = "locale"; //$NON-NLS-1$
+ public static final String ATTR_KEYWORD = "keyword"; //$NON-NLS-1$
+
+ public static final String ELEMENT_NODE = "node"; //$NON-NLS-1$
+ public static final String ELEMENT_HIT = "hit"; //$NON-NLS-1$
+ public static final String ELEMENT_HITS = "searchHits"; //$NON-NLS-1$
+ public static final String ELEMENT_CATEGORY = "category"; //$NON-NLS-1$
+ public static final String ELEMENT_SUMMARY = "summary"; //$NON-NLS-1$
+ public static final String ELEMENT_DESCRIPTION = "description"; //$NON-NLS-1$
+ public static final String ELEMENT_INDEX = "index"; //$NON-NLS-1$
+ public static final String ELEMENT_INDEX_CONTRIBUTIONS = "indexContributions"; //$NON-NLS-1$
+ public static final String ELEMENT_TOC_CONTRIBUTIONS = "tocContributions"; //$NON-NLS-1$
+
+ public static final String CATEGORY_HREF = "categoryHref"; //$NON-NLS-1$
+}
diff --git a/org.eclipse.ua.tests/data/help/jsp/server.js b/org.eclipse.ua.tests/data/help/jsp/server.js
deleted file mode 100644
index 5b1fd51ce..000000000
--- a/org.eclipse.ua.tests/data/help/jsp/server.js
+++ /dev/null
@@ -1,45 +0,0 @@
-
-var defaultName = "http://help.eclipse.org/helios/";
-
-function getHelpPath() {
- var path = getCookie();
- if (path !== null) return decodeURIComponent(path);
- return defaultName;
-}
-
-function showHelpPath() {
- var pathNode = document.getElementById("path");
- var pathValue=document.createTextNode("Testing help system: " + getHelpPath() + "index.jsp");
- pathNode.appendChild(pathValue);
-}
-
-// Patches every anchor in a page
-function patchAnchors() {
- var doclinks = document.getElementsByTagName("a");
- for (var i = 0; i < doclinks.length; i++) {
- var slash = doclinks[i].href.indexOf('/', 8);
- slash = doclinks[i].href.indexOf('/', slash + 1);
- doclinks[i].href = getHelpPath() + doclinks[i].href.substring(slash + 1);
- }
-}
-
-function getCookie() {
- var nameEquals = "server=";
- var cookies = document.cookie.split(";");
- for (var i=0;i<cookies.length;++i) {
- var cookie = cookies[i];
- if (cookie.charAt(0) == ' ') {
- cookie = cookie.substring(1, cookie.length);
- }
- if (cookie.indexOf(nameEquals) == 0) {
- return cookie.substring(nameEquals.length, cookie.length);
- }
- }
- return null;
-}
-
-function setCookie(value) {
- var date = new Date();
- date.setTime(date.getTime()+(365*24*60*60*1000));
- document.cookie = "server=" + value + "; expires=" + date.toGMTString();
-} \ No newline at end of file
diff --git a/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/AllHelpTests.java b/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/AllHelpTests.java
index 78996dbd1..06bee8eaf 100644
--- a/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/AllHelpTests.java
+++ b/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/AllHelpTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2010 IBM Corporation and others.
+ * Copyright (c) 2006, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -23,6 +23,7 @@ import org.eclipse.ua.tests.help.scope.AllScopeTests;
import org.eclipse.ua.tests.help.search.AllSearchTests;
import org.eclipse.ua.tests.help.toc.AllTocTests;
import org.eclipse.ua.tests.help.webapp.AllWebappTests;
+import org.eclipse.ua.tests.help.webapp.service.AllWebappServiceTests;
/*
* Tests help functionality (automated).
@@ -50,5 +51,6 @@ public class AllHelpTests extends TestSuite {
addTest(AllOtherHelpTests.suite());
addTest(AllRemoteTests.suite());
addTest(AllScopeTests.suite());
+ addTest(AllWebappServiceTests.suite());
}
}
diff --git a/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/remote/ContextServletTest.java b/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/remote/ContextServletTest.java
index 917cfd653..16bb41b58 100644
--- a/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/remote/ContextServletTest.java
+++ b/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/remote/ContextServletTest.java
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Snehasish Paul <snehpaul@in.ibm.com> - Eclipse help public API services
*******************************************************************************/
package org.eclipse.ua.tests.help.remote;
@@ -70,14 +71,14 @@ public class ContextServletTest extends TestCase {
}
}
- private Element[] getContextsFromServlet(String phrase)
+ protected Element[] getContextsFromServlet(String phrase)
throws Exception {
int port = WebappManager.getPort();
URL url = new URL("http", "localhost", port, "/help/context?id=" + URLEncoder.encode(phrase, "UTF-8"));
return makeServletCall(url);
}
- private Element[] getContextsUsingLocale(String phrase, String locale)
+ protected Element[] getContextsUsingLocale(String phrase, String locale)
throws Exception {
int port = WebappManager.getPort();
URL url = new URL("http", "localhost", port, "/help/context?id="
@@ -85,7 +86,7 @@ public class ContextServletTest extends TestCase {
return makeServletCall(url);
}
- private Element[] makeServletCall(URL url) throws IOException,
+ protected Element[] makeServletCall(URL url) throws IOException,
ParserConfigurationException, FactoryConfigurationError,
SAXException {
InputStream is = url.openStream();
diff --git a/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/remote/IndexServletTest.java b/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/remote/IndexServletTest.java
index ca9e0f40f..2f4c41d79 100644
--- a/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/remote/IndexServletTest.java
+++ b/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/remote/IndexServletTest.java
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Snehasish Paul <snehpaul@in.ibm.com> - Eclipse help public API services
*******************************************************************************/
package org.eclipse.ua.tests.help.remote;
@@ -146,7 +147,7 @@ public class IndexServletTest extends TestCase {
}
}
- private Node getIndexContributions( String locale)
+ protected Node getIndexContributions( String locale)
throws Exception {
int port = WebappManager.getPort();
URL url = new URL("http", "localhost", port, "/help/index?lang=" + locale);
diff --git a/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/remote/SearchServletTest.java b/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/remote/SearchServletTest.java
index b2eaf5d99..4cc36c1dc 100755
--- a/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/remote/SearchServletTest.java
+++ b/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/remote/SearchServletTest.java
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Snehasish Paul <snehpaul@in.ibm.com> - Eclipse help public API services
*******************************************************************************/
package org.eclipse.ua.tests.help.remote;
@@ -97,14 +98,14 @@ public class SearchServletTest extends TestCase {
assertEquals(0, hits.length);
}
- private Node[] getSearchHitsFromServlet(String phrase)
+ protected Node[] getSearchHitsFromServlet(String phrase)
throws Exception {
int port = WebappManager.getPort();
URL url = new URL("http", "localhost", port, "/help/search?phrase=" + URLEncoder.encode(phrase, "UTF-8"));
return makeServletCall(url);
}
- private Node[] getSearchHitsUsingLocale(String phrase, String locale)
+ protected Node[] getSearchHitsUsingLocale(String phrase, String locale)
throws Exception {
int port = WebappManager.getPort();
URL url = new URL("http", "localhost", port, "/help/search?phrase="
@@ -112,7 +113,7 @@ public class SearchServletTest extends TestCase {
return makeServletCall(url);
}
- private Node[] makeServletCall(URL url) throws IOException,
+ protected Node[] makeServletCall(URL url) throws IOException,
ParserConfigurationException, FactoryConfigurationError,
SAXException {
InputStream is = url.openStream();
diff --git a/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/remote/TocServletTest.java b/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/remote/TocServletTest.java
index fda5de956..bd1fe780a 100644
--- a/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/remote/TocServletTest.java
+++ b/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/remote/TocServletTest.java
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Snehasish Paul <snehpaul@in.ibm.com> - Eclipse help public API services
*******************************************************************************/
package org.eclipse.ua.tests.help.remote;
@@ -110,7 +111,7 @@ public class TocServletTest extends TestCase {
}
- private Node getTocContributions( String locale)
+ protected Node getTocContributions( String locale)
throws Exception {
int port = WebappManager.getPort();
URL url = new URL("http", "localhost", port, "/help/toc?lang=" + locale);
diff --git a/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/AdvancedSearchServiceTest.java b/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/AdvancedSearchServiceTest.java
new file mode 100644
index 000000000..36d288891
--- /dev/null
+++ b/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/AdvancedSearchServiceTest.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ua.tests.help.webapp.service;
+
+
+import java.net.URL;
+import java.net.URLEncoder;
+
+import org.eclipse.help.internal.server.WebappManager;
+import org.eclipse.ua.tests.help.remote.SearchServletTest;
+import org.w3c.dom.Node;
+
+public class AdvancedSearchServiceTest extends SearchServletTest {
+
+ protected Node[] getSearchHitsFromServlet(String searchWord)
+ throws Exception {
+ int port = WebappManager.getPort();
+ URL url = new URL("http", "localhost", port, "/help/vs/service/advancedsearch?searchWord=" + URLEncoder.encode(searchWord, "UTF-8"));
+ return makeServletCall(url);
+ }
+
+ protected Node[] getSearchHitsUsingLocale(String searchWord, String locale)
+ throws Exception {
+ int port = WebappManager.getPort();
+ URL url = new URL("http", "localhost", port, "/help/vs/service/advancedsearch?searchWord="
+ + URLEncoder.encode(searchWord, "UTF-8") + "&lang=" + locale);
+ return makeServletCall(url);
+ }
+
+ public void testRemoteSearchXMLSchema()
+ throws Exception {
+ int port = WebappManager.getPort();
+ URL url = new URL("http", "localhost", port,
+ "/help/vs/service/advancedsearch?searchWord=" + URLEncoder.encode("jehcyqpfjs vkrhjewiwh", "UTF-8"));
+ URL schemaUrl = new URL("http", "localhost", port, "/help/test/schema/xml/advancedsearch.xsd");
+ String schema = schemaUrl.toString();
+ String uri = url.toString();
+ String result = SchemaValidator.testXMLSchema(uri, schema);
+
+ assertEquals("URL: \"" + uri + "\" is ", "valid", result);
+ }
+
+ public void testRemoteSearchXMLSchemaExactMatchFound()
+ throws Exception {
+ int port = WebappManager.getPort();
+ URL url = new URL("http", "localhost", port,
+ "/help/vs/service/advancedsearch?searchWord=" + URLEncoder.encode("\"jehcyqpfjs vkrhjewiwh\"", "UTF-8"));
+ URL schemaUrl = new URL("http", "localhost", port, "/help/test/schema/xml/advancedsearch.xsd");
+ String schema = schemaUrl.toString();
+ String uri = url.toString();
+ String result = SchemaValidator.testXMLSchema(uri, schema);
+
+ assertEquals("URL: \"" + uri + "\" is ", "valid", result);
+ }
+
+ public void testRemoteSearchJSONSchema()
+ throws Exception {
+// fail("Not yet implemented.");
+ }
+
+}
diff --git a/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/AllWebappServiceTests.java b/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/AllWebappServiceTests.java
new file mode 100644
index 000000000..dc2a167f8
--- /dev/null
+++ b/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/AllWebappServiceTests.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ua.tests.help.webapp.service;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/*
+ * Tests utility classes and servlets used in Web Application
+ */
+public class AllWebappServiceTests extends TestSuite {
+
+ /*
+ * Returns the entire test suite.
+ */
+ public static Test suite() {
+ TestSuite suite = new TestSuite(
+ "org.eclipse.ua.tests.help.AllWebappServiceTests");
+ //$JUnit-BEGIN$
+ suite.addTestSuite(AdvancedSearchServiceTest.class);
+ suite.addTestSuite(ContentServiceTest.class);
+ suite.addTestSuite(ContextServiceTest.class);
+ suite.addTestSuite(ExtensionServiceTest.class);
+ suite.addTestSuite(IndexFragmentServiceTest.class);
+ suite.addTestSuite(IndexServiceTest.class);
+ suite.addTestSuite(SearchServiceTest.class);
+ suite.addTestSuite(TocFragmentServiceTest.class);
+ suite.addTestSuite(TocServiceTest.class);
+ //$JUnit-END$
+ return suite;
+ }
+
+}
diff --git a/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/ContentServiceTest.java b/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/ContentServiceTest.java
new file mode 100644
index 000000000..96264b8dc
--- /dev/null
+++ b/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/ContentServiceTest.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ua.tests.help.webapp.service;
+
+import java.io.IOException;
+
+import org.eclipse.ua.tests.help.remote.ContentServletTest;
+
+public class ContentServiceTest extends ContentServletTest {
+
+ private static final String UA_TESTS = "org.eclipse.ua.tests";
+
+ public void testSimpleContent() throws Exception {
+ final String path = "/data/help/index/topic1.html";
+ String remoteContent = ServicesTestUtils.getRemoteContent(UA_TESTS, path, "en");
+ String localContent = ServicesTestUtils.getLocalContent(UA_TESTS, path);
+ assertEquals(remoteContent, localContent);
+ }
+
+ public void testFilteredContent() throws Exception {
+ final String path = "/data/help/manual/filter.xhtml";
+ String remoteContent = ServicesTestUtils.getRemoteContent(UA_TESTS, path, "en");
+ String localContent = ServicesTestUtils.getLocalContent(UA_TESTS, path);
+ assertEquals(remoteContent, localContent);
+ }
+
+ public void testContentInEnLocale() throws Exception {
+ final String path = "/data/help/search/testnl1.xhtml";
+ String remoteContent = ServicesTestUtils.getRemoteContent(UA_TESTS, path, "en");
+ String localContent = ServicesTestUtils.getLocalContent(UA_TESTS, path);
+ assertEquals(remoteContent, localContent);
+ }
+
+ public void testContentInDeLocale() throws Exception {
+ final String path = "/data/help/search/testnl1.xhtml";
+ String remoteContent = ServicesTestUtils.getRemoteContent(UA_TESTS, path, "de");
+ String enLocalContent = ServicesTestUtils.getLocalContent(UA_TESTS, path);
+ String deLocalContent = ServicesTestUtils.getLocalContent(UA_TESTS, "/nl/de" + path);
+ assertEquals(remoteContent, deLocalContent);
+ assertFalse(remoteContent.equals(enLocalContent));
+ }
+
+ public void testRemoteContentNotFound() throws Exception {
+ try {
+ ServicesTestUtils.getRemoteContent(UA_TESTS, "/no/such/path.html", "en");
+ fail("No exception thrown");
+ } catch (IOException e) {
+ // Exception caught as expected
+ }
+ }
+
+}
diff --git a/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/ContextServiceTest.java b/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/ContextServiceTest.java
new file mode 100644
index 000000000..08d681832
--- /dev/null
+++ b/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/ContextServiceTest.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ua.tests.help.webapp.service;
+
+import java.net.URL;
+import java.net.URLEncoder;
+
+import org.eclipse.help.internal.server.WebappManager;
+import org.eclipse.ua.tests.help.remote.ContextServletTest;
+import org.w3c.dom.Element;
+
+public class ContextServiceTest extends ContextServletTest {
+
+ protected Element[] getContextsFromServlet(String phrase)
+ throws Exception {
+ int port = WebappManager.getPort();
+ URL url = new URL("http", "localhost", port, "/help/vs/service/context?id="
+ + URLEncoder.encode(phrase, "UTF-8"));
+ return makeServletCall(url);
+ }
+
+ protected Element[] getContextsUsingLocale(String phrase, String locale)
+ throws Exception {
+ int port = WebappManager.getPort();
+ URL url = new URL("http", "localhost", port, "/help/vs/service/context?id="
+ + URLEncoder.encode(phrase, "UTF-8") + "&lang=" + locale);
+ return makeServletCall(url);
+ }
+
+ public void testContextServiceXMLSchema()
+ throws Exception {
+ int port = WebappManager.getPort();
+ URL url = new URL("http", "localhost", port, "/help/vs/service/context?id=org.eclipse.ua.tests.test_cheatsheets&lang=en");
+ URL schemaUrl = new URL("http", "localhost", port, "/help/test/schema/xml/context.xsd");
+ String schema = schemaUrl.toString();
+ String uri = url.toString();
+ String result = SchemaValidator.testXMLSchema(uri, schema);
+
+ assertEquals("URL: \"" + uri + "\" is ", "valid", result);
+ }
+
+ public void testContextServiceJSONSchema()
+ throws Exception {
+// fail("Not yet implemented.");
+ }
+
+}
diff --git a/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/ExtensionServiceTest.java b/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/ExtensionServiceTest.java
new file mode 100644
index 000000000..0000efc5c
--- /dev/null
+++ b/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/ExtensionServiceTest.java
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ua.tests.help.webapp.service;
+
+
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import junit.framework.TestCase;
+
+import org.eclipse.help.internal.base.BaseHelpSystem;
+import org.eclipse.help.internal.entityresolver.LocalEntityResolver;
+import org.eclipse.help.internal.server.WebappManager;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+
+public class ExtensionServiceTest extends TestCase {
+
+ private int mode;
+
+ protected void setUp() throws Exception {
+ BaseHelpSystem.ensureWebappRunning();
+ mode = BaseHelpSystem.getMode();
+ BaseHelpSystem.setMode(BaseHelpSystem.MODE_INFOCENTER);
+ }
+
+ protected void tearDown() throws Exception {
+ BaseHelpSystem.setMode(mode);
+ }
+
+ public void testExtensionServiceContributionExactMatch1() throws Exception {
+ Node root = getContentExtensions("en");
+ Element[] UARoot = findContributionByContent(root,
+ "/org.eclipse.ua.tests/data/help/dynamic/shared/doc2.xml#element.1");
+ assertEquals(1, UARoot.length);
+ }
+
+ public void testExtensionServiceContributionExactMatch3() throws Exception {
+ Node root = getContentExtensions("en");
+ Element[] UARoot = findContributionByContent(root,
+ "/org.eclipse.ua.tests/data/help/dynamic/shared/doc2.xml#element.3");
+ assertEquals(1, UARoot.length);
+ }
+
+ public void testExtensionServiceContributionNoMatch() throws Exception {
+ Node root = getContentExtensions("en");
+ Element[] UARoot = findContributionByContent(root,
+ "/org.eclipse.ua.tests/data/help/dynamic/shared/doc2.xml#element.4");
+ assertEquals(0, UARoot.length);
+ }
+
+ public void testExtensionServiceContributionByPath() throws Exception {
+ Node root = getContentExtensions("en");
+ Element[] UARoot = findContributionByPath(root,
+ "/org.eclipse.ua.tests/data/help/dynamic/extension.xml#anchor.invalidcontribution");
+ assertEquals(2, UARoot.length);
+ }
+
+ public void testExtensionServiceReplacementExactMatch() throws Exception {
+ Node root = getContentExtensions("en");
+ Element[] UARoot = findReplacementByContent(root,
+ "/org.eclipse.ua.tests/data/help/dynamic/shared/doc2.xml#element.1");
+ assertEquals(1, UARoot.length);
+ }
+
+ public void testExtensionServiceReplacementNoMatch() throws Exception {
+ Node root = getContentExtensions("en");
+ Element[] UARoot = findReplacementByContent(root,
+ "/org.eclipse.ua.tests/data/help/dynamic/shared/doc2.xml#element.3");
+ assertEquals(0, UARoot.length);
+ }
+
+ public void testExtensionServiceReplacementByPath() throws Exception {
+ Node root = getContentExtensions("en");
+ Element[] UARoot = findReplacementByPath(root,
+ "/org.eclipse.ua.tests/data/help/dynamic/shared/doc1.xml#element.2");
+ assertEquals(1, UARoot.length);
+ }
+
+ private Element[] findContributionByContent(Node root, String content) {
+ return findChildren(root, "contribution", "content", content);
+ }
+
+ private Element[] findContributionByPath(Node root, String path) {
+ return findChildren(root, "contribution", "path", path);
+ }
+
+ private Element[] findReplacementByContent(Node root, String content) {
+ return findChildren(root, "replacement", "content", content);
+ }
+
+ private Element[] findReplacementByPath(Node root, String path) {
+ return findChildren(root, "replacement", "path", path);
+ }
+
+ private Element[] findChildren(Node parent, String childKind,
+ String attributeName, String attributeValue) {
+ NodeList contributions = parent.getChildNodes();
+ List<Node> results = new ArrayList<Node>();
+ for (int i = 0; i < contributions.getLength(); i++) {
+ Node next = contributions.item(i);
+ if (next instanceof Element) {
+ Element nextElement = (Element)next;
+ if ( childKind.equals(nextElement.getTagName()) && attributeValue.equals(nextElement.getAttribute(attributeName))) {
+
+ results.add(next);
+ }
+ }
+ }
+ return results.toArray(new Element[results.size()]);
+ }
+
+ private Node getContentExtensions(String locale)
+ throws Exception {
+ int port = WebappManager.getPort();
+ URL url = new URL("http", "localhost", port, "/help/vs/service/extension?lang=" + locale);
+ InputStream is = url.openStream();
+ InputSource inputSource = new InputSource(is);
+ DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ documentBuilder.setEntityResolver(new LocalEntityResolver());
+ Document document = documentBuilder.parse(inputSource);
+ Node root = document.getFirstChild();
+ is.close();
+ assertEquals("contentExtensions", root.getNodeName());
+ return root;
+ }
+
+ public void testExtensionFragmentServiceXMLSchema()
+ throws Exception {
+ int port = WebappManager.getPort();
+ URL url = new URL("http", "localhost", port, "/help/vs/service/extension?lang=en");
+ URL schemaUrl = new URL("http", "localhost", port, "/help/test/schema/xml/extension.xsd");
+ String schema = schemaUrl.toString();
+ String uri = url.toString();
+ String result = SchemaValidator.testXMLSchema(uri, schema);
+
+ assertEquals("URL: \"" + uri + "\" is ", "valid", result);
+ }
+
+ public void testExtensionFragmentServiceJSONSchema()
+ throws Exception {
+// fail("Not yet implemented.");
+ }
+
+}
diff --git a/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/IndexFragmentServiceTest.java b/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/IndexFragmentServiceTest.java
new file mode 100644
index 000000000..e488d07b3
--- /dev/null
+++ b/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/IndexFragmentServiceTest.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ua.tests.help.webapp.service;
+
+
+import java.io.InputStream;
+import java.net.URL;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import junit.framework.TestCase;
+
+import org.eclipse.help.internal.base.BaseHelpSystem;
+import org.eclipse.help.internal.entityresolver.LocalEntityResolver;
+import org.eclipse.help.internal.server.WebappManager;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.xml.sax.InputSource;
+
+public class IndexFragmentServiceTest extends TestCase {
+
+ private int mode;
+
+ protected void setUp() throws Exception {
+ BaseHelpSystem.ensureWebappRunning();
+ mode = BaseHelpSystem.getMode();
+ BaseHelpSystem.setMode(BaseHelpSystem.MODE_INFOCENTER);
+ }
+
+ protected void tearDown() throws Exception {
+ BaseHelpSystem.setMode(mode);
+ }
+
+ public void testIndexServletEn() throws Exception {
+ getTreeData("en");
+ }
+
+ public void testIndexServletDe() throws Exception {
+ getTreeData("de");
+ }
+
+ private void getTreeData(String locale)
+ throws Exception {
+ int port = WebappManager.getPort();
+ URL url = new URL("http", "localhost", port, "/help/vs/service/indexfragment?lang=" + locale);
+ InputStream is = url.openStream();
+ InputSource inputSource = new InputSource(is);
+ DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ documentBuilder.setEntityResolver(new LocalEntityResolver());
+ Document document = documentBuilder.parse(inputSource);
+ Node root = document.getFirstChild();
+ is.close();
+ assertEquals("tree_data", root.getNodeName());
+ }
+
+ public void testIndexFragmentServiceXMLSchema()
+ throws Exception {
+ int port = WebappManager.getPort();
+ URL url = new URL("http", "localhost", port, "/help/vs/service/indexfragment?lang=en");
+ URL schemaUrl = new URL("http", "localhost", port, "/help/test/schema/xml/indexfragment.xsd");
+ String schema = schemaUrl.toString();
+ String uri = url.toString();
+ String result = SchemaValidator.testXMLSchema(uri, schema);
+
+ assertEquals("URL: \"" + uri + "\" is ", "valid", result);
+ }
+
+ public void testIndexFragmentServiceJSONSchema()
+ throws Exception {
+// fail("Not yet implemented.");
+ }
+
+}
diff --git a/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/IndexServiceTest.java b/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/IndexServiceTest.java
new file mode 100644
index 000000000..29589fee6
--- /dev/null
+++ b/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/IndexServiceTest.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ua.tests.help.webapp.service;
+
+import java.io.InputStream;
+import java.net.URL;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.eclipse.help.internal.entityresolver.LocalEntityResolver;
+import org.eclipse.help.internal.server.WebappManager;
+import org.eclipse.ua.tests.help.remote.IndexServletTest;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.xml.sax.InputSource;
+
+public class IndexServiceTest extends IndexServletTest {
+
+ protected Node getIndexContributions( String locale)
+ throws Exception {
+ int port = WebappManager.getPort();
+ URL url = new URL("http", "localhost", port, "/help/vs/service/index?lang=" + locale);
+ InputStream is = url.openStream();
+ InputSource inputSource = new InputSource(is);
+ DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ documentBuilder.setEntityResolver(new LocalEntityResolver());
+ Document document = documentBuilder.parse(inputSource);
+ Node root = document.getFirstChild();
+ is.close();
+ assertEquals("indexContributions", root.getNodeName());
+ return root;
+ }
+
+ public void testIndexServiceXMLSchema()
+ throws Exception {
+ int port = WebappManager.getPort();
+ URL url = new URL("http", "localhost", port, "/help/vs/service/index?lang=en");
+ URL schemaUrl = new URL("http", "localhost", port, "/help/test/schema/xml/index.xsd");
+ String schema = schemaUrl.toString();
+ String uri = url.toString();
+ String result = SchemaValidator.testXMLSchema(uri, schema);
+
+ assertEquals("URL: \"" + uri + "\" is ", "valid", result);
+ }
+
+ public void testIndexServiceJSONSchema()
+ throws Exception {
+// fail("Not yet implemented.");
+ }
+
+}
diff --git a/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/SchemaValidator.java b/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/SchemaValidator.java
new file mode 100644
index 000000000..e220db3ed
--- /dev/null
+++ b/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/SchemaValidator.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ua.tests.help.webapp.service;
+
+import java.io.File;
+import java.net.URL;
+
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import javax.xml.validation.Validator;
+
+import org.xml.sax.SAXException;
+
+public class SchemaValidator {
+
+ public static String testXMLSchema(String uri, String schemaFile) {
+ String msg = ""; //$NON-NLS-1$
+ try {
+ SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema"); //$NON-NLS-1$
+ Schema schema = null;
+ if (schemaFile.startsWith("http") || schemaFile.startsWith("ftp"))
+ schema = factory.newSchema(new URL(schemaFile));
+ else
+ schema = factory.newSchema(new File(schemaFile));
+
+ Validator validator = schema.newValidator();
+ Source source = new StreamSource(uri);
+ try {
+ validator.validate(source);
+ msg = "valid"; //$NON-NLS-1$
+ } catch (SAXException ex) {
+ msg = "not valid. Details: " + ex.getMessage(); //$NON-NLS-1$
+ }
+ } catch(Exception e) {
+ msg = "Exception e: " + e; //$NON-NLS-1$
+ }
+
+ return msg;
+ }
+
+ public static String testJSONSchema(String uri, String schemaFile) {
+ // TODO: Not yet implemented
+ return ""; //$NON-NLS-1$
+ }
+}
diff --git a/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/SearchServiceTest.java b/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/SearchServiceTest.java
new file mode 100644
index 000000000..8965169a5
--- /dev/null
+++ b/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/SearchServiceTest.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ua.tests.help.webapp.service;
+
+
+import java.net.URL;
+import java.net.URLEncoder;
+
+import org.eclipse.help.internal.server.WebappManager;
+import org.eclipse.ua.tests.help.remote.SearchServletTest;
+import org.w3c.dom.Node;
+
+public class SearchServiceTest extends SearchServletTest {
+
+ protected Node[] getSearchHitsFromServlet(String phrase)
+ throws Exception {
+ int port = WebappManager.getPort();
+ URL url = new URL("http", "localhost", port, "/help/vs/service/search?phrase=" + URLEncoder.encode(phrase, "UTF-8"));
+ return makeServletCall(url);
+ }
+
+ protected Node[] getSearchHitsUsingLocale(String phrase, String locale)
+ throws Exception {
+ int port = WebappManager.getPort();
+ URL url = new URL("http", "localhost", port, "/help/vs/service/search?phrase="
+ + URLEncoder.encode(phrase, "UTF-8") + "&lang=" + locale);
+ return makeServletCall(url);
+ }
+
+ public void testRemoteSearchXMLSchema()
+ throws Exception {
+ int port = WebappManager.getPort();
+ URL url = new URL("http", "localhost", port,
+ "/help/vs/service/search?phrase=" + URLEncoder.encode("jehcyqpfjs vkrhjewiwh", "UTF-8"));
+ URL schemaUrl = new URL("http", "localhost", port, "/help/test/schema/xml/search.xsd");
+ String schema = schemaUrl.toString();
+ String uri = url.toString();
+ String result = SchemaValidator.testXMLSchema(uri, schema);
+
+ assertEquals("URL: \"" + uri + "\" is ", "valid", result);
+ }
+
+ public void testRemoteSearchXMLSchemaExactMatchFound()
+ throws Exception {
+ int port = WebappManager.getPort();
+ URL url = new URL("http", "localhost", port,
+ "/help/vs/service/search?phrase=" + URLEncoder.encode("\"jehcyqpfjs vkrhjewiwh\"", "UTF-8"));
+ URL schemaUrl = new URL("http", "localhost", port, "/help/test/schema/xml/search.xsd");
+ String schema = schemaUrl.toString();
+ String uri = url.toString();
+ String result = SchemaValidator.testXMLSchema(uri, schema);
+
+ assertEquals("URL: \"" + uri + "\" is ", "valid", result);
+ }
+
+ public void testRemoteSearchJSONSchema()
+ throws Exception {
+// fail("Not yet implemented.");
+ }
+
+}
diff --git a/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/ServicesTestUtils.java b/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/ServicesTestUtils.java
new file mode 100644
index 000000000..096de8159
--- /dev/null
+++ b/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/ServicesTestUtils.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ua.tests.help.webapp.service;
+
+import java.io.IOException;
+import java.net.URL;
+
+import org.eclipse.help.internal.server.WebappManager;
+import org.eclipse.help.internal.webapp.utils.Utils;
+import org.eclipse.ua.tests.help.remote.RemoteTestUtils;
+
+public class ServicesTestUtils extends RemoteTestUtils {
+
+ public static String getRemoteContent(String plugin, String path,
+ String locale) throws Exception {
+ int port = WebappManager.getPort();
+ URL url = new URL("http", "localhost", port, "/help/vs/service/rtopic/" + plugin
+ + path + "?lang=" + locale);
+ return readFromURL(url);
+ }
+
+ public static String getLocalContent(String plugin, String path)
+ throws IOException {
+ String localContent = RemoteTestUtils.getLocalContent(plugin, path);
+ try {
+ localContent = Utils.updateResponse(localContent);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return localContent;
+ }
+
+}
diff --git a/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/TocFragmentServiceTest.java b/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/TocFragmentServiceTest.java
new file mode 100644
index 000000000..3b65d9fab
--- /dev/null
+++ b/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/TocFragmentServiceTest.java
@@ -0,0 +1,169 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ua.tests.help.webapp.service;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import junit.framework.TestCase;
+
+import org.eclipse.help.internal.base.BaseHelpSystem;
+import org.eclipse.help.internal.entityresolver.LocalEntityResolver;
+import org.eclipse.help.internal.server.WebappManager;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+
+public class TocFragmentServiceTest extends TestCase {
+
+ private int mode;
+
+ protected void setUp() throws Exception {
+ BaseHelpSystem.ensureWebappRunning();
+ mode = BaseHelpSystem.getMode();
+ BaseHelpSystem.setMode(BaseHelpSystem.MODE_INFOCENTER);
+ }
+
+ protected void tearDown() throws Exception {
+ BaseHelpSystem.setMode(mode);
+ }
+
+ public void testTocFragmentServiceContainsUAToc() throws Exception {
+ int port = WebappManager.getPort();
+ URL url = new URL("http", "localhost", port,
+ "/help/vs/service/tocfragment?lang=en");
+ Node root = getTreeData(url);
+ Element[] UARoot = findNodeById(root,
+ "/org.eclipse.ua.tests/data/help/toc/root.xml");
+ assertEquals(1, UARoot.length);
+ }
+
+ public void testTocFragmentServiceContainsFilteredToc() throws Exception {
+ int port = WebappManager.getPort();
+ URL url = new URL("http", "localhost", port,
+ "/help/vs/service/tocfragment?lang=en&toc=/org.eclipse.ua.tests/data/help/toc/root.xml&path=2");
+ Node root = getTreeData(url);
+ Element[] UARoot = findNodeById(root,
+ "/org.eclipse.ua.tests/data/help/toc/root.xml");
+ assertEquals(1, UARoot.length);
+ Element[] filterNode = findNodeById(UARoot[0], "2");
+ assertEquals(1, filterNode.length);
+ Element[] results = findChildren(filterNode[0], "node", "href",
+ "../topic/org.eclipse.ua.tests/data/help/toc/filteredToc/simple_page.html");
+ assertEquals(24, results.length);
+
+ results = findChildren(filterNode[0], "node", "href",
+ "../topic/org.eclipse.ua.tests/data/help/toc/filteredToc/helpInstalled.html");
+ assertEquals(1, results.length);
+ }
+
+ /*
+ * These tests are still failing - see Bug 338732
+ *
+ *
+ public void testReadEnToc() throws Exception {
+ int port = WebappManager.getPort();
+ URL url = new URL("http", "localhost", port,
+ "/help/vs/service/tocfragment?lang=en&toc=/org.eclipse.ua.tests/data/help/toc/root.xml&path=7");
+ Node root = getTreeData(url);
+ Element[] UARoot = findNodeById(root,
+ "/org.eclipse.ua.tests/data/help/toc/root.xml");
+ assertEquals(1, UARoot.length);
+ Element[] searchNode = findNodeById(UARoot[0], "7");
+ assertEquals(1, searchNode.length);
+ Element[] topicEn = findChildren(searchNode[0], "node", "href",
+ "../topic/org.eclipse.ua.tests/data/help/search/test_en.html");
+ assertEquals(1, topicEn.length);
+ Element[] topicDe = findChildren(searchNode[0], "node", "href",
+ "../topic/org.eclipse.ua.tests/data/help/search/test_de.html");
+ assertEquals(0, topicDe.length);
+ }
+
+ public void testReadDeToc() throws Exception {
+ int port = WebappManager.getPort();
+ URL url = new URL("http", "localhost", port,
+ "/help/vs/service/tocfragment?lang=de&toc=/org.eclipse.ua.tests/data/help/toc/root.xml&path=7");
+ Node root = getTreeData(url);
+ Element[] UARoot = findNodeById(root,
+ "/org.eclipse.ua.tests/data/help/toc/root.xml");
+ assertEquals(1, UARoot.length);
+ Element[] searchNode = findNodeById(UARoot[0], "7");
+ Element[] topicEn = findChildren(searchNode[0], "node", "href",
+ "../topic/org.eclipse.ua.tests/data/help/search/test_en.html");
+ assertEquals(0, topicEn.length);
+ Element[] topicDe = findChildren(searchNode[0], "node", "href",
+ "../topic/org.eclipse.ua.tests/data/help/search/test_de.html");
+ assertEquals(1, topicDe.length);
+ }
+
+ */
+
+ private Element[] findNodeById(Node root, String id) {
+ return findChildren(root, "node", "id", id);
+ }
+
+ private Element[] findChildren(Node parent, String childKind,
+ String attributeName, String attributeValue) {
+ NodeList nodes = parent.getChildNodes();
+ List<Node> results = new ArrayList<Node>();
+ for (int i = 0; i < nodes.getLength(); i++) {
+ Node next = nodes.item(i);
+ if (next instanceof Element) {
+ Element nextElement = (Element)next;
+ if ( childKind.equals(nextElement.getTagName())
+ && attributeValue.equals(nextElement.getAttribute(attributeName))) {
+
+ results.add(next);
+ }
+ }
+ }
+ return (Element[]) results.toArray(new Element[results.size()]);
+ }
+
+
+ private Node getTreeData(URL url)
+ throws Exception {
+ InputStream is = url.openStream();
+ InputSource inputSource = new InputSource(is);
+ DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ documentBuilder.setEntityResolver(new LocalEntityResolver());
+ Document document = documentBuilder.parse(inputSource);
+ Node root = document.getFirstChild();
+ is.close();
+ assertEquals("tree_data", root.getNodeName());
+ return root;
+ }
+
+ public void testTocFragmentServiceXMLSchema()
+ throws Exception {
+ int port = WebappManager.getPort();
+ URL url = new URL("http", "localhost", port, "/help/vs/service/tocfragment?lang=en");
+ URL schemaUrl = new URL("http", "localhost", port, "/help/test/schema/xml/tocfragment.xsd");
+ String schema = schemaUrl.toString();
+ String uri = url.toString();
+ String result = SchemaValidator.testXMLSchema(uri, schema);
+
+ assertEquals("URL: \"" + uri + "\" is ", "valid", result);
+ }
+
+ public void testTocFragmentServiceJSONSchema()
+ throws Exception {
+// fail("Not yet implemented.");
+ }
+
+}
diff --git a/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/TocServiceTest.java b/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/TocServiceTest.java
new file mode 100644
index 000000000..b49feffa0
--- /dev/null
+++ b/org.eclipse.ua.tests/help/org/eclipse/ua/tests/help/webapp/service/TocServiceTest.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ua.tests.help.webapp.service;
+
+import java.io.InputStream;
+import java.net.URL;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.eclipse.help.internal.entityresolver.LocalEntityResolver;
+import org.eclipse.help.internal.server.WebappManager;
+import org.eclipse.ua.tests.help.remote.TocServletTest;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.xml.sax.InputSource;
+
+public class TocServiceTest extends TocServletTest {
+
+ protected Node getTocContributions( String locale)
+ throws Exception {
+ int port = WebappManager.getPort();
+ URL url = new URL("http", "localhost", port, "/help/vs/service/toc?lang=" + locale);
+ InputStream is = url.openStream();
+ InputSource inputSource = new InputSource(is);
+ DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ documentBuilder.setEntityResolver(new LocalEntityResolver());
+ Document document = documentBuilder.parse(inputSource);
+ Node root = document.getFirstChild();
+ is.close();
+ assertEquals("tocContributions", root.getNodeName());
+ return root;
+ }
+
+ public void testTocServiceXMLSchema()
+ throws Exception {
+ int port = WebappManager.getPort();
+ URL url = new URL("http", "localhost", port, "/help/vs/service/toc?lang=en");
+ URL schemaUrl = new URL("http", "localhost", port, "/help/test/schema/xml/toc.xsd");
+ String schema = schemaUrl.toString();
+ String uri = url.toString();
+ String result = SchemaValidator.testXMLSchema(uri, schema);
+
+ assertEquals("URL: \"" + uri + "\" is ", "valid", result);
+ }
+
+ public void testTocServiceJSONSchema()
+ throws Exception {
+ /*int port = WebappManager.getPort();
+ URL url = new URL("http", "localhost", port, "/help/vs/service/toc?lang=en");
+ URL schemaUrl = new URL("http", "localhost", port, "/help/test/schema/json/toc.json");
+ String schema = schemaUrl.toString();
+ String uri = url.toString();
+ String result = SchemaValidator.testJSONSchema(uri, schema);
+
+ assertEquals("URL: \"" + uri + "\" is ", "valid", result);*/
+// fail("Not yet implemented.");
+ }
+
+}
diff --git a/org.eclipse.ua.tests/plugin.xml b/org.eclipse.ua.tests/plugin.xml
index 3579ac3fb..a12493d48 100644
--- a/org.eclipse.ua.tests/plugin.xml
+++ b/org.eclipse.ua.tests/plugin.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.0"?> <!--
- Copyright (c) 2005, 2010 IBM Corporation and others.
+ Copyright (c) 2005, 2011 IBM Corporation and others.
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
which accompanies this distribution, and is available at
@@ -546,6 +546,10 @@
alias="/titlesearch/script"
base-name="/script">
</resource>
+ <resource
+ alias="/test"
+ base-name="/service">
+ </resource>
<serviceSelector
filter="(other.info=org.eclipse.help)">
</serviceSelector>
diff --git a/org.eclipse.ua.tests/service/schema/xml/advancedsearch.xsd b/org.eclipse.ua.tests/service/schema/xml/advancedsearch.xsd
new file mode 100644
index 000000000..f1057b8a6
--- /dev/null
+++ b/org.eclipse.ua.tests/service/schema/xml/advancedsearch.xsd
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ elementFormDefault="qualified">
+ <xs:element name="searchHits">
+ <xs:complexType mixed="false">
+ <xs:sequence>
+ <xs:element ref="hit" minOccurs="0" maxOccurs="unbounded" /> <!-- hits result could be zero -->
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="hit" abstract="false" nillable="false">
+ <xs:complexType mixed="false">
+ <xs:sequence>
+ <xs:element name="category" minOccurs="1" maxOccurs="1"> <!-- at least and at most one category element -->
+ <xs:complexType>
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="href" type="xs:string" use="required" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="summary" type="xs:string" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ <xs:attribute name="href" type="xs:string" use="required" /> <!-- attribute for hit -->
+ <xs:attribute name="label" type="xs:string" use="required" /> <!-- attribute for hit -->
+ <xs:attribute name="isPotentialHit" type="xs:boolean" /> <!-- optional attribute for hit -->
+ <xs:attribute name="score" type="xs:double" use="required" /> <!-- attribute for hit -->
+ </xs:complexType>
+ </xs:element>
+
+</xs:schema>
diff --git a/org.eclipse.ua.tests/service/schema/xml/context.xsd b/org.eclipse.ua.tests/service/schema/xml/context.xsd
new file mode 100644
index 000000000..7c0dbce43
--- /dev/null
+++ b/org.eclipse.ua.tests/service/schema/xml/context.xsd
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ elementFormDefault="qualified">
+
+ <xs:element name="context">
+ <xs:complexType mixed="false">
+ <xs:sequence>
+ <xs:element name="description" type="xs:string" minOccurs="1" maxOccurs="1" /> <!-- at least and at most one description element -->
+ <xs:element ref="topic" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:attribute name="title" type="xs:string" /> <!-- optional attribute for context -->
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="topic">
+ <xs:complexType mixed="true">
+ <xs:attribute name="label" type="xs:string" /> <!-- optional attribute for topic -->
+ <xs:attribute name="href" type="xs:string" /> <!-- optional attribute for topic -->
+ </xs:complexType>
+ </xs:element>
+</xs:schema> \ No newline at end of file
diff --git a/org.eclipse.ua.tests/service/schema/xml/extension.xsd b/org.eclipse.ua.tests/service/schema/xml/extension.xsd
new file mode 100644
index 000000000..b4c5ac819
--- /dev/null
+++ b/org.eclipse.ua.tests/service/schema/xml/extension.xsd
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ elementFormDefault="qualified">
+
+ <xs:element name="contentExtensions">
+ <xs:complexType mixed="false">
+ <xs:sequence>
+ <xs:element ref="contribution" minOccurs="0"
+ maxOccurs="unbounded" />
+ <xs:element ref="replacement" minOccurs="0"
+ maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="contribution">
+ <xs:complexType mixed="true">
+ <xs:attribute name="content" type="xs:string"/> <!-- optional attribute for contribution -->
+ <xs:attribute name="path" type="xs:string"/> <!-- optional attribute for contribution -->
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="replacement">
+ <xs:complexType mixed="true">
+ <xs:attribute name="content" type="xs:string"/> <!-- optional attribute for replacement -->
+ <xs:attribute name="path" type="xs:string"/> <!-- optional attribute for replacement -->
+ </xs:complexType>
+ </xs:element>
+
+</xs:schema>
diff --git a/org.eclipse.ua.tests/service/schema/xml/index.xsd b/org.eclipse.ua.tests/service/schema/xml/index.xsd
new file mode 100644
index 000000000..8fc5c93bc
--- /dev/null
+++ b/org.eclipse.ua.tests/service/schema/xml/index.xsd
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ elementFormDefault="qualified">
+
+<xs:element name="indexContributions">
+ <xs:complexType mixed="false">
+ <xs:sequence>
+ <xs:element ref="indexContribution" minOccurs="0"
+ maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+
+ <xs:element name="indexContribution">
+ <xs:complexType mixed="false">
+ <xs:sequence>
+ <xs:element ref="index" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ <xs:attribute name="id" type="xs:string" use="required"/> <!-- attribute for indexContribution -->
+ <xs:attribute name="locale" type="xs:string" use="required"/> <!-- attribute for indexContribution -->
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="index">
+ <xs:complexType mixed="false">
+ <xs:sequence>
+ <xs:element ref="entry" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:attribute name="version" type="xs:string"/> <!-- optional attribute for index -->
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="entry">
+ <xs:complexType mixed="false">
+ <xs:sequence>
+ <xs:element ref="topic" minOccurs="0" maxOccurs="unbounded" /> <!-- optional attribute for entry -->
+ <xs:element ref="entry" minOccurs="0" maxOccurs="unbounded" /> <!-- optional attribute for entry -->
+ <xs:element ref="see" minOccurs="0" maxOccurs="unbounded" /> <!-- optional attribute for entry -->
+ </xs:sequence>
+ <xs:attribute name="keyword" type="xs:string" use="required"/> <!-- attribute for entry -->
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="topic">
+ <xs:complexType mixed="false">
+ <xs:attribute name="href" type="xs:string" /> <!-- optional attribute for topic -->
+ <xs:attribute name="title" type="xs:string" /> <!-- optional attribute for topic -->
+ <xs:attribute name="label" type="xs:string" /> <!-- optional attribute for topic -->
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="see">
+ <xs:complexType mixed="false">
+ <xs:sequence>
+ <xs:element ref="subpath" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:attribute name="keyword" type="xs:string" use="required"/> <!-- attribute for see -->
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="subpath">
+ <xs:complexType mixed="false">
+ <xs:attribute name="keyword" type="xs:string" use="required"/> <!-- attribute for subpath -->
+ </xs:complexType>
+ </xs:element>
+</xs:schema> \ No newline at end of file
diff --git a/org.eclipse.ua.tests/service/schema/xml/indexfragment.xsd b/org.eclipse.ua.tests/service/schema/xml/indexfragment.xsd
new file mode 100644
index 000000000..1f9b005f3
--- /dev/null
+++ b/org.eclipse.ua.tests/service/schema/xml/indexfragment.xsd
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ elementFormDefault="qualified">
+ <xs:element name="tree_data">
+ <xs:complexType mixed="false">
+ <xs:sequence>
+ <xs:element ref="node" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:attribute name="enableNext" type="xs:boolean" use="required" /> <!-- attribute for tree_data -->
+ <xs:attribute name="enablePrevious" type="xs:boolean" use="required" /> <!-- attribute for tree_data -->
+
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="node" abstract="false" nillable="false">
+ <xs:complexType mixed="false">
+ <xs:sequence>
+ <xs:element ref="node" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+
+ <xs:attribute name="title" type="xs:string" /> <!-- optional attribute for node -->
+ <xs:attribute name="id" type="xs:ID" use="required" /> <!-- attribute for node -->
+ <xs:attribute name="href" type="xs:string"/> <!-- optional attribute for node -->
+ </xs:complexType>
+ </xs:element>
+
+</xs:schema> \ No newline at end of file
diff --git a/org.eclipse.ua.tests/service/schema/xml/search.xsd b/org.eclipse.ua.tests/service/schema/xml/search.xsd
new file mode 100644
index 000000000..b71105144
--- /dev/null
+++ b/org.eclipse.ua.tests/service/schema/xml/search.xsd
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ elementFormDefault="qualified">
+ <xs:element name="searchHits">
+ <xs:complexType mixed="false">
+ <xs:sequence>
+ <xs:element ref="hit" minOccurs="0" maxOccurs="unbounded" /> <!-- hits result could be zero -->
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="hit" abstract="false" nillable="false">
+ <xs:complexType mixed="false">
+ <xs:sequence>
+ <xs:element name="summary" type="xs:string" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ <xs:attribute name="href" type="xs:string" use="required" /> <!-- attribute for hit -->
+ <xs:attribute name="label" type="xs:string" use="required" /> <!-- attribute for hit -->
+ <xs:attribute name="isPotentialHit" type="xs:boolean" /> <!-- optional attribute for hit -->
+ <xs:attribute name="score" type="xs:double" use="required" /> <!-- attribute for hit -->
+ </xs:complexType>
+ </xs:element>
+
+</xs:schema>
diff --git a/org.eclipse.ua.tests/service/schema/xml/toc.xsd b/org.eclipse.ua.tests/service/schema/xml/toc.xsd
new file mode 100644
index 000000000..873d51c50
--- /dev/null
+++ b/org.eclipse.ua.tests/service/schema/xml/toc.xsd
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ elementFormDefault="qualified">
+
+ <xs:element name="tocContributions">
+ <xs:complexType mixed="true">
+ <xs:sequence>
+ <xs:element ref="tocContribution" minOccurs="0"
+ maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="tocContribution " abstract="false"
+ nillable="false">
+ <xs:complexType mixed="true">
+ <xs:sequence>
+ <xs:element ref="toc" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element ref="extraDocument" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:attribute name="categoryId" type="xs:string" /> <!-- optional attribute for tree_data -->
+ <xs:attribute name="contributorId" type="xs:string" /> <!-- optional attribute for tree_data -->
+ <xs:attribute name="id" type="xs:string" use="required" /> <!-- attribute for tree_data -->
+ <xs:attribute name="locale" type="xs:string" use="required" /> <!-- attribute for tree_data -->
+ <xs:attribute name="isPrimary" type="xs:boolean" use="required" /> <!-- attribute for tree_data -->
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="toc" abstract="false">
+ <xs:complexType mixed="true">
+ <xs:sequence>
+
+
+ <xs:any namespace="##any" minOccurs="0" maxOccurs="unbounded" />
+
+ </xs:sequence>
+ <xs:attribute name="href" type="xs:string" /> <!-- optional attribute for node -->
+ <xs:attribute name="label" type="xs:string" use="required" /> <!-- optional attribute for node -->
+ <xs:attribute name="link_to" type="xs:string" /> <!-- attribute for node -->
+ <xs:attribute name="topic" type="xs:string" /> <!-- optional attribute for node -->
+ <xs:attribute name="unknownAttribute" type="xs:string" /> <!-- optional attribute for node -->
+ <xs:attribute name="sort" type="xs:string" /> <!-- optional attribute for node -->
+ </xs:complexType>
+
+ </xs:element>
+
+ <xs:element name="extraDocument" abstract="false" nillable="false">
+ <xs:complexType mixed="true">
+ <xs:attribute name="href" type="xs:string"/>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="topic" abstract="false" nillable="false">
+ <xs:complexType mixed="true">
+ <xs:sequence>
+ <xs:any namespace="##any" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+
+ <xs:attribute name="label" type="xs:string" /> <!-- optional attribute for node -->
+ <xs:attribute name="href" type="xs:string" /> <!-- optional attribute for node -->
+ <xs:attribute name="unknownAttribute2" type="xs:string" /> <!-- optional attribute for node -->
+ <xs:attribute name="aegraerg" type="xs:string" /> <!-- optional attribute for node -->
+ <xs:attribute name="filter" type="xs:string" /> <!-- optional attribute for node -->
+ <xs:attribute name="sort" type="xs:string" /> <!-- optional attribute for node -->
+ <xs:attribute name="icon" type="xs:string" /> <!-- optional attribute for node -->
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="anchor" abstract="false" nillable="false">
+ <xs:complexType mixed="true">
+ <xs:attribute name="id" type="xs:string" /> <!-- optional attribute for node -->
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="link" abstract="false" nillable="false">
+ <xs:complexType mixed="true">
+ <xs:attribute name="toc" type="xs:string" /> <!-- optional attribute for node -->
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="enablement" abstract="false" nillable="false">
+ <xs:complexType mixed="true">
+ <xs:sequence>
+ <xs:element ref="with" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element ref="test" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element ref="systemTest" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="test" abstract="false" nillable="false">
+ <xs:complexType mixed="true">
+
+ <xs:sequence>
+ <xs:any namespace="##any" minOccurs="0" maxOccurs="unbounded" /> <!-- accept any data -->
+ </xs:sequence>
+
+ <xs:attribute name="args" type="xs:string" /> <!-- optional attribute for node -->
+ <xs:attribute name="property" type="xs:string" /> <!-- attribute for node -->
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="with" abstract="false" nillable="false">
+ <xs:complexType mixed="true">
+ <xs:sequence>
+ <xs:element ref="test" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:attribute name="variable" type="xs:string" /> <!-- optional attribute for node -->
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="systemTest" abstract="false" nillable="false">
+ <xs:complexType mixed="true">
+ <xs:attribute name="property" type="xs:string" /> <!-- optional attribute for node -->
+ <xs:attribute name="value" type="xs:string" /> <!-- attribute for node -->
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="criteria" abstract="false" nillable="false">
+ <xs:complexType mixed="true">
+ <xs:attribute name="name" type="xs:string" /> <!-- optional attribute for node -->
+ <xs:attribute name="value" type="xs:string" /> <!-- attribute for node -->
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="blah" abstract="false" nillable="false">
+ <xs:complexType mixed="true">
+ <xs:attribute name="value" type="xs:string" /> <!-- attribute for node -->
+ </xs:complexType>
+ </xs:element>
+
+
+ <xs:element name="test2" abstract="false" nillable="false">
+ <xs:complexType mixed="true">
+ <xs:sequence>
+ <xs:any namespace="##any" minOccurs="0" maxOccurs="unbounded" /> <!-- accept any data -->
+ </xs:sequence>
+ <xs:attribute name="attr" type="xs:string" /> <!-- optional attribute for node -->
+
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="aergaer" abstract="false" nillable="false">
+ <xs:complexType mixed="true">
+ <xs:sequence>
+ <xs:any namespace="##any" minOccurs="0" maxOccurs="unbounded" /> <!-- accept any data -->
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="gaergr" abstract="false" nillable="false">
+ <xs:complexType mixed="true">
+ <xs:sequence>
+ <xs:any namespace="##any" minOccurs="0" maxOccurs="unbounded" /> <!-- accept any data -->
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="filter" abstract="false" nillable="false">
+ <xs:complexType mixed="true">
+ <xs:sequence>
+ <xs:any namespace="##any" minOccurs="0" maxOccurs="unbounded" /> <!-- accept any data -->
+ </xs:sequence>
+ <xs:attribute name="name" type="xs:string" /> <!-- optional attribute for node -->
+ <xs:attribute name="value" type="xs:string" /> <!-- optional attribute for node -->
+ </xs:complexType>
+ </xs:element>
+</xs:schema> \ No newline at end of file
diff --git a/org.eclipse.ua.tests/service/schema/xml/tocfragment.xsd b/org.eclipse.ua.tests/service/schema/xml/tocfragment.xsd
new file mode 100644
index 000000000..da26d33b6
--- /dev/null
+++ b/org.eclipse.ua.tests/service/schema/xml/tocfragment.xsd
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ elementFormDefault="qualified">
+ <xs:element name="tree_data">
+ <xs:complexType mixed="false">
+ <xs:sequence>
+ <xs:element name="error" minOccurs="0" />
+ <xs:element ref="numeric_path" minOccurs="0" maxOccurs="1" />
+ <xs:element name="node" minOccurs="0" maxOccurs="unbounded">
+ <!--
+ toc node, only difference b/w toc and topic level node is of
+ is_leaf attrb and order of attrb
+ -->
+ <xs:complexType mixed="false">
+ <xs:sequence>
+ <xs:element name="node" type="TopicNode" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:attribute name="title" type="xs:string" /> <!-- optional attribute for node -->
+ <xs:attribute name="id" type="xs:string" use="required" /> <!-- attribute for node -->
+ <xs:attribute name="href" type="xs:string" use="required" /> <!-- attribute for node -->
+ <xs:attribute name="openImage" type="xs:string" /> <!-- optional attribute for node -->
+ <xs:attribute name="closedImage" type="xs:string" /> <!-- optional attribute for node -->
+ <xs:attribute name="imageAlt" type="xs:string" /> <!-- optional attribute for node -->
+ <xs:attribute name="image" type="xs:string" default="toc_closed" /> <!-- optional attribute for node -->
+ <xs:attribute name="is_selected" type="xs:boolean"
+ default="true" /> <!-- attribute for node -->
+ <xs:attribute name="is_highlighted" type="xs:boolean"
+ default="true" /> <!-- attribute for node -->
+
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="numeric_path">
+ <xs:complexType>
+ <xs:attribute name="path" type="xs:string" />
+ </xs:complexType>
+ </xs:element>
+
+
+ <xs:complexType name="TopicNode" mixed="false">
+ <xs:sequence>
+ <xs:element name="node" type="TopicNode" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+
+ <xs:attribute name="title" type="xs:string" /> <!-- optional attribute for node -->
+ <xs:attribute name="id" type="xs:string" use="required" /> <!-- attribute for node -->
+ <xs:attribute name="href" type="xs:string" use="required" /> <!-- attribute for node -->
+ <xs:attribute name="is_leaf" type="xs:boolean" default="true" /> <!-- attribute for node -->
+ <xs:attribute name="is_selected" type="xs:boolean"
+ default="true" /> <!-- attribute for node -->
+ <xs:attribute name="is_highlighted" type="xs:boolean"
+ default="true" /> <!-- attribute for node -->
+ <xs:attribute name="openImage" type="xs:string" /> <!-- optional attribute for node -->
+ <xs:attribute name="closedImage" type="xs:string" /> <!-- optional attribute for node -->
+ <xs:attribute name="imageAlt" type="xs:string" /> <!-- optional attribute for node -->
+ <xs:attribute name="image" type="xs:string" default="toc_closed" /> <!-- optional attribute for node -->
+
+ </xs:complexType>
+
+
+</xs:schema> \ No newline at end of file

Back to the top