1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.fourthline.cling.model.meta;
17
18 import org.fourthline.cling.model.Namespace;
19 import org.fourthline.cling.model.profile.RemoteClientInfo;
20 import org.fourthline.cling.model.profile.DeviceDetailsProvider;
21 import org.fourthline.cling.model.resource.DeviceDescriptorResource;
22 import org.fourthline.cling.model.resource.IconResource;
23 import org.fourthline.cling.model.resource.ServiceControlResource;
24 import org.fourthline.cling.model.resource.ServiceDescriptorResource;
25 import org.fourthline.cling.model.resource.ServiceEventSubscriptionResource;
26 import org.fourthline.cling.model.resource.Resource;
27 import org.fourthline.cling.model.ValidationError;
28 import org.fourthline.cling.model.ValidationException;
29 import org.fourthline.cling.model.types.DeviceType;
30 import org.fourthline.cling.model.types.ServiceId;
31 import org.fourthline.cling.model.types.ServiceType;
32 import org.fourthline.cling.model.types.UDN;
33
34 import java.net.URI;
35 import java.util.ArrayList;
36 import java.util.Arrays;
37 import java.util.Collection;
38 import java.util.List;
39
40
41
42
43
44
45 public class LocalDevice extends Device<DeviceIdentity, LocalDevice, LocalService> {
46
47 final private DeviceDetailsProvider deviceDetailsProvider;
48
49 public LocalDevice(DeviceIdentity identity) throws ValidationException {
50 super(identity);
51 this.deviceDetailsProvider = null;
52 }
53
54 public LocalDevice(DeviceIdentity identity, DeviceType type, DeviceDetails details,
55 LocalService service) throws ValidationException {
56 super(identity, type, details, null, new LocalService[]{service});
57 this.deviceDetailsProvider = null;
58 }
59
60 public LocalDevice(DeviceIdentity identity, DeviceType type, DeviceDetailsProvider deviceDetailsProvider,
61 LocalService service) throws ValidationException {
62 super(identity, type, null, null, new LocalService[]{service});
63 this.deviceDetailsProvider = deviceDetailsProvider;
64 }
65
66 public LocalDevice(DeviceIdentity identity, DeviceType type, DeviceDetailsProvider deviceDetailsProvider,
67 LocalService service, LocalDevice embeddedDevice) throws ValidationException {
68 super(identity, type, null, null, new LocalService[]{service}, new LocalDevice[]{embeddedDevice});
69 this.deviceDetailsProvider = deviceDetailsProvider;
70 }
71
72 public LocalDevice(DeviceIdentity identity, DeviceType type, DeviceDetails details,
73 LocalService service, LocalDevice embeddedDevice) throws ValidationException {
74 super(identity, type, details, null, new LocalService[]{service}, new LocalDevice[]{embeddedDevice});
75 this.deviceDetailsProvider = null;
76 }
77
78 public LocalDevice(DeviceIdentity identity, DeviceType type, DeviceDetails details,
79 LocalService[] services) throws ValidationException {
80 super(identity, type, details, null, services);
81 this.deviceDetailsProvider = null;
82 }
83
84 public LocalDevice(DeviceIdentity identity, DeviceType type, DeviceDetails details,
85 LocalService[] services, LocalDevice[] embeddedDevices) throws ValidationException {
86 super(identity, type, details, null, services, embeddedDevices);
87 this.deviceDetailsProvider = null;
88 }
89
90 public LocalDevice(DeviceIdentity identity, DeviceType type, DeviceDetails details,
91 Icon icon, LocalService service) throws ValidationException {
92 super(identity, type, details, new Icon[]{icon}, new LocalService[]{service});
93 this.deviceDetailsProvider = null;
94 }
95
96 public LocalDevice(DeviceIdentity identity, DeviceType type, DeviceDetails details,
97 Icon icon, LocalService service, LocalDevice embeddedDevice) throws ValidationException {
98 super(identity, type, details, new Icon[]{icon}, new LocalService[]{service}, new LocalDevice[]{embeddedDevice});
99 this.deviceDetailsProvider = null;
100 }
101
102 public LocalDevice(DeviceIdentity identity, DeviceType type, DeviceDetails details,
103 Icon icon, LocalService[] services) throws ValidationException {
104 super(identity, type, details, new Icon[]{icon}, services);
105 this.deviceDetailsProvider = null;
106 }
107
108 public LocalDevice(DeviceIdentity identity, DeviceType type, DeviceDetailsProvider deviceDetailsProvider,
109 Icon icon, LocalService[] services) throws ValidationException {
110 super(identity, type, null, new Icon[]{icon}, services);
111 this.deviceDetailsProvider = deviceDetailsProvider;
112 }
113
114 public LocalDevice(DeviceIdentity identity, DeviceType type, DeviceDetails details,
115 Icon icon, LocalService[] services, LocalDevice[] embeddedDevices) throws ValidationException {
116 super(identity, type, details, new Icon[]{icon}, services, embeddedDevices);
117 this.deviceDetailsProvider = null;
118 }
119
120 public LocalDevice(DeviceIdentity identity, DeviceType type, DeviceDetails details,
121 Icon[] icons, LocalService service) throws ValidationException {
122 super(identity, type, details, icons, new LocalService[]{service});
123 this.deviceDetailsProvider = null;
124 }
125
126 public LocalDevice(DeviceIdentity identity, DeviceType type, DeviceDetails details,
127 Icon[] icons, LocalService service, LocalDevice embeddedDevice) throws ValidationException {
128 super(identity, type, details, icons, new LocalService[]{service}, new LocalDevice[]{embeddedDevice});
129 this.deviceDetailsProvider = null;
130 }
131
132 public LocalDevice(DeviceIdentity identity, DeviceType type, DeviceDetailsProvider deviceDetailsProvider,
133 Icon[] icons, LocalService service, LocalDevice embeddedDevice) throws ValidationException {
134 super(identity, type, null, icons, new LocalService[]{service}, new LocalDevice[]{embeddedDevice});
135 this.deviceDetailsProvider = deviceDetailsProvider;
136 }
137
138 public LocalDevice(DeviceIdentity identity, DeviceType type, DeviceDetails details,
139 Icon[] icons, LocalService[] services) throws ValidationException {
140 super(identity, type, details, icons, services);
141 this.deviceDetailsProvider = null;
142 }
143
144 public LocalDevice(DeviceIdentity identity, DeviceType type, DeviceDetails details,
145 Icon[] icons, LocalService[] services, LocalDevice[] embeddedDevices) throws ValidationException {
146 super(identity, type, details, icons, services, embeddedDevices);
147 this.deviceDetailsProvider = null;
148 }
149
150 public LocalDevice(DeviceIdentity identity, UDAVersion version, DeviceType type, DeviceDetails details,
151 Icon[] icons, LocalService[] services, LocalDevice[] embeddedDevices) throws ValidationException {
152 super(identity, version, type, details, icons, services, embeddedDevices);
153 this.deviceDetailsProvider = null;
154 }
155
156 public LocalDevice(DeviceIdentity identity, UDAVersion version, DeviceType type, DeviceDetailsProvider deviceDetailsProvider,
157 Icon[] icons, LocalService[] services, LocalDevice[] embeddedDevices) throws ValidationException {
158 super(identity, version, type, null, icons, services, embeddedDevices);
159 this.deviceDetailsProvider = deviceDetailsProvider;
160 }
161
162 public DeviceDetailsProvider getDeviceDetailsProvider() {
163 return deviceDetailsProvider;
164 }
165
166 @Override
167 public DeviceDetails getDetails(RemoteClientInfo info) {
168 if (getDeviceDetailsProvider() != null) {
169 return getDeviceDetailsProvider().provide(info);
170 }
171 return this.getDetails();
172 }
173
174 @Override
175 public LocalService[] getServices() {
176 return this.services != null ? this.services : new LocalService[0];
177 }
178
179 @Override
180 public LocalDevice[] getEmbeddedDevices() {
181 return this.embeddedDevices != null ? this.embeddedDevices : new LocalDevice[0];
182 }
183
184 @Override
185 public LocalDevice newInstance(UDN udn, UDAVersion version, DeviceType type, DeviceDetails details,
186 Icon[] icons, LocalService[] services, List<LocalDevice> embeddedDevices)
187 throws ValidationException {
188 return new LocalDevice(
189 new DeviceIdentity(udn, getIdentity().getMaxAgeSeconds()),
190 version, type, details, icons,
191 services,
192 embeddedDevices.size() > 0 ? embeddedDevices.toArray(new LocalDevice[embeddedDevices.size()]) : null
193 );
194 }
195
196 @Override
197 public LocalService newInstance(ServiceType serviceType, ServiceId serviceId,
198 URI descriptorURI, URI controlURI, URI eventSubscriptionURI,
199 Action<LocalService>[] actions, StateVariable<LocalService>[] stateVariables) throws ValidationException {
200 return new LocalService(
201 serviceType, serviceId,
202 actions, stateVariables
203 );
204 }
205
206 @Override
207 public LocalDevice[] toDeviceArray(Collection<LocalDevice> col) {
208 return col.toArray(new LocalDevice[col.size()]);
209 }
210
211 @Override
212 public LocalService[] newServiceArray(int size) {
213 return new LocalService[size];
214 }
215
216 @Override
217 public LocalService[] toServiceArray(Collection<LocalService> col) {
218 return col.toArray(new LocalService[col.size()]);
219 }
220
221 @Override
222 public List<ValidationError> validate() {
223 List<ValidationError> errors = new ArrayList<>();
224 errors.addAll(super.validate());
225
226
227
228 if (hasIcons()) {
229 for (Icon icon : getIcons()) {
230 if (icon.getUri().isAbsolute()) {
231 errors.add(new ValidationError(
232 getClass(),
233 "icons",
234 "Local icon URI can not be absolute: " + icon.getUri()
235 ));
236 }
237 if (icon.getUri().toString().contains("../")) {
238 errors.add(new ValidationError(
239 getClass(),
240 "icons",
241 "Local icon URI must not contain '../': " + icon.getUri()
242 ));
243 }
244 if (icon.getUri().toString().startsWith("/")) {
245 errors.add(new ValidationError(
246 getClass(),
247 "icons",
248 "Local icon URI must not start with '/': " + icon.getUri()
249 ));
250 }
251 }
252 }
253
254 return errors;
255 }
256
257 @Override
258 public Resource[] discoverResources(Namespace namespace) {
259 List<Resource> discovered = new ArrayList<>();
260
261
262 if (isRoot()) {
263
264
265 discovered.add(new DeviceDescriptorResource(namespace.getDescriptorPath(this), this));
266 }
267
268
269 for (LocalService service : getServices()) {
270
271 discovered.add(
272 new ServiceDescriptorResource(namespace.getDescriptorPath(service), service)
273 );
274
275
276 discovered.add(
277 new ServiceControlResource(namespace.getControlPath(service), service)
278 );
279
280
281 discovered.add(
282 new ServiceEventSubscriptionResource(namespace.getEventSubscriptionPath(service), service)
283 );
284
285 }
286
287
288 for (Icon icon : getIcons()) {
289 discovered.add(new IconResource(namespace.prefixIfRelative(this, icon.getUri()), icon));
290 }
291
292
293 if (hasEmbeddedDevices()) {
294 for (Device embeddedDevice : getEmbeddedDevices()) {
295 discovered.addAll(Arrays.asList(embeddedDevice.discoverResources(namespace)));
296 }
297 }
298
299 return discovered.toArray(new Resource[discovered.size()]);
300 }
301
302 @Override
303 public LocalDevice getRoot() {
304 if (isRoot()) return this;
305 LocalDevice current = this;
306 while (current.getParentDevice() != null) {
307 current = current.getParentDevice();
308 }
309 return current;
310 }
311
312 @Override
313 public LocalDevice findDevice(UDN udn) {
314 return find(udn, this);
315 }
316
317 }