1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.fourthline.cling.model.types;
17
18 import org.fourthline.cling.model.Constants;
19
20 import java.util.logging.Logger;
21 import java.util.regex.Pattern;
22 import java.util.regex.Matcher;
23
24
25
26
27
28
29 public class ServiceId {
30
31 final private static Logger log = Logger.getLogger(ServiceId.class.getName());
32
33 public static final String UNKNOWN = "UNKNOWN";
34
35 public static final Pattern PATTERN =
36 Pattern.compile("urn:(" + Constants.REGEX_NAMESPACE + "):serviceId:(" + Constants.REGEX_ID + ")");
37
38
39 public static final Pattern BROKEN_PATTERN =
40 Pattern.compile("urn:(" + Constants.REGEX_NAMESPACE + "):service:(" + Constants.REGEX_ID+ ")");
41
42 private String namespace;
43 private String id;
44
45 public ServiceId(String namespace, String id) {
46 if (namespace != null && !namespace.matches(Constants.REGEX_NAMESPACE)) {
47 throw new IllegalArgumentException("Service ID namespace contains illegal characters");
48 }
49 this.namespace = namespace;
50
51 if (id != null && !id.matches(Constants.REGEX_ID)) {
52 throw new IllegalArgumentException("Service ID suffix too long (64) or contains illegal characters");
53 }
54 this.id = id;
55 }
56
57 public String getNamespace() {
58 return namespace;
59 }
60
61 public String getId() {
62 return id;
63 }
64
65 public static ServiceId valueOf(String s) throws InvalidValueException {
66
67 ServiceId serviceId = null;
68
69
70 try {
71 serviceId = UDAServiceId.valueOf(s);
72 } catch (Exception ex) {
73
74 }
75
76 if (serviceId != null)
77 return serviceId;
78
79
80 Matcher matcher = ServiceId.PATTERN.matcher(s);
81 if (matcher.matches() && matcher.groupCount() >= 2) {
82 return new ServiceId(matcher.group(1), matcher.group(2));
83 }
84
85 matcher = ServiceId.BROKEN_PATTERN.matcher(s);
86 if (matcher.matches() && matcher.groupCount() >= 2) {
87 return new ServiceId(matcher.group(1), matcher.group(2));
88 }
89
90
91
92 matcher = Pattern.compile("urn:(" + Constants.REGEX_NAMESPACE + "):serviceId:").matcher(s);
93 if (matcher.matches() && matcher.groupCount() >= 1) {
94 log.warning("UPnP specification violation, no service ID token, defaulting to " + UNKNOWN + ": " + s);
95 return new ServiceId(matcher.group(1), UNKNOWN);
96 }
97
98
99 String tokens[] = s.split("[:]");
100 if (tokens.length == 4) {
101 log.warning("UPnP specification violation, trying a simple colon-split of: " + s);
102 return new ServiceId(tokens[1], tokens[3]);
103 }
104
105 throw new InvalidValueException("Can't parse service ID string (namespace/id): " + s);
106 }
107
108 @Override
109 public String toString() {
110 return "urn:" + getNamespace() + ":serviceId:" + getId();
111 }
112
113 @Override
114 public boolean equals(Object o) {
115 if (this == o) return true;
116 if (o == null || !(o instanceof ServiceId)) return false;
117
118 ServiceId serviceId = (ServiceId) o;
119
120 if (!id.equals(serviceId.id)) return false;
121 if (!namespace.equals(serviceId.namespace)) return false;
122
123 return true;
124 }
125
126 @Override
127 public int hashCode() {
128 int result = namespace.hashCode();
129 result = 31 * result + id.hashCode();
130 return result;
131 }
132 }