1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.fourthline.cling.transport.impl;
17
18 import org.fourthline.cling.model.UnsupportedDataException;
19 import org.fourthline.cling.model.XMLUtil;
20 import org.fourthline.cling.model.message.gena.IncomingEventRequestMessage;
21 import org.fourthline.cling.transport.spi.GENAEventProcessor;
22 import org.seamless.xml.XmlPullParserUtils;
23
24 import javax.enterprise.inject.Alternative;
25 import java.util.logging.Logger;
26 import java.util.regex.Matcher;
27 import java.util.regex.Pattern;
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 @Alternative
51 public class RecoveringGENAEventProcessorImpl extends PullGENAEventProcessorImpl {
52
53 private static Logger log = Logger.getLogger(GENAEventProcessor.class.getName());
54
55 public void readBody(IncomingEventRequestMessage requestMessage) throws UnsupportedDataException {
56 try {
57 super.readBody(requestMessage);
58 } catch (UnsupportedDataException ex) {
59
60
61 if (!requestMessage.isBodyNonEmptyString())
62 throw ex;
63
64 log.warning("Trying to recover from invalid GENA XML event: " + ex);
65
66
67 requestMessage.getStateVariableValues().clear();
68
69 String body = getMessageBody(requestMessage);
70
71 String fixedBody = fixXMLEncodedLastChange(
72 XmlPullParserUtils.fixXMLEntities(body)
73 );
74
75 try {
76
77 requestMessage.setBody(fixedBody);
78 super.readBody(requestMessage);
79 } catch (UnsupportedDataException ex2) {
80
81 if (requestMessage.getStateVariableValues().isEmpty()) {
82
83 throw ex;
84 }
85 log.warning("Partial read of GENA event properties (probably due to truncated XML)");
86 }
87 }
88 }
89
90 protected String fixXMLEncodedLastChange(String xml) {
91 Pattern pattern = Pattern.compile("<LastChange>(.*)</LastChange>", Pattern.DOTALL);
92 Matcher matcher = pattern.matcher(xml);
93
94 if (matcher.find() && matcher.groupCount() == 1) {
95
96 String lastChange = matcher.group(1);
97
98 if (XmlPullParserUtils.isNullOrEmpty(lastChange))
99 return xml;
100
101 lastChange = lastChange.trim();
102
103 String fixedLastChange = lastChange;
104
105 if (lastChange.charAt(0) == '<') {
106
107 fixedLastChange = XMLUtil.encodeText(fixedLastChange);
108 } else {
109
110
111
112
113
114 }
115
116 if (fixedLastChange.equals(lastChange)) {
117 return xml;
118 }
119
120 return "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
121 "<e:propertyset xmlns:e=\"urn:schemas-upnp-org:event-1-0\">" +
122 "<e:property>" +
123 "<LastChange>" +
124 fixedLastChange +
125 "</LastChange>" +
126 "</e:property>" +
127 "</e:propertyset>";
128 }
129 return xml;
130 }
131 }