| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package flex.messaging.io.amfx; |
| |
| import flex.messaging.io.MessageSerializer; |
| import flex.messaging.io.amf.MessageBody; |
| import flex.messaging.io.amf.MessageHeader; |
| import flex.messaging.io.amf.ActionMessage; |
| import flex.messaging.io.amf.AmfTrace; |
| import flex.messaging.io.SerializationContext; |
| |
| import java.io.OutputStream; |
| import java.io.IOException; |
| |
| /** |
| * |
| */ |
| public class AmfxMessageSerializer implements MessageSerializer, AmfxTypes |
| { |
| protected AmfxOutput amfxOut; |
| protected int version; |
| |
| /* |
| * DEBUG LOGGING |
| */ |
| protected boolean isDebug; |
| protected AmfTrace debugTrace; |
| |
| public static final String XML_DIRECTIVE = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n"; |
| |
| public AmfxMessageSerializer() |
| { |
| } |
| |
| /** |
| * @param value - The default version of AMFX encoding to be used. |
| */ |
| public void setVersion(int value) |
| { |
| version = value; |
| } |
| |
| /** |
| * Establishes the context for writing out data to the given OutputStream. |
| * A null value can be passed for the trace parameter if a record of the |
| * AMFX data should not be made. |
| * |
| * @param context The SerializationContext specifying the custom options. |
| * @param out The OutputStream to write out the AMFX data. |
| * @param trace If not null, turns on "trace" debugging for AMFX responses. |
| */ |
| public void initialize(SerializationContext context, OutputStream out, AmfTrace trace) |
| { |
| amfxOut = new AmfxOutput(context); |
| amfxOut.setOutputStream(out); |
| debugTrace = trace; |
| isDebug = debugTrace != null; |
| amfxOut.setDebugTrace(trace); |
| |
| } |
| |
| public void writeMessage(ActionMessage m) throws IOException |
| { |
| if (isDebug) |
| debugTrace.startResponse("Serializing AMFX/HTTP response"); |
| |
| amfxOut.writeUTF(XML_DIRECTIVE); |
| |
| int version = m.getVersion(); |
| writeOpenAMFX(version); |
| |
| if (isDebug) |
| debugTrace.version(version); |
| |
| // Write out headers |
| int headerCount = m.getHeaderCount(); |
| for (int i = 0; i < headerCount; ++i) |
| { |
| MessageHeader header = m.getHeader(i); |
| |
| if (isDebug) |
| debugTrace.startHeader(header.getName(), header.getMustUnderstand(), i); |
| |
| writeHeader(header); |
| |
| if (isDebug) |
| debugTrace.endHeader(); |
| } |
| |
| // Write out the body |
| int bodyCount = m.getBodyCount(); |
| for (int i = 0; i < bodyCount; ++i) |
| { |
| MessageBody body = m.getBody(i); |
| |
| if (isDebug) |
| debugTrace.startMessage(body.getTargetURI(), body.getResponseURI(), i); |
| |
| writeBody(body); |
| |
| if (isDebug) |
| debugTrace.endMessage(); |
| } |
| |
| writeCloseAMFX(); |
| |
| if (isDebug) |
| debugTrace.endMessage(); |
| } |
| |
| protected void writeOpenAMFX(int version) throws IOException |
| { |
| int buflen = 14; // <amfx ver="3"> |
| StringBuffer sb = new StringBuffer(buflen); |
| sb.append("<").append(AMFX_TYPE).append(" ver=\""); |
| sb.append(version); |
| sb.append("\">"); |
| |
| amfxOut.writeUTF(sb); |
| } |
| |
| protected void writeCloseAMFX() throws IOException |
| { |
| amfxOut.writeUTF(AMFX_CLOSE_TAG); |
| } |
| |
| protected void writeHeader(MessageHeader h) throws IOException |
| { |
| int buflen = 127; // <header name="..." mustUnderstand="true"> |
| StringBuffer sb = new StringBuffer(buflen); |
| sb.append("<").append(HEADER_TYPE).append(" name=\""); |
| sb.append(h.getName()); |
| sb.append("\""); |
| |
| if (h.getMustUnderstand()) |
| { |
| sb.append(" mustUnderstand=\""); |
| sb.append(h.getMustUnderstand()); |
| sb.append("\""); |
| } |
| |
| sb.append(">"); |
| |
| amfxOut.writeUTF(sb); |
| |
| writeObject(h.getData()); |
| |
| amfxOut.writeUTF(HEADER_CLOSE_TAG); |
| } |
| |
| protected void writeBody(MessageBody b) throws IOException |
| { |
| if (b.getTargetURI() == null && b.getResponseURI() == null) |
| { |
| amfxOut.writeUTF(BODY_OPEN_TAG); |
| } |
| else |
| { |
| int buflen = 127; // <body targetURI="..." responseURI="..."> |
| StringBuffer sb = new StringBuffer(buflen); |
| sb.append("<").append(BODY_TYPE); |
| |
| if (b.getTargetURI() != null) |
| sb.append(" targetURI=\"").append(b.getTargetURI()).append("\""); |
| |
| if (b.getResponseURI() != null) |
| sb.append(" responseURI=\"").append(b.getResponseURI()).append("\""); |
| |
| sb.append(">"); |
| amfxOut.writeUTF(sb); |
| } |
| |
| Object data = b.getData(); |
| writeObject(data); |
| |
| amfxOut.writeUTF(BODY_CLOSE_TAG); |
| } |
| |
| public void writeObject(Object value) throws IOException |
| { |
| amfxOut.writeObject(value); |
| } |
| |
| } |