servicefinder.java

来自「resetful样式的ws样例,一种面向资源的webservices服务」· Java 代码 · 共 689 行 · 第 1/3 页

JAVA
689
字号
/* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. *  * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. *  * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development * and Distribution License("CDDL") (collectively, the "License").  You * may not use this file except in compliance with the License. You can obtain * a copy of the License at https://jersey.dev.java.net/CDDL+GPL.html * or jersey/legal/LICENSE.txt.  See the License for the specific * language governing permissions and limitations under the License. *  * When distributing the software, include this License Header Notice in each * file and include the License file at jersey/legal/LICENSE.txt. * Sun designates this particular file as subject to the "Classpath" exception * as provided by Sun in the GPL Version 2 section of the License file that * accompanied this code.  If applicable, add the following below the License * Header, with the fields enclosed by brackets [] replaced by your own * identifying information: "Portions Copyrighted [year] * [name of copyright owner]" *  * Contributor(s): *  * If you wish your version of this file to be governed by only the CDDL or * only the GPL Version 2, indicate your decision by adding "[Contributor] * elects to include this software in this distribution under the [CDDL or GPL * Version 2] license."  If you don't indicate a single choice of license, a * recipient has the option to distribute your version of this file under * either the CDDL, the GPL Version 2 or to extend the choice of license to * its licensees as provided above.  However, if you add GPL Version 2 code * and therefore, elected the GPL Version 2 license, then the option applies * only if the new code is made subject to such option by the copyright * holder. */package com.sun.jersey.spi.service;import com.sun.jersey.spi.SpiMessages;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.lang.reflect.Array;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;import java.net.URL;import java.net.URLConnection;import java.util.ArrayList;import java.util.Enumeration;import java.util.Iterator;import java.util.List;import java.util.NoSuchElementException;import java.util.Set;import java.util.TreeSet;import java.util.logging.Level;import java.util.logging.Logger;/** * A simple service-provider lookup mechanism.  A <i>service</i> is a * well-known set of interfaces and (usually abstract) classes.  A <i>service * provider</i> is a specific implementation of a service.  The classes in a * provider typically implement the interfaces and subclass the classes defined * in the service itself.  Service providers may be installed in an * implementation of the Java platform in the form of extensions, that is, jar * files placed into any of the usual extension directories.  Providers may * also be made available by adding them to the applet or application class * path or by some other platform-specific means. * <p/> * <p> In this lookup mechanism a service is represented by an interface or an * abstract class.  (A concrete class may be used, but this is not * recommended.)  A provider of a given service contains one or more concrete * classes that extend this <i>service class</i> with data and code specific to * the provider.  This <i>provider class</i> will typically not be the entire * provider itself but rather a proxy that contains enough information to * decide whether the provider is able to satisfy a particular request together * with code that can create the actual provider on demand.  The details of * provider classes tend to be highly service-specific; no single class or * interface could possibly unify them, so no such class has been defined.  The * only requirement enforced here is that provider classes must have a * zero-argument constructor so that they may be instantiated during lookup. * <p/> * <p> A service provider identifies itself by placing a provider-configuration * file in the resource directory <tt>META-INF/services</tt>.  The file's name * should consist of the fully-qualified name of the abstract service class. * The file should contain a list of fully-qualified concrete provider-class * names, one per line.  Space and tab characters surrounding each name, as * well as blank lines, are ignored.  The comment character is <tt>'#'</tt> * (<tt>0x23</tt>); on each line all characters following the first comment * character are ignored.  The file must be encoded in UTF-8. * <p/> * <p> If a particular concrete provider class is named in more than one * configuration file, or is named in the same configuration file more than * once, then the duplicates will be ignored.  The configuration file naming a * particular provider need not be in the same jar file or other distribution * unit as the provider itself.  The provider must be accessible from the same * class loader that was initially queried to locate the configuration file; * note that this is not necessarily the class loader that found the file. * <p/> * <p> <b>Example:</b> Suppose we have a service class named * <tt>java.io.spi.CharCodec</tt>.  It has two abstract methods: * <p/> * <pre> *   public abstract CharEncoder getEncoder(String encodingName); *   public abstract CharDecoder getDecoder(String encodingName); * </pre> * <p/> * Each method returns an appropriate object or <tt>null</tt> if it cannot * translate the given encoding.  Typical <tt>CharCodec</tt> providers will * support more than one encoding. * <p/> * <p> If <tt>sun.io.StandardCodec</tt> is a provider of the <tt>CharCodec</tt> * service then its jar file would contain the file * <tt>META-INF/services/java.io.spi.CharCodec</tt>.  This file would contain * the single line: * <p/> * <pre> *   sun.io.StandardCodec    # Standard codecs for the platform * </pre> * <p/> * To locate an codec for a given encoding name, the internal I/O code would * do something like this: * <p/> * <pre> *   CharEncoder getEncoder(String encodingName) { *       for( CharCodec cc : ServiceFinder.find(CharCodec.class) ) { *           CharEncoder ce = cc.getEncoder(encodingName); *           if (ce != null) *               return ce; *       } *       return null; *   } * </pre> * <p/> * The provider-lookup mechanism always executes in the security context of the * caller.  Trusted system code should typically invoke the methods in this * class from within a privileged security context. * * @author Mark Reinhold * @version 1.11, 03/12/19 * @since 1.3 */public final class ServiceFinder<T> implements Iterable<T> {    private static final Logger LOGGER = Logger.getLogger(ServiceFinder.class.getName());        private static final String PREFIX = "META-INF/services/";        private static final ComponentProvider DEFAULT_COMPONENT_PROVIDER = new ComponentProvider() {        public <T> T getInstance(Scope scope, Class<T> c)                 throws InstantiationException, IllegalAccessException {            return c.newInstance();        }        public <T> T getInstance(Scope scope, Constructor<T> contructor, Object[] parameters)                 throws InstantiationException, IllegalArgumentException,                 IllegalAccessException, InvocationTargetException {            throw new UnsupportedOperationException("");        }        public <T> T getInstance(ComponentContext cc, Scope scope, Class<T> c)                 throws InstantiationException, IllegalAccessException {            return getInstance(scope, c);        }                public <T> T getInjectableInstance(T instance) {            return instance;        }                public void inject(Object instance) {            throw new UnsupportedOperationException("");        }    };                private final Class<T> serviceClass;    private final ClassLoader classLoader;    private final boolean ignoreOnClassNotFound;    private final ComponentProvider componentProvider;            /**     * Locates and incrementally instantiates the available providers of a     * given service using the given class loader.     * <p/>     * <p> This method transforms the name of the given service class into a     * provider-configuration filename as described above and then uses the     * <tt>getResources</tt> method of the given class loader to find all     * available files with that name.  These files are then read and parsed to     * produce a list of provider-class names.  The iterator that is returned     * uses the given class loader to lookup and then instantiate each element     * of the list.     * <p/>     * <p> Because it is possible for extensions to be installed into a running     * Java virtual machine, this method may return different results each time     * it is invoked. <p>     * @param service The service's abstract service class     * @param loader The class loader to be used to load provider-configuration files     *                and instantiate provider classes, or <tt>null</tt> if the system     *                class loader (or, failing that the bootstrap class loader) is to     *                be used     * @throws ServiceConfigurationError If a provider-configuration file violates the specified format     *                                   or names a provider class that cannot be found and instantiated     * @see #find(Class)     * @return the service finder     */    public static <T> ServiceFinder<T> find(Class<T> service, ClassLoader loader)             throws ServiceConfigurationError {        return find(service,                 loader,                 false,                 DEFAULT_COMPONENT_PROVIDER);    }        /**     * Locates and incrementally instantiates the available providers of a     * given service using the given class loader.     * <p/>     * <p> This method transforms the name of the given service class into a     * provider-configuration filename as described above and then uses the     * <tt>getResources</tt> method of the given class loader to find all     * available files with that name.  These files are then read and parsed to     * produce a list of provider-class names.  The iterator that is returned     * uses the given class loader to lookup and then instantiate each element     * of the list.     * <p/>     * <p> Because it is possible for extensions to be installed into a running     * Java virtual machine, this method may return different results each time     * it is invoked. <p>     * @param service The service's abstract service class

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?