Subversion Repositories HomeAutomation

Rev

Details | Last modification | View Log | SVN | RSS feed

Rev Author Line No. Line
15 arune 1
/*
2
 * MbPacket.java
3
 *
4
 * Created on den 24 augusti 2003, 12:55
5
 */
6
package Macbeth.System;
7
 
8
import Macbeth.XML.XMLDataHandler;
9
import Macbeth.XML.XMLParser;
10
import Macbeth.Utilities.MySystem;
11
import java.util.Iterator;
12
import java.util.HashMap;
13
import java.io.IOException;
14
 
15
import org.xml.sax.SAXException;
16
 
17
/**
18
 * This class represents a Macbeth packet, containing both its destination,
19
 * its source, and its contents.
20
 * @author Jimmy
21
 */
22
public class MbPacket {
23
 
24
    /**
25
     * The Macbeth location to which this packet is addressed.
26
     * If the kernel-field is set to "self", it means that
27
     * the packet will be delivered locally only (that is,
28
     * within the same kernel it was sent from). If the field
29
     * is set to something else, however, this name will be
30
     * looked up in the list of known kernels, which, in case
31
     * the kernel was found, also provides the internet address
32
     * of the specified kernel.
33
     */
34
    private MbLocation destination;
35
 
36
    /**
37
     * The Macbeth location from which this packet was sent.
38
     * This can be used by receiver module (or kernel)
39
     * to identify the sender.
40
     */
41
    private MbLocation source;
42
 
43
    /**
44
     * The packet contents (an XML-document).
45
     */
46
    private String contents;
47
 
48
    /**
49
     * The remote address of the client that sent us this packet.
50
     * If the packet has never been transported via any networks,
51
     * this value is "self" (that is, source kernel and dest kernel
52
     * are equal).
53
     */
54
    private String originAddress;
55
 
56
    /**
57
     * Gets the destination of this packet.
58
     * @return The packet destination.
59
     */
60
    public MbLocation getDestination() {
61
        return destination;
62
    }
63
    /**
64
     * Sets the destination of this packet.
65
     * @param destination The new destination.
66
     */
67
    public void setDestination(MbLocation destination) {
68
        this.destination = destination;
69
    }
70
    /**
71
     * Sets the kernel field in the destination of this packet.
72
     * @param kernel The new destination kernel.
73
     */
74
    public void setDestinationKernel(String kernel) {
75
        destination.setKernel(kernel);
76
    }
77
    /**
78
     * Sets the module field in the destination of this packet.
79
     * @param module The new destination module.
80
     */
81
    public void setDestinationModule(String module) {
82
        destination.setModule(module);
83
    }
84
 
85
    /**
86
     * Gets the source of this packet.
87
     * @return The packet source.
88
     */
89
    public MbLocation getSource() {
90
        return source;
91
    }
92
    /**
93
     * Sets the source of this packet.
94
     * @param source The new packet source.
95
     */
96
    public void setSource(MbLocation source) {
97
        this.source = source;
98
    }
99
 
100
    /**
101
     * Gets the packet contents. This is an XML-string.
102
     * @return The packet contents.
103
     */
104
    public synchronized String getContents() {
105
        return contents;
106
    }
107
    /**
108
     * Sets the packet contents. This must be valid XML-data.
109
     * @param contents The new packet contents.
110
     */
111
    public synchronized void setContents(String contents) {
112
        this.contents = contents;
113
    }
114
    /**
115
     * Appends a string to the packet contents. This must be
116
     * valid XML-data.
117
     * @param s The string to append.
118
     */
119
    public synchronized void appendContents(String s) {
120
        this.contents += s;
121
    }
122
 
123
    /**
124
     * Gets the source remote address of this packet.
125
     * @return The remote address of the packet source.
126
     */
127
    public synchronized String getOriginAddress() {
128
        return originAddress;
129
    }
130
 
131
    /**
132
     * Creates a new instance of MbPacket.
133
     */
134
    public MbPacket() {
135
        destination = new MbLocation();
136
        source = new MbLocation();
137
        originAddress = "self";
138
        contents = "";
139
    }
140
 
141
    /**
142
     * Serializes this packet into a string object (XML-formatted)
143
     * @return the packet as an XML-string.
144
     */
145
    public String serializeToString() {
146
        String s = "<mbpacket ";
147
        s += "sourcekernel=\"" + source.getKernel() + "\" ";
148
        s += "sourcemodule=\"" + source.getModule() + "\" ";
149
        //s += "destkernel=\"" + destination.kernel + "\" ";
150
        s += "destmodule=\"" + destination.getModule() + "\" ";
151
        s += ">" + MySystem.lineBreak;
152
        s += contents;
153
        s += MySystem.lineBreak + "</mbpacket>";
154
        return s;
155
    }
156
 
157
    /**
158
     * Tries to deserialize an XML-string into a packet.
159
     * The format of the string must be:
160
     * <mbpacket destmodule="modulename">
161
     *     Only valid XML-data in here!
162
     * </mbpacket>
163
     * or else this function will not succeed.
164
     * @param s The XML-string
165
     * @return true if successful, false otherwise.
166
     * @throws SAXException if the string contains an invalid XML document (syntax errors).
167
     */
168
    synchronized public boolean createFromString(String s) throws SAXException {
169
        //destination kernel is always set to "self"
170
        destination = new MbLocation("self",null);
171
        source = new MbLocation("external","external");
172
        contents = "";
173
        XMLParser xmlParser = new XMLParser(new DataHandler());
174
        try {
175
            xmlParser.parseString(s);
176
        } catch (IOException e) {
177
            System.err.println(e);
178
            e.printStackTrace();
179
            return false;
180
        }
181
        //TODO: why check this? can it happen?
182
        if (destination==null) {
183
            return false;
184
        }
185
        return true;
186
    }
187
 
188
    /**
189
     * A data handler for XML parser.
190
     */
191
    private class DataHandler implements XMLDataHandler {
192
        //current element name
193
        private String currentElement = null;
194
        //current data for the element
195
        private String currentElementData = null;
196
 
197
        public void XMLstartElement(String element, HashMap attributes) {
198
            currentElementData = null;
199
            if (element.equals("mbpacket")) {
200
                if (attributes.containsKey("sourcekernel")) {
201
                    source.setKernel((String)attributes.get("sourcekernel"));
202
                }
203
                if (attributes.containsKey("sourcemodule")) {
204
                    source.setModule((String)attributes.get("sourcemodule"));
205
                }
206
                if (attributes.containsKey("destmodule")) {
207
                    destination.setModule((String)attributes.get("destmodule"));
208
                }
209
                // NOTE: destination kernel is IGNORED in all incoming packets!
210
                // (for security reasons, since no relaying is allowed. destkernel is always set to "self")
211
            } else if (element.equals("remoteaddress") && originAddress.equals("self")) {
212
                //(it must equal self, or else it can be set more than once, and can thus be faked)
213
                //remember remote address
214
                if (attributes.containsKey("value")) {
215
                    originAddress = (String)attributes.get("value");
216
                }
217
            } else {
218
                //this is user data, so put it into the contents field
219
                currentElement = element;
220
                contents += "<" + element;
221
                Iterator it = attributes.keySet().iterator();
222
                while (it.hasNext()) {
223
                    String key = (String)it.next();
224
                    contents += " " + key + "=\"" + attributes.get(key) + "\"";
225
                }
226
                //NEW CODE:
227
                contents += ">";
228
            }
229
        }
230
        public void XMLelementData(String data) {
231
            //NEW CODE
232
            if (currentElement!=null) {
233
                contents += MySystem.lineBreak + data;
234
                currentElementData = data;
235
            }
236
        }
237
        public void XMLendElement(String element) {
238
            if (!element.equals("remoteaddress") && !element.equals("mbpacket")) {
239
                //NEW CODE:
240
                //always add full end tag
241
                //TODO: maybe fix this again. OLD CODE caused some ">" to be missing though!
242
                contents += "</" + element + ">";
243
            }
244
            currentElement = null;
245
        }
246
        public void XMLdocumentStart() {}
247
        public void XMLdocumentEnd() {}
248
    }
249
}