aboutsummaryrefslogtreecommitdiffstats
path: root/src/net/java/sip/communicator/impl/protocol/msn/ReferenceURLStreamHandlerService.java
blob: b483c92225fb7ebf0686ebba5fbbfc9e73e9458f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
 * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
 *
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */
package net.java.sip.communicator.impl.protocol.msn;

import java.io.*;
import java.net.*;
import java.util.*;

import net.java.sip.communicator.util.*;

import org.osgi.framework.*;
import org.osgi.service.url.*;

/**
 * Implements {@link URLStreamHandlerService} for the "reference"
 * protocol used inside felix.client.run.properties in order to fix issue #647
 * (MalformedURLException in java-jml) by translating the URL to the
 * "jar" protocol which is natively supported by Java.
 *
 * @author Lubomir Marinov
 */
public class ReferenceURLStreamHandlerService
    extends AbstractURLStreamHandlerService
{

    /**
     * The <tt>Logger</tt> instance used by the
     * <tt>ReferenceURLStreamHandlerService</tt> class and instances for logging
     * output.
     */
    private static final Logger logger
        = Logger.getLogger(ReferenceURLStreamHandlerService.class);

    /**
     * Registers a new <tt>ReferenceURLStreamHandlerService</tt> instance as an
     * implementation of {@link URLStreamHandlerService} in a specific
     * <tt>BundleContext</tt> for the &quot;reference&quot; protocol  if there is
     * no such registered implementation already. Otherwise, the existing
     * registered implementation is considered to be more complete in terms of
     * features than <tt>ReferenceURLStreamHandlerService</tt> and this method
     * does nothing.
     *
     * @param bundleContext the <tt>BundleContext</tt> in which a new
     * <tt>ReferenceURLStreamHandlerService</tt> instance is to be registered
     */
    public static void registerService(BundleContext bundleContext)
    {
        ServiceReference[] serviceReferences;
        String clazz = URLStreamHandlerService.class.getName();
        String propertyName = URLConstants.URL_HANDLER_PROTOCOL;
        String propertyValue = "reference";

        try
        {
            serviceReferences
                = bundleContext
                    .getServiceReferences(
                        clazz,
                        "(" + propertyName + "=" + propertyValue + ")");
        }
        catch (InvalidSyntaxException ise)
        {
            logger
                .warn(
                    "Failed to determine whether there are registered "
                        + "URLStreamHandlerService implementations for the "
                        + "\"reference\" protocol",
                    ise);
            serviceReferences = null;
        }

        if ((serviceReferences != null) && (serviceReferences.length > 0))
            return;

        Dictionary<String, String> properties = new Hashtable<String, String>();

        properties.put(propertyName, propertyValue);
        bundleContext
            .registerService(
                clazz,
                new ReferenceURLStreamHandlerService(),
                properties);
    }

    /**
     * Implements <tt>AbstractURLStreamHandlerService#openConnection(URL)</tt>.
     * Opens a connection to the object referenced by the <tt>URL</tt> argument
     * by rewriting the &quot;reference&quot; protocol in it with the
     * &quot;jar&quot; protocol and then handing it for opening to
     * {@link JarURLConnection}.
     *
     * @param url the <tt>URL</tt> that <tt>this</tt> connects to
     * @return an <tt>URLConnection</tt> instance for the specified <tt>URL</tt>
     * @throws IOException if an I/O error occurs while opening the connection
     */
    @Override
    public URLConnection openConnection(URL url)
        throws IOException
    {
        String referenceSpec = url.toString();
        String jarSpec = referenceSpec.replaceFirst("reference:", "jar:");
        String jarSeparator = "!/";

        // JarURLConnection mandates jarSeparator.
        if (!jarSpec.contains(jarSeparator))
            jarSpec += jarSeparator;

        return new URL(jarSpec).openConnection();
    }
}