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.core.MessageContext;
022: import org.apache.axis2.jaxws.message.Message;
023: import org.apache.commons.logging.Log;
024: import org.apache.commons.logging.LogFactory;
025:
026: import javax.activation.DataHandler;
027:
028: import java.util.Collection;
029: import java.util.HashMap;
030: import java.util.HashSet;
031: import java.util.Map;
032: import java.util.Set;
033:
034: /**
035: * The JAX-WS exposes attachment properties whose value is Map<String, DataHandler>. The
036: * String is the content-id and DataHandler is the data handler representing the attachment.
037: *
038: * The JAX-WS MessageContext stores attachments in an Axiom Attachments object located on the JAX-WS
039: * Message.
040: *
041: * This class, AttachmentAdapter, is an adapter between the Map<String, DataHandler> interface needed
042: * by the properties and the actual implementation. All useful function is delegated through the MessageContext, so
043: * that we only have one copy of the attachment information.
044: *
045: * To use this class, invoke the install method. This will create an AttachmentAdapter (if necessary) and install it
046: * on the property JAX-WS standard attachment property. (See BaseMessageContext.)
047: */
048: public class AttachmentsAdapter implements Map<String, DataHandler> {
049:
050: private static final Log log = LogFactory
051: .getLog(AttachmentsAdapter.class);
052:
053: MessageContext mc; // MessageContext which provides the backing implementation of Attachments
054: String propertyName; // The name of the JAX-WS property
055:
056: /**
057: * The backing storage of the Attachments is the JAX-WS MessageContext.
058: * Intentionally private, use install(MessageContext)
059: */
060: private AttachmentsAdapter(MessageContext mc, String propertyName) {
061: this .mc = mc;
062: this .propertyName = propertyName;
063: }
064:
065: /**
066: * Add the AttachmentAdapter as the property for the inbound or
067: * outbound attachment property
068: * @param mc MessageContext
069: */
070: public static void install(MessageContext mc) {
071:
072: Message m = mc.getMessage();
073:
074: if (m == null) {
075: // Probably a unit test, can't continue.
076: return;
077: }
078:
079: boolean isOutbound = mc.isOutbound();
080:
081: // The property is either an inbound or outbound property
082: String propertyName = (isOutbound) ? javax.xml.ws.handler.MessageContext.OUTBOUND_MESSAGE_ATTACHMENTS
083: : javax.xml.ws.handler.MessageContext.INBOUND_MESSAGE_ATTACHMENTS;
084:
085: if (log.isDebugEnabled()) {
086: log.debug("Installing AttachmentsAdapter for "
087: + propertyName);
088: }
089:
090: // See if there is an existing map
091: Object map = mc.getProperty(propertyName);
092:
093: // Reuse existing AttachmentsAdapter
094: if (map instanceof AttachmentsAdapter) {
095: if (log.isDebugEnabled()) {
096: log
097: .debug("An AttachmentsAdapter is already installed. Reusing the existing one.");
098: }
099: return;
100: }
101:
102: // Create a new AttachmentsAdapter and set it on the property
103: AttachmentsAdapter aa = new AttachmentsAdapter(mc, propertyName);
104:
105: if (map != null) {
106: if (log.isDebugEnabled()) {
107: log.debug("The DataHandlers in the existing map ("
108: + propertyName
109: + ") are copied to the AttachmentsAdapter.");
110: }
111: // Copy the existing Map contents to this new adapter
112: aa.putAll((Map<String, DataHandler>) map);
113: }
114: mc.setProperty(propertyName, aa);
115: }
116:
117: public void clear() {
118: if (log.isDebugEnabled()) {
119: log.debug("clear()");
120: }
121: Message m = mc.getMessage();
122: Set<String> keys = this .keySet();
123: for (String key : keys) {
124: m.removeDataHandler(key);
125: }
126: }
127:
128: public boolean containsKey(Object key) {
129: Message m = mc.getMessage();
130: Set<String> keys = this .keySet();
131: return keys.contains(key);
132: }
133:
134: public boolean containsValue(Object value) {
135: Message m = mc.getMessage();
136:
137: Set<String> keys = this .keySet();
138: for (String key : keys) {
139: DataHandler dh = m.getDataHandler(key);
140: if (dh.equals(value)) {
141: return true;
142: }
143: }
144: return false;
145: }
146:
147: public Set<Entry<String, DataHandler>> entrySet() {
148: Map tempMap = new HashMap<String, DataHandler>();
149: tempMap.putAll(this );
150: return tempMap.entrySet();
151: }
152:
153: public DataHandler get(Object key) {
154: Message m = mc.getMessage();
155: DataHandler dh = m.getDataHandler((String) key);
156: if (log.isDebugEnabled()) {
157: log.debug("get(" + key + ") returns dh=" + dh);
158: }
159: return dh;
160: }
161:
162: public boolean isEmpty() {
163: return this .keySet().isEmpty();
164: }
165:
166: public Set<String> keySet() {
167: Set<String> keys = new HashSet<String>();
168: Message m = mc.getMessage();
169: // Note that the SOAPPart is ignored
170: int i = 0;
171: String key = m.getAttachmentID(i);
172: while (key != null) {
173: keys.add(key);
174: i++;
175: key = m.getAttachmentID(i);
176: }
177: return keys;
178: }
179:
180: public DataHandler put(String key, DataHandler dh) {
181: Message m = mc.getMessage();
182: if (log.isDebugEnabled()) {
183: log.debug("put(" + key + " , " + dh + ")");
184: }
185: DataHandler old = get(key);
186: m.addDataHandler(dh, key);
187: m.setDoingSWA(true); // Can't really tell if the attachment is MTOM or SWA, etc. Mark as SWA to make sure it is written out
188: return old;
189:
190: }
191:
192: public void putAll(Map<? extends String, ? extends DataHandler> t) {
193: Message m = mc.getMessage();
194: for (String key : t.keySet()) {
195: DataHandler dh = t.get(key);
196: if (log.isDebugEnabled()) {
197: log.debug("addDataHandler via putAll (" + key + " , "
198: + dh + ")");
199: }
200: m.addDataHandler(dh, key);
201: m.setDoingSWA(true); // Can't really tell if the attachment is MTOM or SWA, etc. Mark as SWA to make sure it is written out
202: }
203: }
204:
205: public DataHandler remove(Object key) {
206: Message m = mc.getMessage();
207: // Note that the SOAPPart is ignored
208: return m.removeDataHandler((String) key);
209: }
210:
211: public int size() {
212: Message m = mc.getMessage();
213: Set<String> keys = this .keySet();
214: return keys.size();
215: }
216:
217: public Collection<DataHandler> values() {
218: Map tempMap = new HashMap<String, DataHandler>();
219: tempMap.putAll(this);
220: return tempMap.values();
221: }
222:
223: }
|