diff options
author | mkersten | 2007-02-07 15:20:52 +0000 |
---|---|---|
committer | mkersten | 2007-02-07 15:20:52 +0000 |
commit | 789589a5bad518483726a01d385258e02c71b216 (patch) | |
tree | 817940be3d2b8a42d5c707538416985b7d377619 /org.eclipse.mylyn.tasks.core | |
parent | 84977abcd58285e36722c4b7dc62b2eedc5bb952 (diff) | |
download | org.eclipse.mylyn.tasks-789589a5bad518483726a01d385258e02c71b216.tar.gz org.eclipse.mylyn.tasks-789589a5bad518483726a01d385258e02c71b216.tar.xz org.eclipse.mylyn.tasks-789589a5bad518483726a01d385258e02c71b216.zip |
NEW - bug 170838: refactor org.eclipse.mylar.monitor for headless usage
https://bugs.eclipse.org/bugs/show_bug.cgi?id=170838
Diffstat (limited to 'org.eclipse.mylyn.tasks.core')
19 files changed, 40 insertions, 1976 deletions
diff --git a/org.eclipse.mylyn.tasks.core/META-INF/MANIFEST.MF b/org.eclipse.mylyn.tasks.core/META-INF/MANIFEST.MF index eaa644f91..82478be3f 100644 --- a/org.eclipse.mylyn.tasks.core/META-INF/MANIFEST.MF +++ b/org.eclipse.mylyn.tasks.core/META-INF/MANIFEST.MF @@ -2,13 +2,14 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Mylar Tasks Core Plug-in Bundle-SymbolicName: org.eclipse.mylar.tasks.core;singleton:=true -Bundle-Version: 1.0.1.v20070206-1500 +Bundle-Version: 1.0.1.v20070202-1900 Eclipse-AutoStart: true Bundle-Vendor: Eclipse.org Bundle-RequiredExecutionEnvironment: J2SE-1.5 Require-Bundle: org.eclipse.core.runtime, org.eclipse.mylar.context.core, - org.eclipse.update.core + org.eclipse.update.core, + org.eclipse.mylar.monitor.core, + org.eclipse.mylar Export-Package: org.eclipse.mylar.internal.tasks.core, - org.eclipse.mylar.tasks.core, - org.eclipse.mylar.tasks.core.web + org.eclipse.mylar.tasks.core diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/AuthenticatedProxy.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/AuthenticatedProxy.java deleted file mode 100644 index 5decbbd87..000000000 --- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/AuthenticatedProxy.java +++ /dev/null @@ -1,39 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2004 - 2006 University Of British Columbia 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: - * University Of British Columbia - initial API and implementation - *******************************************************************************/ - -package org.eclipse.mylar.internal.tasks.core; - -import java.net.Proxy; -import java.net.SocketAddress; - -/** - * @author Rob Elves - */ -public class AuthenticatedProxy extends Proxy { - - private String userName = ""; - private String password = ""; - - public AuthenticatedProxy(Type type, SocketAddress sa, String userName, String password) { - super(type, sa); - this.userName = userName; - this.password = password; - } - - public String getUserName() { - return userName; - } - - public String getPassword() { - return password; - } - -} diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/RepositoryTrustManager.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/RepositoryTrustManager.java deleted file mode 100644 index aca5d6e9f..000000000 --- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/RepositoryTrustManager.java +++ /dev/null @@ -1,58 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2004 - 2006 University Of British Columbia 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: - * University Of British Columbia - initial API and implementation - *******************************************************************************/ - -package org.eclipse.mylar.internal.tasks.core; - -import javax.net.ssl.X509TrustManager; - -/** - * TrustAll class implements X509TrustManager to access all https servers with - * signed and unsigned certificates. - */ -public class RepositoryTrustManager implements X509TrustManager { - // seems to be no purpose - public boolean checkClientTrusted(java.security.cert.X509Certificate[] chain) { - return true; - } - - // seems to be no purpose - public boolean isServerTrusted(java.security.cert.X509Certificate[] chain) { - return true; - } - - // seems to be no purpose - public boolean isClientTrusted(java.security.cert.X509Certificate[] chain) { - return true; - } - - /** - * @see javax.net.ssl.X509TrustManager#getAcceptedIssuers() - */ - public java.security.cert.X509Certificate[] getAcceptedIssuers() { - return null; - } - - /** - * @see javax.net.ssl.X509TrustManager#checkClientTrusted(java.security.cert.X509Certificate[], - * java.lang.String) - */ - public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) { - // don't need to do any checks - } - - /** - * @see javax.net.ssl.X509TrustManager#checkServerTrusted(java.security.cert.X509Certificate[], - * java.lang.String) - */ - public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) { - // don't need to do any checks - } -} diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/SaxRepositoriesContentHandler.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/SaxRepositoriesContentHandler.java index 072b8ae85..a9a0c9f89 100644 --- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/SaxRepositoriesContentHandler.java +++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/SaxRepositoriesContentHandler.java @@ -13,7 +13,7 @@ package org.eclipse.mylar.internal.tasks.core; import java.util.HashSet; import java.util.Set; -import org.eclipse.mylar.internal.context.core.util.XmlStringConverter; +import org.eclipse.mylar.internal.core.util.XmlStringConverter; import org.eclipse.mylar.tasks.core.IRepositoryConstants; import org.eclipse.mylar.tasks.core.TaskRepository; import org.xml.sax.Attributes; diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/SaxRepositoriesWriter.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/SaxRepositoriesWriter.java index 336582edb..f738be4ec 100644 --- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/SaxRepositoriesWriter.java +++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/SaxRepositoriesWriter.java @@ -22,8 +22,8 @@ import javax.xml.transform.TransformerFactory; import javax.xml.transform.sax.SAXSource; import javax.xml.transform.stream.StreamResult; -import org.eclipse.mylar.context.core.MylarStatusHandler; -import org.eclipse.mylar.internal.context.core.util.XmlStringConverter; +import org.eclipse.mylar.core.MylarStatusHandler; +import org.eclipse.mylar.internal.core.util.XmlStringConverter; import org.eclipse.mylar.tasks.core.TaskRepository; import org.xml.sax.ContentHandler; import org.xml.sax.DTDHandler; diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/SslProtocolSocketFactory.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/SslProtocolSocketFactory.java deleted file mode 100644 index 6abc88ed5..000000000 --- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/SslProtocolSocketFactory.java +++ /dev/null @@ -1,107 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2004 - 2006 University Of British Columbia 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: - * University Of British Columbia - initial API and implementation - *******************************************************************************/ - -package org.eclipse.mylar.internal.tasks.core; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.Proxy; -import java.net.Socket; -import java.net.UnknownHostException; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManager; - -import org.apache.commons.httpclient.ConnectTimeoutException; -import org.apache.commons.httpclient.Credentials; -import org.apache.commons.httpclient.ProxyClient; -import org.apache.commons.httpclient.UsernamePasswordCredentials; -import org.apache.commons.httpclient.auth.AuthScope; -import org.apache.commons.httpclient.params.HttpConnectionParams; -import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; -import org.eclipse.mylar.context.core.MylarStatusHandler; -import org.eclipse.mylar.tasks.core.web.WebClientUtil; - -/** - * @author Nathan Hapke - * @author Rob Elves - */ -public class SslProtocolSocketFactory implements ProtocolSocketFactory { - - private SSLContext sslContext; - - private Proxy proxy; - - public SslProtocolSocketFactory(Proxy proxy) { - this.proxy = proxy; - } - - private SSLContext getSslContext() { - if (sslContext == null) { - try { - sslContext = SSLContext.getInstance("SSL"); - sslContext.init(null, new TrustManager[] { new RepositoryTrustManager() }, null); - } catch (Exception e) { - MylarStatusHandler.log(e, "could not get SSL context"); - } - } - return sslContext; - } - - public Socket createSocket(String remoteHost, int remotePort) throws IOException, UnknownHostException { - return getSslContext().getSocketFactory().createSocket(remoteHost, remotePort); - } - - public Socket createSocket(String remoteHost, int remotePort, InetAddress clientHost, int clientPort) - throws IOException, UnknownHostException { - return getSslContext().getSocketFactory().createSocket(remoteHost, remotePort, clientHost, clientPort); - } - - public Socket createSocket(String remoteHost, int remotePort, InetAddress clientHost, int clientPort, - HttpConnectionParams params) throws IOException, UnknownHostException, ConnectTimeoutException { - if (params == null || params.getConnectionTimeout() == 0) - return getSslContext().getSocketFactory().createSocket(remoteHost, remotePort, clientHost, clientPort); - - if (proxy != null && !Proxy.NO_PROXY.equals(proxy) && proxy.address() instanceof InetSocketAddress) { - ProxyClient proxyClient = new ProxyClient(); - - InetSocketAddress address = (InetSocketAddress) proxy.address(); - proxyClient.getHostConfiguration().setProxy(WebClientUtil.getDomain(address.getHostName()), - address.getPort()); - proxyClient.getHostConfiguration().setHost(remoteHost, remotePort); - if (proxy instanceof AuthenticatedProxy) { - AuthenticatedProxy authProxy = (AuthenticatedProxy) proxy; - Credentials credentials = new UsernamePasswordCredentials(authProxy.getUserName(), authProxy - .getPassword()); - AuthScope proxyAuthScope = new AuthScope(address.getHostName(), address.getPort(), AuthScope.ANY_REALM); - proxyClient.getState().setProxyCredentials(proxyAuthScope, credentials); - } - - ProxyClient.ConnectResponse response = proxyClient.connect(); - if (response.getSocket() != null) { - // tunnel SSL via the resultant socket - Socket sslsocket = getSslContext().getSocketFactory().createSocket(response.getSocket(), remoteHost, - remotePort, true); - return sslsocket; - } else { - MylarStatusHandler.log("Could not make proxy connection. Trying direct...", this); - } - - } - - Socket socket = getSslContext().getSocketFactory().createSocket(); - socket.bind(new InetSocketAddress(clientHost, clientPort)); - socket.connect(new InetSocketAddress(remoteHost, remotePort), params.getConnectionTimeout()); - return socket; - } - -} diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/TaskDataManager.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/TaskDataManager.java index 785c9fb94..40297b59b 100644 --- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/TaskDataManager.java +++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/TaskDataManager.java @@ -24,7 +24,7 @@ import java.util.List; import java.util.Map; import java.util.Set; -import org.eclipse.mylar.context.core.MylarStatusHandler; +import org.eclipse.mylar.core.MylarStatusHandler; import org.eclipse.mylar.tasks.core.AbstractAttributeFactory; import org.eclipse.mylar.tasks.core.AbstractRepositoryConnector; import org.eclipse.mylar.tasks.core.AbstractRepositoryTask; diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/TaskRepositoriesExternalizer.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/TaskRepositoriesExternalizer.java index c1cc2788e..0c31d7b49 100644 --- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/TaskRepositoriesExternalizer.java +++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/internal/tasks/core/TaskRepositoriesExternalizer.java @@ -22,7 +22,7 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; -import org.eclipse.mylar.context.core.MylarStatusHandler; +import org.eclipse.mylar.core.MylarStatusHandler; import org.eclipse.mylar.tasks.core.TaskRepository; import org.eclipse.mylar.tasks.core.TaskRepositoryManager; import org.xml.sax.InputSource; diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/.AbstractRepositoryTask.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/.AbstractRepositoryTask.java index 8ed0d2d67..ede3bdf5b 100644 --- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/.AbstractRepositoryTask.java +++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/.AbstractRepositoryTask.java @@ -14,7 +14,7 @@ package org.eclipse.mylar.tasks.core; import java.util.Date; import org.eclipse.core.runtime.IStatus; -import org.eclipse.mylar.tasks.core.web.HtmlStreamTokenizer; +import org.eclipse.mylar.core.net.HtmlStreamTokenizer; /** * Virtual proxy for a repository task. diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/AbstractRepositoryTask.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/AbstractRepositoryTask.java index 8ed0d2d67..ede3bdf5b 100644 --- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/AbstractRepositoryTask.java +++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/AbstractRepositoryTask.java @@ -14,7 +14,7 @@ package org.eclipse.mylar.tasks.core; import java.util.Date; import org.eclipse.core.runtime.IStatus; -import org.eclipse.mylar.tasks.core.web.HtmlStreamTokenizer; +import org.eclipse.mylar.core.net.HtmlStreamTokenizer; /** * Virtual proxy for a repository task. diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/AttributeContainer.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/AttributeContainer.java index 6ad3b4c3e..71b0f1d5e 100644 --- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/AttributeContainer.java +++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/AttributeContainer.java @@ -17,7 +17,7 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; -import org.eclipse.mylar.context.core.MylarStatusHandler; +import org.eclipse.mylar.core.MylarStatusHandler; /** * @author Rob Elves diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/DelegatingTaskExternalizer.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/DelegatingTaskExternalizer.java index 8e4cb8070..c71a9d8fe 100644 --- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/DelegatingTaskExternalizer.java +++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/DelegatingTaskExternalizer.java @@ -19,7 +19,7 @@ import java.util.Date; import java.util.List; import java.util.Locale; -import org.eclipse.mylar.context.core.MylarStatusHandler; +import org.eclipse.mylar.core.MylarStatusHandler; import org.eclipse.mylar.internal.tasks.core.TaskDataManager; import org.eclipse.mylar.tasks.core.AbstractRepositoryTask.RepositoryTaskSyncState; import org.w3c.dom.Document; diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/Task.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/Task.java index df32f0e2c..78ca2e846 100644 --- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/Task.java +++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/Task.java @@ -17,7 +17,7 @@ import java.util.Date; import java.util.HashSet; import java.util.Set; -import org.eclipse.mylar.context.core.MylarStatusHandler; +import org.eclipse.mylar.core.MylarStatusHandler; /** * @author Mik Kersten diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/TaskList.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/TaskList.java index 3d3e19891..eb48efe56 100644 --- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/TaskList.java +++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/TaskList.java @@ -22,7 +22,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArraySet; -import org.eclipse.mylar.context.core.MylarStatusHandler; +import org.eclipse.mylar.core.MylarStatusHandler; /** * TODO: some asymetry left between query containers and other task containers diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/TaskRepository.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/TaskRepository.java index 94599b91d..4dcdad77d 100644 --- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/TaskRepository.java +++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/TaskRepository.java @@ -11,9 +11,11 @@ package org.eclipse.mylar.tasks.core; +import java.net.InetSocketAddress; import java.net.MalformedURLException; import java.net.Proxy; import java.net.URL; +import java.net.Proxy.Type; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; @@ -21,8 +23,9 @@ import java.util.TimeZone; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.Platform; -import org.eclipse.mylar.context.core.MylarStatusHandler; -import org.eclipse.mylar.tasks.core.web.WebClientUtil; +import org.eclipse.mylar.core.MylarStatusHandler; +import org.eclipse.mylar.core.net.WebClientUtil; +import org.eclipse.update.internal.core.UpdateCore; /** * Note that task repositories use Strings for storing time stamps because using @@ -390,7 +393,7 @@ public class TaskRepository { public Proxy getProxy() { Proxy proxy = Proxy.NO_PROXY; if (useDefaultProxy()) { - proxy = WebClientUtil.getSystemProxy(); + proxy = getSystemProxy(); } else { String proxyHost = getProperty(PROXY_HOSTNAME); @@ -409,4 +412,21 @@ public class TaskRepository { public boolean useDefaultProxy() { return "true".equals(getProperty(PROXY_USEDEFAULT)) || (getProperty(PROXY_HOSTNAME) == null); } + + /** + * TODO: move + * utility method, should use TaskRepository.getProxy() + */ + public static Proxy getSystemProxy() { + Proxy proxy = Proxy.NO_PROXY; + if (UpdateCore.getPlugin() != null + && UpdateCore.getPlugin().getPluginPreferences().getBoolean(UpdateCore.HTTP_PROXY_ENABLE)) { + String proxyHost = UpdateCore.getPlugin().getPluginPreferences().getString(UpdateCore.HTTP_PROXY_HOST); + int proxyPort = UpdateCore.getPlugin().getPluginPreferences().getInt(UpdateCore.HTTP_PROXY_PORT); + + InetSocketAddress sockAddr = new InetSocketAddress(proxyHost, proxyPort); + proxy = new Proxy(Type.HTTP, sockAddr); + } + return proxy; + } } diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/TaskRepositoryManager.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/TaskRepositoryManager.java index bd9c493b7..5a5ff151e 100644 --- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/TaskRepositoryManager.java +++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/TaskRepositoryManager.java @@ -26,7 +26,7 @@ import java.util.Set; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.Platform; -import org.eclipse.mylar.context.core.MylarStatusHandler; +import org.eclipse.mylar.core.MylarStatusHandler; import org.eclipse.mylar.internal.tasks.core.TaskRepositoriesExternalizer; /** diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/web/HtmlStreamTokenizer.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/web/HtmlStreamTokenizer.java deleted file mode 100644 index 1670c9da7..000000000 --- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/web/HtmlStreamTokenizer.java +++ /dev/null @@ -1,1117 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2004 - 2006 University Of British Columbia 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: - * University Of British Columbia - initial API and implementation - *******************************************************************************/ - -package org.eclipse.mylar.tasks.core.web; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.Reader; -import java.net.URL; -import java.text.ParseException; -import java.util.HashMap; -import java.util.Locale; - -public class HtmlStreamTokenizer { - - /** parser state */ - private State state; - - /** reader from which to parse the text */ - private BufferedReader in; - - /** base URL for resolving relative URLs */ - private URL base; - - /** buffer holding the text of the current token */ - private StringBuffer textBuffer; - - /** buffer holding whitespace preceding the current token */ - private StringBuffer whitespaceBuffer; - - /** - * holds a token that was read and then put back in the queue to be returned - * again on <code>nextToken</code> call - */ - private Token pushbackToken; - - /** - * holds a character that was read and then determined not to be part of the - * current token - */ - private int pushbackChar; - - /** current quote delimiter (single or double) */ - private int quoteChar; - - /** Allow class client to choose if tag attributes are escaped or not */ - private boolean escapeTagValues; - - /** - * Constructor. - * - * @param in - * reader for the HTML document to tokenize - * @param base - * URL for resolving relative URLs - */ - public HtmlStreamTokenizer(Reader in, URL base) { - textBuffer = new StringBuffer(); - whitespaceBuffer = new StringBuffer(); - pushbackChar = 0; - state = State.TEXT; - this.in = new BufferedReader(in); - this.base = base; - escapeTagValues = true; - } - - public void escapeTagAttributes(boolean value) { - escapeTagValues = value; - } - - /** - * Returns the next token from the stream. - */ - public Token nextToken() throws IOException, ParseException { - if (pushbackToken != null) { - Token token = pushbackToken; - pushbackToken = null; - return token; - } - - int closingComment = 0; - - textBuffer.setLength(0); - whitespaceBuffer.setLength(0); - do { - int ch; - if (pushbackChar != 0) { - ch = pushbackChar; - pushbackChar = 0; - } else { - ch = in.read(); - } - if (ch < 0) { - State oldState = state; - state = State.EOF; - if (textBuffer.length() > 0 && oldState == State.TEXT) { - return new Token(textBuffer, whitespaceBuffer, false); - } else { - return new Token(); - } - } - if (state == State.TEXT) { - if (ch == '<') { - state = State.TAG; - if (textBuffer.length() > 0) - return new Token(textBuffer, whitespaceBuffer, false); - } else if (Character.isWhitespace((char) ch)) { - pushbackChar = ch; - state = State.WS; - if (textBuffer.length() > 0) - return new Token(textBuffer, whitespaceBuffer, false); - } else { - textBuffer.append((char) ch); - } - } else if (state == State.WS) { - if (!Character.isWhitespace((char) ch)) { - pushbackChar = ch; - state = State.TEXT; - } else { - whitespaceBuffer.append((char) ch); - } - } else if (state == State.TAG) { - if (ch == '>') { - state = State.TEXT; - HtmlTag tag = new HtmlTag(base); - parseTag(textBuffer.toString(), tag, escapeTagValues); - return new Token(tag, whitespaceBuffer); - } - if (ch == '<' && textBuffer.length() == 0) { - textBuffer.append("<<"); - state = State.TEXT; - } else if (ch == '-' && textBuffer.length() == 2 && textBuffer.charAt(1) == '-' - && textBuffer.charAt(0) == '!') { - textBuffer.setLength(0); - state = State.COMMENT; - } else if (ch == '\'' || ch == '"') { - quoteChar = ch; - textBuffer.append((char) ch); - state = State.TAG_QUOTE; - } else { - textBuffer.append((char) ch); - } - } else if (state == State.TAG_QUOTE) { - if (ch == '>') { - pushbackChar = ch; - state = State.TAG; - } else { - textBuffer.append((char) ch); - if (ch == quoteChar) - state = State.TAG; - } - } else if (state == State.COMMENT) { - if (ch == '>' && closingComment >= 2) { - textBuffer.setLength(textBuffer.length() - 2); - closingComment = 0; - state = State.TEXT; - return new Token(textBuffer, whitespaceBuffer, true); - } - if (ch == '-') { - closingComment++; - } else { - closingComment = 0; - } - textBuffer.append((char) ch); - } - } while (true); - } - - /** - * Pushes the token back into the queue, to be returned by the subsequent - * call to <code>nextToken</code> - */ - public void pushback(Token token) { - pushbackToken = token; - } - - /** - * Parses an HTML tag out of a string of characters. - */ - private static void parseTag(String s, HtmlTag tag, boolean escapeValues) throws ParseException { - - int i = 0; - for (; i < s.length() && Character.isWhitespace(s.charAt(i)); i++) { - // just move forward - } - if (i == s.length()) - throw new ParseException("parse empty tag", 0); - - int start = i; - for (; i < s.length() && !Character.isWhitespace(s.charAt(i)); i++) { - // just move forward - } - tag.setTagName(s.substring(start, i)); - - for (; i < s.length() && Character.isWhitespace(s.charAt(i)); i++) { - // just move forward - } - if (i == s.length()) { - return; - } else { - parseAttributes(tag, s, i, escapeValues); - return; - } - } - - /** - * parses HTML tag attributes from a buffer and sets them in an HtmlTag - */ - private static void parseAttributes(HtmlTag tag, String s, int i, boolean escapeValues) throws ParseException { - while (i < s.length()) { - // skip whitespace - while (i < s.length() && Character.isWhitespace(s.charAt(i))) - i++; - - if (i == s.length()) - return; - - // read the attribute name -- the rule might be looser than the RFC - // specifies: - // everything up to a space or an equal sign is included - int start = i; - for (; i < s.length() && !Character.isWhitespace(s.charAt(i)) && s.charAt(i) != '='; i++) { - // just move forward - } - String attributeName = s.substring(start, i).toLowerCase(Locale.ENGLISH); - - if (attributeName.equals("/")) { - tag.setSelfTerminating(true); - continue; - } - - for (; i < s.length() && Character.isWhitespace(s.charAt(i)); i++) { - // just move forward - } - if (i == s.length() || s.charAt(i) != '=') { - // no attribute value - tag.setAttribute(attributeName, ""); - continue; - } - - // skip whitespace to the start of attribute value - for (i = i + 1; i < s.length() && Character.isWhitespace(s.charAt(i)); i++) { - // just move forward - } - if (i == s.length()) - return; - - // read the attribute value -- the rule for unquoted attribute value - // is - // looser than the one in Conolly's W3C 1996 lexical analyzer draft: - // everything - // is included up to the next space - String attributeValue; - if (s.charAt(i) == '"') { - start = ++i; - for (; i < s.length() && s.charAt(i) != '"'; i++) { - // just move forward - } - if (i == s.length()) - return; // shouldn't happen if input returned by nextToken - if (escapeValues) - attributeValue = unescape(s.substring(start, i)); - else - attributeValue = s.substring(start, i); - i++; - } else if (s.charAt(i) == '\'') { - start = ++i; - for (; i < s.length() && s.charAt(i) != '\''; i++) { - // just move forward - } - if (i == s.length()) - return; // shouldn't happen if input returned by nextToken - attributeValue = unescape(s.substring(start, i)); - i++; - } else { - start = i; - for (; i < s.length() && !Character.isWhitespace(s.charAt(i)); i++) { - // just move forward - } - attributeValue = s.substring(start, i); - } - tag.setAttribute(attributeName, attributeValue); - } - } - - /** - * Returns a string with HTML escapes changed into their corresponding - * characters. - */ - public static String unescape(String s) { - if (s.indexOf('&') == -1) { - return s; - } else { - StringBuffer sb = new StringBuffer(s); - unescape(sb); - return sb.toString(); - } - } - - /** - * Replaces (in-place) HTML escapes in a StringBuffer with their - * corresponding characters. - */ - public static StringBuffer unescape(StringBuffer sb) { - int i = 0; // index into the unprocessed section of the buffer - int j = 0; // index into the processed section of the buffer - - while (i < sb.length()) { - char ch = sb.charAt(i); - if (ch == '&') { - int start = i; - String escape = null; - for (i = i + 1; i < sb.length(); i++) { - ch = sb.charAt(i); - if (!Character.isLetterOrDigit(ch) && !(ch == '#' && i == (start + 1))) { - escape = sb.substring(start + 1, i); - break; - } - } - if (i == sb.length() && i != (start + 1)) { - escape = sb.substring(start + 1); - } - if (escape != null) { - Character character = parseReference(escape); - if (character != null) { - ch = character.charValue(); - } else { - // not an HTML escape; rewind - i = start; - ch = '&'; - } - } - } - sb.setCharAt(j, ch); - i++; - j++; - } - - sb.setLength(j); - return sb; - } - - /** - * Parses HTML character and entity references and returns the corresponding - * character. - */ - private static Character parseReference(String s) { - if (s.length() == 0) - return null; - - if (s.charAt(0) == '#') { - // character reference - if (s.length() == 1) - return null; - - try { - int value; - if (s.charAt(1) == 'x') { - // Hex reference - value = Integer.parseInt(s.substring(2), 16); - } else { - // Decimal reference - value = Integer.parseInt(s.substring(1)); - } - return new Character((char) value); - } catch (NumberFormatException e) { - return null; - } - } else { - return entities.get(s); - } - } - - /** - * Class for current token. - */ - public static class Token { - public static final Type EOF = new Type(); - - public static final Type TEXT = new Type(); - - public static final Type TAG = new Type(); - - public static final Type COMMENT = new Type(); - - /** token's type */ - private Type type; - - /** token's value */ - private Object value; - - /** whitespace preceding the token */ - private StringBuffer whitespace; - - /** - * Constructor for the EOF token. - */ - protected Token() { - type = EOF; - value = null; - whitespace = null; - } - - /** - * Constructor for the HTML tag tokens. - */ - protected Token(HtmlTag tag, StringBuffer whitespace) { - type = TAG; - value = tag; - this.whitespace = whitespace; - } - - /** - * Constructor for regular text and comments. - */ - protected Token(StringBuffer text, StringBuffer whitespace, boolean comment) { - if (comment) { - type = COMMENT; - } else { - type = TEXT; - } - this.value = text; - this.whitespace = whitespace; - } - - /** - * Returns the token's type. - */ - public Type getType() { - return type; - } - - /** - * Returns the whitespace preceding the token. - */ - public StringBuffer getWhitespace() { - return whitespace; - } - - /** - * Returns the token's value. This is an HtmlTag for tokens of type - * <code>TAG</code> and a StringBuffer for tokens of type - * <code>TEXT</code> and <code>COMMENT</code>. For tokens of type - * <code>EOF</code>, the value is <code>null</code>. - */ - public Object getValue() { - return value; - } - - /** - * Returns the string representation of the token, including the - * preceding whitespace. - */ - @Override - public String toString() { - StringBuffer sb = new StringBuffer(); - if (whitespace != null) { - sb.append(whitespace); - } - if (value != null) { - if (type == TAG) { - // sb.append('<'); - } else if (type == COMMENT) { - sb.append("<!--"); - } - sb.append(value); - if (type == TAG) { - // if(value instanceof HtmlTag) { - // HtmlTag htmlTag = (HtmlTag)value; - // if(htmlTag.getTagName().startsWith("?xml")) { - // sb.append("?>"); - // } - // } else { - // sb.append('>'); - - } else if (type == COMMENT) { - sb.append("-->"); - } - - } - return sb.toString(); - } - - /** - * Private enum class for token type. - */ - private static class Type { - private Type() { - // don't need to do anything - } - } - } - - /** - * Enum class for parser state. - */ - private static class State { - static final State EOF = new State(); - - static final State COMMENT = new State(); - - static final State TEXT = new State(); - - static final State TAG = new State(); - - static final State WS = new State(); - - static final State TAG_QUOTE = new State(); - - private State() { - // don't need to do anything - } - } - - /** names and values of HTML entity references */ - private static HashMap<String, Character> entities; - - /* - * Based on ISO 8879. - * - * Portions (c) International Organization for Standardization 1986 - * Permission to copy in any form is granted for use with conforming SGML - * systems and applications as defined in ISO 8879, provided this notice is - * included in all copies. - * - */ - static { - entities = new HashMap<String, Character>(); - entities.put("nbsp",Character.valueOf('\240')); // no-break - // space = - // non-breaking - // space - entities.put("iexcl",Character.valueOf('\241')); // inverted - // exclamation - // mark - entities.put("cent",Character.valueOf('\242')); // cent sign - entities.put("pound",Character.valueOf('\243')); // pound - // sign - entities.put("curren",Character.valueOf('\244')); // currency - // sign - entities.put("yen",Character.valueOf('\245')); // yen sign = - // yuan sign - entities.put("brvbar",Character.valueOf('\246')); // broken - // bar = - // broken - // vertical - // bar - entities.put("sect",Character.valueOf('\247')); // section - // sign - entities.put("uml",Character.valueOf('\250')); // diaeresis = - // spacing - // diaeresis - entities.put("copy",Character.valueOf('\251')); // copyright - // sign - entities.put("ordf",Character.valueOf('\252')); // feminine - // ordinal - // indicator - entities.put("laquo",Character.valueOf('\253')); // left-pointing - // double - // angle - // quotation - // mark = - // left - // pointing - // guillemet - entities.put("not",Character.valueOf('\254')); // not sign - entities.put("shy",Character.valueOf('\255')); // soft hyphen = - // discretionary - // hyphen - entities.put("reg",Character.valueOf('\256')); // registered - // sign = - // registered - // trade mark - // sign - entities.put("macr",Character.valueOf('\257')); // macron = - // spacing - // macron = - // overline - // = APL - // overbar - entities.put("deg",Character.valueOf('\260')); // degree sign - entities.put("plusmn",Character.valueOf('\261')); // plus-minus - // sign = - // plus-or-minus - // sign - entities.put("sup2",Character.valueOf('\262')); // superscript - // two = - // superscript - // digit two - // = squared - entities.put("sup3",Character.valueOf('\263')); // superscript - // three = - // superscript - // digit - // three = - // cubed - entities.put("acute",Character.valueOf('\264')); // acute - // accent = - // spacing - // acute - entities.put("micro",Character.valueOf('\265')); // micro - // sign - entities.put("para",Character.valueOf('\266')); // pilcrow - // sign = - // paragraph - // sign - entities.put("middot",Character.valueOf('\267')); // middle - // dot = - // Georgian - // comma = - // Greek - // middle - // dot - entities.put("cedil",Character.valueOf('\270')); // cedilla = - // spacing - // cedilla - entities.put("sup1",Character.valueOf('\271')); // superscript - // one = - // superscript - // digit one - entities.put("ordm",Character.valueOf('\272')); // masculine - // ordinal - // indicator - entities.put("raquo",Character.valueOf('\273')); // right-pointing - // double - // angle - // quotation - // mark = - // right - // pointing - // guillemet - entities.put("frac14",Character.valueOf('\274')); // vulgar - // fraction - // one - // quarter = - // fraction - // one - // quarter - entities.put("frac12",Character.valueOf('\275')); // vulgar - // fraction - // one half - // = - // fraction - // one half - entities.put("frac34",Character.valueOf('\276')); // vulgar - // fraction - // three - // quarters - // = - // fraction - // three - // quarters - entities.put("iquest",Character.valueOf('\277')); // inverted - // question - // mark = - // turned - // question - // mark - entities.put("Agrave",Character.valueOf('\300')); // latin - // capital - // letter A - // with - // grave = - // latin - // capital - // letter A - // grave - entities.put("Aacute",Character.valueOf('\301')); // latin - // capital - // letter A - // with - // acute - entities.put("Acirc",Character.valueOf('\302')); // latin - // capital - // letter A - // with - // circumflex - entities.put("Atilde",Character.valueOf('\303')); // latin - // capital - // letter A - // with - // tilde - entities.put("Auml",Character.valueOf('\304')); // latin - // capital - // letter A - // with - // diaeresis - entities.put("Aring",Character.valueOf('\305')); // latin - // capital - // letter A - // with ring - // above = - // latin - // capital - // letter A - // ring - entities.put("AElig",Character.valueOf('\306')); // latin - // capital - // letter AE - // = latin - // capital - // ligature - // AE - entities.put("Ccedil",Character.valueOf('\307')); // latin - // capital - // letter C - // with - // cedilla - entities.put("Egrave",Character.valueOf('\310')); // latin - // capital - // letter E - // with - // grave - entities.put("Eacute",Character.valueOf('\311')); // latin - // capital - // letter E - // with - // acute - entities.put("Ecirc",Character.valueOf('\312')); // latin - // capital - // letter E - // with - // circumflex - entities.put("Euml",Character.valueOf('\313')); // latin - // capital - // letter E - // with - // diaeresis - entities.put("Igrave",Character.valueOf('\314')); // latin - // capital - // letter I - // with - // grave - entities.put("Iacute",Character.valueOf('\315')); // latin - // capital - // letter I - // with - // acute - entities.put("Icirc",Character.valueOf('\316')); // latin - // capital - // letter I - // with - // circumflex - entities.put("Iuml",Character.valueOf('\317')); // latin - // capital - // letter I - // with - // diaeresis - entities.put("ETH",Character.valueOf('\320')); // latin capital - // letter ETH - entities.put("Ntilde",Character.valueOf('\321')); // latin - // capital - // letter N - // with - // tilde - entities.put("Ograve",Character.valueOf('\322')); // latin - // capital - // letter O - // with - // grave - entities.put("Oacute",Character.valueOf('\323')); // latin - // capital - // letter O - // with - // acute - entities.put("Ocirc",Character.valueOf('\324')); // latin - // capital - // letter O - // with - // circumflex - entities.put("Otilde",Character.valueOf('\325')); // latin - // capital - // letter O - // with - // tilde - entities.put("Ouml",Character.valueOf('\326')); // latin - // capital - // letter O - // with - // diaeresis - entities.put("times",Character.valueOf('\327')); // multiplication - // sign - entities.put("Oslash",Character.valueOf('\330')); // latin - // capital - // letter O - // with - // stroke = - // latin - // capital - // letter O - // slash - entities.put("Ugrave",Character.valueOf('\331')); // latin - // capital - // letter U - // with - // grave - entities.put("Uacute",Character.valueOf('\332')); // latin - // capital - // letter U - // with - // acute - entities.put("Ucirc",Character.valueOf('\333')); // latin - // capital - // letter U - // with - // circumflex - entities.put("Uuml",Character.valueOf('\334')); // latin - // capital - // letter U - // with - // diaeresis - entities.put("Yacute",Character.valueOf('\335')); // latin - // capital - // letter Y - // with - // acute - entities.put("THORN",Character.valueOf('\336')); // latin - // capital - // letter - // THORN - entities.put("szlig",Character.valueOf('\337')); // latin - // small - // letter - // sharp s = - // ess-zed - entities.put("agrave",Character.valueOf('\340')); // latin - // small - // letter a - // with - // grave = - // latin - // small - // letter a - // grave - entities.put("aacute",Character.valueOf('\341')); // latin - // small - // letter a - // with - // acute - entities.put("acirc",Character.valueOf('\342')); // latin - // small - // letter a - // with - // circumflex - entities.put("atilde",Character.valueOf('\343')); // latin - // small - // letter a - // with - // tilde - entities.put("auml",Character.valueOf('\344')); // latin - // small - // letter a - // with - // diaeresis - entities.put("aring",Character.valueOf('\345')); // latin - // small - // letter a - // with ring - // above = - // latin - // small - // letter a - // ring - entities.put("aelig",Character.valueOf('\346')); // latin - // small - // letter ae - // = latin - // small - // ligature - // ae - entities.put("ccedil",Character.valueOf('\347')); // latin - // small - // letter c - // with - // cedilla - entities.put("egrave",Character.valueOf('\350')); // latin - // small - // letter e - // with - // grave - entities.put("eacute",Character.valueOf('\351')); // latin - // small - // letter e - // with - // acute - entities.put("ecirc",Character.valueOf('\352')); // latin - // small - // letter e - // with - // circumflex - entities.put("euml",Character.valueOf('\353')); // latin - // small - // letter e - // with - // diaeresis - entities.put("igrave",Character.valueOf('\354')); // latin - // small - // letter i - // with - // grave - entities.put("iacute",Character.valueOf('\355')); // latin - // small - // letter i - // with - // acute - entities.put("icirc",Character.valueOf('\356')); // latin - // small - // letter i - // with - // circumflex - entities.put("iuml",Character.valueOf('\357')); // latin - // small - // letter i - // with - // diaeresis - entities.put("eth",Character.valueOf('\360')); // latin small - // letter eth - entities.put("ntilde",Character.valueOf('\361')); // latin - // small - // letter n - // with - // tilde - entities.put("ograve",Character.valueOf('\362')); // latin - // small - // letter o - // with - // grave - entities.put("oacute",Character.valueOf('\363')); // latin - // small - // letter o - // with - // acute - entities.put("ocirc",Character.valueOf('\364')); // latin - // small - // letter o - // with - // circumflex - entities.put("otilde",Character.valueOf('\365')); // latin - // small - // letter o - // with - // tilde - entities.put("ouml",Character.valueOf('\366')); // latin - // small - // letter o - // with - // diaeresis - entities.put("divide",Character.valueOf('\367')); // division - // sign - entities.put("oslash",Character.valueOf('\370')); // latin - // small - // letter o - // with - // stroke = - // latin - // small - // letter o - // slash - entities.put("ugrave",Character.valueOf('\371')); // latin - // small - // letter u - // with - // grave - entities.put("uacute",Character.valueOf('\372')); // latin - // small - // letter u - // with - // acute - entities.put("ucirc",Character.valueOf('\373')); // latin - // small - // letter u - // with - // circumflex - entities.put("uuml",Character.valueOf('\374')); // latin - // small - // letter u - // with - // diaeresis - entities.put("yacute",Character.valueOf('\375')); // latin - // small - // letter y - // with - // acute - entities.put("thorn",Character.valueOf('\376')); // latin - // small - // letter - // thorn - entities.put("yuml",Character.valueOf('\377')); // latin - // small - // letter y - // with - // diaeresis - - // Special characters - entities.put("quot",Character.valueOf('\42')); // quotation - // mark = APL - // quote - entities.put("amp",Character.valueOf('\46')); // ampersand - entities.put("lt",Character.valueOf('\74')); // less-than - // sign - entities.put("gt",Character.valueOf('\76')); // greater-than - // sign - // Latin Extended-A - entities.put("OElig",Character.valueOf('\u0152')); // latin - // capital - // ligature - // OE - entities.put("oelig",Character.valueOf('\u0153')); // latin - // small - // ligature - // oe, - // ligature - // is a - // misnomer, - // this is a - // separate - // character - // in some - // languages - entities.put("Scaron",Character.valueOf('\u0160')); // latin - // capital - // letter - // S - // with - // caron - entities.put("scaron",Character.valueOf('\u0161')); // latin - // small - // letter - // s - // with - // caron - entities.put("Yuml",Character.valueOf('\u0178')); // latin - // capital - // letter Y - // with - // diaeresis - // Spacing Modifier Letters - entities.put("circ",Character.valueOf('\u02c6')); // modifier - // letter - // circumflex - // accent - entities.put("tilde",Character.valueOf('\u02dc')); // small - // tilde - // General punctuation - entities.put("ensp",Character.valueOf('\u2002')); // en space - entities.put("emsp",Character.valueOf('\u2003')); // em space - entities.put("thinsp",Character.valueOf('\u2009')); // thin - // space - entities.put("zwnj",Character.valueOf('\u200c')); // zero - // width - // non-joiner - entities.put("zwj",Character.valueOf('\u200d')); // zero - // width - // joiner - entities.put("lrm",Character.valueOf('\u200e')); // left-to-right - // mark - entities.put("rlm",Character.valueOf('\u200f')); // right-to-left - // mark - entities.put("ndash",Character.valueOf('\u2013')); // en dash - entities.put("mdash",Character.valueOf('\u2014')); // em dash - entities.put("lsquo",Character.valueOf('\u2018')); // left - // single - // quotation - // mark - entities.put("rsquo",Character.valueOf('\u2019')); // right - // single - // quotation - // mark - entities.put("sbquo",Character.valueOf('\u201a')); // single - // low-9 - // quotation - // mark - entities.put("ldquo",Character.valueOf('\u201c')); // left - // double - // quotation - // mark - entities.put("rdquo",Character.valueOf('\u201d')); // right - // double - // quotation - // mark - entities.put("bdquo",Character.valueOf('\u201e')); // double - // low-9 - // quotation - // mark - entities.put("dagger",Character.valueOf('\u2020')); // dagger - entities.put("Dagger",Character.valueOf('\u2021')); // double - // dagger - entities.put("permil",Character.valueOf('\u2030')); // per - // mille - // sign - entities.put("lsaquo",Character.valueOf('\u2039')); // single - // left-pointing - // angle - // quotation - // mark, - // not - // yet - // standardized - entities.put("rsaquo",Character.valueOf('\u203a')); // single - // right-pointing - // angle - // quotation - // mark, - // not - // yet - // standardized - entities.put("euro",Character.valueOf('\u20ac')); // euro sign - } -} diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/web/HtmlTag.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/web/HtmlTag.java deleted file mode 100644 index bb34b9312..000000000 --- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/web/HtmlTag.java +++ /dev/null @@ -1,364 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2004 - 2006 University Of British Columbia 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: - * University Of British Columbia - initial API and implementation - *******************************************************************************/ - -package org.eclipse.mylar.tasks.core.web; - -import java.net.URL; -import java.text.ParseException; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Locale; - -import javax.swing.text.html.HTML.Tag; - -/** - * Class representing an HTML (3.2) tag and its attributes. - */ -public class HtmlTag { - /** tag's name */ - private String tagName; - - /** tag type enum */ - private Tag tagType; - - /** true if the tag is a closing tag */ - private boolean isEndTag; - - /** tag's attributes (keys are lowercase attribute names) */ - private HashMap<String, String> attributes; - - /** tag's base url */ - private URL baseUrl; - - /** tag is self terminated */ - private boolean selfTerminating; - - /** - * Basic constructor. The tag is uninitialized. - */ - public HtmlTag() { - tagName = null; - tagType = Type.UNKNOWN; - isEndTag = false; - attributes = new HashMap<String, String>(); - baseUrl = null; - } - - /** - * Copy constructor. - */ - @SuppressWarnings("unchecked") - public HtmlTag(HtmlTag htmltag) { - tagName = null; - tagType = Type.UNKNOWN; - isEndTag = false; - attributes = new HashMap<String, String>(); - tagName = htmltag.tagName; - baseUrl = htmltag.baseUrl; - tagType = htmltag.tagType; - isEndTag = htmltag.isEndTag; - attributes = (HashMap) htmltag.attributes.clone(); - } - - /** - * Constructor. - */ - public HtmlTag(String s) throws ParseException { - attributes = new HashMap<String, String>(); - setTagName(s); - baseUrl = null; - } - - /** - * Constructor creating an otherwise empty tag, but with a given base url. - */ - public HtmlTag(URL url) { - tagName = null; - tagType = Type.UNKNOWN; - isEndTag = false; - attributes = new HashMap<String, String>(); - baseUrl = url; - } - - /** - * Returns the tag's type (linked to the tag's name). - */ - public Tag getTagType() { - return tagType; - } - - /** - * Returns the tag's name (e.g., "HEAD", "P", etc.). - */ - public String getTagName() { - return tagName; - } - - /** - * Sets the tag's name and type, if known. - * - * @throws IllegalArgumentException - * if the argument is <code>null</code> or empty string - */ - public void setTagName(String s) throws IllegalArgumentException { - if (s == null || s.length() == 0) - throw new IllegalArgumentException("Empty tag name"); - if (s.charAt(0) == '/') { - isEndTag = true; - s = s.substring(1); - } - if (s.length() == 0) - throw new IllegalArgumentException("Empty tag name"); - tagName = s; - tagType = tags.get(s.toUpperCase(Locale.ENGLISH)); - if (tagType == null) { - tagType = Type.UNKNOWN; - } - } - - /** - * Returns <code>true</code> if the tag is a closing tag. - */ - public boolean isEndTag() { - return isEndTag; - } - - /** - * Returns the value of a tag's attribute as an integer. - */ - public int getIntAttribute(String s) throws NumberFormatException { - return Integer.parseInt(getAttribute(s)); - } - - /** - * Returns the value of a tag's attribute, or NULL if it doesn't exist. - */ - public String getAttribute(String s) { - return attributes.get(s); - } - - /** - * Returns <code>true</code> if the tag contains attribute with the given - * name. - */ - public boolean hasAttribute(String s) { - return getAttribute(s) != null; - } - - /** - * Sets the value of a tag's attribute. - */ - public void setAttribute(String name, String value) { - attributes.put(name.toLowerCase(Locale.ENGLISH), value); - } - - public StringBuffer getURLs() { - StringBuffer sb = new StringBuffer(); - - Iterator<String> attributeNames = attributes.keySet().iterator(); - Iterator<String> attributeValues = attributes.values().iterator(); - while (attributeNames.hasNext()) { - String attributeName = attributeNames.next(); - if (attributeName.compareTo("href") == 0 || attributeName.compareTo("src") == 0) { - String target = attributeValues.next(); - if (!target.endsWith(".jpg") && !target.endsWith(".gif") && !target.endsWith(".css") - && !target.endsWith(".js") && !target.startsWith("mailto") && target.lastIndexOf("#") == -1 - && target.length() > 0) { - - for (int i = 0; i < target.length(); i++) { - char ch = target.charAt(i); - if (!Character.isWhitespace(ch)) { - if (i > 0) - target = target.substring(i + 1); - break; - } - } - target = target.replace('\\', '/'); - - if (target.startsWith("news:") || (target.indexOf("://") != -1 && target.length() >= 7)) { - // Absolute URL - if (target.substring(0, 7).compareToIgnoreCase("http://") == 0) - sb.append(target); - } else { - // Relative URL - - String baseDir = baseUrl.getPath(); - int lastSep = -1; - for (int i = 0; i < baseDir.length(); i++) { - char ch = baseDir.charAt(i); - if (ch == '/') - lastSep = i; - else if (ch == '?') - break; - } - if (lastSep >= 0) - baseDir = baseDir.substring(0, lastSep); - while (baseDir.length() > 1 && baseDir.endsWith("/.")) { - baseDir = baseDir.substring(0, baseDir.length() - 2); - } - - if (target.startsWith("//")) { - sb.append(baseUrl.getProtocol() + ":" + target); - } else if (target.startsWith("/")) { - sb.append(baseUrl.getProtocol() + "://" + baseUrl.getHost() + target); - } else { - while (target.startsWith("../")) { - if (baseDir.length() > 0) { - // can't go above root - baseDir = baseDir.substring(0, baseDir.lastIndexOf("/")); - } - target = target.substring(3); - } - sb.append(baseUrl.getProtocol() + "://" + baseUrl.getHost() + baseDir + "/" + target); - } - } - } - } else { - attributeValues.next(); - } - } - - return sb; - } - - @Override - public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append('<'); - if (isEndTag) - sb.append('/'); - sb.append(tagName); - Iterator<String> keys = attributes.keySet().iterator(); - Iterator<String> values = attributes.values().iterator(); - while (keys.hasNext()) { - String name = keys.next(); - sb.append(' '); - sb.append(name); - String value = values.next(); - sb.append("=\""); - if (value.length() > 0) { - sb.append(value); - } - sb.append('"'); - } - if(selfTerminating) { - sb.append('/'); - } - sb.append('>'); - - return sb.toString(); - } - - /** - * Enum class for tag types. - */ - public static class Type extends Tag { - public static final Tag UNKNOWN = new Tag(); - - public static final Tag THEAD = new Type("THEAD"); - - public static final Tag DOCTYPE = new Type("!DOCTYPE"); - - public static final Tag LABEL = new Type("LABEL"); - - private Type(String name) { - super(name); - } - } - - private static HashMap<String, Tag> tags; - static { - tags = new HashMap<String, Tag>(); - tags.put("A", Tag.A); - tags.put("ADDRESS", Tag.ADDRESS); - tags.put("APPLET", Tag.APPLET); - tags.put("AREA", Tag.AREA); - tags.put("B", Tag.B); - tags.put("BASE", Tag.BASE); - tags.put("BASEFONT", Tag.BASEFONT); - tags.put("BIG", Tag.BIG); - tags.put("BLOCKQUOTE", Tag.BLOCKQUOTE); - tags.put("BODY", Tag.BODY); - tags.put("BR", Tag.BR); - tags.put("CAPTION", Tag.CAPTION); - tags.put("CENTER", Tag.CENTER); - tags.put("CITE", Tag.CITE); - tags.put("CODE", Tag.CODE); - tags.put("DD", Tag.DD); - tags.put("DFN", Tag.DFN); - tags.put("DIR", Tag.DIR); - tags.put("DIV", Tag.DIV); - tags.put("DL", Tag.DL); - tags.put("!DOCTYPE", Type.DOCTYPE); - tags.put("DT", Tag.DT); - tags.put("EM", Tag.EM); - tags.put("FONT", Tag.FONT); - tags.put("FORM", Tag.FORM); - tags.put("FRAME", Tag.FRAME); - tags.put("FRAMESET", Tag.FRAMESET); - tags.put("H1", Tag.H1); - tags.put("H2", Tag.H2); - tags.put("H3", Tag.H3); - tags.put("H4", Tag.H4); - tags.put("H5", Tag.H5); - tags.put("H6", Tag.H6); - tags.put("HEAD", Tag.HEAD); - tags.put("HTML", Tag.HTML); - tags.put("HR", Tag.HR); - tags.put("I", Tag.I); - tags.put("IMG", Tag.IMG); - tags.put("INPUT", Tag.INPUT); - tags.put("ISINDEX", Tag.ISINDEX); - tags.put("KBD", Tag.KBD); - tags.put("LI", Tag.LI); - tags.put("LABEL", Type.LABEL); - tags.put("LINK", Tag.LINK); - tags.put("MAP", Tag.MAP); - tags.put("MENU", Tag.MENU); - tags.put("META", Tag.META); - tags.put("NOFRAMES", Tag.NOFRAMES); - tags.put("OBJECT", Tag.OBJECT); - tags.put("OL", Tag.OL); - tags.put("OPTION", Tag.OPTION); - tags.put("P", Tag.P); - tags.put("PARAM", Tag.PARAM); - tags.put("PRE", Tag.PRE); - tags.put("S", Tag.S); - tags.put("SAMP", Tag.SAMP); - tags.put("SCRIPT", Tag.SCRIPT); - tags.put("SELECT", Tag.SELECT); - tags.put("SMALL", Tag.SMALL); - tags.put("STRONG", Tag.STRONG); - tags.put("STYLE", Tag.STYLE); - tags.put("SUB", Tag.SUB); - tags.put("SUP", Tag.SUP); - tags.put("TABLE", Tag.TABLE); - tags.put("TD", Tag.TD); - tags.put("TEXTAREA", Tag.TEXTAREA); - tags.put("TH", Tag.TH); - tags.put("THEAD", Type.THEAD); - tags.put("TITLE", Tag.TITLE); - tags.put("TR", Tag.TR); - tags.put("TT", Tag.TT); - tags.put("U", Tag.U); - tags.put("UL", Tag.UL); - tags.put("VAR", Tag.VAR); - } - - public void setSelfTerminating(boolean terminating) { - this.selfTerminating = terminating; - - } - - public boolean isSelfTerminating() { - return selfTerminating; - } -} diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/web/WebClientUtil.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/web/WebClientUtil.java deleted file mode 100644 index 19e8114d2..000000000 --- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/web/WebClientUtil.java +++ /dev/null @@ -1,272 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2004 - 2006 University Of British Columbia 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: - * University Of British Columbia - initial API and implementation - *******************************************************************************/ - -package org.eclipse.mylar.tasks.core.web; - -import java.net.InetSocketAddress; -import java.net.Proxy; -import java.net.Proxy.Type; - -import org.apache.commons.httpclient.Credentials; -import org.apache.commons.httpclient.HttpClient; -import org.apache.commons.httpclient.UsernamePasswordCredentials; -import org.apache.commons.httpclient.auth.AuthScope; -import org.apache.commons.httpclient.params.HttpClientParams; -import org.apache.commons.httpclient.protocol.Protocol; -import org.eclipse.mylar.internal.tasks.core.AuthenticatedProxy; -import org.eclipse.mylar.internal.tasks.core.SslProtocolSocketFactory; -import org.eclipse.update.internal.core.UpdateCore; - -/** - * @author Mik Kersten - * @author Steffen Pingel - */ -public class WebClientUtil { - - private static final int HTTP_PORT = 80; - - private static final int HTTPS_PORT = 443; - - // private static final int COM_TIME_OUT = 30000; - - //public static final String ENCODING_GZIP = "gzip"; - - public static void initCommonsLoggingSettings() { - // TODO: move? - System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog"); - System.setProperty("org.apache.commons.logging.simplelog.log.httpclient.wire.header", "off"); - System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.commons.httpclient", "off"); - } - - /** - * public for testing - */ - public static boolean repositoryUsesHttps(String repositoryUrl) { - return repositoryUrl.matches("https.*"); - } - - public static int getPort(String repositoryUrl) { - int colonSlashSlash = repositoryUrl.indexOf("://"); - int colonPort = repositoryUrl.indexOf(':', colonSlashSlash + 1); - if (colonPort < 0) - return repositoryUsesHttps(repositoryUrl) ? HTTPS_PORT : HTTP_PORT; - - int requestPath = repositoryUrl.indexOf('/', colonPort + 1); - - int end; - if (requestPath < 0) - end = repositoryUrl.length(); - else - end = requestPath; - - return Integer.parseInt(repositoryUrl.substring(colonPort + 1, end)); - } - - public static String getDomain(String repositoryUrl) { - String result = repositoryUrl; - int colonSlashSlash = repositoryUrl.indexOf("://"); - - if (colonSlashSlash >= 0) { - result = repositoryUrl.substring(colonSlashSlash + 3); - } - - int colonPort = result.indexOf(':'); - int requestPath = result.indexOf('/'); - - int substringEnd; - - // minimum positive, or string length - if (colonPort > 0 && requestPath > 0) - substringEnd = Math.min(colonPort, requestPath); - else if (colonPort > 0) - substringEnd = colonPort; - else if (requestPath > 0) - substringEnd = requestPath; - else - substringEnd = result.length(); - - return result.substring(0, substringEnd); - } - - public static String getRequestPath(String repositoryUrl) { - int colonSlashSlash = repositoryUrl.indexOf("://"); - int requestPath = repositoryUrl.indexOf('/', colonSlashSlash + 3); - - if (requestPath < 0) { - return ""; - } else { - return repositoryUrl.substring(requestPath); - } - } - - public static void setupHttpClient(HttpClient client, Proxy proxySettings, String repositoryUrl, String user, - String password) { - - client.getParams().setBooleanParameter(HttpClientParams.ALLOW_CIRCULAR_REDIRECTS, true); - - // Note: The following debug code requires http commons-logging and - // commons-logging-api jars - //System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog"); - //System.setProperty("org.apache.commons.logging.simplelog.showdatetime", "true"); - //System.setProperty("org.apache.commons.logging.simplelog.log.httpclient.wire", "debug"); - //System.setProperty("org.apache.commons.logging.simplelog.log.httpclient.wire.header", "debug"); - //System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.commons.httpclient", "debug"); - - - if (proxySettings != null && !Proxy.NO_PROXY.equals(proxySettings) && !WebClientUtil.repositoryUsesHttps(repositoryUrl) && proxySettings.address() instanceof InetSocketAddress) { - InetSocketAddress address = (InetSocketAddress) proxySettings.address(); - client.getHostConfiguration().setProxy(WebClientUtil.getDomain(address.getHostName()), address.getPort()); - if (proxySettings instanceof AuthenticatedProxy) { - AuthenticatedProxy authProxy = (AuthenticatedProxy) proxySettings; - Credentials credentials = new UsernamePasswordCredentials(authProxy.getUserName(), authProxy - .getPassword()); - AuthScope proxyAuthScope = new AuthScope(address.getHostName(), address.getPort(), AuthScope.ANY_REALM); - client.getState().setProxyCredentials(proxyAuthScope, credentials); - } - } - - if (user != null && password != null) { - AuthScope authScope = new AuthScope(WebClientUtil.getDomain(repositoryUrl), WebClientUtil - .getPort(repositoryUrl), AuthScope.ANY_REALM); - client.getState().setCredentials(authScope, new UsernamePasswordCredentials(user, password)); - } - - if (WebClientUtil.repositoryUsesHttps(repositoryUrl)) { - Protocol acceptAllSsl = new Protocol("https", new SslProtocolSocketFactory(proxySettings), WebClientUtil - .getPort(repositoryUrl)); - client.getHostConfiguration().setHost(WebClientUtil.getDomain(repositoryUrl), - WebClientUtil.getPort(repositoryUrl), acceptAllSsl); - } else { - client.getHostConfiguration().setHost(WebClientUtil.getDomain(repositoryUrl), - WebClientUtil.getPort(repositoryUrl)); - } - } - - /** utility method, should use TaskRepository.getProxy() */ - public static Proxy getSystemProxy() { - Proxy proxy = Proxy.NO_PROXY; - if (UpdateCore.getPlugin() != null - && UpdateCore.getPlugin().getPluginPreferences().getBoolean(UpdateCore.HTTP_PROXY_ENABLE)) { - String proxyHost = UpdateCore.getPlugin().getPluginPreferences().getString(UpdateCore.HTTP_PROXY_HOST); - int proxyPort = UpdateCore.getPlugin().getPluginPreferences().getInt(UpdateCore.HTTP_PROXY_PORT); - - InetSocketAddress sockAddr = new InetSocketAddress(proxyHost, proxyPort); - proxy = new Proxy(Type.HTTP, sockAddr); - } - return proxy; - } - - /** utility method, should use TaskRepository.getProxy() */ - public static Proxy getProxy(String proxyHost, String proxyPort, String proxyUsername, String proxyPassword) { - boolean authenticated = (proxyUsername != null && proxyPassword != null && proxyUsername.length() > 0 && proxyPassword - .length() > 0); - if (proxyHost != null && proxyHost.length() > 0 && proxyPort != null && proxyPort.length() > 0) { - int proxyPortNum = Integer.parseInt(proxyPort); - InetSocketAddress sockAddr = new InetSocketAddress(proxyHost, proxyPortNum); - if (authenticated) { - return new AuthenticatedProxy(Type.HTTP, sockAddr, proxyUsername, proxyPassword); - } else { - return new Proxy(Type.HTTP, sockAddr); - } - } - return Proxy.NO_PROXY; - } - -} - -// /** -// * Returns an opened HttpURLConnection. If the proxy fails a direct -// * connection is attempted. -// */ -// public static HttpURLConnection openUrlConnection(URL url, Proxy proxy, -// boolean useTls, String htAuthUser, -// String htAuthPass) throws IOException, KeyManagementException, -// GeneralSecurityException { -// -// if (proxy == null) { -// proxy = Proxy.NO_PROXY; -// } -// -// HttpURLConnection remoteConnection = getUrlConnection(url, proxy, useTls, -// htAuthUser, htAuthPass); -// try { -// remoteConnection = openConnection(url, proxy); -// } catch (ConnectException e) { -// remoteConnection = openConnection(url, Proxy.NO_PROXY); -// } -// -// return remoteConnection; -// } - -// /** -// * Returns connection that has yet to be opened (can still set connection -// * parameters). Catch ConnectException and retry with Proxy.NO_PROXY if -// * necessary. -// */ -// public static HttpURLConnection getUrlConnection(URL url, Proxy proxy, -// boolean useTls, String htAuthUser, -// String htAuthPass) throws IOException, KeyManagementException, -// GeneralSecurityException { -// SSLContext ctx; -// if (useTls) { -// ctx = SSLContext.getInstance("TLS"); -// } else { -// ctx = SSLContext.getInstance("SSL"); -// } -// -// javax.net.ssl.TrustManager[] tm = new javax.net.ssl.TrustManager[] { new -// RepositoryTrustManager() }; -// ctx.init(null, tm, null); -// HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory()); -// -// if (proxy == null) { -// proxy = Proxy.NO_PROXY; -// } -// -// URLConnection connection = url.openConnection(proxy); -// -// // Add http basic authentication credentials if supplied -// // Ref: http://www.javaworld.com/javaworld/javatips/jw-javatip47.html -// if (htAuthUser != null && htAuthPass != null && !htAuthUser.equals("")) { -// String authenticationString = htAuthUser + ":" + htAuthPass; -// String encodedAuthenticationString = null; -// try { -// sun.misc.BASE64Encoder encoder = (sun.misc.BASE64Encoder) -// Class.forName("sun.misc.BASE64Encoder") -// .newInstance(); -// encodedAuthenticationString = -// encoder.encode(authenticationString.getBytes()); -// connection.setRequestProperty("Authorization", "Basic " + -// encodedAuthenticationString); -// } catch (Exception ex) { -// // ignore, encoder not available -// } -// } -// -// if (connection == null || !(connection instanceof HttpURLConnection)) { -// throw new MalformedURLException(); -// } -// return (HttpURLConnection) connection; -// } - -// private static HttpURLConnection openConnection(URL url, Proxy proxy) -// throws IOException { -// URLConnection connection = url.openConnection(proxy); -// if (connection == null || !(connection instanceof HttpURLConnection)) { -// throw new MalformedURLException(); -// } -// HttpURLConnection remoteConnection = (HttpURLConnection) connection; -// remoteConnection.addRequestProperty("Accept-Encoding", ENCODING_GZIP); -// remoteConnection.setConnectTimeout(COM_TIME_OUT); -// remoteConnection.setReadTimeout(COM_TIME_OUT); -// remoteConnection.connect(); -// return remoteConnection; -// } |