001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019: package org.apache.axis2.jaxws.handler;
020:
021: import org.apache.axis2.jaxws.ExceptionFactory;
022: import org.apache.axis2.jaxws.core.MessageContext;
023: import org.apache.axis2.transport.http.HTTPConstants;
024: import org.apache.commons.logging.Log;
025: import org.apache.commons.logging.LogFactory;
026:
027: import java.util.ArrayList;
028: import java.util.Collection;
029: import java.util.HashMap;
030: import java.util.List;
031: import java.util.Map;
032: import java.util.Set;
033:
034: /**
035: * The JAX-WS exposes transport properties whose value is Map<String, List<String>>. The
036: * String is the content-id and DataHandler is the data handler representing the TransportHeaders.
037: *
038: * The JAX-WS MessageContext stores transport properties in an Map object located on the AXIS2
039: * MessageContext.
040: *
041: * This class, TransportHeadersAdapter, is an adapter between the Map<String, List<String>>
042: * interface needed by the properties and the actual implementation.
043: * All useful function is delegated through the MessageContext,
044: * so that we only have one copy of the information.
045: *
046: * To use this class, invoke the install method. This will create an TransportHeadersAdapter
047: * (if necessary) and install it on the property JAX-WS standard TransportHeaders properties.
048: * (See BaseMessageContext.)
049: */
050: public class TransportHeadersAdapter implements Map {
051:
052: private static final Log log = LogFactory
053: .getLog(TransportHeadersAdapter.class);
054:
055: MessageContext mc; // MessageContext which provides the backing implementation
056: String propertyName; // The name of the JAX-WS property
057:
058: /**
059: * @param mc
060: * @param propertyName
061: */
062: private TransportHeadersAdapter(MessageContext mc,
063: String propertyName) {
064: this .mc = mc;
065: this .propertyName = propertyName;
066: }
067:
068: /**
069: * Add the TransportHeadersAdapter as the property for TransportHeaders
070: * @param mc MessageContext
071: */
072: public static void install(MessageContext mc) {
073:
074: boolean isRequest = (mc.getMEPContext()
075: .getRequestMessageContext() == mc);
076:
077: // The property is either a request or response
078: String propertyName = (isRequest) ? javax.xml.ws.handler.MessageContext.HTTP_REQUEST_HEADERS
079: : javax.xml.ws.handler.MessageContext.HTTP_RESPONSE_HEADERS;
080:
081: if (log.isDebugEnabled()) {
082: log.debug("Installing TransportHeadersAdapter for "
083: + propertyName);
084: }
085:
086: // See if there is an existing map
087: Object map = mc.getProperty(propertyName);
088:
089: // Reuse existing TransportHeadersAdapter
090: if (map instanceof TransportHeadersAdapter) {
091: if (log.isDebugEnabled()) {
092: log
093: .debug("An TransportHeadersAdapter is already installed. "
094: + "Reusing the existing one.");
095: }
096: return;
097: }
098:
099: // Create a new TransportHeadersAdapter and set it on the property
100: TransportHeadersAdapter tha = new TransportHeadersAdapter(mc,
101: propertyName);
102:
103: if (map != null) {
104: if (log.isDebugEnabled()) {
105: log
106: .debug("The TransportHeaders in the existing map ("
107: + propertyName
108: + ") are copied to the TransportHeadersAdapter.");
109: }
110: // Copy the existing Map contents to this new adapter
111: tha.putAll((Map) map);
112: }
113: mc.setProperty(propertyName, tha);
114:
115: // If this is a response, then also set the property for the response code
116: if (!isRequest) {
117: Object value = mc
118: .getProperty(HTTPConstants.MC_HTTP_STATUS_CODE);
119: mc
120: .setProperty(
121: javax.xml.ws.handler.MessageContext.HTTP_RESPONSE_CODE,
122: value);
123: }
124: }
125:
126: /**
127: * Get/Create the implementation map from the Axis2 properties
128: * @param mc
129: * @return Map
130: */
131: private static Map getDelegateMap(MessageContext mc) {
132: // Get the axis2 Map
133: Map map = (Map) mc
134: .getProperty(org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS);
135: if (map == null) {
136: map = new HashMap();
137: mc
138: .setProperty(
139: org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS,
140: map);
141: }
142: return map;
143: }
144:
145: /**
146: * Convert intput into a List
147: * @param o
148: * @return List
149: */
150: private static List<String> convertToList(Object o) {
151: if (o == null) {
152: return null;
153: } else if (o instanceof List) {
154: return (List) o;
155: } else if (o instanceof String) {
156: List l = new ArrayList();
157: l.add(o);
158: return l;
159: } else {
160: throw ExceptionFactory
161: .makeWebServiceException("Cannot convert from "
162: + o.getClass() + " to List<String>");
163: }
164: }
165:
166: private static String convertToString(Object o) {
167: if (o == null) {
168: return null;
169: } else if (o instanceof String) {
170: return (String) o;
171: } else if (o instanceof List) {
172:
173: List l = (List) o;
174: if (l.size() == 0) {
175: return null;
176: } else if (l.size() == 1) {
177: return (String) l.get(0);
178: }
179: }
180: throw ExceptionFactory
181: .makeWebServiceException("Cannot convert from "
182: + o.getClass() + " to String");
183: }
184:
185: public int size() {
186: return getDelegateMap(mc).size();
187: }
188:
189: public boolean isEmpty() {
190: return getDelegateMap(mc).isEmpty();
191: }
192:
193: public boolean containsKey(Object key) {
194: return getDelegateMap(mc).containsKey(key);
195: }
196:
197: public boolean containsValue(Object value) {
198: // TODO Should walk all of the values to do this correctly.
199: String valueString = convertToString(value);
200: return getDelegateMap(mc).containsValue(valueString);
201: }
202:
203: public Object get(Object key) {
204: Object value = convertToList(getDelegateMap(mc).get(key));
205: if (log.isDebugEnabled()) {
206: log.debug("get(" + key + ") returns value=" + value);
207: }
208: return value;
209: }
210:
211: public Object put(Object key, Object value) {
212: if (log.isDebugEnabled()) {
213: log.debug("put(" + key + " , " + value + ")");
214: }
215: String valueString = convertToString(value);
216: return convertToList(getDelegateMap(mc).put(key, valueString));
217: }
218:
219: public Object remove(Object key) {
220: return convertToList(getDelegateMap(mc).remove(key));
221: }
222:
223: public void putAll(Map t) {
224: for (Object key : t.keySet()) {
225: Object value = t.get(key);
226: if (log.isDebugEnabled()) {
227: log.debug("put via putAll (" + key + " , " + value
228: + ")");
229: }
230: put(key, value);
231: }
232: }
233:
234: public void clear() {
235: getDelegateMap(mc).clear();
236: }
237:
238: public Set keySet() {
239: return getDelegateMap(mc).keySet();
240: }
241:
242: public Collection values() {
243: Map tempMap = new HashMap<String, List<String>>();
244: tempMap.putAll(this );
245: return tempMap.values();
246: }
247:
248: public Set entrySet() {
249: Map tempMap = new HashMap<String, List<String>>();
250: tempMap.putAll(this );
251: return tempMap.entrySet();
252: }
253:
254: public String toString() {
255: return "TransportHeadersAdapter: "
256: + getDelegateMap(mc).toString();
257: }
258: }
|