1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.fourthline.cling.model.message;
17
18 import org.seamless.http.Headers;
19 import org.fourthline.cling.model.message.header.UpnpHeader;
20
21 import java.io.ByteArrayInputStream;
22 import java.util.LinkedHashMap;
23 import java.util.LinkedList;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.logging.Level;
27 import java.util.logging.Logger;
28
29
30
31
32
33
34 public class UpnpHeaders extends Headers {
35
36 private static final Logger log = Logger.getLogger(UpnpHeaders.class.getName());
37
38 protected Map<UpnpHeader.Type, List<UpnpHeader>> parsedHeaders;
39
40 public UpnpHeaders() {
41 }
42
43 public UpnpHeaders(Map<String, List<String>> headers) {
44 super(headers);
45 }
46
47 public UpnpHeaders(ByteArrayInputStream inputStream) {
48 super(inputStream);
49 }
50
51 public UpnpHeaders(boolean normalizeHeaders) {
52 super(normalizeHeaders);
53 }
54
55 protected void parseHeaders() {
56
57 parsedHeaders = new LinkedHashMap<>();
58 if (log.isLoggable(Level.FINE))
59 log.fine("Parsing all HTTP headers for known UPnP headers: " + size());
60 for (Entry<String, List<String>> entry : entrySet()) {
61
62 if (entry.getKey() == null) continue;
63
64 UpnpHeader.Type type = UpnpHeader.Type.getByHttpName(entry.getKey());
65 if (type == null) {
66 if (log.isLoggable(Level.FINE))
67 log.fine("Ignoring non-UPNP HTTP header: " + entry.getKey());
68 continue;
69 }
70
71 for (String value : entry.getValue()) {
72 UpnpHeader upnpHeader = UpnpHeader.newInstance(type, value);
73 if (upnpHeader == null || upnpHeader.getValue() == null) {
74 if (log.isLoggable(Level.FINE))
75 log.fine(
76 "Ignoring known but irrelevant header (value violates the UDA specification?) '"
77 + type.getHttpName()
78 + "': "
79 + value
80 );
81 } else {
82 addParsedValue(type, upnpHeader);
83 }
84 }
85 }
86 }
87
88 protected void addParsedValue(UpnpHeader.Type type, UpnpHeader value) {
89 if (log.isLoggable(Level.FINE))
90 log.fine("Adding parsed header: " + value);
91 List<UpnpHeader> list = parsedHeaders.get(type);
92 if (list == null) {
93 list = new LinkedList<>();
94 parsedHeaders.put(type, list);
95 }
96 list.add(value);
97 }
98
99 @Override
100 public List<String> put(String key, List<String> values) {
101 parsedHeaders = null;
102 return super.put(key, values);
103 }
104
105 @Override
106 public void add(String key, String value) {
107 parsedHeaders = null;
108 super.add(key, value);
109 }
110
111 @Override
112 public List<String> remove(Object key) {
113 parsedHeaders = null;
114 return super.remove(key);
115 }
116
117 @Override
118 public void clear() {
119 parsedHeaders = null;
120 super.clear();
121 }
122
123 public boolean containsKey(UpnpHeader.Type type) {
124 if (parsedHeaders == null) parseHeaders();
125 return parsedHeaders.containsKey(type);
126 }
127
128 public List<UpnpHeader> get(UpnpHeader.Type type) {
129 if (parsedHeaders == null) parseHeaders();
130 return parsedHeaders.get(type);
131 }
132
133 public void add(UpnpHeader.Type type, UpnpHeader value) {
134 super.add(type.getHttpName(), value.getString());
135 if (parsedHeaders != null)
136 addParsedValue(type, value);
137 }
138
139 public void remove(UpnpHeader.Type type) {
140 super.remove(type.getHttpName());
141 if (parsedHeaders != null)
142 parsedHeaders.remove(type);
143 }
144
145 public UpnpHeader[] getAsArray(UpnpHeader.Type type) {
146 if (parsedHeaders == null) parseHeaders();
147 return parsedHeaders.get(type) != null
148 ? parsedHeaders.get(type).toArray(new UpnpHeader[parsedHeaders.get(type).size()])
149 : new UpnpHeader[0];
150 }
151
152 public UpnpHeader getFirstHeader(UpnpHeader.Type type) {
153 return getAsArray(type).length > 0
154 ? getAsArray(type)[0]
155 : null;
156 }
157
158 public <H extends UpnpHeader> H getFirstHeader(UpnpHeader.Type type, Class<H> subtype) {
159 UpnpHeader[] headers = getAsArray(type);
160 if (headers.length == 0) return null;
161
162 for (UpnpHeader header : headers) {
163 if (subtype.isAssignableFrom(header.getClass())) {
164 return (H) header;
165 }
166 }
167 return null;
168 }
169
170 public String getFirstHeaderString(UpnpHeader.Type type) {
171 UpnpHeader header = getFirstHeader(type);
172 return header != null ? header.getString() : null;
173 }
174
175 public void log() {
176 if (log.isLoggable(Level.FINE)) {
177 log.fine("############################ RAW HEADERS ###########################");
178 for (Entry<String, List<String>> entry : entrySet()) {
179 log.fine("=== NAME : " + entry.getKey());
180 for (String v : entry.getValue()) {
181 log.fine("VALUE: " + v);
182 }
183 }
184 if (parsedHeaders != null && parsedHeaders.size() > 0) {
185 log.fine("########################## PARSED HEADERS ##########################");
186 for (Map.Entry<UpnpHeader.Type, List<UpnpHeader>> entry : parsedHeaders.entrySet()) {
187 log.fine("=== TYPE: " + entry.getKey());
188 for (UpnpHeader upnpHeader : entry.getValue()) {
189 log.fine("HEADER: " + upnpHeader);
190 }
191 }
192 }
193 log.fine("####################################################################");
194 }
195 }
196
197 }