diff options
author | Chris Austin | 2011-03-02 21:06:00 +0000 |
---|---|---|
committer | Chris Austin | 2011-03-02 21:06:00 +0000 |
commit | f80d928f29a67bfad5d8779e0d916627e5c035d7 (patch) | |
tree | 3eae5c4a5e0e05a8062c9bdaeffca2bad7056034 /org.eclipse.help.webapp/src/org | |
parent | 6954a216bfa05fb8ce639426c60a2c5d211e1512 (diff) | |
download | eclipse.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
Diffstat (limited to 'org.eclipse.help.webapp/src/org')
38 files changed, 2767 insertions, 85 deletions
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$ +} |