URLStreamHandlerWrapper.java

00001 /*
00002  * Copyright (c) 2003-2006, KNOPFLERFISH project
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following
00007  * conditions are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  *
00012  * - Redistributions in binary form must reproduce the above
00013  *   copyright notice, this list of conditions and the following
00014  *   disclaimer in the documentation and/or other materials
00015  *   provided with the distribution.
00016  *
00017  * - Neither the name of the KNOPFLERFISH project nor the names of its
00018  *   contributors may be used to endorse or promote products derived
00019  *   from this software without specific prior written permission.
00020  *
00021  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00027  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00028  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00029  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
00030  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00031  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
00032  * OF THE POSSIBILITY OF SUCH DAMAGE.
00033  */
00034 
00035 package org.knopflerfish.framework;
00036 
00037 import java.io.*;
00038 import java.net.*;
00039 
00040 import org.osgi.service.url.*;
00041 import org.osgi.framework.*;
00042 
00043 import org.osgi.framework.Constants;
00044 
00054 public class URLStreamHandlerWrapper
00055   extends    URLStreamHandler 
00056   implements URLStreamHandlerSetter
00057 {
00058 
00059   Framework              framework;
00060   String                 protocol;
00061   String                 filter;
00062   
00063   private ServiceReference best;
00064 
00065   URLStreamHandlerWrapper(Framework  fw,
00066                           String     proto) {
00067 
00068     this.framework = fw;
00069     this.protocol  = proto;
00070 
00071     filter = 
00072       "(&" + 
00073       "(" + Constants.OBJECTCLASS + "=" + 
00074       URLStreamHandlerService.class.getName() + ")" + 
00075       "(" + URLConstants.URL_HANDLER_PROTOCOL + "=" + protocol + 
00076       ")" + 
00077       ")";
00078 
00079     ServiceListener serviceListener = 
00080       new ServiceListener() {
00081         public void serviceChanged(ServiceEvent evt) {
00082           ServiceReference ref = 
00083             evt.getServiceReference();
00084             
00085           switch (evt.getType()) {
00086           case ServiceEvent.MODIFIED: {
00087             // fall through
00088           } 
00089           case ServiceEvent.REGISTERED: {
00090             if (best == null) {
00091               updateBest();
00092               return ;
00093             }
00094             if (compare(best, ref) > 0) {
00095               best = ref;
00096             }
00097             
00098           }; break;
00099           case ServiceEvent.UNREGISTERING: {
00100             if (best.equals(ref)) {
00101               best = null;
00102             }
00103           }
00104           }
00105         }
00106       };
00107     
00108     try {
00109       framework.systemBC.addServiceListener(serviceListener, filter);
00110       
00111     } catch (Exception e) {
00112       throw new IllegalArgumentException("Could not register service listener for url handler: " + e);
00113     }
00114     
00115     if(Debug.url) {
00116       Debug.println("created wrapper for " + protocol + ", filter=" + filter + ", " + toString());
00117     }
00118   }
00119 
00120   private int compare(ServiceReference ref1, ServiceReference ref2) {
00121     Object tmp1 = ref1.getProperty(Constants.SERVICE_RANKING);
00122     Object tmp2 = ref2.getProperty(Constants.SERVICE_RANKING);
00123     
00124     int r1 = (tmp1 instanceof Integer) ? ((Integer)tmp1).intValue() : 0;
00125     int r2 = (tmp2 instanceof Integer) ? ((Integer)tmp2).intValue() : 0;
00126 
00127     if (r2 == r1) {
00128       Long i1 = (Long)ref1.getProperty(Constants.SERVICE_ID);      
00129       Long i2 = (Long)ref2.getProperty(Constants.SERVICE_ID);
00130       return i1.compareTo(i2);
00131 
00132     } else {
00133       return r2 -r1;
00134     }
00135   }
00136 
00137   private void updateBest() {
00138     try {
00139       ServiceReference[] refs =
00140         framework.systemBC.getServiceReferences(URLStreamHandlerService.class.getName(), 
00141                                                 filter);
00142       if (refs != null) {
00143         best = refs[0];
00144       } 
00145 
00146       for (int i = 1; i < refs.length; i++) {
00147         if (compare(best, refs[i]) > 0) {
00148           best = refs[i];
00149         }
00150       }
00151 
00152     } catch (Exception e) {
00153       // this should not happen.
00154       throw new IllegalArgumentException("Could not register url handler: " + e);
00155     }
00156   }
00157 
00158 
00159 
00160   private URLStreamHandlerService getService() {
00161     URLStreamHandlerService obj;
00162 
00163     try {
00164       if (best == null) {
00165         updateBest();
00166       }
00167 
00168       if (best == null) {
00169         throw new IllegalStateException("null: Lost service for protocol="+ protocol);
00170       }
00171       obj = (URLStreamHandlerService)framework.systemBC.getService(best);
00172 
00173       if (obj == null) {
00174         throw new IllegalStateException("null: Lost service for protocol=" + protocol);
00175       }
00176       
00177     } catch (Exception e) {
00178       throw new IllegalStateException("null: Lost service for protocol=" + protocol);
00179     }
00180 
00181     return obj;
00182   }
00183 
00184   public boolean equals(URL u1, URL u2) {
00185     return getService().equals(u1, u2);
00186   }
00187 
00188   protected int getDefaultPort() {
00189     return getService().getDefaultPort();
00190   }
00191 
00192   protected InetAddress getHostAddress(URL u) {
00193     return getService().getHostAddress(u);
00194   }
00195 
00196   protected int hashCode(URL u) {
00197     return getService().hashCode(u);
00198   }
00199 
00200   protected boolean hostsEqual(URL u1, URL u2) {
00201     return getService().hostsEqual(u1, u2);
00202   }
00203 
00204   protected URLConnection openConnection(URL u) throws IOException {
00205     try {
00206       return getService().openConnection(u);
00207     } catch(IllegalStateException e) {
00208       throw new MalformedURLException(e.getMessage());
00209     }
00210   }
00211 
00212   protected  void parseURL(URL u, String spec, int start, int limit) {
00213     getService().parseURL(this, u, spec, start, limit);
00214   }
00215     
00216   protected  boolean sameFile(URL u1, URL u2) {
00217     return getService().sameFile(u1, u2);
00218   }
00219 
00220   
00225   public  void setURL(URL u, String protocol, String host, int port, String file, String ref) {
00226     
00227     // parse host as "user:passwd@host"
00228 
00229     String authority = null;
00230     String userInfo = null;
00231 
00232     if (host != null && host.length() != 0) {
00233 
00234       authority = (port == -1) ? host : host + ":" + port;
00235 
00236       int ix = host.lastIndexOf('@');
00237       if (ix != -1) {
00238         userInfo = host.substring(0, ix);
00239         host     = host.substring(ix+1);
00240       }
00241     }
00242         
00243 
00244     // Parse query part from file ending with '?'
00245     String path  = null;
00246     String query = null;
00247 
00248     if (file != null) {
00249       int ix = file.lastIndexOf('?');
00250       if (ix != -1) {
00251         query = file.substring(ix + 1);
00252         path  = file.substring(0, ix);
00253       } else {
00254         path = file;
00255       }
00256     }
00257     setURL(u, protocol, host, port, authority, userInfo, path, query, ref);
00258   }    
00259 
00260   public  void setURL(URL    u, 
00261                       String protocol,
00262                       String host, 
00263                       int    port, 
00264                       String authority, 
00265                       String userInfo, 
00266                       String path, 
00267                       String query, 
00268                       String ref) {
00269     super.setURL(u, protocol, host, port, 
00270                  authority, userInfo, 
00271                  path, query, 
00272                  ref);
00273   }
00274 
00275   protected  String toExternalForm(URL u) {
00276     return getService().toExternalForm(u);
00277   }
00278 
00279   public String toString() {
00280     StringBuffer sb = new StringBuffer();
00281 
00282     sb.append("URLStreamHandlerWrapper[");
00283 
00284     ServiceReference ref = best;
00285     sb.append("protocol=" + protocol);
00286     //    sb.append(", size=" + tracker.size());
00287     if(ref != null) {
00288       sb.append(", id=" + ref.getProperty(Constants.SERVICE_ID));
00289       sb.append(", rank=" + ref.getProperty(Constants.SERVICE_RANKING));
00290 
00291 //       ServiceReference[] srl = tracker.getServiceReferences();
00292 //       for(int i = 0; srl != null && i < srl.length; i++) {
00293 //      sb.append(", {");
00294 //      sb.append("id=" + srl[i].getProperty(Constants.SERVICE_ID));
00295 //      sb.append(", rank=" + srl[i].getProperty(Constants.SERVICE_RANKING));
00296 
00297 //      String[] sa = (String[])srl[i].getProperty(URLConstants.URL_HANDLER_PROTOCOL);
00298 //      sb.append(", proto=");
00299         
00300 //      for(int j = 0; j < sa.length; j++) {
00301 //        sb.append(sa[j]);
00302 //        if(j < sa.length - 1) {
00303 //          sb.append(", ");
00304 //        }
00305 //      }
00306 //      sb.append("}");
00307 //       }
00308       
00309     } else {
00310       sb.append(" no service tracked");
00311     }
00312 
00313     sb.append("]");
00314 
00315     return sb.toString();
00316   }
00317 }
00318   

Generated on Mon Jan 11 21:19:17 2010 for OpenMobileIS by  doxygen 1.5.4