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.discovery.tools; 018 019 import java.lang.reflect.InvocationTargetException; 020 021 import org.apache.commons.discovery.DiscoveryException; 022 023 024 /** 025 * Represents a Service Programming Interface (spi). 026 * - SPI's name 027 * - SPI's (provider) class 028 * - SPI's (alternate) override property name 029 * 030 * In addition, while there are many cases where this is NOT 031 * usefull, for those in which it is: 032 * 033 * - expected constructor argument types and parameters values. 034 * 035 * @author Richard A. Sitze 036 */ 037 public class SPInterface { 038 /** 039 * The service programming interface: intended to be 040 * an interface or abstract class, but not limited 041 * to those two. 042 */ 043 private final Class spi; 044 045 /** 046 * The property name to be used for finding the name of 047 * the SPI implementation class. 048 */ 049 private final String propertyName; 050 051 052 private Class paramClasses[] = null; 053 private Object params[] = null; 054 055 056 /** 057 * Construct object representing Class <code>provider</code>. 058 * 059 * @param provider The SPI class 060 */ 061 public SPInterface(Class provider) { 062 this(provider, provider.getName()); 063 } 064 065 /** 066 * Construct object representing Class <code>provider</code>. 067 * 068 * @param spi The SPI class 069 * 070 * @param propertyName when looking for the name of a class implementing 071 * the provider class, a discovery strategy may involve looking for 072 * (system or other) properties having either the name of the class 073 * (provider) or the <code>propertyName</code>. 074 */ 075 public SPInterface(Class spi, String propertyName) { 076 this.spi = spi; 077 this.propertyName = propertyName; 078 } 079 080 /** 081 * Construct object representing Class <code>provider</code>. 082 * 083 * @param provider The SPI class 084 * 085 * @param constructorParamClasses classes representing the 086 * constructor argument types. 087 * 088 * @param constructorParams objects representing the 089 * constructor arguments. 090 */ 091 public SPInterface(Class provider, 092 Class constructorParamClasses[], 093 Object constructorParams[]) 094 { 095 this(provider, 096 provider.getName(), 097 constructorParamClasses, 098 constructorParams); 099 } 100 101 /** 102 * Construct object representing Class <code>provider</code>. 103 * 104 * @param spi The SPI class 105 * 106 * @param propertyName when looking for the name of a class implementing 107 * the provider class, a discovery strategy may involve looking for 108 * (system or other) properties having either the name of the class 109 * (provider) or the <code>propertyName</code>. 110 * 111 * @param constructorParamClasses classes representing the 112 * constructor argument types. 113 * 114 * @param constructorParams objects representing the 115 * constructor arguments. 116 */ 117 public SPInterface(Class spi, 118 String propertyName, 119 Class constructorParamClasses[], 120 Object constructorParams[]) 121 { 122 this.spi = spi; 123 this.propertyName = propertyName; 124 this.paramClasses = constructorParamClasses; 125 this.params = constructorParams; 126 } 127 128 public String getSPName() { 129 return spi.getName(); 130 } 131 132 public Class getSPClass() { 133 return spi; 134 } 135 136 public String getPropertyName() { 137 return propertyName; 138 } 139 140 /** 141 * Instantiate a new 142 */ 143 public Object newInstance(Class impl) 144 throws DiscoveryException, 145 InstantiationException, 146 IllegalAccessException, 147 NoSuchMethodException, 148 InvocationTargetException 149 { 150 verifyAncestory(impl); 151 152 return ClassUtils.newInstance(impl, paramClasses, params); 153 } 154 155 public void verifyAncestory(Class impl) { 156 ClassUtils.verifyAncestory(spi, impl); 157 } 158 }