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 }