1 /***
2 * Java DAB EPG API - Serialize/Deserialize To/From POJOs to XML/Binary as per
3 * ETSI specifications TS 102 818 (XML Specification for DAB EPG) and TS 102
4 * 371 (Transportation and Binary Encoding Specification for EPG).
5 *
6 * Copyright (C) 2007 GCap Media PLC
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22 package com.gcapmedia.dab.epg;
23
24 import java.io.Serializable;
25 import java.util.regex.Pattern;
26
27 /***
28 * Contains t he Eureka-147 bearer ID, usually expressed in the format:
29 * <b><ECC>.<EId>.<SId>.<SCIdS>.<X-PAD></b>
30 * in hex:
31 *
32 * <ul>
33 * <li><b>ECC</b> Extended Country Code (optional)</li>
34 * <li><b>EId</b> Ensemble Identifier (optional) - either a 16-bit service identifier (for audio services) or a 32-bit service identifier (for data services)</li>
35 * <li><b>SId</b> Service Identifier</li>
36 * <li><b>SCIds</b> Service Component Identifier within the Service</li>
37 * <li><b>X-PAD</b> X-PAD application type (optional)</li>
38 * </ul>
39 *
40 * <p>For example, <code>e1.ce15.c224.0</code></p>
41 *
42 * <p>This only covers DAB Content IDs, rather than DRM.</p>
43 */
44 public class ContentId implements Serializable {
45
46 /***
47 * Serial version
48 */
49 private static final long serialVersionUID = 7413578623009063666L;
50
51 /***
52 * Bearer ID validation pattern
53 */
54 private final static Pattern idPattern = Pattern.compile("(([0-9a-fA-F]{2}//.[0-9a-fA-F]{4}//.)?[0-9a-fA-F]{4,8}//.[0-9a-fA-F]{1}(//.[0-9a-fA-F]{2})?)|([0-9a-fA-F]{6})");
55
56 private String ecc;
57
58 private String eid;
59
60 private String sid;
61
62 private String scids;
63
64 private String xpad;
65
66 private ServiceType type;
67
68 /***
69 * Create a new Bearer ID
70 * @param ecc Extended Country Code (ECC) of the ensemble on which the service
71 * is broadcast.
72 * @param eid Ensemble ID (EId) of the ensemble on which the service is broadcast.
73 * @param sid Service Identifier (SId).
74 * @param scids Service Identifier within the Service (SCIdS).
75 */
76 public ContentId(String ecc, String eid, String sid, String scids) {
77 if((ecc == null && eid != null) || (ecc != null && eid == null)) {
78 throw new IllegalArgumentException("Extended Country Code (ECC) and Ensemble Identifier (EId) are optional but must either be both set to null or a valid value");
79 }
80 if(sid == null) {
81 throw new IllegalArgumentException("Must specify a Service Identifier (SId)");
82 }
83 if(scids == null) {
84 throw new IllegalArgumentException("Must specify a Service Component Identifier (SCIdS)");
85 }
86 if(sid.length() == 4) {
87 type = ServiceType.AUDIO;
88 } else if(sid.length() == 8) {
89 type = ServiceType.DATA;
90 } else {
91 throw new IllegalArgumentException("Invalid Service Identifier field specified - must be 16 or 32 bits");
92 }
93 this.ecc = ecc;
94 this.eid = eid;
95 this.sid = sid;
96 this.scids = scids;
97 }
98
99 /***
100 * Create a new Bearer ID
101 * @param sid Service Identifier (SId).
102 * @param scids Service Identifier within the Service (SCIdS).
103 */
104 public ContentId(String sid, String scids) {
105 this(null, null, sid, scids);
106 }
107
108 /***
109 * Create a new Bearer ID
110 * @param id Bearer ID
111 */
112 public ContentId(String id) {
113 if(!idPattern.matcher(id).matches()) {
114 throw new IllegalArgumentException("ID does not match the required pattern: " + idPattern.pattern());
115 }
116
117 String[] splits = id.split("//.");
118 switch(splits.length) {
119 case 3:
120 this.ecc = splits[0];
121 this.sid = splits[1];
122 this.scids = splits[2];
123 break;
124 case 4:
125 this.ecc = splits[0];
126 this.eid = splits[1];
127 this.sid = splits[2];
128 this.scids = splits[3];
129 break;
130 }
131 if(sid.length() == 4) {
132 type = ServiceType.AUDIO;
133 } else if(sid.length() == 8) {
134 type = ServiceType.DATA;
135 } else {
136 throw new IllegalArgumentException("Invalid Service Identifier field specified - must be 16 or 32 bits");
137 }
138 }
139
140 public String getExtendedCountryCode() {
141 return ecc;
142 }
143
144 public String getEnsembleId() {
145 return eid;
146 }
147
148 /***
149 * @return Returns the Service Identifier
150 */
151 public String getServiceId() {
152 return sid;
153 }
154
155 /***
156 * @return Returns the Service Component ID within the Service (SCIdS)
157 */
158 public String getServiceComponentId() {
159 return scids;
160 }
161
162 /***
163 * Sets the XPad application type. Set to zero to indicate no application.
164 * @param xpad
165 */
166 public void setXPadApplicationType(String xpad) {
167 this.xpad = xpad;
168 }
169
170 /***
171 * @return Returns the XPad Application type
172 */
173 public String getXPadApplicationType() {
174 return xpad;
175 }
176
177 /***
178 * @return Returns the Service Type this Identifer is referring to: either
179 * an Audio or a Data service.
180 */
181 public ServiceType getServiceType() {
182 return type;
183 }
184
185 /***
186 * @return True if the Extended Country Code (ECC) is defined.
187 */
188 public boolean hasExtendedCountryCode() {
189 return ecc != null;
190 }
191
192 /***
193 * @return True if the Ensemble ID (EId) is defined.
194 */
195 public boolean hasEnsembleId() {
196 return eid != null;
197 }
198
199 /***
200 * @return True if the X-PAD application type (XPAD) is defined
201 */
202 public boolean hasXpadApplication() {
203 return xpad != null;
204 }
205
206 /***
207 * @see java.lang.Object#equals(java.lang.Object)
208 */
209 @Override
210 public boolean equals(Object obj) {
211 if(!(obj instanceof ContentId)) {
212 return false;
213 }
214 ContentId that = (ContentId)obj;
215 return this.toString().equals(that.toString());
216 }
217
218 /***
219 * @return Returns the The Eureka-147 bearer ID string in the format: <b><ECC>.<EId>.<SId>
220 * .<SCIdS>.<X-PAD></b> in hex:
221 *
222 * <ul>
223 * <li><b>ECC</b> Extended Country Code (optional)</li>
224 * <li><b>EId</b> Ensemble Identifier (optional) - either a 16-bit service identifier (for audio services) or
225 * a 32-bit service identifier (for data services)</li>
226 * <li><b>SId</b> Service Identifier</li>
227 * <li><b>SCIds</b> Service Component Identifier within the Service</li>
228 * <li><b>X-PAD</b> X-PAD application type (optional)</li>
229 * </ul>
230 *
231 * @see java.lang.Object#toString()
232 */
233 public String toString() {
234 StringBuilder buf = new StringBuilder();
235 buf.append(ecc);
236 if(eid != null) {
237 buf.append("." + eid);
238 }
239 buf.append("." + sid);
240 buf.append("." + scids);
241 if(xpad != null) {
242 buf.append(xpad);
243 }
244 return buf.toString();
245 }
246
247 public enum ServiceType {
248
249 AUDIO,
250
251 DATA
252
253 }
254
255 }