1 package org.objectweb.celtix.bus.context; 2 3 4 import java.lang.annotation.Annotation ; 5 import java.lang.reflect.Method ; 6 import java.util.ArrayList ; 7 import java.util.Collection ; 8 import java.util.logging.Level ; 9 import java.util.logging.Logger ; 10 import javax.jws.WebParam; 11 import javax.jws.WebResult; 12 import javax.xml.bind.JAXBContext; 13 import javax.xml.transform.Source ; 14 import javax.xml.ws.LogicalMessage; 15 import javax.xml.ws.RequestWrapper; 16 import javax.xml.ws.ResponseWrapper; 17 import javax.xml.ws.handler.MessageContext; 18 import org.objectweb.celtix.common.logging.LogUtils; 19 import org.objectweb.celtix.context.ObjectMessageContext; 20 import org.objectweb.celtix.jaxb.WrapperHelper; 21 22 public class LogicalMessageImpl implements LogicalMessage { 23 24 private static final Logger LOG = LogUtils.getL7dLogger(LogicalMessageImpl.class); 25 26 private final LogicalMessageContextImpl msgContext; 27 28 public LogicalMessageImpl(LogicalMessageContextImpl lmctx) { 29 msgContext = lmctx; 30 } 31 32 public Source getPayload() { 33 throw new UnsupportedOperationException ("getPayload"); 34 } 35 36 public void setPayload(Source arg0) { 37 throw new UnsupportedOperationException ("setPayload"); 38 } 39 40 public Object getPayload(JAXBContext jaxbCtx) { 41 42 if (msgContext.get(ObjectMessageContext.MESSAGE_PAYLOAD) == null) { 43 buildMessagePayload(); 44 } 45 46 return msgContext.get(ObjectMessageContext.MESSAGE_PAYLOAD); 47 } 48 49 public void setPayload(Object payload, JAXBContext ctx) { 50 msgContext.put(ObjectMessageContext.MESSAGE_PAYLOAD, payload); 51 writePayloadToContext(payload); 52 } 53 54 55 private void buildMessagePayload() { 56 57 Object payload = null; 58 59 if (isRequest()) { 60 Object [] args = (Object [])msgContext.get(ObjectMessageContext.METHOD_PARAMETERS); 61 if (args == null || args.length == 0) { 62 63 assert msgContext.get(ObjectMessageContext.MESSAGE_PAYLOAD) == null; 66 return; 67 } 68 payload = buildPayloadFromRequest(args); 69 } else { 70 payload = buildPayloadFromResponse(); 71 } 72 msgContext.put(ObjectMessageContext.MESSAGE_PAYLOAD, payload); 73 } 74 75 76 private Object buildPayloadFromResponse() { 77 Method m = (Method )msgContext.get(ObjectMessageContext.METHOD_OBJ); 78 if (!Void.TYPE.equals(m.getReturnType())) { 81 ResponseWrapper ann = m.getAnnotation(ResponseWrapper.class); 82 assert ann != null : "ResponseWrapper is null"; 83 WebResult wr = m.getAnnotation(WebResult.class); 84 assert wr != null : "WebResult is null for method " + m; 85 86 Object returnVal = msgContext.get(ObjectMessageContext.METHOD_RETURN); 87 88 if (returnVal != null) { 91 Object wrapper = createWrapperInstance(ann.className()); 92 setWrapperValue(wrapper, wr.name(), returnVal); 93 return wrapper; 94 } 95 } 96 return null; 97 } 98 99 100 private Object buildPayloadFromRequest(Object [] args) { 101 102 RequestWrapper ann = getMethod().getAnnotation(RequestWrapper.class); 103 assert ann != null : "failed to get request wrapper annotation"; 104 105 Object wrapper = createWrapperInstance(ann.className()); 106 int argIndex = 0; 107 108 Collection <WebParam> annotations = getWebParamAnnotations(getMethod()); 109 110 for (WebParam wp : annotations) { 111 setWrapperValue(wrapper, wp.name(), args[argIndex++]); 112 } 113 114 return wrapper; 115 } 116 117 118 private Object createWrapperInstance(String className) { 119 try { 120 Class <?> wrapperClass = Class.forName(className, true, 121 LogicalMessageContextImpl.class.getClassLoader()); 122 return wrapperClass.newInstance(); 123 } catch (IllegalAccessException ex) { 124 LOG.log(Level.SEVERE, "WRAPPER_MISSING_DEFAULT_CTOR_MSG", ex); 125 } catch (InstantiationException ex) { 126 LOG.log(Level.SEVERE, "WRAPPER_INSTANTIATION_FAILURE_MSG", ex); 127 } catch (ClassNotFoundException ex) { 128 LOG.log(Level.SEVERE, "WRAPPER_LOAD_FAILURE_MSG", ex); 129 } 130 assert false : "unable to create wrappper " + className; 132 return null; 133 } 134 135 136 private void writeRequestToContext(Object payload) { 137 Method method = getMethod(); 138 Object [] args = new Object [method.getParameterTypes().length]; 139 Collection <WebParam> annotations = getWebParamAnnotations(method); 140 141 int i = 0; 142 for (WebParam wp : annotations) { 143 args[i++] = getAttributeFromWrapper(payload, wp.name()); 144 } 145 146 msgContext.put(ObjectMessageContext.METHOD_PARAMETERS, args); 147 } 148 149 private void writeResponseToContext(Object payload) { 150 151 WebResult wr = getMethod().getAnnotation(WebResult.class); 152 assert wr != null : "WebResult is null for method " + getMethod(); 153 154 Object retVal = getAttributeFromWrapper(payload, wr.name()); 155 msgContext.put(ObjectMessageContext.METHOD_RETURN, retVal); 156 } 157 158 private void writePayloadToContext(Object payload) { 159 160 if (isRequestPayload(payload)) { 161 writeRequestToContext(payload); 162 } else { 163 writeResponseToContext(payload); 164 } 165 } 166 167 private Object getAttributeFromWrapper(Object wrapper, String name) { 168 assert wrapper != null; 169 assert name != null; 170 171 Object ret = null; 172 try { 173 String getterName = "get" + Character.toUpperCase(name.charAt(0)) + name.substring(1); 174 Method getter = wrapper.getClass().getMethod(getterName); 175 ret = getter.invoke(wrapper); 176 } catch (Exception e) { 177 e.printStackTrace(); 178 } 179 assert ret != null : "unable to get attribute: " + name + " from " + wrapper; 180 return ret; 181 } 182 183 184 private boolean isRequestPayload(Object payload) { 185 186 Method m = getMethod(); 187 188 RequestWrapper reqWrapper = m.getAnnotation(RequestWrapper.class); 189 ResponseWrapper respWrapper = m.getAnnotation(ResponseWrapper.class); 190 191 if (reqWrapper != null) { 192 return payload.getClass().getName().equals(reqWrapper.className()); 193 } else if (respWrapper != null) { 194 return !payload.getClass().getName().equals(respWrapper.className()); 195 } 196 return true; 197 } 198 199 200 private boolean isRequest() { 201 202 Boolean isInputMsg = (Boolean )msgContext.get(ObjectMessageContext.MESSAGE_INPUT); 203 Boolean isOutbound = (Boolean )msgContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); 204 205 assert isOutbound != null : "MessageContext.MESSAGE_OUTBOUND must be set in context"; 206 assert isInputMsg != null : "ObjectMessageContext.MESSAGE_INPUT must be set in context " + msgContext; 207 208 return (isOutbound && !isInputMsg) || (!isOutbound && !isInputMsg); 209 } 210 211 private void setWrapperValue(Object wrapper, String name, Object value) { 212 213 try { 214 WrapperHelper.setWrappedPart(name, wrapper, value); 215 } catch (Exception e) { 216 e.printStackTrace(); 217 } 218 } 219 220 221 private Collection <WebParam> getWebParamAnnotations(Method m) { 222 223 Collection <WebParam> ret = new ArrayList <WebParam>(); 224 225 for (Annotation [] anns : m.getParameterAnnotations()) { 226 for (Annotation a : anns) { 227 if (a instanceof WebParam) { 228 ret.add((WebParam)a); 229 } 230 } 231 } 232 return ret; 233 } 234 235 private Method getMethod() { 236 Method m = (Method )msgContext.get(ObjectMessageContext.METHOD_OBJ); 237 assert m != null : "failed to get method from ObjectMessageContext"; 238 return m; 239 } 240 } 241 | Popular Tags |