Java程序  |  143行  |  4.67 KB

/*
 * Copyright (C) 2009 Google Inc.  All rights reserved.
 *
 * Licensed 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 com.google.polo.wire.xml;

import com.google.polo.exception.PoloException;
import com.google.polo.pairing.HexDump;
import com.google.polo.pairing.PairingContext;
import com.google.polo.pairing.message.PoloMessage;
import com.google.polo.pairing.message.PoloMessage.PoloMessageType;
import com.google.polo.wire.PoloWireInterface;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class XmlWireAdapter implements PoloWireInterface {
  
    /**
     * Enables extra verbose debug logging.
     */
    private static final boolean DEBUG_VERBOSE = false;
    
    private static final int STATUS_OK = 1;

    /**
     * The output coming from the peer.
     */
    private final InputStream mInputStream;
    
    /**
     * The input going to the peer.
     */
    private final OutputStream mOutputStream;
    
    private final XmlMessageBuilder mBuilder;

    /**
     * Constructor.
     * 
     * @param input  the {@link InputStream} from the peer
     * @param output  the {@link OutputStream} to the peer
     */
    public XmlWireAdapter(InputStream input, OutputStream output) {
      mInputStream = input;
      mOutputStream = output;
      mBuilder = new XmlMessageBuilder();
    }
    
    /**
     * Generates a new instance from a {@link PairingContext}.
     * @param context  the {@link PairingContext}
     * @return  the new instance
     */
    public static XmlWireAdapter fromContext(PairingContext context) {
      return new XmlWireAdapter(context.getPeerInputStream(),
          context.getPeerOutputStream());
    }
    
    public PoloMessage getNextMessage() throws IOException, PoloException {
        XmlMessageWrapper outerMessage =
                XmlMessageWrapper.fromInputStream(mInputStream);
        if (DEBUG_VERBOSE) {
            debug(">>> Incoming Message:");
            debug(HexDump.dumpHexString(outerMessage.serializeToByteArray()));
        }
        
        String outerXML = new String(outerMessage.getPayload());
        return mBuilder.outerXMLToPoloMessage(outerXML);
    }
    
    public PoloMessage getNextMessage(PoloMessageType type) throws IOException, PoloException {
        PoloMessage message = getNextMessage();
        if (message.getType() != type) {
            throw new PoloException("Wrong message type (wanted " + type +
                ", got " + message.getType() + ")");
          }
          return message;
    }

    public void sendErrorMessage(Exception exception) throws IOException {
        String errorXml;
        try {
          errorXml = mBuilder.getErrorXML(exception);
        } catch (PoloException e) {
          // just ignore it; nothing we can do
          return;
        }
        byte[] outBytes = errorXml.getBytes();
        XmlMessageWrapper message = new XmlMessageWrapper("client", 1,
            (byte) 0, outBytes);
        writeXML(message);
    }
    
    public void sendMessage(PoloMessage poloMessage) throws IOException {
        String outString = mBuilder.getOuterXML(poloMessage, STATUS_OK);
        
        // NOTE(mikey): A particular parser is very sensitive to newline
        // placement. Strip all newlines, then add them to separate adjacent
        // XML entities.
        outString = outString.replace("\n", "");
        outString = outString.replace("><", ">\n<");
        
        byte[] outBytes = outString.getBytes();
        XmlMessageWrapper message = new XmlMessageWrapper("client", 1,
            (byte) 0, outBytes);
        writeXML(message);
    }
    
    /**
     * Writes a {@link XmlMessageWrapper} to the output stream as a
     * {@link String}.
     * 
     * @param message       the message to write
     * @throws IOException  on error generating the serialized message
     */
    private void writeXML(XmlMessageWrapper message) throws IOException {
      if (DEBUG_VERBOSE) {
          debug("<<< Outgoing Message:");
          debug(HexDump.dumpHexString(message.serializeToByteArray()));
      }
      mOutputStream.write(message.serializeToByteArray());
    }
    
    private void debug(String message) {
      System.out.println(message);
    }
 
}