package com.sun.xml.ws.test; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.security.AccessController; import java.security.PrivilegedAction; import javax.jws.WebParam; import javax.jws.WebResult; import javax.xml.bind.annotation.XmlTransient; import javax.xml.namespace.QName; import javax.xml.ws.Holder; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlSchema; import javax.xml.bind.annotation.XmlType; //import org.apache.xmlbeans.SchemaType; import com.sun.xml.ws.model.ReflectAnnotationReader; import static com.sun.xml.ws.model.RuntimeModeler.erasure; /** * JWSAnnotationReader extends the ReflectAnnotationReader to allow customizing the parameter names with dummy * WebParam and WebResult. * * @author shih-chang.chen@oracle.com */ @SuppressWarnings("unchecked") public class JWSAnnotationReader extends ReflectAnnotationReader { String defaultArgPrefix = "param"; String defaultResultName = "return"; public Annotation[] getAnnotations(Method m) { Annotation[] anno = m.getAnnotations(); int webResultPos = -1; for(int i = 0; i < anno.length; i++) if (anno[i] instanceof WebParam){ webResultPos = i; } WebResult webResult = getAnnotation(WebResult.class, m); if (webResultPos == -1) { anno = append(anno, webResult); } else { anno[webResultPos] = webResult; } return anno; } public Annotation[][] getParameterAnnotations(final Method method) { return AccessController.doPrivileged(new PrivilegedAction<Annotation[][]>() { public Annotation[][] run() { Annotation[][] paramAnno = method.getParameterAnnotations(); Class<?>[] paramType = method.getParameterTypes(); Type[] genericParamType = method.getGenericParameterTypes(); for(int pos = 0; pos < paramType.length; pos ++) { Annotation[] anno = paramAnno[pos]; Class<?> type = paramType[pos]; if(Holder.class.equals(type)) type = erasure(((ParameterizedType)genericParamType[pos]).getActualTypeArguments()[0]); WebParam webParam = null; int webParamPos = -1; for(int i = 0; i < anno.length; i++) if (anno[i] instanceof WebParam){ webParam = (WebParam)anno[i]; webParamPos = i; } String pname = "param"+pos; String ptns = ""; QName elemName = getGlobalElementName(type); if (elemName != null) { ptns = elemName.getNamespaceURI(); pname = elemName.getLocalPart(); } webParam = new DummyWebParam(webParam, pname, ptns); if (webParamPos == -1) { paramAnno[pos] = append(anno, webParam); } else { anno[webParamPos] = webParam; } } return paramAnno; } }); } static Annotation[] append(Annotation[] anno, Annotation oneMore) { Annotation[] newArray = new Annotation[anno.length+1]; System.arraycopy(anno, 0, newArray, 0, anno.length); newArray[anno.length] = oneMore; return newArray; } public <A extends Annotation> A getAnnotation(final Class<A> annType, final Method m) { return AccessController.doPrivileged(new PrivilegedAction<A>() { public A run() { Annotation anno = m.getAnnotation(annType); if (WebResult.class.equals(annType)) { String pname = defaultResultName; String ptns = ""; QName elemName = getGlobalElementName(m.getReturnType()); if (elemName != null) { ptns = elemName.getNamespaceURI(); pname = elemName.getLocalPart(); } anno = new DummyWebResult((WebResult)anno, pname, ptns); } return (A) anno; } }); } public <A extends Annotation> A getAnnotation(final Class<A> annType, final Class<?> cls) { return AccessController.doPrivileged(new PrivilegedAction<A>() { public A run() { if (Exception.class.equals(cls) && XmlTransient.class.equals(annType)) { return (A) new XmlTransient() { public Class<? extends Annotation> annotationType() { return XmlTransient.class; } }; } return cls.getAnnotation(annType); } }); } static class DummyWebParam implements WebParam { private WebParam delegate; private String defaultName; private String defaultNS; public DummyWebParam(WebParam delegate, String defaultName, String defaultNS) { this.delegate = delegate; this.defaultName = defaultName; this.defaultNS = defaultNS; } @Override public Class<? extends Annotation> annotationType() { return (delegate != null)? delegate.annotationType() : WebParam.class; } @Override public boolean header() { return (delegate != null)? delegate.header() : false; } @Override public Mode mode() { return (delegate != null)? delegate.mode() : javax.jws.WebParam.Mode.IN; } @Override public String name() { String name = (delegate != null)? delegate.name() : ""; if (name == null || "".equals(name)) return defaultName; return name; } @Override public String partName() { return (delegate != null)? delegate.partName() : ""; } @Override public String targetNamespace() { String ns = (delegate != null)? delegate.targetNamespace() : ""; if (ns == null || "".equals(ns)) return defaultNS; return ns; } } static class DummyWebResult implements WebResult { private WebResult delegate; private String defaultName; private String defaultNS; public DummyWebResult(WebResult delegate, String defaultName, String defaultNS) { this.delegate = delegate; this.defaultName = defaultName; this.defaultNS = defaultNS; } @Override public Class<? extends Annotation> annotationType() { return (delegate != null)? delegate.annotationType() : WebResult.class; } @Override public boolean header() { return (delegate != null)? delegate.header() : false; } @Override public String name() { String name = (delegate != null)? delegate.name() : ""; if (name == null || "".equals(name)) return defaultName; return name; } @Override public String partName() { return (delegate != null)? delegate.partName() : ""; } @Override public String targetNamespace() { String ns = (delegate != null)? delegate.targetNamespace() : ""; if (ns == null || "".equals(ns)) return defaultNS; return ns; } } //This is the XMLBeans way ... // static QName getGlobalElementName(Class<?> cls) { // SchemaType schemaType = XMLBeansContext.type(cls); // return (schemaType != null && schemaType.isDocumentType()) ? schemaType.getDocumentElementName() : null; // } static QName getGlobalElementName(Class<?> cls) { XmlRootElement xre = (XmlRootElement) cls.getAnnotation(XmlRootElement.class); XmlType xt = (XmlType) cls.getAnnotation(XmlType.class); if (xt != null && xt.name() != null && !"".equals(xt.name())) return null; if (xre != null) { String lp = xre.name(); String ns = xre.namespace(); if (ns.equals("##default")) { XmlSchema xs = cls.getPackage().getAnnotation(XmlSchema.class); if (xs != null) ns = xs.namespace(); else ns = ""; } return new QName(ns, lp); } return null; } }