1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.fourthline.cling.model.meta;
17
18
19 import org.fourthline.cling.model.ModelUtil;
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.List;
25 import java.util.ArrayList;
26 import java.util.logging.Logger;
27
28
29
30
31
32
33 public class StateVariable<S extends Service> implements Validatable {
34
35 final private static Logger log = Logger.getLogger(StateVariable.class.getName());
36
37 final private String name;
38 final private StateVariableTypeDetails type;
39 final private StateVariableEventDetails eventDetails;
40
41
42 private S service;
43
44 public StateVariable(String name, StateVariableTypeDetails type) {
45 this(name, type, new StateVariableEventDetails());
46 }
47
48 public StateVariable(String name, StateVariableTypeDetails type, StateVariableEventDetails eventDetails) {
49 this.name = name;
50 this.type = type;
51 this.eventDetails = eventDetails;
52 }
53
54 public String getName() {
55 return name;
56 }
57
58 public StateVariableTypeDetails getTypeDetails() {
59 return type;
60 }
61
62 public StateVariableEventDetails getEventDetails() {
63 return eventDetails;
64 }
65
66 public S getService() {
67 return service;
68 }
69
70 void setService(S service) {
71 if (this.service != null)
72 throw new IllegalStateException("Final value has been set already, model is immutable");
73 this.service = service;
74 }
75
76 public List<ValidationError> validate() {
77 List<ValidationError> errors = new ArrayList<>();
78
79 if (getName() == null || getName().length() == 0) {
80 errors.add(new ValidationError(
81 getClass(),
82 "name",
83 "StateVariable without name of: " + getService()
84 ));
85 } else if (!ModelUtil.isValidUDAName(getName())) {
86 log.warning("UPnP specification violation of: " + getService().getDevice());
87 log.warning("Invalid state variable name: " + this);
88 }
89
90 errors.addAll(getTypeDetails().validate());
91
92 return errors;
93 }
94
95 public boolean isModeratedNumericType() {
96 return Datatype.Builtin.isNumeric(
97 getTypeDetails().getDatatype().getBuiltin()
98 ) && getEventDetails().getEventMinimumDelta() > 0;
99 }
100
101 public StateVariable<S> deepCopy() {
102 return new StateVariable(
103 getName(),
104 getTypeDetails(),
105 getEventDetails()
106 );
107 }
108
109 @Override
110 public String toString() {
111 StringBuilder sb = new StringBuilder();
112 sb.append("(").append(getClass().getSimpleName());
113 sb.append(", Name: ").append(getName());
114 sb.append(", Type: ").append(getTypeDetails().getDatatype().getDisplayString()).append(")");
115 if (!getEventDetails().isSendEvents()) {
116 sb.append(" (No Events)");
117 }
118 if (getTypeDetails().getDefaultValue() != null) {
119 sb.append(" Default Value: ").append("'").append(getTypeDetails().getDefaultValue()).append("'");
120 }
121 if (getTypeDetails().getAllowedValues() != null) {
122 sb.append(" Allowed Values: ");
123 for (String s : getTypeDetails().getAllowedValues()) {
124 sb.append(s).append("|");
125 }
126 }
127 return sb.toString();
128 }
129 }