2 * Copyright (c) 2010-2024 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
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
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.icalendar.internal.logic;
15 import java.util.Arrays;
16 import java.util.List;
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;
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..
41 * BEGIN:<itemName>:<targetState>
42 * BEGIN:<itemName>:<targetState>:<authorizationCode>
43 * END:<itemName>:<targetState>
44 * END:<itemName>:<targetState>:<authorizationCode>
48 * @author Andrew Fiddian-Green - Initial contribution
51 public class CommandTag {
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);
57 private static final List<Class<? extends Command>> percentCommandType = Arrays.asList(PercentType.class);
59 private static final Logger logger = LoggerFactory.getLogger(CommandTag.class);
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;
68 public CommandTag(String inputLine) throws IllegalArgumentException {
69 this.inputLine = inputLine.trim();
71 if (!CommandTagType.prefixValid(inputLine)) {
72 throw new IllegalArgumentException(
73 String.format("Command Tag Exception \"%s\" => Bad tag prefix!", inputLine));
76 if (!inputLine.contains(":")) {
77 throw new IllegalArgumentException(
78 String.format("Command Tag Exception \"%s\" => Missing \":\" delimiters!", inputLine));
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));
87 if (fields.length > 4) {
88 throw new IllegalArgumentException(
89 String.format("Command Tag Exception \"%s\" => Too many fields!", inputLine));
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));
99 itemName = fields[1].trim();
100 if (itemName.isEmpty()) {
101 throw new IllegalArgumentException(
102 String.format("Command Tag Exception \"%s\" => Item name empty!", inputLine));
105 if (!itemName.matches("^\\w+$")) {
106 throw new IllegalArgumentException(
107 String.format("Command Tag Exception \"%s\" => Bad syntax for Item name!", inputLine));
110 targetState = fields[2].trim();
111 if (targetState.isEmpty()) {
112 throw new IllegalArgumentException(
113 String.format("Command Tag Exception \"%s\" => Target State empty!", inputLine));
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("\"", ""));
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("'", ""));
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));
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);
144 if (fields.length == 4) {
145 authorizationCode = fields[3].trim();
147 authorizationCode = "";
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);
157 final CommandTag tag = new CommandTag(inputLine);
158 logger.trace("Command Tag Trace: \"{}\" => Fully valid Command Tag!", inputLine);
160 } catch (IllegalArgumentException e) {
161 logger.warn("{}", e.getMessage());
166 public @Nullable Command getCommand() {
170 public String getFullTag() {
174 public String getItemName() {
178 public CommandTagType getTagType() {
182 public boolean isAuthorized(@Nullable String userAuthorizationCode) {
183 return (userAuthorizationCode == null || userAuthorizationCode.isEmpty()
184 || userAuthorizationCode.equals(authorizationCode));