ProviderEndpointModel.java revision 524:dcaa586ab756
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.server.provider;
27
28import com.sun.istack.internal.NotNull;
29import com.sun.xml.internal.ws.api.WSBinding;
30import com.sun.xml.internal.ws.api.server.AsyncProvider;
31import com.sun.xml.internal.ws.resources.ServerMessages;
32import com.sun.xml.internal.ws.spi.db.BindingHelper;
33
34import javax.activation.DataSource;
35import javax.xml.soap.SOAPMessage;
36import javax.xml.transform.Source;
37import javax.xml.ws.Provider;
38import javax.xml.ws.Service;
39import javax.xml.ws.ServiceMode;
40import javax.xml.ws.WebServiceException;
41import javax.xml.ws.soap.SOAPBinding;
42import java.lang.reflect.ParameterizedType;
43import java.lang.reflect.Type;
44
45
46/**
47 * Keeps the runtime information like Service.Mode and erasure of Provider class
48 * about Provider endpoint. It proccess annotations to find about Service.Mode
49 * It also finds about parameterized type(e.g. Source, SOAPMessage, DataSource)
50 * of endpoint class.
51 *
52 * @author Jitendra Kotamraju
53 * @author Kohsuke Kawaguchi
54 */
55final class ProviderEndpointModel<T> {
56    /**
57     * True if this is {@link AsyncProvider}.
58     */
59    final boolean isAsync;
60
61    /**
62     * In which mode does this provider operate?
63     */
64    @NotNull final Service.Mode mode;
65    /**
66     * T of {@link Provider}&lt;T>.
67     */
68    @NotNull final Class datatype;
69    /**
70     * User class that extends {@link Provider}.
71     */
72    @NotNull final Class implClass;
73
74    ProviderEndpointModel(Class<T> implementorClass, WSBinding binding) {
75        assert implementorClass != null;
76        assert binding != null;
77
78        implClass = implementorClass;
79        mode = getServiceMode(implementorClass);
80        Class otherClass = (binding instanceof SOAPBinding)
81            ? SOAPMessage.class : DataSource.class;
82        isAsync = AsyncProvider.class.isAssignableFrom(implementorClass);
83
84
85        Class<? extends Object> baseType = isAsync ? AsyncProvider.class : Provider.class;
86        Type baseParam = BindingHelper.getBaseType(implementorClass, baseType);
87        if (baseParam==null)
88            throw new WebServiceException(ServerMessages.NOT_IMPLEMENT_PROVIDER(implementorClass.getName()));
89        if (!(baseParam instanceof ParameterizedType))
90            throw new WebServiceException(ServerMessages.PROVIDER_NOT_PARAMETERIZED(implementorClass.getName()));
91
92        ParameterizedType pt = (ParameterizedType)baseParam;
93        Type[] types = pt.getActualTypeArguments();
94        if(!(types[0] instanceof Class))
95            throw new WebServiceException(ServerMessages.PROVIDER_INVALID_PARAMETER_TYPE(implementorClass.getName(),types[0]));
96        datatype = (Class)types[0];
97
98        if (mode == Service.Mode.PAYLOAD && datatype!=Source.class) {
99            // Illegal to have PAYLOAD && SOAPMessage
100            // Illegal to have PAYLOAD && DataSource
101            throw new IllegalArgumentException(
102                "Illeagal combination - Mode.PAYLOAD and Provider<"+otherClass.getName()+">");
103        }
104    }
105
106    /**
107     * Is it PAYLOAD or MESSAGE ??
108     *
109     * @param c endpoint class
110     * @return Service.Mode.PAYLOAD or Service.Mode.MESSAGE
111     */
112    private static Service.Mode getServiceMode(Class<?> c) {
113        ServiceMode mode = c.getAnnotation(ServiceMode.class);
114        return (mode == null) ? Service.Mode.PAYLOAD : mode.value();
115    }
116}
117