/* ********************************************************************** ** ** Copyright notice ** ** ** ** (c) 2005-2009 RSSOwl Development Team ** ** http://www.rssowl.org/ ** ** ** ** 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.rssowl.org/legal/epl-v10.html ** ** ** ** A copy is found in the file epl-v10.html and important notices to the ** ** license from the team is found in the textfile LICENSE.txt distributed ** ** in this package. ** ** ** ** This copyright notice MUST APPEAR in all copies of the file! ** ** ** ** Contributors: ** ** RSSOwl Development Team - initial API and implementation ** ** ** ** ********************************************************************** */ package org.rssowl.core.internal.connection; import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtensionRegistry; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.InvalidRegistryObjectException; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Platform; import org.eclipse.osgi.util.NLS; import org.osgi.service.url.URLConstants; import org.osgi.service.url.URLStreamHandlerService; import org.rssowl.core.Owl; import org.rssowl.core.connection.ConnectionException; import org.rssowl.core.connection.CredentialsException; import org.rssowl.core.connection.IConnectionService; import org.rssowl.core.connection.ICredentials; import org.rssowl.core.connection.ICredentialsProvider; import org.rssowl.core.connection.IProtocolHandler; import org.rssowl.core.connection.IProxyCredentials; import org.rssowl.core.connection.UnknownProtocolException; import org.rssowl.core.internal.Activator; import org.rssowl.core.internal.InternalOwl; import org.rssowl.core.persist.IConditionalGet; import org.rssowl.core.persist.IFeed; import org.rssowl.core.persist.dao.DynamicDAO; import org.rssowl.core.persist.event.FeedAdapter; import org.rssowl.core.persist.event.FeedEvent; import org.rssowl.core.persist.event.FeedListener; import org.rssowl.core.util.ExtensionUtils; import org.rssowl.core.util.StringUtils; import org.rssowl.core.util.Triple; import java.net.URI; import java.util.HashMap; import java.util.Hashtable; import java.util.Map; import java.util.Set; /** * The ConnectionManager is the main class of the connection plugin. It is * responsible to retrieve the contents of a Feed by supplying an InputStream. * * @author bpasero */ public class ConnectionServiceImpl implements IConnectionService { /* ID of the contributed ProtocolHandlers */ private static final String PROTHANDLER_EXTENSION_POINT = "org.rssowl.core.ProtocolHandler"; //$NON-NLS-1$ /* ID of the contributed CredentialsProviders */ private static final String CREDPROVIDER_EXTENSION_POINT = "org.rssowl.core.CredentialsProvider"; //$NON-NLS-1$ /* Extension Point: SSL Handler */ private static final String SSL_HANDLER_EXTENSION_POINT = "org.rssowl.core.SSLHandler"; //$NON-NLS-1$ private final Map<String, IProtocolHandler> fProtocolHandler; private final Map<String, ICredentialsProvider> fCredentialsProvider; private final SecureProtocolSocketFactory fSecureProtocolSocketFactory; private final FeedListener fFeedListener; /** Default Constructor */ public ConnectionServiceImpl() { fProtocolHandler = new HashMap<String, IProtocolHandler>(); fCredentialsProvider = new HashMap<String, ICredentialsProvider>(); /* Init */ fFeedListener = createFeedListener(); startup(); fSecureProtocolSocketFactory = loadSSLHandler(); } private void startup() { /* Load Contributions */ loadProtocolHandlers(); loadCredentialsProvider(); /* Register URL Stream Handlers to OSGI */ registerURLStreamHandlers(); /* Register Listeners */ registerListeners(); } private FeedListener createFeedListener() { return new FeedAdapter() { @Override public void entitiesDeleted(Set<FeedEvent> events) { for (FeedEvent feedEvent : events) { URI feedLink = feedEvent.getEntity().getLink(); try { String protocol = feedLink.getScheme(); if (protocol != null) { ICredentialsProvider credentialsProvider = fCredentialsProvider.get(protocol); /* Delete Auth Credentials if provided */ if (credentialsProvider != null && credentialsProvider.getAuthCredentials(feedLink, null) != null) credentialsProvider.deleteAuthCredentials(feedLink, null); } } catch (CredentialsException e) { Activator.getDefault().getLog().log(e.getStatus()); } } } }; } private void registerListeners() { /* We register listeners as part of initialisation, we must use InternalOwl */ InternalOwl.getDefault().getPersistenceService().getDAOService().getFeedDAO().addEntityListener(fFeedListener); } /* * @see org.rssowl.core.connection.IConnectionService#shutdown() */ public void shutdown() { unregisterListeners(); } private void unregisterListeners() { if (Owl.isStarted()) DynamicDAO.removeEntityListener(IFeed.class, fFeedListener); } /* * @see org.rssowl.core.connection.IConnectionService#getHandler(java.net.URI) */ public IProtocolHandler getHandler(URI link) throws ConnectionException { String protocol = link.getScheme(); IProtocolHandler handler = fProtocolHandler.get(protocol); /* Handler present */ if (handler != null) return handler; /* No Handler present */ throw new UnknownProtocolException(Activator.getDefault().createErrorStatus(NLS.bind(Messages.ConnectionServiceImpl_ERROR_NO_PROTOCOL_HANDLER, protocol), null), protocol); } /* * @see org.rssowl.core.connection.IConnectionService#getLabel(java.net.URI, * org.eclipse.core.runtime.IProgressMonitor) */ public String getLabel(URI link, IProgressMonitor monitor) throws ConnectionException { String protocol = link.getScheme(); IProtocolHandler handler = fProtocolHandler.get(protocol); /* Handler present */ if (handler != null) return handler.getLabel(link, monitor); /* No Handler present */ throw new UnknownProtocolException(Activator.getDefault().createErrorStatus(NLS.bind(Messages.ConnectionServiceImpl_ERROR_NO_PROTOCOL_HANDLER, protocol), null), protocol); } /* * @see org.rssowl.core.connection.IConnectionService#reload(java.net.URI, * org.eclipse.core.runtime.IProgressMonitor, java.util.Map) */ public Triple<IFeed, IConditionalGet, URI> reload(URI link, IProgressMonitor monitor, Map<Object, Object> properties) throws CoreException { String protocol = link.getScheme(); IProtocolHandler handler = fProtocolHandler.get(protocol); /* Make sure to provide a Monitor */ if (monitor == null) monitor = new NullProgressMonitor(); /* Handler present */ if (handler != null) return handler.reload(link, monitor, properties); /* No Handler present */ throw new UnknownProtocolException(Activator.getDefault().createErrorStatus(NLS.bind(Messages.ConnectionServiceImpl_ERROR_NO_PROTOCOL_HANDLER, protocol), null), protocol); } /* * @see * org.rssowl.core.connection.IConnectionService#getFeedIcon(java.net.URI, * org.eclipse.core.runtime.IProgressMonitor) */ public byte[] getFeedIcon(URI link, IProgressMonitor monitor) throws ConnectionException { String protocol = link.getScheme(); IProtocolHandler handler = fProtocolHandler.get(protocol); /* Handler present */ if (handler != null) return handler.getFeedIcon(link, monitor); /* No Handler present */ throw new UnknownProtocolException(Activator.getDefault().createErrorStatus(NLS.bind(Messages.ConnectionServiceImpl_ERROR_NO_PROTOCOL_HANDLER, protocol), null), protocol); } /* * @see org.rssowl.core.connection.IConnectionService#getFeed(java.net.URI, * org.eclipse.core.runtime.IProgressMonitor) */ public URI getFeed(URI link, IProgressMonitor monitor) throws ConnectionException { String protocol = link.getScheme(); IProtocolHandler handler = fProtocolHandler.get(protocol); /* Handler present */ if (handler != null) return handler.getFeed(link, monitor); /* No Handler present */ throw new UnknownProtocolException(Activator.getDefault().createErrorStatus(NLS.bind(Messages.ConnectionServiceImpl_ERROR_NO_PROTOCOL_HANDLER, protocol), null), protocol); } /* * @see * org.rssowl.core.connection.IConnectionService#getCredentialsProvider(java * .net.URI) */ public ICredentialsProvider getCredentialsProvider(URI link) { return fCredentialsProvider.get(link.getScheme()); } /* * @see * org.rssowl.core.connection.IConnectionService#getSecureProtocolSocketFactory * () */ public SecureProtocolSocketFactory getSecureProtocolSocketFactory() { return fSecureProtocolSocketFactory; } /* * @see * org.rssowl.core.connection.IConnectionService#getAuthCredentials(java.net * .URI, java.lang.String) */ public ICredentials getAuthCredentials(URI link, String realm) throws CredentialsException { /* Require credentials provider */ ICredentialsProvider credentialsProvider = internalGetCredentialsProvider(link); /* Retrieve Credentials */ ICredentials credentials = credentialsProvider.getAuthCredentials(link, realm); return credentials; } /* * @see * org.rssowl.core.connection.IConnectionService#getProxyCredentials(java. * net.URI) */ public IProxyCredentials getProxyCredentials(URI link) throws CredentialsException { /* Require credentials provider */ ICredentialsProvider credentialsProvider = internalGetCredentialsProvider(link); /* Retrieve Credentials */ IProxyCredentials credentials = credentialsProvider.getProxyCredentials(link); return credentials; } private ICredentialsProvider internalGetCredentialsProvider(URI link) throws CredentialsException { String protocol = link.getScheme(); /* Require protocol */ if (!StringUtils.isSet(protocol)) throw new CredentialsException(Activator.getDefault().createErrorStatus(Messages.ConnectionServiceImpl_ERROR_UNKNOWN_PROTOCOL, null)); /* Require credentials provider */ ICredentialsProvider credentialsProvider = fCredentialsProvider.get(protocol); if (credentialsProvider == null) throw new CredentialsException(Activator.getDefault().createErrorStatus(NLS.bind(Messages.ConnectionServiceImpl_ERROR_NO_CREDENTIAL_PROVIDER, protocol), null)); return credentialsProvider; } private void loadProtocolHandlers() { IExtensionRegistry reg = Platform.getExtensionRegistry(); IConfigurationElement elements[] = reg.getConfigurationElementsFor(PROTHANDLER_EXTENSION_POINT); for (IConfigurationElement element : elements) { try { String protocol = element.getAttribute("protocol"); //$NON-NLS-1$ /* Let 3d-Party contributions override our contributions */ if (fProtocolHandler.containsKey(protocol) && element.getNamespaceIdentifier().contains(ExtensionUtils.RSSOWL_NAMESPACE)) continue; fProtocolHandler.put(protocol, (IProtocolHandler) element.createExecutableExtension("class"));//$NON-NLS-1$ } catch (InvalidRegistryObjectException e) { Activator.getDefault().logError(e.getMessage(), e); } catch (CoreException e) { Activator.getDefault().getLog().log(e.getStatus()); } } } /* Load Credentials Provider contribution */ private void loadCredentialsProvider() { IExtensionRegistry reg = Platform.getExtensionRegistry(); IConfigurationElement elements[] = reg.getConfigurationElementsFor(CREDPROVIDER_EXTENSION_POINT); for (IConfigurationElement element : elements) { try { String protocol = element.getAttribute("protocol"); //$NON-NLS-1$ /* Let 3d-Party contributions override our contributions */ String nsId = element.getNamespaceIdentifier(); if (fCredentialsProvider.containsKey(protocol) && nsId.contains(ExtensionUtils.RSSOWL_NAMESPACE) && !nsId.contains(ExtensionUtils.RSSOWL_TESTS_NAMESPACE)) continue; fCredentialsProvider.put(protocol, (ICredentialsProvider) element.createExecutableExtension("class"));//$NON-NLS-1$ } catch (InvalidRegistryObjectException e) { Activator.getDefault().logError(e.getMessage(), e); } catch (CoreException e) { Activator.getDefault().getLog().log(e.getStatus()); } } } /* Load SSLHandler Contribution */ private SecureProtocolSocketFactory loadSSLHandler() { return (SecureProtocolSocketFactory) ExtensionUtils.loadSingletonExecutableExtension(SSL_HANDLER_EXTENSION_POINT); } private void registerURLStreamHandlers() { /* Foreach Contributed Protocol */ for (String protocol : fProtocolHandler.keySet()) { IProtocolHandler protocolHandler = fProtocolHandler.get(protocol); /* A URLStreamHandler is provided */ try { if (protocolHandler.getURLStreamHandler() != null) { Hashtable<String, String[]> properties = new Hashtable<String, String[]>(1); properties.put(URLConstants.URL_HANDLER_PROTOCOL, new String[] { protocol }); Activator.getDefault().getContext().registerService(URLStreamHandlerService.class.getName(), protocolHandler.getURLStreamHandler(), properties); } } catch (ConnectionException e) { Activator.getDefault().getLog().log(e.getStatus()); } } } }