]> git.basschouten.com Git - openhab-addons.git/blob
451a7377530d48626be4d112ba69581d9f344660
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2024 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  * <pre>
40  * {@code
41  * BEGIN:<itemName>:<targetState>
42  * BEGIN:<itemName>:<targetState>:<authorizationCode>
43  * END:<itemName>:<targetState>
44  * END:<itemName>:<targetState>:<authorizationCode>
45  * }
46  * </pre>
47  *
48  * @author Andrew Fiddian-Green - Initial contribution
49  */
50 @NonNullByDefault
51 public class CommandTag {
52
53     private static final List<Class<? extends Command>> otherCommandTypes = Arrays.asList(HSBType.class,
54             DecimalType.class, QuantityType.class, OnOffType.class, OpenClosedType.class, UpDownType.class,
55             PlayPauseType.class, RewindFastforwardType.class, StringType.class);
56
57     private static final List<Class<? extends Command>> percentCommandType = Arrays.asList(PercentType.class);
58
59     private static final Logger logger = LoggerFactory.getLogger(CommandTag.class);
60
61     private String inputLine;
62     private CommandTagType tagType;
63     private String itemName;
64     private String targetState;
65     private String authorizationCode;
66     private @Nullable Command theCommand;
67
68     public CommandTag(String inputLine) throws IllegalArgumentException {
69         this.inputLine = inputLine.trim();
70
71         if (!CommandTagType.prefixValid(inputLine)) {
72             throw new IllegalArgumentException(
73                     String.format("Command Tag Exception \"%s\" => Bad tag prefix!", inputLine));
74         }
75
76         if (!inputLine.contains(":")) {
77             throw new IllegalArgumentException(
78                     String.format("Command Tag Exception \"%s\" => Missing \":\" delimiters!", inputLine));
79         }
80
81         String[] fields = inputLine.split(":");
82         if (fields.length < 3) {
83             throw new IllegalArgumentException(
84                     String.format("Command Tag Exception \"%s\" => Not enough fields!", inputLine));
85         }
86
87         if (fields.length > 4) {
88             throw new IllegalArgumentException(
89                     String.format("Command Tag Exception \"%s\" => Too many fields!", inputLine));
90         }
91
92         try {
93             tagType = CommandTagType.valueOf(fields[0]);
94         } catch (IllegalArgumentException e) {
95             throw new IllegalArgumentException(
96                     String.format("Command Tag Exception \"%s\" => Invalid Tag Type!", inputLine));
97         }
98
99         itemName = fields[1].trim();
100         if (itemName.isEmpty()) {
101             throw new IllegalArgumentException(
102                     String.format("Command Tag Exception \"%s\" => Item name empty!", inputLine));
103         }
104
105         if (!itemName.matches("^\\w+$")) {
106             throw new IllegalArgumentException(
107                     String.format("Command Tag Exception \"%s\" => Bad syntax for Item name!", inputLine));
108         }
109
110         targetState = fields[2].trim();
111         if (targetState.isEmpty()) {
112             throw new IllegalArgumentException(
113                     String.format("Command Tag Exception \"%s\" => Target State empty!", inputLine));
114         }
115
116         // string is in double quotes => force StringType
117         if (targetState.startsWith("\"") && targetState.endsWith("\"")) {
118             // new StringType() should always succeed
119             theCommand = new StringType(targetState.replace("\"", ""));
120         }
121
122         // string is in single quotes => ditto
123         else if (targetState.startsWith("'") && targetState.endsWith("'")) {
124             // new StringType() should always succeed
125             theCommand = new StringType(targetState.replace("'", ""));
126         }
127
128         // string ends with % => try PercentType
129         else if (targetState.endsWith("%")) {
130             theCommand = TypeParser.parseCommand(percentCommandType,
131                     targetState.substring(0, targetState.length() - 1));
132             if (theCommand == null) {
133                 throw new IllegalArgumentException(String
134                         .format("Command Tag Exception \"%s\" => Invalid Target State percent value!", inputLine));
135             }
136         }
137
138         // try all other possible CommandTypes
139         if (theCommand == null) {
140             // TypeParser.parseCommand(otherCommandTypes should always succeed (with new StringType())
141             theCommand = TypeParser.parseCommand(otherCommandTypes, targetState);
142         }
143
144         if (fields.length == 4) {
145             authorizationCode = fields[3].trim();
146         } else {
147             authorizationCode = "";
148         }
149     }
150
151     public static @Nullable CommandTag createCommandTag(String inputLine) {
152         if (inputLine.isEmpty() || !CommandTagType.prefixValid(inputLine)) {
153             logger.trace("Command Tag Trace: \"{}\" => NOT a (valid) Command Tag!", inputLine);
154             return null;
155         }
156         try {
157             final CommandTag tag = new CommandTag(inputLine);
158             logger.trace("Command Tag Trace: \"{}\" => Fully valid Command Tag!", inputLine);
159             return tag;
160         } catch (IllegalArgumentException e) {
161             logger.warn("{}", e.getMessage());
162             return null;
163         }
164     }
165
166     public @Nullable Command getCommand() {
167         return theCommand;
168     }
169
170     public String getFullTag() {
171         return inputLine;
172     }
173
174     public String getItemName() {
175         return itemName;
176     }
177
178     public CommandTagType getTagType() {
179         return tagType;
180     }
181
182     public boolean isAuthorized(@Nullable String userAuthorizationCode) {
183         return (userAuthorizationCode == null || userAuthorizationCode.isEmpty()
184                 || userAuthorizationCode.equals(authorizationCode));
185     }
186 }