Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'org.eclipse.help/Eclipse Help/org/eclipse/help/internal/server/HighlightProcessor.java')
-rw-r--r--org.eclipse.help/Eclipse Help/org/eclipse/help/internal/server/HighlightProcessor.java239
1 files changed, 239 insertions, 0 deletions
diff --git a/org.eclipse.help/Eclipse Help/org/eclipse/help/internal/server/HighlightProcessor.java b/org.eclipse.help/Eclipse Help/org/eclipse/help/internal/server/HighlightProcessor.java
new file mode 100644
index 000000000..4ac528f1b
--- /dev/null
+++ b/org.eclipse.help/Eclipse Help/org/eclipse/help/internal/server/HighlightProcessor.java
@@ -0,0 +1,239 @@
+package org.eclipse.help.internal.server;
+
+/*
+ * Licensed Materials - Property of IBM,
+ * WebSphere Studio Workbench
+ * (c) Copyright IBM Corp 2000
+ */
+
+import java.util.*;
+import java.net.URLDecoder;
+import org.eclipse.help.internal.navigation.HelpNavigationManager;
+import org.eclipse.help.internal.HelpSystem;
+
+/**
+ * This class should perhaps be changed a bit, and so
+ * should the SearchURL. Factor out some search utility
+ * and have it return the correct processed stream.
+ */
+class HighlightProcessor implements OutputProcessor {
+ private HelpURL url;
+ private static final byte[] headTagBegin = "<head".getBytes();
+ private static final byte[] headTagBeginCaps = "<HEAD".getBytes();
+ private static final char headTagEnd = '>';
+ private static final String scriptPart1 =
+ "\n<script language=\"JavaScript\">\n<!--\nvar keywords = new Array (";
+ private static final String scriptPart3 =
+ ");\nonload=highlight;\nfunction highlight()\n{\nvar newText = document.body.createTextRange();\nfor (var i = 0; i < keywords.length; i++) {\nwhile (newText.findText(keywords[i]) )\n{\nvar replacement = newText.text\nnewText.pasteHTML(\"<span class=highlight style='background-color:lightgrey'>\" + replacement + \"</span>\");\n}\nnewText = document.body.createTextRange();\n}\n}\n// -->\n</script>\n";
+
+ //private int docNumber;
+ private String query;
+
+ /**
+ * HighlightProcessor constructor.
+ */
+ public HighlightProcessor() {
+ super();
+ }
+ public HighlightProcessor(HelpURL url) {
+ this.url = url;
+ //docNumber = Integer.parseInt(url.getValue("hitOrder"));
+ query = url.getValue("resultof");
+ }
+ /**
+ * Crates Java Script that does hightlighting
+ */
+ private byte[] createJScript(Collection keywords) {
+ StringBuffer buf = new StringBuffer(scriptPart1);
+ Iterator it = keywords.iterator();
+ if (!it.hasNext())
+ return null;
+ String keyword = (String) it.next();
+ buf.append("\"").append(keyword).append("\"");
+ while (it.hasNext()) {
+ keyword = (String) it.next();
+ buf.append(", \"").append(keyword).append("\"");
+ }
+ buf.append(scriptPart3);
+ return buf.toString().getBytes();
+ }
+ /**
+ * Extract keywords from query in the GTR format
+ * @return Collection of String
+ */
+ private Collection getKeywords() {
+ Collection tokens = new ArrayList();
+ //Divide along quotation marks and brackets
+ StringTokenizer qTokenizer = new StringTokenizer(query.trim(), "\"()", true);
+ boolean withinQuotation = false;
+ String quotedString = "";
+ while (qTokenizer.hasMoreTokens()) {
+ String curToken = qTokenizer.nextToken();
+ if (curToken.equals("\"")) {
+ if (!withinQuotation) {
+ //beginning of quoted string
+ quotedString = "";
+ } else {
+ //end of quoted string
+ tokens.add(quotedString);
+ }
+ withinQuotation = !withinQuotation;
+ continue;
+ }
+ if (withinQuotation) {
+ quotedString += (curToken);
+ } else {
+ //divide not quoted strings along white space
+ StringTokenizer parser = new StringTokenizer(curToken.trim());
+ while (parser.hasMoreTokens()) {
+ tokens.add(parser.nextToken());
+ }
+ }
+
+ }
+
+ Collection keywords = new HashSet(); // to eliminate duplicate words
+ for (Iterator it = tokens.iterator(); it.hasNext();) {
+ String token = (String) it.next();
+ String tokenLowerCase = token.toLowerCase();
+ if (!tokenLowerCase.equals("\"")
+ && !tokenLowerCase.equals("(")
+ && !tokenLowerCase.equals(")")
+ && !tokenLowerCase.equals("and")
+ && !tokenLowerCase.equals("or")
+ && !tokenLowerCase.equals("not"))
+ keywords.add(token);
+ }
+ return keywords;
+
+ }
+ /**
+ * Encodes strings inside collection for embedding in HTML source
+ * @return Collection of String
+ */
+ private Collection JavaScriptEncode(Collection col) {
+ if (col == null)
+ return col;
+ Collection result = new ArrayList();
+ for (Iterator it = col.iterator(); it.hasNext();) {
+ String keyword = (String) it.next();
+
+ int l = keyword.length();
+ if (l < 1)
+ continue;
+ char[] keywordChars = new char[l];
+ keyword.getChars(0, l, keywordChars, 0);
+ StringBuffer jsEncoded = new StringBuffer();
+ for (int j = 0; j < keywordChars.length; j++) {
+ String charInHex = Integer.toString((int) keywordChars[j], 16).toUpperCase();
+ switch (charInHex.length()) {
+ case 1 :
+ jsEncoded.append("\\u000").append(charInHex);
+ break;
+ case 2 :
+ jsEncoded.append("\\u00").append(charInHex);
+ break;
+ case 3 :
+ jsEncoded.append("\\u0").append(charInHex);
+ break;
+ default :
+ jsEncoded.append("\\u").append(charInHex);
+ break;
+ }
+ }
+ result.add(jsEncoded.toString());
+
+ }
+ return result;
+ }
+ public byte[] processOutput(byte[] input) {
+ if (query == null)
+ return input;
+
+ Collection keywords = getKeywords();
+ keywords = removeWildCards(keywords);
+ keywords = JavaScriptEncode(keywords);
+ byte[] script = createJScript(keywords);
+ if (script == null)
+ return input;
+
+ // Create new buffer
+ byte[] buffer = new byte[input.length + script.length];
+ int bufPointer = 0;
+ int inputPointer = 0;
+ boolean foundHeadTagBegin = false;
+ boolean foundHeadTagEnd = false;
+ while (inputPointer < input.length) {
+ // copy character
+ buffer[bufPointer++] = input[inputPointer++];
+ // look for head tag copied
+ if (!foundHeadTagEnd
+ && !foundHeadTagBegin
+ && (bufPointer >= headTagBegin.length)) {
+ for (int i = 0; i < headTagBegin.length; i++) {
+ if ((buffer[bufPointer - headTagBegin.length + i] != headTagBegin[i])
+ && (buffer[bufPointer - headTagBegin.length + i] != headTagBeginCaps[i])) {
+ break;
+ }
+ if (i == headTagBegin.length - 1)
+ foundHeadTagBegin = true;
+ }
+ }
+ if (!foundHeadTagEnd && foundHeadTagBegin && buffer[bufPointer - 1] == '>') {
+ foundHeadTagEnd = true;
+ //embed Script
+ System.arraycopy(script, 0, buffer, bufPointer, script.length);
+ bufPointer += script.length;
+ // copy rest
+ System.arraycopy(
+ input,
+ inputPointer,
+ buffer,
+ bufPointer,
+ input.length - inputPointer);
+ return buffer;
+ }
+ }
+ return buffer;
+ }
+ /**
+ * Removes wildcard characters from keywords, by splitting keywords around wild cards
+ * @return Collection of String
+ */
+ private Collection removeWildCards(Collection col) {
+ if (col == null)
+ return col;
+
+ // Split keywords into parts: before "*" and after "*"
+ Collection resultPass1 = new ArrayList();
+ for (Iterator it = col.iterator(); it.hasNext();) {
+ String keyword = (String) it.next();
+ int index;
+ while((index=keyword.indexOf("*"))>=0){
+ if(index>0)
+ resultPass1.add(keyword.substring(0, index));
+ if(keyword.length()>index)
+ keyword=keyword.substring(index+1);
+ }
+ if(keyword.length()>0)
+ resultPass1.add(keyword);
+ }
+
+ // Split keywords into parts: before "?" and after "?"
+ Collection resultPass2 = new ArrayList();
+ for (Iterator it = resultPass1.iterator(); it.hasNext();) {
+ String keyword = (String) it.next();
+ int index;
+ while((index=keyword.indexOf("?"))>=0){
+ if(index>0)
+ resultPass2.add(keyword.substring(0, index));
+ if(keyword.length()>index)
+ keyword=keyword.substring(index+1);
+ }
+ if(keyword.length()>0)
+ resultPass2.add(keyword);
+ }
+
+ return resultPass2;
+ }
+}

Back to the top