001package silicondust;
002/*-
003 * ##########################################################################
004 * TV H/W, EPGs, and Recording
005 * $Id: HDHRProgram.java 6086 2020-06-02 04:16:55Z ball $
006 * $HeadURL: svn+ssh://svn.hcf.dev/var/spool/scm/repository.svn/silicondust/trunk/src/main/java/silicondust/HDHRProgram.java $
007 * %%
008 * Copyright (C) 2013 - 2020 Allen D. Ball
009 * %%
010 * Licensed under the Apache License, Version 2.0 (the "License");
011 * you may not use this file except in compliance with the License.
012 * You may obtain a copy of the License at
013 *
014 *      http://www.apache.org/licenses/LICENSE-2.0
015 *
016 * Unless required by applicable law or agreed to in writing, software
017 * distributed under the License is distributed on an "AS IS" BASIS,
018 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
019 * See the License for the specific language governing permissions and
020 * limitations under the License.
021 * ##########################################################################
022 */
023import ball.annotation.CompileTimeCheck;
024import ball.annotation.ConstantValueMustConvertTo;
025import java.util.Arrays;
026import java.util.LinkedHashSet;
027import java.util.Set;
028import java.util.regex.Matcher;
029import java.util.regex.Pattern;
030
031import static org.apache.commons.lang3.StringUtils.EMPTY;
032
033/**
034 * {@link.uri http://www.silicondust.com/ SiliconDust} HDHomeRun program
035 * (sub-channel).
036 *
037 * @author {@link.uri mailto:ball@hcf.dev Allen D. Ball}
038 * @version $Revision: 6086 $
039 */
040public class HDHRProgram {
041
042    /**
043     * {@link #REGEX} = {@value #REGEX}
044     */
045    @ConstantValueMustConvertTo(value = Pattern.class, method = "compile")
046    protected static final String REGEX =
047        "(?<number>[\\p{Digit}]+)"
048        + ":[\\p{Space}]+(?<virtual>[\\p{Digit}]+([.][\\p{Digit}]+)?)"
049        + "([\\p{Space}]+(?<name>[^()]+))?"
050        + "([\\p{Space}]+([(](?<flags>.*)[)]))?";
051
052    /**
053     * Compiled {@link #REGEX}.
054     */
055    @CompileTimeCheck
056    protected static final Pattern PATTERN = Pattern.compile(REGEX);
057
058    private final int frequency;
059    private final String modulation;
060    private final Integer tsid;
061    private final int number;
062    private final String virtual;
063    private final String name;
064    private final LinkedHashSet<String> flags = new LinkedHashSet<>();
065
066    private static final String COLON = ":";
067    private static final String COMMA = ",";
068
069    /**
070     * Sole constructor.
071     *
072     * @param   frequency       The {@link Channel} frequency.
073     * @param   modulation      The modulation.
074     * @param   tsid            The transport stream ID.
075     * @param   line            The line to parse.
076     */
077    protected HDHRProgram(int frequency,
078                          String modulation, Integer tsid, String line) {
079        this.frequency = frequency;
080        this.modulation = modulation;
081        this.tsid = tsid;
082
083        Matcher matcher = PATTERN.matcher(line);
084
085        if (matcher.matches()) {
086            this.number = Integer.decode(matcher.group("number"));
087            this.virtual = matcher.group("virtual");
088            this.name = matcher.group("name");
089
090            String string = matcher.group("flags");
091
092            if (string != null) {
093                this.flags.addAll(Arrays.asList(string.split(COMMA)));
094                this.flags.remove(EMPTY);
095            }
096        } else {
097            throw new ExceptionInInitializerError(line);
098        }
099    }
100
101    public int getFrequency() { return frequency; }
102    public String getModulation() { return modulation; }
103    public Integer getTSID() { return tsid; }
104    public int getNumber() { return number; }
105    public String getVirtual() { return virtual; }
106    public String getName() { return name; }
107    public Set<String> getFlags() { return flags; }
108
109    @Override
110    public String toString() {
111        return (getModulation()
112                + COLON + String.valueOf(getFrequency())
113                + COLON + String.valueOf(getNumber())
114                + COLON + getVirtual()
115                + COLON + ((getName() != null) ? getName() : EMPTY)
116                + COLON + String.valueOf(getFlags()));
117    }
118}