001: package org.objectweb.celtix.bus.jaxws.io;
002:
003: import java.lang.reflect.Method;
004: import java.lang.reflect.ParameterizedType;
005: import java.lang.reflect.Type;
006: import java.util.concurrent.Future;
007:
008: import javax.jws.WebParam;
009: import javax.xml.namespace.QName;
010: import javax.xml.ws.Holder;
011: import javax.xml.ws.WebServiceException;
012:
013: import org.w3c.dom.Node;
014:
015: import org.objectweb.celtix.bindings.DataReader;
016: import org.objectweb.celtix.bus.jaxws.ClassHelper;
017: import org.objectweb.celtix.bus.jaxws.JAXBDataBindingCallback;
018: import org.objectweb.celtix.bus.jaxws.JAXBEncoderDecoder;
019: import org.objectweb.celtix.context.ObjectMessageContext;
020: import org.objectweb.celtix.helpers.NodeUtils;
021: import org.objectweb.celtix.jaxb.JAXBUtils;
022:
023: public class NodeDataReader<T> implements DataReader<T> {
024: final JAXBDataBindingCallback callback;
025:
026: public NodeDataReader(JAXBDataBindingCallback cb) {
027: callback = cb;
028: }
029:
030: public Object read(int idx, T input) {
031: return read(null, idx, input);
032: }
033:
034: public Object read(QName name, int idx, T input) {
035: Class<?> cls;
036: if (idx == -1) {
037: cls = callback.getMethod().getReturnType();
038: } else {
039: cls = callback.getMethod().getParameterTypes()[idx];
040: if (cls.isAssignableFrom(Holder.class)) {
041: //INOUT and OUT Params are mapped to Holder<T>.
042: Type[] genericParameterTypes = callback.getMethod()
043: .getGenericParameterTypes();
044: //ParameterizedType represents Holder<?>
045: ParameterizedType paramType = (ParameterizedType) genericParameterTypes[idx];
046: cls = JAXBEncoderDecoder.getClassFromType(paramType
047: .getActualTypeArguments()[0]);
048: }
049: }
050: Node xmlNode = (Node) input;
051:
052: return JAXBEncoderDecoder.unmarshall(callback.getJAXBContext(),
053: callback.getSchema(), xmlNode, name, cls);
054: }
055:
056: public void readWrapper(ObjectMessageContext objCtx,
057: boolean isOutBound, T input) {
058: Node xmlNode = (Node) input;
059: String wrapperType = isOutBound ? callback
060: .getResponseWrapperType() : callback
061: .getRequestWrapperType();
062:
063: Node childNode = NodeUtils.getChildElementNode(xmlNode);
064: Object[] methodArgs = objCtx.getMessageObjects();
065:
066: QName elName = isOutBound ? callback.getResponseWrapperQName()
067: : callback.getRequestWrapperQName();
068:
069: Object obj = null;
070:
071: try {
072: obj = JAXBEncoderDecoder.unmarshall(callback
073: .getJAXBContext(), callback.getSchema(), childNode,
074: elName, ClassHelper.forName(wrapperType));
075: } catch (ClassNotFoundException e) {
076: throw new WebServiceException(
077: "Could not unmarshall wrapped type (" + wrapperType
078: + ") ", e);
079: }
080:
081: if (isOutBound && callback.getWebResult() != null) {
082: Method method = callback.getMethod();
083: if (JAXBUtils.isAsync(method)) {
084: Method syncMethod = callback.getSyncMethod();
085: Type gtype = method.getGenericReturnType();
086:
087: if (Future.class.equals(method.getReturnType())) {
088: Type types[] = method.getGenericParameterTypes();
089: if (types.length > 0
090: && types[types.length - 1] instanceof ParameterizedType) {
091: gtype = types[types.length - 1];
092: }
093: }
094: if (gtype instanceof ParameterizedType
095: && ((ParameterizedType) gtype)
096: .getActualTypeArguments().length == 1
097: && ((ParameterizedType) gtype)
098: .getActualTypeArguments()[0] instanceof Class) {
099: Class cls = (Class) ((ParameterizedType) gtype)
100: .getActualTypeArguments()[0];
101: if (cls.getName().equals(wrapperType)) {
102: syncMethod = null;
103: }
104: }
105: method = syncMethod;
106: }
107: if (method != null) {
108: Object retVal = callback.getWrappedPart(callback
109: .getWebResultQName().getLocalPart(), obj,
110: method.getReturnType());
111: objCtx.setReturn(retVal);
112: } else {
113: objCtx.setReturn(obj);
114: }
115: }
116:
117: WebParam.Mode ignoreParamMode = isOutBound ? WebParam.Mode.IN
118: : WebParam.Mode.OUT;
119: int noArgs = callback.getMethod().getParameterTypes().length;
120: try {
121: for (int idx = 0; idx < noArgs; idx++) {
122: WebParam param = callback.getWebParam(idx);
123: if ((param.mode() != ignoreParamMode)
124: && !param.header()) {
125: Class<?> cls = callback.getMethod()
126: .getParameterTypes()[idx];
127: if (param.mode() != WebParam.Mode.IN) {
128: //INOUT and OUT Params are mapped to Holder<T>.
129: Type[] genericParameterTypes = callback
130: .getMethod().getGenericParameterTypes();
131: //ParameterizedType represents Holder<?>
132: ParameterizedType paramType = (ParameterizedType) genericParameterTypes[idx];
133: Class<?> c = JAXBEncoderDecoder
134: .getClassFromType(paramType
135: .getActualTypeArguments()[0]);
136: Object partValue = callback.getWrappedPart(
137: param.name(), obj, c);
138: //TO avoid type safety warning the Holder
139: //needs tobe set as below.
140: cls.getField("value").set(methodArgs[idx],
141: partValue);
142: } else {
143: methodArgs[idx] = callback.getWrappedPart(param
144: .name(), obj, cls);
145: }
146: }
147: }
148: } catch (IllegalAccessException iae) {
149: throw new WebServiceException(
150: "Could not unwrap the parts.", iae);
151: } catch (NoSuchFieldException nsfe) {
152: throw new WebServiceException(
153: "Could not unwrap the parts.", nsfe);
154: }
155: }
156: }
|