KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > osgi > framework > internal > protocol > ContentHandlerProxy


1 /*******************************************************************************
2  * Copyright (c) 2003, 2005 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11
12 package org.eclipse.osgi.framework.internal.protocol;
13
14 import java.io.IOException JavaDoc;
15 import java.net.ContentHandler JavaDoc;
16 import java.net.URLConnection JavaDoc;
17 import org.osgi.framework.*;
18 import org.osgi.service.url.URLConstants;
19 import org.osgi.util.tracker.ServiceTracker;
20 import org.osgi.util.tracker.ServiceTrackerCustomizer;
21
22 /**
23  * The ContentHandlerProxy is a ContentHandler that acts as a proxy for registered ContentHandlers.
24  * When a ContentHandler is requested from the ContentHandlerFactory and it exists in the service
25  * registry, a ContentHandlerProxy is created which will pass all the requests from the requestor to
26  * the real ContentHandler. We can't return the real ContentHandler from the ContentHandlerFactory
27  * because the JVM caches ContentHandlers and therefore would not support a dynamic environment of
28  * ContentHandlers being registered and unregistered.
29  */

30 public class ContentHandlerProxy extends ContentHandler JavaDoc implements ServiceTrackerCustomizer {
31     protected ContentHandler JavaDoc realHandler;
32
33     //TODO avoid type-based names
34
protected ServiceTracker contentHandlerServiceTracker;
35
36     protected BundleContext context;
37     protected ServiceReference contentHandlerServiceReference;
38
39     protected String JavaDoc contentType;
40
41     protected int ranking = Integer.MIN_VALUE;
42
43     public ContentHandlerProxy(String JavaDoc contentType, ServiceReference reference, BundleContext context) {
44         this.context = context;
45         this.contentType = contentType;
46
47         // In case the reference == null, the proxy is constructed with DefaultContentHandler for a Content Handler
48
// until a real ContentHandler for this mime-type is registered
49
setNewHandler(reference, getRank(reference));
50
51         contentHandlerServiceTracker = new ServiceTracker(context, ContentHandler JavaDoc.class.getName(), this);
52         StreamHandlerFactory.secureAction.open(contentHandlerServiceTracker);
53     }
54
55     private void setNewHandler(ServiceReference reference, int rank) {
56         if (contentHandlerServiceReference != null)
57             context.ungetService(contentHandlerServiceReference);
58
59         contentHandlerServiceReference = reference;
60         ranking = rank;
61
62         if (reference == null)
63             realHandler = new DefaultContentHandler();
64         else
65             realHandler = (ContentHandler JavaDoc) StreamHandlerFactory.secureAction.getService(reference, context);
66     }
67
68     /**
69      * @see org.osgi.util.tracker.ServiceTrackerCustomizer#addingService(ServiceReference)
70      */

71     public Object JavaDoc addingService(ServiceReference reference) {
72         //check to see if our contentType is being registered by another service
73
Object JavaDoc prop = reference.getProperty(URLConstants.URL_CONTENT_MIMETYPE);
74         if (!(prop instanceof String JavaDoc[]))
75             return null;
76         String JavaDoc[] contentTypes = (String JavaDoc[]) prop;
77         for (int i = 0; i < contentTypes.length; i++) {
78             if (contentTypes[i].equals(contentType)) {
79                 //If our contentType is registered by another service, check the service ranking and switch URLStreamHandlers if nessecary.
80
int newServiceRanking = getRank(reference);
81                 if (newServiceRanking > ranking || contentHandlerServiceReference == null)
82                     setNewHandler(reference, newServiceRanking);
83                 return (reference);
84             }
85         }
86
87         //we don't want to continue hearing events about a ContentHandler service not registered under our contentType
88
return (null);
89     }
90
91     /**
92      * @see org.osgi.util.tracker.ServiceTrackerCustomizer#modifiedService(ServiceReference, Object)
93      */

94
95     public void modifiedService(ServiceReference reference, Object JavaDoc service) {
96         int newrank = getRank(reference);
97         if (reference == contentHandlerServiceReference) {
98             if (newrank < ranking) {
99                 // The ContentHandler we are currently using has dropped it's ranking below a ContentHandler
100
// registered for the same protocol. We need to swap out ContentHandlers.
101
// this should get us the highest ranked service, if available
102
ServiceReference newReference = contentHandlerServiceTracker.getServiceReference();
103                 if (newReference != contentHandlerServiceReference && newReference != null) {
104                     setNewHandler(newReference, ((Integer JavaDoc) newReference.getProperty(Constants.SERVICE_RANKING)).intValue());
105                 }
106             }
107         } else if (newrank > ranking) {
108             // the service changed is another URLHandler that we are not currently using
109
// If it's ranking is higher, we must swap it in.
110
setNewHandler(reference, newrank);
111         }
112     }
113
114     /**
115      * @see org.osgi.util.tracker.ServiceTrackerCustomizer#removedService(ServiceReference, Object)
116      */

117     public void removedService(ServiceReference reference, Object JavaDoc service) {
118         //check to see if our URLStreamHandler was unregistered.
119
if (reference != contentHandlerServiceReference)
120             return;
121         // If so, look for a lower ranking URLHandler
122
// this should get us the highest ranking service left, if available
123
ServiceReference newReference = contentHandlerServiceTracker.getServiceReference();
124         // if newReference == null then we will use the DefaultContentHandler here
125
setNewHandler(newReference, getRank(newReference));
126     }
127
128     /**
129      * @see java.net.ContentHandler#getContent(URLConnection)
130      */

131
132     public Object JavaDoc getContent(URLConnection JavaDoc uConn) throws IOException JavaDoc {
133         return realHandler.getContent(uConn);
134     }
135
136     private int getRank(ServiceReference reference) {
137         if (reference == null)
138             return Integer.MIN_VALUE;
139         Object JavaDoc property = reference.getProperty(Constants.SERVICE_RANKING);
140         return (property instanceof Integer JavaDoc) ? ((Integer JavaDoc) property).intValue() : 0;
141     }
142
143     class DefaultContentHandler extends ContentHandler JavaDoc {
144
145         /**
146          * @see java.net.ContentHandler#getContent(URLConnection)
147          */

148         public Object JavaDoc getContent(URLConnection JavaDoc uConn) throws IOException JavaDoc {
149             return uConn.getInputStream();
150         }
151     }
152 }
153
Popular Tags