KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2003, 2006 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.lang.reflect.Method JavaDoc;
15 import java.net.ContentHandler JavaDoc;
16 import java.net.URLConnection JavaDoc;
17 import java.util.*;
18 import org.eclipse.osgi.framework.adaptor.FrameworkAdaptor;
19 import org.eclipse.osgi.framework.internal.core.Msg;
20 import org.eclipse.osgi.framework.log.FrameworkLogEntry;
21 import org.eclipse.osgi.util.NLS;
22 import org.osgi.framework.BundleContext;
23 import org.osgi.service.url.URLConstants;
24 import org.osgi.util.tracker.ServiceTracker;
25
26 /**
27  * The ContentHandlerFactory is registered with the JVM to provide content handlers
28  * to requestors. The ContentHandlerFactory will first look for built-in content handlers.
29  * If a built in handler exists, this factory will return null. Otherwise, this ContentHandlerFactory
30  * will search the service registry for a maching Content-Handler and, if found, return a
31  * proxy for that content handler.
32  */

33 // TODO rename this class!!! its really confusing to name the impl the same as the interface
34
public class ContentHandlerFactory extends MultiplexingFactory implements java.net.ContentHandlerFactory JavaDoc {
35     private ServiceTracker contentHandlerTracker;
36
37     private static final String JavaDoc contentHandlerClazz = "java.net.ContentHandler"; //$NON-NLS-1$
38
private static final String JavaDoc CONTENT_HANDLER_PKGS = "java.content.handler.pkgs"; //$NON-NLS-1$
39
private static final String JavaDoc DEFAULT_VM_CONTENT_HANDLERS = "sun.net.www.content"; //$NON-NLS-1$
40

41     private static final List ignoredClasses = Arrays.asList(new Class JavaDoc[] {MultiplexingContentHandler.class, ContentHandlerFactory.class, URLConnection JavaDoc.class});
42
43     private Hashtable proxies;
44     private java.net.ContentHandlerFactory JavaDoc parentFactory;
45
46     public ContentHandlerFactory(BundleContext context, FrameworkAdaptor adaptor) {
47         super(context, adaptor);
48
49         proxies = new Hashtable(5);
50
51         //We need to track content handler registrations
52
contentHandlerTracker = new ServiceTracker(context, contentHandlerClazz, null);
53         contentHandlerTracker.open();
54     }
55
56     /**
57      * @see java.net.ContentHandlerFactory#createContentHandler(String)
58      */

59     //TODO method is too long... consider reducing indentation (returning quickly) and moving complex steps to private methods
60
public ContentHandler JavaDoc createContentHandler(String JavaDoc contentType) {
61         //first, we check to see if there exists a built in content handler for
62
//this content type. we can not overwrite built in ContentHandlers
63
String JavaDoc builtInHandlers = StreamHandlerFactory.secureAction.getProperty(CONTENT_HANDLER_PKGS);
64         builtInHandlers = builtInHandlers == null ? DEFAULT_VM_CONTENT_HANDLERS : DEFAULT_VM_CONTENT_HANDLERS + '|' + builtInHandlers;
65         Class JavaDoc clazz = null;
66         if (builtInHandlers != null) {
67             //replace '/' with a '.' and all characters not allowed in a java class name
68
//with a '_'.
69

70             // find all characters not allowed in java names
71
String JavaDoc convertedContentType = contentType.replace('.', '_');
72             convertedContentType = convertedContentType.replace('/', '.');
73             convertedContentType = convertedContentType.replace('-', '_');
74             StringTokenizer tok = new StringTokenizer(builtInHandlers, "|"); //$NON-NLS-1$
75
while (tok.hasMoreElements()) {
76                 StringBuffer JavaDoc name = new StringBuffer JavaDoc();
77                 name.append(tok.nextToken());
78                 name.append("."); //$NON-NLS-1$
79
name.append(convertedContentType);
80                 try {
81                     clazz = StreamHandlerFactory.secureAction.loadSystemClass(name.toString());
82                     if (clazz != null) {
83                         return (null); //this class exists, it is a built in handler, let the JVM handle it
84
}
85                 } catch (ClassNotFoundException JavaDoc ex) {
86                     //keep looking
87
}
88             }
89         }
90
91         if (isMultiplexing())
92             return new MultiplexingContentHandler(contentType, this);
93
94         return createInternalContentHandler(contentType);
95     }
96
97     public ContentHandler JavaDoc createInternalContentHandler(String JavaDoc contentType) {
98         //first check to see if the handler is in the cache
99
ContentHandlerProxy proxy = (ContentHandlerProxy) proxies.get(contentType);
100         if (proxy != null) {
101             return (proxy);
102         }
103         org.osgi.framework.ServiceReference[] serviceReferences = contentHandlerTracker.getServiceReferences();
104         if (serviceReferences != null) {
105             for (int i = 0; i < serviceReferences.length; i++) {
106                 Object JavaDoc prop = serviceReferences[i].getProperty(URLConstants.URL_CONTENT_MIMETYPE);
107                 if (prop instanceof String JavaDoc)
108                     prop = new String JavaDoc[] {(String JavaDoc) prop}; // TODO should this be a warning?
109
if (!(prop instanceof String JavaDoc[])) {
110                     String JavaDoc message = NLS.bind(Msg.URL_HANDLER_INCORRECT_TYPE, new Object JavaDoc[] {URLConstants.URL_CONTENT_MIMETYPE, contentHandlerClazz, serviceReferences[i].getBundle()});
111                     adaptor.getFrameworkLog().log(new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.WARNING, 0, message, 0, null, null));
112                     continue;
113                 }
114                 String JavaDoc[] contentHandler = (String JavaDoc[]) prop;
115                 for (int j = 0; j < contentHandler.length; j++) {
116                     if (contentHandler[j].equals(contentType)) {
117                         proxy = new ContentHandlerProxy(contentType, serviceReferences[i], context);
118                         proxies.put(contentType, proxy);
119                         return (proxy);
120                     }
121                 }
122             }
123         }
124         // if parent is present do parent lookup before returning a proxy
125
if (parentFactory != null) {
126             ContentHandler JavaDoc parentHandler = parentFactory.createContentHandler(contentType);
127             if (parentHandler != null)
128                 return parentHandler;
129         }
130         //If we can't find the content handler in the service registry, return Proxy with DefaultContentHandler set.
131
//We need to do this because if we return null, we won't get called again for this content type.
132
proxy = new ContentHandlerProxy(contentType, null, context);
133         proxies.put(contentType, proxy);
134         return (proxy);
135     }
136
137     public synchronized ContentHandler JavaDoc findAuthorizedContentHandler(String JavaDoc contentType) {
138         Object JavaDoc factory = findAuthorizedFactory(ignoredClasses);
139         if (factory == null)
140             return null;
141
142         if (factory == this)
143             return createInternalContentHandler(contentType);
144
145         try {
146             Method JavaDoc createInternalContentHandlerMethod = factory.getClass().getMethod("createInternalContentHandler", new Class JavaDoc[] {String JavaDoc.class}); //$NON-NLS-1$
147
return (ContentHandler JavaDoc) createInternalContentHandlerMethod.invoke(factory, new Object JavaDoc[] {contentType});
148         } catch (Exception JavaDoc e) {
149             adaptor.getFrameworkLog().log(new FrameworkLogEntry(ContentHandlerFactory.class.getName(), "findAuthorizedContentHandler-loop", FrameworkLogEntry.ERROR, e, null)); //$NON-NLS-1$
150
throw new RuntimeException JavaDoc(e.getMessage());
151         }
152     }
153
154     public Object JavaDoc getParentFactory() {
155         return parentFactory;
156     }
157
158     public void setParentFactory(Object JavaDoc parentFactory) {
159         if (this.parentFactory == null) // only allow it to be set once
160
this.parentFactory = (java.net.ContentHandlerFactory JavaDoc) parentFactory;
161     }
162 }
163
Popular Tags