View Javadoc
1   /*
2    * Copyright (C) 2013 4th Line GmbH, Switzerland
3    *
4    * The contents of this file are subject to the terms of either the GNU
5    * Lesser General Public License Version 2 or later ("LGPL") or the
6    * Common Development and Distribution License Version 1 or later
7    * ("CDDL") (collectively, the "License"). You may not use this file
8    * except in compliance with the License. See LICENSE.txt for more
9    * information.
10   *
11   * This program is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
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   * Header in SOAP action messages, naturally declaring the same thing as the body of the SOAP message.
26   *
27   * @author Christian Bauer
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)); // throws IllegalArgumentException
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 }