1/*
2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package com.sun.xml.internal.ws.api.server;
27
28import com.sun.istack.internal.Nullable;
29import com.sun.istack.internal.localization.Localizable;
30import com.sun.xml.internal.ws.api.server.InstanceResolver;
31import com.sun.xml.internal.ws.api.server.ResourceInjector;
32import com.sun.xml.internal.ws.api.server.WSEndpoint;
33import com.sun.xml.internal.ws.resources.ServerMessages;
34import com.sun.xml.internal.ws.server.ServerRtException;
35
36import java.lang.annotation.Annotation;
37import java.lang.reflect.InvocationTargetException;
38import java.lang.reflect.Method;
39import java.security.AccessController;
40import java.security.PrivilegedAction;
41
42/**
43 * Partial implementation of {@link InstanceResolver} with
44 * convenience methods to do the resource injection.
45 *
46 * @author Kohsuke Kawaguchi
47 * @since 2.2.6
48 */
49public abstract class AbstractInstanceResolver<T> extends InstanceResolver<T> {
50
51    protected static ResourceInjector getResourceInjector(WSEndpoint endpoint) {
52        ResourceInjector ri = endpoint.getContainer().getSPI(ResourceInjector.class);
53        if(ri==null)
54            ri = ResourceInjector.STANDALONE;
55        return ri;
56    }
57
58    /**
59     * Helper for invoking a method with elevated privilege.
60     */
61    protected static void invokeMethod(final @Nullable Method method, final Object instance, final Object... args) {
62        if(method==null)    return;
63        AccessController.doPrivileged(new PrivilegedAction<Void>() {
64            public Void run() {
65                try {
66                    if (!method.isAccessible()) {
67                        method.setAccessible(true);
68                    }
69                    MethodUtil.invoke(instance,method, args);
70                } catch (IllegalAccessException e) {
71                    throw new ServerRtException("server.rt.err",e);
72                } catch (InvocationTargetException e) {
73                    throw new ServerRtException("server.rt.err",e);
74                }
75                return null;
76            }
77        });
78    }
79
80    /**
81     * Finds the method that has the given annotation, while making sure that
82     * there's only at most one such method.
83     */
84    protected final @Nullable Method findAnnotatedMethod(Class clazz, Class<? extends Annotation> annType) {
85        boolean once = false;
86        Method r = null;
87        for(Method method : clazz.getDeclaredMethods()) {
88            if (method.getAnnotation(annType) != null) {
89                if (once)
90                    throw new ServerRtException(ServerMessages.ANNOTATION_ONLY_ONCE(annType));
91                if (method.getParameterTypes().length != 0)
92                    throw new ServerRtException(ServerMessages.NOT_ZERO_PARAMETERS(method));
93                r = method;
94                once = true;
95            }
96        }
97        return r;
98    }
99}
100