]> git.basschouten.com Git - openhab-addons.git/blob
01c7191b33d23b17373c3974ceabdb57da9692f9
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.icalendar.internal.logic;
14
15 import java.util.Arrays;
16 import java.util.List;
17
18 import org.eclipse.jdt.annotation.NonNullByDefault;
19 import org.eclipse.jdt.annotation.Nullable;
20 import org.openhab.core.library.types.DecimalType;
21 import org.openhab.core.library.types.HSBType;
22 import org.openhab.core.library.types.OnOffType;
23 import org.openhab.core.library.types.OpenClosedType;
24 import org.openhab.core.library.types.PercentType;
25 import org.openhab.core.library.types.PlayPauseType;
26 import org.openhab.core.library.types.QuantityType;
27 import org.openhab.core.library.types.RewindFastforwardType;
28 import org.openhab.core.library.types.StringType;
29 import org.openhab.core.library.types.UpDownType;
30 import org.openhab.core.types.Command;
31 import org.openhab.core.types.TypeParser;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34
35 /**
36  * This is a class that implements a Command Tag that may be embedded in an
37  * Event Description. Valid Tags must follow one of the following forms..
38  *
39  * BEGIN:<itemName>:<targetState>
40  * BEGIN:<itemName>:<targetState>:<authorizationCode>
41  * END:<itemName>:<targetState>
42  * END:<itemName>:<targetState>:<authorizationCode>
43  *
44  * @author Andrew Fiddian-Green - Initial contribution
45  */
46 @NonNullByDefault
47 public class CommandTag {
48
49     private static final List<Class<? extends Command>> otherCommandTypes = Arrays.asList(HSBType.class,
50             DecimalType.class, QuantityType.class, OnOffType.class, OpenClosedType.class, UpDownType.class,
51             PlayPauseType.class, RewindFastforwardType.class, StringType.class);
52
53     private static final List<Class<? extends Command>> percentCommandType = Arrays.asList(PercentType.class);
54
55     private static final Logger logger = LoggerFactory.getLogger(CommandTag.class);
56
57     private String inputLine;
58     private CommandTagType tagType;
59     private String itemName;
60     private String targetState;
61     private String authorizationCode;
62     private @Nullable Command theCommand;
63
64     public CommandTag(String inputLine) throws IllegalArgumentException {
65         this.inputLine = inputLine.trim();
66
67         if (!CommandTagType.prefixValid(inputLine)) {
68             throw new IllegalArgumentException(
69                     String.format("Command Tag Exception \"%s\" => Bad tag prefix!", inputLine));
70         }
71
72         if (!inputLine.contains(":")) {
73             throw new IllegalArgumentException(
74                     String.format("Command Tag Exception \"%s\" => Missing \":\" delimiters!", inputLine));
75         }
76
77         String[] fields = inputLine.split(":");
78         if (fields.length < 3) {
79             throw new IllegalArgumentException(
80                     String.format("Command Tag Exception \"%s\" => Not enough fields!", inputLine));
81         }
82
83         if (fields.length > 4) {
84             throw new IllegalArgumentException(
85                     String.format("Command Tag Exception \"%s\" => Too many fields!", inputLine));
86         }
87
88         try {
89             tagType = CommandTagType.valueOf(fields[0]);
90         } catch (IllegalArgumentException e) {
91             throw new IllegalArgumentException(
92                     String.format("Command Tag Exception \"%s\" => Invalid Tag Type!", inputLine));
93         }
94
95         itemName = fields[1].trim();
96         if (itemName.isEmpty()) {
97             throw new IllegalArgumentException(
98                     String.format("Command Tag Exception \"%s\" => Item name empty!", inputLine));
99         }
100
101         if (!itemName.matches("^\\w+$")) {
102             throw new IllegalArgumentException(
103                     String.format("Command Tag Exception \"%s\" => Bad syntax for Item name!", inputLine));
104         }
105
106         targetState = fields[2].trim();
107         if (targetState.isEmpty()) {
108             throw new IllegalArgumentException(
109                     String.format("Command Tag Exception \"%s\" => Target State empty!", inputLine));
110         }
111
112         // string is in double quotes => force StringType
113         if (targetState.startsWith("\"") && targetState.endsWith("\"")) {
114             // new StringType() should always succeed
115             theCommand = new StringType(targetState.replace("\"", ""));
116         }
117
118         // string is in single quotes => ditto
119         else if (targetState.startsWith("'") && targetState.endsWith("'")) {
120             // new StringType() should always succeed
121             theCommand = new StringType(targetState.replace("'", ""));
122         }
123
124         // string ends with % => try PercentType
125         else if (targetState.endsWith("%")) {
126             theCommand = TypeParser.parseCommand(percentCommandType,
127                     targetState.substring(0, targetState.length() - 1));
128             if (theCommand == null) {
129                 throw new IllegalArgumentException(String
130                         .format("Command Tag Exception \"%s\" => Invalid Target State percent value!", inputLine));
131             }
132         }
133
134         // try all other possible CommandTypes
135         if (theCommand == null) {
136             // TypeParser.parseCommand(otherCommandTypes should always succeed (with new StringType())
137             theCommand = TypeParser.parseCommand(otherCommandTypes, targetState);
138         }
139
140         if (fields.length == 4) {
141             authorizationCode = fields[3].trim();
142         } else {
143             authorizationCode = "";
144         }
145     }
146
147     public static @Nullable CommandTag createCommandTag(String inputLine) {
148         if (inputLine.isEmpty() || !CommandTagType.prefixValid(inputLine)) {
149             logger.trace("Command Tag Trace: \"{}\" => NOT a (valid) Command Tag!", inputLine);
150             return null;
151         }
152         try {
153             final CommandTag tag = new CommandTag(inputLine);
154             logger.trace("Command Tag Trace: \"{}\" => Fully valid Command Tag!", inputLine);
155             return tag;
156         } catch (IllegalArgumentException e) {
157             logger.warn("{}", e.getMessage());
158             return null;
159         }
160     }
161
162     public @Nullable Command getCommand() {
163         return theCommand;
164     }
165
166     public String getFullTag() {
167         return inputLine;
168     }
169
170     public String getItemName() {
171         return itemName;
172     }
173
174     public CommandTagType getTagType() {
175         return tagType;
176     }
177
178     public boolean isAuthorized(@Nullable String userAuthorizationCode) {
179         return (userAuthorizationCode == null || userAuthorizationCode.isEmpty()
180                 || userAuthorizationCode.equals(authorizationCode));
181     }
182 }