2 * Copyright (c) 2010-2020 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.HSBType;
21 import org.openhab.core.library.types.OnOffType;
22 import org.openhab.core.library.types.OpenClosedType;
23 import org.openhab.core.library.types.PercentType;
24 import org.openhab.core.library.types.PlayPauseType;
25 import org.openhab.core.library.types.QuantityType;
26 import org.openhab.core.library.types.RewindFastforwardType;
27 import org.openhab.core.library.types.StringType;
28 import org.openhab.core.library.types.UpDownType;
29 import org.openhab.core.types.Command;
30 import org.openhab.core.types.TypeParser;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
35 * This is a class that implements a Command Tag that may be embedded in an
36 * Event Description. Valid Tags must follow one of the following forms..
38 * BEGIN:<itemName>:<targetState>
39 * BEGIN:<itemName>:<targetState>:<authorizationCode>
40 * END:<itemName>:<targetState>
41 * END:<itemName>:<targetState>:<authorizationCode>
43 * @author Andrew Fiddian-Green - Initial contribution
46 public class CommandTag {
48 private static final List<Class<? extends Command>> otherCommandTypes = Arrays.asList(QuantityType.class,
49 OnOffType.class, OpenClosedType.class, UpDownType.class, HSBType.class, PlayPauseType.class,
50 RewindFastforwardType.class, StringType.class);
52 private static final List<Class<? extends Command>> percentCommandType = Arrays.asList(PercentType.class);
54 private static final Logger logger = LoggerFactory.getLogger(CommandTag.class);
56 private String inputLine;
57 private CommandTagType tagType;
58 private String itemName;
59 private String targetState;
60 private String authorizationCode;
61 private @Nullable Command theCommand;
63 public CommandTag(String inputLine) throws IllegalArgumentException {
64 this.inputLine = inputLine.trim();
66 if (!CommandTagType.prefixValid(inputLine)) {
67 throw new IllegalArgumentException(
68 String.format("Command Tag Exception \"%s\" => Bad tag prefix!", inputLine));
71 if (!inputLine.contains(":")) {
72 throw new IllegalArgumentException(
73 String.format("Command Tag Exception \"%s\" => Missing \":\" delimiters!", inputLine));
76 String[] fields = inputLine.split(":");
77 if (fields.length < 3) {
78 throw new IllegalArgumentException(
79 String.format("Command Tag Exception \"%s\" => Not enough fields!", inputLine));
82 if (fields.length > 4) {
83 throw new IllegalArgumentException(
84 String.format("Command Tag Exception \"%s\" => Too many fields!", inputLine));
88 tagType = CommandTagType.valueOf(fields[0]);
89 } catch (IllegalArgumentException e) {
90 throw new IllegalArgumentException(
91 String.format("Command Tag Exception \"%s\" => Invalid Tag Type!", inputLine));
94 itemName = fields[1].trim();
95 if (itemName.isEmpty()) {
96 throw new IllegalArgumentException(
97 String.format("Command Tag Exception \"%s\" => Item name empty!", inputLine));
100 if (!itemName.matches("^\\w+$")) {
101 throw new IllegalArgumentException(
102 String.format("Command Tag Exception \"%s\" => Bad syntax for Item name!", inputLine));
105 targetState = fields[2].trim();
106 if (targetState.isEmpty()) {
107 throw new IllegalArgumentException(
108 String.format("Command Tag Exception \"%s\" => Target State empty!", inputLine));
111 // string is in double quotes => force StringType
112 if (targetState.startsWith("\"") && targetState.endsWith("\"")) {
113 // new StringType() should always succeed
114 theCommand = new StringType(targetState.replace("\"", ""));
117 // string is in single quotes => ditto
118 else if (targetState.startsWith("'") && targetState.endsWith("'")) {
119 // new StringType() should always succeed
120 theCommand = new StringType(targetState.replace("'", ""));
123 // string ends with % => try PercentType
124 else if (targetState.endsWith("%")) {
125 theCommand = TypeParser.parseCommand(percentCommandType,
126 targetState.substring(0, targetState.length() - 1));
127 if (theCommand == null) {
128 throw new IllegalArgumentException(String
129 .format("Command Tag Exception \"%s\" => Invalid Target State percent value!", inputLine));
133 // try all other possible CommandTypes
134 if (theCommand == null) {
135 // TypeParser.parseCommand(otherCommandTypes should always succeed (with new StringType())
136 theCommand = TypeParser.parseCommand(otherCommandTypes, targetState);
139 if (fields.length == 4) {
140 authorizationCode = fields[3].trim();
142 authorizationCode = "";
146 public static @Nullable CommandTag createCommandTag(String inputLine) {
147 if (inputLine.isEmpty() || !CommandTagType.prefixValid(inputLine)) {
148 logger.trace("Command Tag Trace: \"{}\" => NOT a (valid) Command Tag!", inputLine);
152 final CommandTag tag = new CommandTag(inputLine);
153 logger.trace("Command Tag Trace: \"{}\" => Fully valid Command Tag!", inputLine);
155 } catch (IllegalArgumentException e) {
156 logger.warn("{}", e.getMessage());
161 public @Nullable Command getCommand() {
165 public String getFullTag() {
169 public String getItemName() {
173 public CommandTagType getTagType() {
177 public boolean isAuthorized(@Nullable String userAuthorizationCode) {
178 return (userAuthorizationCode == null || userAuthorizationCode.isEmpty()
179 || userAuthorizationCode.equals(authorizationCode));