2 * Copyright (c) 2010-2023 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..
39 * BEGIN:<itemName>:<targetState>
40 * BEGIN:<itemName>:<targetState>:<authorizationCode>
41 * END:<itemName>:<targetState>
42 * END:<itemName>:<targetState>:<authorizationCode>
44 * @author Andrew Fiddian-Green - Initial contribution
47 public class CommandTag {
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);
53 private static final List<Class<? extends Command>> percentCommandType = Arrays.asList(PercentType.class);
55 private static final Logger logger = LoggerFactory.getLogger(CommandTag.class);
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;
64 public CommandTag(String inputLine) throws IllegalArgumentException {
65 this.inputLine = inputLine.trim();
67 if (!CommandTagType.prefixValid(inputLine)) {
68 throw new IllegalArgumentException(
69 String.format("Command Tag Exception \"%s\" => Bad tag prefix!", inputLine));
72 if (!inputLine.contains(":")) {
73 throw new IllegalArgumentException(
74 String.format("Command Tag Exception \"%s\" => Missing \":\" delimiters!", inputLine));
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));
83 if (fields.length > 4) {
84 throw new IllegalArgumentException(
85 String.format("Command Tag Exception \"%s\" => Too many fields!", inputLine));
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));
95 itemName = fields[1].trim();
96 if (itemName.isEmpty()) {
97 throw new IllegalArgumentException(
98 String.format("Command Tag Exception \"%s\" => Item name empty!", inputLine));
101 if (!itemName.matches("^\\w+$")) {
102 throw new IllegalArgumentException(
103 String.format("Command Tag Exception \"%s\" => Bad syntax for Item name!", inputLine));
106 targetState = fields[2].trim();
107 if (targetState.isEmpty()) {
108 throw new IllegalArgumentException(
109 String.format("Command Tag Exception \"%s\" => Target State empty!", inputLine));
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("\"", ""));
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("'", ""));
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));
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);
140 if (fields.length == 4) {
141 authorizationCode = fields[3].trim();
143 authorizationCode = "";
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);
153 final CommandTag tag = new CommandTag(inputLine);
154 logger.trace("Command Tag Trace: \"{}\" => Fully valid Command Tag!", inputLine);
156 } catch (IllegalArgumentException e) {
157 logger.warn("{}", e.getMessage());
162 public @Nullable Command getCommand() {
166 public String getFullTag() {
170 public String getItemName() {
174 public CommandTagType getTagType() {
178 public boolean isAuthorized(@Nullable String userAuthorizationCode) {
179 return (userAuthorizationCode == null || userAuthorizationCode.isEmpty()
180 || userAuthorizationCode.equals(authorizationCode));