• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 Google Inc.  All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.polo.wire.xml;
18 
19 import com.google.polo.exception.PoloException;
20 import com.google.polo.pairing.HexDump;
21 import com.google.polo.pairing.PairingContext;
22 import com.google.polo.pairing.message.PoloMessage;
23 import com.google.polo.pairing.message.PoloMessage.PoloMessageType;
24 import com.google.polo.wire.PoloWireInterface;
25 
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.io.OutputStream;
29 
30 public class XmlWireAdapter implements PoloWireInterface {
31 
32     /**
33      * Enables extra verbose debug logging.
34      */
35     private static final boolean DEBUG_VERBOSE = false;
36 
37     private static final int STATUS_OK = 1;
38 
39     /**
40      * The output coming from the peer.
41      */
42     private final InputStream mInputStream;
43 
44     /**
45      * The input going to the peer.
46      */
47     private final OutputStream mOutputStream;
48 
49     private final XmlMessageBuilder mBuilder;
50 
51     /**
52      * Constructor.
53      *
54      * @param input  the {@link InputStream} from the peer
55      * @param output  the {@link OutputStream} to the peer
56      */
XmlWireAdapter(InputStream input, OutputStream output)57     public XmlWireAdapter(InputStream input, OutputStream output) {
58       mInputStream = input;
59       mOutputStream = output;
60       mBuilder = new XmlMessageBuilder();
61     }
62 
63     /**
64      * Generates a new instance from a {@link PairingContext}.
65      * @param context  the {@link PairingContext}
66      * @return  the new instance
67      */
fromContext(PairingContext context)68     public static XmlWireAdapter fromContext(PairingContext context) {
69       return new XmlWireAdapter(context.getPeerInputStream(),
70           context.getPeerOutputStream());
71     }
72 
getNextMessage()73     public PoloMessage getNextMessage() throws IOException, PoloException {
74         XmlMessageWrapper outerMessage =
75                 XmlMessageWrapper.fromInputStream(mInputStream);
76         if (DEBUG_VERBOSE) {
77             debug(">>> Incoming Message:");
78             debug(HexDump.dumpHexString(outerMessage.serializeToByteArray()));
79         }
80 
81         String outerXML = new String(outerMessage.getPayload());
82         return mBuilder.outerXMLToPoloMessage(outerXML);
83     }
84 
getNextMessage(PoloMessageType type)85     public PoloMessage getNextMessage(PoloMessageType type) throws IOException, PoloException {
86         PoloMessage message = getNextMessage();
87         if (message.getType() != type) {
88             throw new PoloException("Wrong message type (wanted " + type +
89                 ", got " + message.getType() + ")");
90           }
91           return message;
92     }
93 
sendErrorMessage(Exception exception)94     public void sendErrorMessage(Exception exception) throws IOException {
95         String errorXml;
96         try {
97           errorXml = mBuilder.getErrorXML(exception);
98         } catch (PoloException e) {
99           // just ignore it; nothing we can do
100           return;
101         }
102         byte[] outBytes = errorXml.getBytes();
103         XmlMessageWrapper message = new XmlMessageWrapper("client", 1,
104             (byte) 0, outBytes);
105         writeXML(message);
106     }
107 
sendMessage(PoloMessage poloMessage)108     public void sendMessage(PoloMessage poloMessage) throws IOException {
109         String outString = mBuilder.getOuterXML(poloMessage, STATUS_OK);
110 
111         // NOTE(mikey): A particular parser is very sensitive to newline
112         // placement. Strip all newlines, then add them to separate adjacent
113         // XML entities.
114         outString = outString.replace("\n", "");
115         outString = outString.replace("><", ">\n<");
116 
117         byte[] outBytes = outString.getBytes();
118         XmlMessageWrapper message = new XmlMessageWrapper("client", 1,
119             (byte) 0, outBytes);
120         writeXML(message);
121     }
122 
123     /**
124      * Writes a {@link XmlMessageWrapper} to the output stream as a
125      * {@link String}.
126      *
127      * @param message       the message to write
128      * @throws IOException  on error generating the serialized message
129      */
writeXML(XmlMessageWrapper message)130     private void writeXML(XmlMessageWrapper message) throws IOException {
131       if (DEBUG_VERBOSE) {
132           debug("<<< Outgoing Message:");
133           debug(HexDump.dumpHexString(message.serializeToByteArray()));
134       }
135       mOutputStream.write(message.serializeToByteArray());
136     }
137 
debug(String message)138     private void debug(String message) {
139       System.out.println(message);
140     }
141 
142 }
143