001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common Development
008: * and Distribution License("CDDL") (collectively, the "License"). You
009: * may not use this file except in compliance with the License. You can obtain
010: * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
011: * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
012: * language governing permissions and limitations under the License.
013: *
014: * When distributing the software, include this License Header Notice in each
015: * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
016: * Sun designates this particular file as subject to the "Classpath" exception
017: * as provided by Sun in the GPL Version 2 section of the License file that
018: * accompanied this code. If applicable, add the following below the License
019: * Header, with the fields enclosed by brackets [] replaced by your own
020: * identifying information: "Portions Copyrighted [year]
021: * [name of copyright owner]"
022: *
023: * Contributor(s):
024: *
025: * If you wish your version of this file to be governed by only the CDDL or
026: * only the GPL Version 2, indicate your decision by adding "[Contributor]
027: * elects to include this software in this distribution under the [CDDL or GPL
028: * Version 2] license." If you don't indicate a single choice of license, a
029: * recipient has the option to distribute your version of this file under
030: * either the CDDL, the GPL Version 2 or to extend the choice of license to
031: * its licensees as provided above. However, if you add GPL Version 2 code
032: * and therefore, elected the GPL Version 2 license, then the option applies
033: * only if the new code is made subject to such option by the copyright
034: * holder.
035: */
036: package com.sun.xml.ws.mex.server;
037:
038: import java.util.logging.Level;
039: import java.util.logging.Logger;
040: import javax.xml.stream.XMLStreamException;
041: import javax.xml.stream.XMLStreamWriter;
042: import javax.xml.ws.WebServiceException;
043:
044: import com.sun.xml.stream.buffer.MutableXMLStreamBuffer;
045: import com.sun.xml.ws.api.addressing.AddressingVersion;
046: import com.sun.xml.ws.api.message.HeaderList;
047: import com.sun.xml.ws.api.message.Message;
048: import com.sun.xml.ws.api.message.Messages;
049: import com.sun.xml.ws.api.message.Packet;
050: import com.sun.xml.ws.api.pipe.Pipe;
051: import com.sun.xml.ws.api.pipe.TubeCloner;
052: import com.sun.xml.ws.api.pipe.NextAction;
053: import com.sun.xml.ws.api.pipe.helper.AbstractFilterTubeImpl;
054: import com.sun.xml.ws.api.pipe.helper.PipeAdapter;
055: import com.sun.xml.ws.api.server.WSEndpoint;
056: import com.sun.xml.ws.api.SOAPVersion;
057: import com.sun.xml.ws.mex.MessagesMessages;
058:
059: import static com.sun.xml.ws.mex.MetadataConstants.GET_MDATA_REQUEST;
060: import static com.sun.xml.ws.mex.MetadataConstants.GET_REQUEST;
061: import static com.sun.xml.ws.mex.MetadataConstants.GET_RESPONSE;
062: import static com.sun.xml.ws.mex.MetadataConstants.MEX_NAMESPACE;
063: import static com.sun.xml.ws.mex.MetadataConstants.MEX_PREFIX;
064: import static com.sun.xml.ws.mex.MetadataConstants.WSA_PREFIX;
065:
066: /**
067: * This pipe handles any mex requests that come through. If a
068: * message comes through that has no headers or does not have
069: * a mex action in the header, then the pipe ignores the message
070: * and passes it on to the next pipe. Otherwise, it responds
071: * to a mex Get request and returns a fault for a GetMetadata
072: * request (these optional requests are not supported).
073: *
074: * TODO: Remove the createANSFault() method after the next
075: * jax-ws integration. See the method for more details.
076: *
077: * @author WS Development Team
078: */
079: public class MetadataServerPipe extends AbstractFilterTubeImpl {
080:
081: private final WSDLRetriever wsdlRetriever;
082: private final SOAPVersion soapVersion;
083:
084: private static final Logger logger = Logger
085: .getLogger(MetadataServerPipe.class.getName());
086:
087: public MetadataServerPipe(WSEndpoint endpoint, Pipe next) {
088: super (PipeAdapter.adapt(next));
089: wsdlRetriever = new WSDLRetriever(endpoint);
090: soapVersion = endpoint.getBinding().getSOAPVersion();
091: }
092:
093: protected MetadataServerPipe(MetadataServerPipe that,
094: TubeCloner cloner) {
095: super (that, cloner);
096: soapVersion = that.soapVersion;
097: wsdlRetriever = that.wsdlRetriever;
098: }
099:
100: public MetadataServerPipe copy(TubeCloner cloner) {
101: return new MetadataServerPipe(this , cloner);
102: }
103:
104: /**
105: * Method returns immediately if there are no headers
106: * in the message to check. If there are, the pipe checks
107: * W3C and then MEMBER addressing for an action header.
108: * If there is an action header, and if it is a mex Get
109: * request, then ask addressing again for the address and
110: * process the request.
111: */
112: @Override
113: public NextAction processRequest(final Packet request) {
114: if (request.getMessage() == null
115: || !request.getMessage().hasHeaders()) {
116: return super .processRequest(request);
117: }
118:
119: // try w3c version of ws-a first, then member submission version
120: final HeaderList headers = request.getMessage().getHeaders();
121: String action = headers.getAction(AddressingVersion.W3C,
122: soapVersion);
123: AddressingVersion adVersion = AddressingVersion.W3C;
124: if (action == null) {
125: action = headers.getAction(AddressingVersion.MEMBER,
126: soapVersion);
127: adVersion = AddressingVersion.MEMBER;
128: }
129:
130: if (action != null) {
131: if (action.equals(GET_REQUEST)) {
132: final String toAddress = headers.getTo(adVersion,
133: soapVersion);
134: return doReturnWith(processGetRequest(request,
135: toAddress, adVersion));
136: } else if (action.equals(GET_MDATA_REQUEST)) {
137: final Message faultMessage = Messages.create(
138: GET_MDATA_REQUEST, adVersion, soapVersion);
139: return doReturnWith(request.createServerResponse(
140: faultMessage, adVersion, soapVersion, adVersion
141: .getDefaultFaultAction()));
142: }
143: }
144: return super .processRequest(request);
145: }
146:
147: /*
148: * This method creates an xml stream buffer, writes the response to
149: * it, and uses it to create a response message.
150: */
151: private Packet processGetRequest(final Packet request,
152: final String address, final AddressingVersion adVersion) {
153:
154: try {
155: final MutableXMLStreamBuffer buffer = new MutableXMLStreamBuffer();
156: final XMLStreamWriter writer = buffer
157: .createFromXMLStreamWriter();
158:
159: writeStartEnvelope(writer, adVersion);
160: wsdlRetriever.addDocuments(writer, request, address);
161: writer.writeEndDocument();
162: writer.flush();
163:
164: final Message responseMessage = Messages.create(buffer);
165: final Packet response = request.createServerResponse(
166: responseMessage, adVersion, soapVersion,
167: GET_RESPONSE);
168: return response;
169: } catch (XMLStreamException streamE) {
170: final String exceptionMessage = MessagesMessages
171: .MEX_0001_RESPONSE_WRITING_FAILURE(address);
172: logger.log(Level.SEVERE, exceptionMessage, streamE);
173: throw new WebServiceException(exceptionMessage, streamE);
174: }
175: }
176:
177: private void writeStartEnvelope(final XMLStreamWriter writer,
178: final AddressingVersion adVersion)
179: throws XMLStreamException {
180:
181: final String soapPrefix = "soapenv";
182:
183: writer.writeStartDocument();
184: writer.writeStartElement(soapPrefix, "Envelope",
185: soapVersion.nsUri);
186:
187: // todo: this line should go away after bug fix - 6418039
188: writer.writeNamespace(soapPrefix, soapVersion.nsUri);
189:
190: writer.writeNamespace(WSA_PREFIX, adVersion.nsUri);
191: writer.writeNamespace(MEX_PREFIX, MEX_NAMESPACE);
192:
193: writer.writeStartElement(soapPrefix, "Body", soapVersion.nsUri);
194: writer.writeStartElement(MEX_PREFIX, "Metadata", MEX_NAMESPACE);
195: }
196:
197: }
|