001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.commons.jnet;
018
019 import java.lang.reflect.Field;
020 import java.lang.reflect.Modifier;
021 import java.net.URL;
022 import java.net.URLStreamHandlerFactory;
023
024 /**
025 * The installer is a general purpose class to install an own
026 * {@link URLStreamHandlerFactory} in any environment.
027 *
028 * TODO Uninstall
029 */
030 public class Installer {
031
032 /**
033 * Set the url stream handler factory.
034 * @param factory
035 * @throws Exception
036 */
037 public static void setURLStreamHandlerFactory(URLStreamHandlerFactory factory)
038 throws Exception {
039 try {
040 // if we can set the factory, its the first!
041 URL.setURLStreamHandlerFactory(factory);
042 } catch (Error err) {
043 // let's use reflection to get the field holding the factory
044 final Field[] fields = URL.class.getDeclaredFields();
045 int index = 0;
046 Field factoryField = null;
047 while ( factoryField == null && index < fields.length ) {
048 final Field current = fields[index];
049 if ( Modifier.isStatic( current.getModifiers() ) && current.getType().equals( URLStreamHandlerFactory.class ) ) {
050 factoryField = current;
051 factoryField.setAccessible(true);
052 } else {
053 index++;
054 }
055 }
056 if ( factoryField == null ) {
057 throw new Exception("Unable to detect static field in the URL class for the URLStreamHandlerFactory. Please report this error together with your exact environment to the Apache Excalibur project.");
058 }
059 try {
060 URLStreamHandlerFactory oldFactory = (URLStreamHandlerFactory)factoryField.get(null);
061 if ( factory instanceof ParentAwareURLStreamHandlerFactory ) {
062 ((ParentAwareURLStreamHandlerFactory)factory).setParentFactory(oldFactory);
063 }
064 factoryField.set(null, factory);
065 } catch (IllegalArgumentException e) {
066 throw new Exception("Unable to set url stream handler factory " + factory);
067 } catch (IllegalAccessException e) {
068 throw new Exception("Unable to set url stream handler factory " + factory);
069 }
070 }
071 }
072
073 protected static Field getStaticURLStreamHandlerFactoryField() {
074 Field[] fields = URL.class.getDeclaredFields();
075 for ( int i = 0; i < fields.length; i++ ) {
076 if ( Modifier.isStatic( fields[i].getModifiers() ) && fields[i].getType().equals( URLStreamHandlerFactory.class ) ) {
077 fields[i].setAccessible( true );
078 return fields[i];
079 }
080 }
081 return null;
082 }
083 }