001    /** 
002     * 
003     * Copyright 2004 Protique Ltd
004     * 
005     * Licensed under the Apache License, Version 2.0 (the "License"); 
006     * you may not use this file except in compliance with the License. 
007     * You may obtain a copy of the License at 
008     * 
009     * http://www.apache.org/licenses/LICENSE-2.0
010     * 
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS, 
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
014     * See the License for the specific language governing permissions and 
015     * limitations under the License. 
016     * 
017     **/
018    package org.codehaus.activesoap;
019    
020    import org.codehaus.activesoap.util.XMLStreamHelper;
021    import org.codehaus.activesoap.util.DocumentFilterXMLStreamWriter;
022    
023    import javax.xml.stream.XMLStreamException;
024    import javax.xml.stream.XMLStreamReader;
025    import javax.xml.stream.XMLStreamWriter;
026    import java.util.HashMap;
027    import java.util.Map;
028    import java.util.Set;
029    
030    
031    /**
032     * Represents the context of the processing of a single message, providing
033     * access to the current REST or SOAP service on which the message is invoked
034     * and providing access to pre-request properties which can be used to communicate
035     * among {@link Handler} instances.
036     *
037     * @version $Revision: 1.3 $
038     */
039    public class MessageExchange {
040        private RestService service;
041    
042        private XMLStreamReader in;
043        private XMLStreamWriter out;
044    
045        // only ever accessed in 1 thread during the processing of 1 message
046        // so no need to synchonize
047        private Map properties;
048    
049        public MessageExchange(RestService service, XMLStreamReader in, XMLStreamWriter out) {
050            this(service, in, out, new HashMap());
051        }
052    
053        public MessageExchange(RestService service, XMLStreamReader in, XMLStreamWriter out, Map properties) {
054            this.service = service;
055            this.in = in;
056            this.out = out;
057            this.properties = properties;
058        }
059    
060    
061        /**
062         * Creates a new message exchange with different input and output
063         */
064        public MessageExchange newInstance(XMLStreamReader in, XMLStreamWriter out) {
065            if (this.in == in && this.out == out) {
066                // no need to create a new instance
067                return this;
068            }
069            return new MessageExchange(service, in, out, properties);
070        }
071    
072        // Access to message context properties
073        //-------------------------------------------------------------------------
074    
075        /**
076         * Looks up the property for the given key which is typically a String or QName
077         * or a QName returning the value or null if it is not present.
078         *
079         * @param name is typically a String or a QName
080         * @return the value or null if there is no property defined for the given name
081         */
082        public Object getProperty(Object name) {
083            return properties.get(name);
084        }
085    
086        /**
087         * Sets the value of the given property name (which is typically a String or a QName)
088         * to the value.
089         *
090         * @param name  is the name of the property which is usually a String or a QName but could be any object
091         * @param value the value of the new attribute
092         */
093        public void setProperty(Object name, Object value) {
094            if (value == null) {
095                properties.remove(value);
096            }
097            else {
098                properties.put(name, value);
099            }
100        }
101    
102        /**
103         * Return a collection of the available property names which are typically String or QName instances
104         */
105        public Set getPropertyNames() {
106            return properties.keySet();
107        }
108    
109    
110        // Access to input and output
111        //-------------------------------------------------------------------------
112        public XMLStreamReader getIn() {
113            return in;
114        }
115    
116        public XMLStreamWriter getOut() {
117            return out;
118        }
119    
120        /**
121         * A helper method which streams the input to the output
122         */
123        public void copy(XMLStreamReader in, XMLStreamWriter out) throws XMLStreamException {
124            boolean repairing = service.isRepairingNamespace();
125            XMLStreamHelper.copy(in, out, repairing);
126    
127        }
128    
129    
130        // Helper methods
131        //-------------------------------------------------------------------------
132    
133        public boolean isRepairingNamespace() {
134            return service.isRepairingNamespace();
135        }
136    
137        /**
138         * Returns the current service instance which is processing the message
139         * so that we can access the details such as the handler registry
140         */
141        public RestService getService() {
142            return service;
143        }
144    
145        /**
146         * Returns the current SOAP service instance, if we are using the SOAP protocol
147         * so that you can access the SOAP details such as available roles, SOAP version,
148         * intermidate mode etc.
149         *
150         * @return the SOAP service if the current service or null if the current service is
151         *         a pure REST service and does not use the SOAP protocol.
152         */
153        public SoapService getSoapService() {
154            if (service instanceof SoapService) {
155                return (SoapService) service;
156            }
157            return null;
158        }
159    }