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 }