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  
20  import org.fourthline.cling.model.Validatable;
21  import org.fourthline.cling.model.ValidationError;
22  import org.fourthline.cling.model.types.Datatype;
23  
24  import java.util.ArrayList;
25  import java.util.Arrays;
26  import java.util.List;
27  import java.util.logging.Logger;
28  
29  /**
30   * Type of a state variable, its default value, and integrity rules for allowed values and ranges.
31   *
32   * @author Christian Bauer
33   */
34  public class StateVariableTypeDetails implements Validatable {
35  
36      final private static Logger log = Logger.getLogger(StateVariableTypeDetails.class.getName());
37  
38      final private Datatype datatype;
39      final private String defaultValue;
40      final private String[] allowedValues;
41      final private StateVariableAllowedValueRange allowedValueRange;
42  
43      public StateVariableTypeDetails(Datatype datatype) {
44          this(datatype, null, null, null);
45      }
46  
47      public StateVariableTypeDetails(Datatype datatype, String defaultValue) {
48          this(datatype, defaultValue, null, null);
49      }
50  
51      public StateVariableTypeDetails(Datatype datatype, String defaultValue, String[] allowedValues, StateVariableAllowedValueRange allowedValueRange) {
52          this.datatype = datatype;
53          this.defaultValue = defaultValue;
54          this.allowedValues = allowedValues;
55          this.allowedValueRange = allowedValueRange;
56      }
57  
58      public Datatype getDatatype() {
59          return datatype;
60      }
61  
62      public String getDefaultValue() {
63          return defaultValue;
64      }
65  
66      public String[] getAllowedValues() {
67          // TODO: UPNP VIOLATION: DirecTV HR23/700 High Definition DVR Receiver has invalid default value
68          if (!foundDefaultInAllowedValues(defaultValue, allowedValues)) {
69              List<String> list = new ArrayList<>(Arrays.asList(allowedValues));
70              list.add(getDefaultValue());
71              return list.toArray(new String[list.size()]);
72          }
73          return allowedValues;
74      }
75  
76      public StateVariableAllowedValueRange getAllowedValueRange() {
77          return allowedValueRange;
78      }
79  
80      protected boolean foundDefaultInAllowedValues(String defaultValue, String[] allowedValues) {
81          if (defaultValue == null || allowedValues == null) return true;
82          for (String s : allowedValues) {
83              if (s.equals(defaultValue)) return true;
84          }
85          return false;
86      }
87  
88      public List<ValidationError> validate() {
89          List<ValidationError> errors = new ArrayList<>();
90  
91          if (getDatatype() == null) {
92              errors.add(new ValidationError(
93                      getClass(),
94                      "datatype",
95                      "Service state variable has no datatype"
96              ));
97          }
98  
99          if (getAllowedValues() != null) {
100 
101             if (getAllowedValueRange() != null) {
102                 errors.add(new ValidationError(
103                         getClass(),
104                         "allowedValues",
105                         "Allowed value list of state variable can not also be restricted with allowed value range"
106                 ));
107             }
108 
109             if (!Datatype.Builtin.STRING.equals(getDatatype().getBuiltin())) {
110                 errors.add(new ValidationError(
111                         getClass(),
112                         "allowedValues",
113                         "Allowed value list of state variable only available for string datatype, not: " + getDatatype()
114                 ));
115             }
116 
117             for (String s : getAllowedValues()) {
118                 if (s.length() > 31) {
119                     log.warning("UPnP specification violation, allowed value string must be less than 32 chars: " + s);
120                 }
121             }
122 
123             if(!foundDefaultInAllowedValues(defaultValue, allowedValues)) {
124                 log.warning("UPnP specification violation, allowed string values " +
125                                     "don't contain default value: " + defaultValue
126                 );
127             }
128         }
129 
130         if (getAllowedValueRange() != null) {
131             errors.addAll(getAllowedValueRange().validate());
132         }
133 
134         return errors;
135     }
136 }