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.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   * The metadata of a named state variable.
30   *
31   * @author Christian Bauer
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      // Package mutable state
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 }