/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.gateway.filter.rewrite.impl;
import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteFunctionDescriptor;
import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteFunctionDescriptorFactory;
import org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteFunctionProcessor;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;
import java.util.ServiceLoader;
public abstract class UrlRewriteFunctionProcessorFactory {
private static Map<Class<? extends UrlRewriteFunctionDescriptor>,Map<String,Class<? extends UrlRewriteFunctionProcessor>>> MAP
= loadProcessors();
private UrlRewriteFunctionProcessorFactory() {
}
public static UrlRewriteFunctionProcessor create( String name, UrlRewriteFunctionDescriptor descriptor )
throws IllegalAccessException, InstantiationException {
UrlRewriteFunctionProcessor processor;
if( descriptor == null ) {
descriptor = UrlRewriteFunctionDescriptorFactory.create( name );
}
Map<String,Class<? extends UrlRewriteFunctionProcessor>> typeMap;
typeMap = MAP.get( descriptor.getClass() );
if( typeMap == null ) {
Class<? extends UrlRewriteFunctionDescriptor> descriptorInterface = getDescriptorInterface( descriptor );
typeMap = MAP.get( descriptorInterface );
}
if( typeMap == null ) {
throw new IllegalArgumentException( descriptor.getClass().getName() );
} else {
Class<? extends UrlRewriteFunctionProcessor> processorClass = typeMap.get( name );
if( processorClass == null ) {
throw new IllegalArgumentException( name );
} else {
processor = processorClass.newInstance();
}
}
return processor;
}
private static Map<Class<? extends UrlRewriteFunctionDescriptor>,Map<String,Class<? extends UrlRewriteFunctionProcessor>>> loadProcessors() {
Map<Class<? extends UrlRewriteFunctionDescriptor>,Map<String,Class<? extends UrlRewriteFunctionProcessor>>> descriptorMap
= new HashMap<Class<? extends UrlRewriteFunctionDescriptor>,Map<String,Class<? extends UrlRewriteFunctionProcessor>>>();
ServiceLoader<UrlRewriteFunctionProcessor> processors = ServiceLoader.load( UrlRewriteFunctionProcessor.class );
for( UrlRewriteFunctionProcessor processor : processors ) {
Class<? extends UrlRewriteFunctionDescriptor> descriptorInterface = getDescriptorInterface( processor );
Map<String,Class<? extends UrlRewriteFunctionProcessor>> typeMap = descriptorMap.get( descriptorInterface );
if( typeMap == null ) {
typeMap = new HashMap<String,Class<? extends UrlRewriteFunctionProcessor>>();
descriptorMap.put( descriptorInterface, typeMap );
}
String functionName = processor.name();
typeMap.put( functionName, processor.getClass() );
}
return descriptorMap;
}
private static Class<? extends UrlRewriteFunctionDescriptor> getDescriptorInterface(
UrlRewriteFunctionDescriptor descriptor ) {
Class<? extends UrlRewriteFunctionDescriptor> descriptorClass = null;
for( Type interfaceType : descriptor.getClass().getGenericInterfaces() ) {
Class genericClass = (Class)interfaceType;
if( UrlRewriteFunctionDescriptor.class.isAssignableFrom( genericClass ) ) {
descriptorClass = uncheckedDescriptorClassCast( genericClass );
break;
}
}
return descriptorClass;
}
private static Class<? extends UrlRewriteFunctionDescriptor> getDescriptorInterface(
UrlRewriteFunctionProcessor processor ) {
Class<? extends UrlRewriteFunctionDescriptor> descriptorClass = null;
Class<? extends UrlRewriteFunctionProcessor> processorClass = processor.getClass();
for( Type interfaceType : processorClass.getGenericInterfaces() ) {
if( UrlRewriteFunctionProcessor.class.isAssignableFrom(
(Class)((ParameterizedType)interfaceType).getRawType() ) ) {
ParameterizedType interfaceClass = (ParameterizedType)interfaceType;
descriptorClass = uncheckedDescriptorClassCast( interfaceClass.getActualTypeArguments()[ 0 ] );
break;
}
}
return descriptorClass;
}
@SuppressWarnings("unchecked")
private static Class<? extends UrlRewriteFunctionDescriptor> uncheckedDescriptorClassCast( Type type ) {
return (Class<? extends UrlRewriteFunctionDescriptor>)type;
}
}