View Javadoc
1   /*
2    * Copyright (C) 2013 4th Line GmbH, Switzerland
3    *
4    * The contents of this file are subject to the terms of either the GNU
5    * Lesser General Public License Version 2 or later ("LGPL") or the
6    * Common Development and Distribution License Version 1 or later
7    * ("CDDL") (collectively, the "License"). You may not use this file
8    * except in compliance with the License. See LICENSE.txt for more
9    * information.
10   *
11   * This program is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14   */
15  
16  package org.fourthline.cling.model.meta;
17  
18  
19  import org.fourthline.cling.model.Namespace;
20  import org.fourthline.cling.model.resource.ServiceEventCallbackResource;
21  import org.fourthline.cling.model.resource.Resource;
22  import org.fourthline.cling.model.ValidationException;
23  import org.fourthline.cling.model.types.DeviceType;
24  import org.fourthline.cling.model.types.ServiceId;
25  import org.fourthline.cling.model.types.ServiceType;
26  import org.fourthline.cling.model.types.UDN;
27  import org.seamless.util.URIUtil;
28  
29  import java.net.URI;
30  import java.net.URL;
31  import java.util.ArrayList;
32  import java.util.Arrays;
33  import java.util.Collection;
34  import java.util.List;
35  
36  /**
37   * The metadata of a device that was discovered on the network.
38   *
39   * @author Christian Bauer
40   */
41  public class RemoteDevice extends Device<RemoteDeviceIdentity, RemoteDevice, RemoteService> {
42  
43      public RemoteDevice(RemoteDeviceIdentity identity) throws ValidationException {
44          super(identity);
45      }
46  
47      public RemoteDevice(RemoteDeviceIdentity identity, DeviceType type, DeviceDetails details,
48                         RemoteService service) throws ValidationException {
49          super(identity, type, details, null, new RemoteService[]{service});
50      }
51  
52      public RemoteDevice(RemoteDeviceIdentity identity, DeviceType type, DeviceDetails details,
53                         RemoteService service, RemoteDevice embeddedDevice) throws ValidationException {
54          super(identity, type, details, null, new RemoteService[]{service}, new RemoteDevice[]{embeddedDevice});
55      }
56  
57      public RemoteDevice(RemoteDeviceIdentity identity, DeviceType type, DeviceDetails details,
58                         RemoteService[] services) throws ValidationException {
59          super(identity, type, details, null, services);
60      }
61  
62      public RemoteDevice(RemoteDeviceIdentity identity, DeviceType type, DeviceDetails details,
63                         RemoteService[] services, RemoteDevice[] embeddedDevices) throws ValidationException {
64          super(identity, type, details, null, services, embeddedDevices);
65      }
66  
67      public RemoteDevice(RemoteDeviceIdentity identity, DeviceType type, DeviceDetails details,
68                         Icon icon, RemoteService service) throws ValidationException {
69          super(identity, type, details, new Icon[]{icon}, new RemoteService[]{service});
70      }
71  
72      public RemoteDevice(RemoteDeviceIdentity identity, DeviceType type, DeviceDetails details,
73                         Icon icon, RemoteService service, RemoteDevice embeddedDevice) throws ValidationException {
74          super(identity, type, details, new Icon[]{icon}, new RemoteService[]{service}, new RemoteDevice[]{embeddedDevice});
75      }
76  
77      public RemoteDevice(RemoteDeviceIdentity identity, DeviceType type, DeviceDetails details,
78                         Icon icon, RemoteService[] services) throws ValidationException {
79          super(identity, type, details, new Icon[]{icon}, services);
80      }
81  
82      public RemoteDevice(RemoteDeviceIdentity identity, DeviceType type, DeviceDetails details,
83                         Icon icon, RemoteService[] services, RemoteDevice[] embeddedDevices) throws ValidationException {
84          super(identity, type, details, new Icon[]{icon}, services, embeddedDevices);
85      }
86  
87      public RemoteDevice(RemoteDeviceIdentity identity, DeviceType type, DeviceDetails details,
88                         Icon[] icons, RemoteService service) throws ValidationException {
89          super(identity, type, details, icons, new RemoteService[]{service});
90      }
91  
92      public RemoteDevice(RemoteDeviceIdentity identity, DeviceType type, DeviceDetails details,
93                         Icon[] icons, RemoteService service, RemoteDevice embeddedDevice) throws ValidationException {
94          super(identity, type, details, icons, new RemoteService[]{service}, new RemoteDevice[]{embeddedDevice});
95      }
96  
97      public RemoteDevice(RemoteDeviceIdentity identity, DeviceType type, DeviceDetails details,
98                         Icon[] icons, RemoteService[] services) throws ValidationException {
99          super(identity, type, details, icons, services);
100     }
101 
102     public RemoteDevice(RemoteDeviceIdentity identity, DeviceType type, DeviceDetails details,
103                        Icon[] icons, RemoteService[] services, RemoteDevice[] embeddedDevices) throws ValidationException {
104         super(identity, type, details, icons, services, embeddedDevices);
105     }
106 
107     public RemoteDevice(RemoteDeviceIdentity identity, UDAVersion version, DeviceType type, DeviceDetails details,
108                        Icon[] icons, RemoteService[] services, RemoteDevice[] embeddedDevices) throws ValidationException {
109         super(identity, version, type, details, icons, services, embeddedDevices);
110     }
111 
112     @Override
113     public RemoteService[] getServices() {
114         return this.services != null ? this.services : new RemoteService[0];
115     }
116 
117     @Override
118     public RemoteDevice[] getEmbeddedDevices() {
119         return this.embeddedDevices != null ? this.embeddedDevices : new RemoteDevice[0];
120     }
121 
122     public URL normalizeURI(URI relativeOrAbsoluteURI) {
123 
124         // TODO: I have one device (Netgear 834DG DSL Router) that sends a <URLBase>, and even that is wrong (port)!
125         // This can be fixed by "re-enabling" UPnP in the upnpService after a reboot, it will then use the right port...
126         // return URIUtil.createAbsoluteURL(getDescriptorURL(), relativeOrAbsoluteURI);
127 
128         if (getDetails() != null && getDetails().getBaseURL() != null) {
129             // If we have an <URLBase>, all URIs are relative to it
130             return URIUtil.createAbsoluteURL(getDetails().getBaseURL(), relativeOrAbsoluteURI);
131         } else {
132             // Otherwise, they are relative to the descriptor location
133             return URIUtil.createAbsoluteURL(getIdentity().getDescriptorURL(), relativeOrAbsoluteURI);
134         }
135 
136     }
137 
138     @Override
139     public RemoteDevice newInstance(UDN udn, UDAVersion version, DeviceType type, DeviceDetails details,
140                                     Icon[] icons, RemoteService[] services,
141                                     List<RemoteDevice> embeddedDevices) throws ValidationException {
142         return new RemoteDevice(
143                 new RemoteDeviceIdentity(udn, getIdentity()),
144                 version, type, details, icons,
145                 services,
146                 embeddedDevices.size() > 0 ? embeddedDevices.toArray(new RemoteDevice[embeddedDevices.size()]) : null
147         );
148     }
149 
150     @Override
151     public RemoteService newInstance(ServiceType serviceType, ServiceId serviceId,
152                                      URI descriptorURI, URI controlURI, URI eventSubscriptionURI,
153                                      Action<RemoteService>[] actions, StateVariable<RemoteService>[] stateVariables) throws ValidationException {
154         return new RemoteService(
155                 serviceType, serviceId,
156                 descriptorURI, controlURI, eventSubscriptionURI,
157                 actions, stateVariables
158         );
159     }
160 
161     @Override
162     public RemoteDevice[] toDeviceArray(Collection<RemoteDevice> col) {
163         return col.toArray(new RemoteDevice[col.size()]);
164     }
165 
166     @Override
167     public RemoteService[] newServiceArray(int size) {
168         return new RemoteService[size];
169     }
170 
171     @Override
172     public RemoteService[] toServiceArray(Collection<RemoteService> col) {
173         return col.toArray(new RemoteService[col.size()]);
174     }
175 
176     @Override
177     public Resource[] discoverResources(Namespace namespace) {
178         List<Resource> discovered = new ArrayList<>();
179 
180         // Services
181         for (RemoteService service : getServices()) {
182         	if(service == null) continue;
183             discovered.add(new ServiceEventCallbackResource(namespace.getEventCallbackPath(service), service));
184         }
185 
186         // Embedded devices
187         if (hasEmbeddedDevices()) {
188             for (Device embeddedDevice : getEmbeddedDevices()) {
189 				if(embeddedDevice == null) continue;
190                 discovered.addAll(Arrays.asList(embeddedDevice.discoverResources(namespace)));
191             }
192         }
193 
194         return discovered.toArray(new Resource[discovered.size()]);
195     }
196 
197     @Override
198     public RemoteDevice getRoot() {
199         if (isRoot()) return this;
200         RemoteDevice current = this;
201         while (current.getParentDevice() != null) {
202             current = current.getParentDevice();
203         }
204         return current;
205     }
206 
207     @Override
208     public RemoteDevice findDevice(UDN udn) {
209         return find(udn, this);
210     }
211 
212 }