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: */package org.apache.cxf.interceptor;
019:
020: import java.io.OutputStream;
021: import java.util.ArrayList;
022: import java.util.Collection;
023: import java.util.List;
024:
025: import javax.xml.stream.XMLStreamException;
026: import javax.xml.stream.XMLStreamWriter;
027: import javax.xml.validation.Schema;
028:
029: import org.apache.cxf.databinding.DataWriter;
030: import org.apache.cxf.message.Attachment;
031: import org.apache.cxf.message.Exchange;
032: import org.apache.cxf.message.Message;
033: import org.apache.cxf.message.MessageContentsList;
034: import org.apache.cxf.message.MessageUtils;
035: import org.apache.cxf.phase.AbstractPhaseInterceptor;
036: import org.apache.cxf.service.Service;
037: import org.apache.cxf.service.model.BindingInfo;
038: import org.apache.cxf.service.model.BindingOperationInfo;
039: import org.apache.cxf.service.model.MessagePartInfo;
040: import org.apache.cxf.wsdl.EndpointReferenceUtils;
041:
042: public abstract class AbstractOutDatabindingInterceptor extends
043: AbstractPhaseInterceptor<Message> {
044:
045: public static final String DISABLE_OUTPUTSTREAM_OPTIMIZATION = "disable.outputstream.optimization";
046:
047: public AbstractOutDatabindingInterceptor(String phase) {
048: super (phase);
049: }
050:
051: public AbstractOutDatabindingInterceptor(String id, String phase) {
052: super (id, phase);
053: }
054:
055: protected boolean isRequestor(Message message) {
056: return Boolean.TRUE.equals(message
057: .containsKey(Message.REQUESTOR_ROLE));
058: }
059:
060: protected void writeParts(Message message, Exchange exchange,
061: BindingOperationInfo operation, MessageContentsList objs,
062: List<MessagePartInfo> parts) {
063: OutputStream out = message.getContent(OutputStream.class);
064: XMLStreamWriter xmlWriter = message
065: .getContent(XMLStreamWriter.class);
066: Service service = exchange.get(Service.class);
067: if (out != null
068: && writeToOutputStream(message, operation.getBinding(),
069: service)
070: && !MessageUtils
071: .isTrue(message
072: .getContextualProperty(DISABLE_OUTPUTSTREAM_OPTIMIZATION))) {
073: if (xmlWriter != null) {
074: try {
075: xmlWriter.writeCharacters("");
076: xmlWriter.flush();
077: } catch (XMLStreamException e) {
078: throw new Fault(e);
079: }
080: }
081:
082: DataWriter<OutputStream> osWriter = getDataWriter(message,
083: service, OutputStream.class);
084:
085: for (MessagePartInfo part : parts) {
086: if (objs.hasValue(part)) {
087: Object o = objs.get(part);
088: osWriter.write(o, part, out);
089: }
090: }
091: } else {
092: DataWriter<XMLStreamWriter> dataWriter = getDataWriter(
093: message, service, XMLStreamWriter.class);
094:
095: for (MessagePartInfo part : parts) {
096: if (objs.hasValue(part)) {
097: Object o = objs.get(part);
098: dataWriter.write(o, part, xmlWriter);
099: }
100: }
101: }
102: }
103:
104: protected boolean writeToOutputStream(Message m, BindingInfo info,
105: Service s) {
106: /**
107: * Yes, all this code is EXTREMELY ugly. But it gives about a 60-70% performance
108: * boost with the JAXB RI, so its worth it.
109: */
110:
111: if (s == null) {
112: return false;
113: }
114:
115: String enc = (String) m.get(Message.ENCODING);
116: return info.getClass().getName().equals(
117: "org.apache.cxf.binding.soap.model.SoapBindingInfo")
118: && s.getDataBinding().getClass().getName().equals(
119: "org.apache.cxf.jaxb.JAXBDataBinding")
120: && !MessageUtils.isDOMPresent(m)
121: && (enc == null || "UTF-8".equals(enc));
122: }
123:
124: protected <T> DataWriter<T> getDataWriter(Message message,
125: Service service, Class<T> output) {
126: DataWriter<T> writer = service.getDataBinding().createWriter(
127: output);
128:
129: Collection<Attachment> atts = message.getAttachments();
130: if (MessageUtils
131: .isTrue(message
132: .getContextualProperty(org.apache.cxf.message.Message.MTOM_ENABLED))
133: && atts == null) {
134: atts = new ArrayList<Attachment>();
135: message.setAttachments(atts);
136: }
137:
138: writer.setAttachments(atts);
139:
140: setSchemaOutMessage(service, message, writer);
141: return writer;
142: }
143:
144: private void setSchemaOutMessage(Service service, Message message,
145: DataWriter<?> writer) {
146: Object en = message
147: .getContextualProperty(Message.SCHEMA_VALIDATION_ENABLED);
148: if (Boolean.TRUE.equals(en) || "true".equals(en)) {
149: Schema schema = EndpointReferenceUtils.getSchema(service
150: .getServiceInfos().get(0));
151: writer.setSchema(schema);
152: }
153: }
154:
155: protected XMLStreamWriter getXMLStreamWriter(Message message) {
156: return message.getContent(XMLStreamWriter.class);
157: }
158: }
|