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 import org.fourthline.cling.model.ModelUtil;
20
21 import java.util.regex.Pattern;
22 import java.util.regex.Matcher;
23
24
25
26
27
28
29 public class SoapActionType {
30
31 public static final String MAGIC_CONTROL_NS = "schemas-upnp-org";
32 public static final String MAGIC_CONTROL_TYPE = "control-1-0";
33
34 public static final Pattern PATTERN_MAGIC_CONTROL =
35 Pattern.compile(Constants.NS_UPNP_CONTROL_10 +"#("+Constants.REGEX_UDA_NAME+")");
36
37 public static final Pattern PATTERN =
38 Pattern.compile("urn:(" + Constants.REGEX_NAMESPACE + "):service:(" + Constants.REGEX_TYPE + "):([0-9]+)#("+Constants.REGEX_UDA_NAME+")");
39
40 private String namespace;
41 private String type;
42 private String actionName;
43 private Integer version;
44
45 public SoapActionType(ServiceType serviceType, String actionName) {
46 this(serviceType.getNamespace(), serviceType.getType(), serviceType.getVersion(), actionName);
47 }
48
49 public SoapActionType(String namespace, String type, Integer version, String actionName) {
50 this.namespace = namespace;
51 this.type = type;
52 this.version = version;
53 this.actionName = actionName;
54
55 if (actionName != null && !ModelUtil.isValidUDAName(actionName)) {
56 throw new IllegalArgumentException("Action name contains illegal characters: " + actionName);
57 }
58 }
59
60 public String getActionName() {
61 return actionName;
62 }
63
64 public String getNamespace() {
65 return namespace;
66 }
67
68 public String getType() {
69 return type;
70 }
71
72 public Integer getVersion() {
73 return version;
74 }
75
76 public static SoapActionType valueOf(String s) throws InvalidValueException {
77 Matcher magicControlMatcher = SoapActionType.PATTERN_MAGIC_CONTROL.matcher(s);
78
79 try {
80 if (magicControlMatcher.matches()) {
81 return new SoapActionType(MAGIC_CONTROL_NS, MAGIC_CONTROL_TYPE, null, magicControlMatcher.group(1));
82 }
83
84 Matcher matcher = SoapActionType.PATTERN.matcher(s);
85 if (matcher.matches())
86 return new SoapActionType(matcher.group(1), matcher.group(2), Integer.valueOf(matcher.group(3)), matcher.group(4));
87
88 } catch(RuntimeException e) {
89 throw new InvalidValueException(String.format(
90 "Can't parse action type string (namespace/type/version#actionName) '%s': %s", s, e.toString()
91 ));
92 }
93 throw new InvalidValueException("Can't parse action type string (namespace/type/version#actionName): " + s);
94 }
95
96 public ServiceType getServiceType() {
97 if (version == null) return null;
98 return new ServiceType(namespace, type, version);
99 }
100
101 @Override
102 public String toString() {
103 return getTypeString() + "#" + getActionName();
104 }
105
106 public String getTypeString() {
107 if (version == null) {
108 return "urn:" + getNamespace() + ":" + getType();
109 } else {
110 return "urn:" + getNamespace() + ":service:" + getType() + ":" + getVersion();
111 }
112 }
113
114 @Override
115 public boolean equals(Object o) {
116 if (this == o) return true;
117 if (o == null || !(o instanceof SoapActionType)) return false;
118
119 SoapActionType that = (SoapActionType) o;
120
121 if (!actionName.equals(that.actionName)) return false;
122 if (!namespace.equals(that.namespace)) return false;
123 if (!type.equals(that.type)) return false;
124 if (version != null ? !version.equals(that.version) : that.version != null) return false;
125
126 return true;
127 }
128
129 @Override
130 public int hashCode() {
131 int result = namespace.hashCode();
132 result = 31 * result + type.hashCode();
133 result = 31 * result + actionName.hashCode();
134 result = 31 * result + (version != null ? version.hashCode() : 0);
135 return result;
136 }
137
138 }