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.test.local;
17  
18  import org.fourthline.cling.binding.annotations.UpnpAction;
19  import org.fourthline.cling.binding.annotations.UpnpOutputArgument;
20  import org.fourthline.cling.binding.annotations.UpnpService;
21  import org.fourthline.cling.binding.annotations.UpnpServiceId;
22  import org.fourthline.cling.binding.annotations.UpnpServiceType;
23  import org.fourthline.cling.binding.annotations.UpnpStateVariable;
24  import org.fourthline.cling.model.action.ActionInvocation;
25  import org.fourthline.cling.model.meta.DeviceDetails;
26  import org.fourthline.cling.model.meta.LocalDevice;
27  import org.fourthline.cling.model.meta.LocalService;
28  import org.fourthline.cling.model.types.UDADeviceType;
29  import org.fourthline.cling.test.data.SampleData;
30  import org.testng.annotations.Test;
31  
32  import java.util.Random;
33  
34  import static org.testng.Assert.assertEquals;
35  
36  /**
37   * @author Christian Bauer
38   */
39  public class LocalActionInvocationDatatypesTest {
40  
41      @Test
42      public void invokeActions() throws Exception {
43  
44          LocalDevice device = new LocalDevice(
45                  SampleData.createLocalDeviceIdentity(),
46                  new UDADeviceType("SomeDevice", 1),
47                  new DeviceDetails("Some Device"),
48                  SampleData.readService(LocalTestServiceOne.class)
49          );
50          LocalService svc = SampleData.getFirstService(device);
51  
52          ActionInvocation getDataInvocation = new ActionInvocation(svc.getAction("GetData"));
53          svc.getExecutor(getDataInvocation.getAction()).execute(getDataInvocation);
54          assertEquals(getDataInvocation.getFailure(), null);
55          assertEquals(getDataInvocation.getOutput().length, 1);
56          assertEquals(((byte[]) getDataInvocation.getOutput()[0].getValue()).length, 512);
57  
58          // This fails, we can't put arbitrary bytes into a String and hope it will be valid unicode characters!
59          /* TODO: This now only logs a warning!
60          ActionInvocation getStringDataInvocation = new ActionInvocation(svc.getAction("GetDataString"));
61          svc.getExecutor(getStringDataInvocation.getAction()).execute(getStringDataInvocation);
62          assertEquals(getStringDataInvocation.getFailure().getErrorCode(), ErrorCode.ARGUMENT_VALUE_INVALID.getCode());
63          assertEquals(
64                  getStringDataInvocation.getFailure().getMessage(),
65                  "The argument value is invalid. Wrong type or invalid value for 'RandomDataString': " +
66                          "Invalid characters in string value (XML 1.0, section 2.2) produced by (StringDatatype)."
67          );
68          */
69  
70          ActionInvocation invocation = new ActionInvocation(svc.getAction("GetStrings"));
71          svc.getExecutor(invocation.getAction()).execute(invocation);
72          assertEquals(invocation.getFailure(), null);
73          assertEquals(invocation.getOutput().length, 2);
74          assertEquals(invocation.getOutput("One").toString(), "foo");
75          assertEquals(invocation.getOutput("Two").toString(), "bar");
76  
77          invocation = new ActionInvocation(svc.getAction("GetThree"));
78          assertEquals(svc.getAction("GetThree").getOutputArguments()[0].getDatatype().getBuiltin().getDescriptorName(), "i2");
79          svc.getExecutor(invocation.getAction()).execute(invocation);
80          assertEquals(invocation.getFailure(), null);
81          assertEquals(invocation.getOutput().length, 1);
82          assertEquals(invocation.getOutput("three").toString(), "123");
83  
84          invocation = new ActionInvocation(svc.getAction("GetFour"));
85          assertEquals(svc.getAction("GetFour").getOutputArguments()[0].getDatatype().getBuiltin().getDescriptorName(), "int");
86          svc.getExecutor(invocation.getAction()).execute(invocation);
87          assertEquals(invocation.getFailure(), null);
88          assertEquals(invocation.getOutput().length, 1);
89          assertEquals(invocation.getOutput("four").toString(), "456");
90  
91          invocation = new ActionInvocation(svc.getAction("GetFive"));
92          assertEquals(svc.getAction("GetFive").getOutputArguments()[0].getDatatype().getBuiltin().getDescriptorName(), "int");
93          svc.getExecutor(invocation.getAction()).execute(invocation);
94          assertEquals(invocation.getFailure(), null);
95          assertEquals(invocation.getOutput().length, 1);
96          assertEquals(invocation.getOutput("five").toString(), "456");
97      }
98  
99      @UpnpService(
100             serviceId = @UpnpServiceId("SomeService"),
101             serviceType = @UpnpServiceType(value = "SomeService", version = 1),
102             supportsQueryStateVariables = false
103     )
104     public static class LocalTestServiceOne {
105 
106         @UpnpStateVariable(sendEvents = false)
107         private byte[] data;
108 
109         @UpnpStateVariable(sendEvents = false, datatype = "string")
110         private String dataString;
111 
112         @UpnpStateVariable(sendEvents = false)
113         private String one;
114 
115         @UpnpStateVariable(sendEvents = false)
116         private String two;
117 
118         @UpnpStateVariable(sendEvents = false)
119         private short three;
120 
121         @UpnpStateVariable(sendEvents = false, name = "four", datatype = "int")
122         private int four;
123 
124         public LocalTestServiceOne() {
125             data = new byte[512];
126             new Random().nextBytes(data);
127 
128             try {
129                 dataString = new String(data, "UTF-8");
130             } catch (Exception ex) {
131                 throw new RuntimeException(ex);
132             }
133         }
134 
135         // This works and the byte[] should not interfere with any Object[] handling in the executors
136         @UpnpAction(out = @UpnpOutputArgument(name = "RandomData"))
137         public byte[] getData() {
138             return data;
139         }
140 
141         // This fails, we can't just put random data into a string
142         @UpnpAction(out = @UpnpOutputArgument(name = "RandomDataString"))
143         public String getDataString() {
144             return dataString;
145         }
146 
147         // We are testing _several_ output arguments returned in a bean, access through getters
148         @UpnpAction(out = {
149                 @UpnpOutputArgument(name = "One", getterName = "getOne"),
150                 @UpnpOutputArgument(name = "Two", getterName = "getTwo")
151         })
152         public StringsHolder getStrings() {
153             return new StringsHolder();
154         }
155 
156         // Conversion of short into integer/UPnP "i2" datatype
157         @UpnpAction(out = @UpnpOutputArgument(name = "three"))
158         public short getThree() {
159             return 123;
160         }
161 
162         // Conversion of int into integer/UPnP "int" datatype
163         @UpnpAction(out = @UpnpOutputArgument(name = "four"))
164         public Integer getFour() {
165             return 456;
166         }
167 
168         @UpnpAction(out = @UpnpOutputArgument(name = "five", stateVariable = "four"))
169         public int getFive() {
170             return 456;
171         }
172     }
173 
174     public static class StringsHolder {
175         String one = "foo";
176         String two = "bar";
177 
178         public String getOne() {
179             return one;
180         }
181 
182         public String getTwo() {
183             return two;
184         }
185     }
186 }