NPE in taglib processing.
[java-idp.git] / src / main / java / edu / internet2 / middleware / shibboleth / idp / ui / ServiceNameTag.java
1 /*\r
2  * Copyright 2011 University Corporation for Advanced Internet Development, Inc.\r
3  *\r
4  * Licensed under the Apache License, Version 2.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  *\r
8  * http://www.apache.org/licenses/LICENSE-2.0\r
9  *\r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  */\r
16 \r
17 package edu.internet2.middleware.shibboleth.idp.ui;\r
18 \r
19 import java.io.IOException;\r
20 import java.net.URI;\r
21 import java.net.URISyntaxException;\r
22 import java.util.List;\r
23 \r
24 import javax.servlet.jsp.JspException;\r
25 import javax.servlet.jsp.JspWriter;\r
26 import javax.servlet.jsp.tagext.BodyContent;\r
27 \r
28 import org.opensaml.saml2.metadata.AttributeConsumingService;\r
29 import org.opensaml.saml2.metadata.EntityDescriptor;\r
30 import org.opensaml.saml2.metadata.LocalizedString;\r
31 import org.opensaml.saml2.metadata.RoleDescriptor;\r
32 import org.opensaml.saml2.metadata.SPSSODescriptor;\r
33 import org.opensaml.saml2.metadata.ServiceName;\r
34 import org.opensaml.samlext.saml2mdui.DisplayName;\r
35 import org.slf4j.Logger;\r
36 import org.slf4j.LoggerFactory;\r
37 \r
38 \r
39 /**\r
40  * Display the serviceName.\r
41  * \r
42  * This is taken in order\r
43  *  1) From the mdui\r
44  *  2) AttributeConsumeService\r
45  *  3) HostName from the EntityId\r
46  *  4) EntityId.\r
47  */\r
48 public class ServiceNameTag extends ServiceTagSupport {\r
49 \r
50     /** checkstyle requires one of these. */\r
51     private static final long serialVersionUID = 8883158293402992407L;\r
52     /** Class logger. */\r
53     private static Logger log = LoggerFactory.getLogger(ServiceNameTag.class);\r
54     \r
55     /** what to emit if the jsp has nothing. */\r
56     private static final String DEFAULT_VALUE = "Unspecified Service Provider";\r
57 \r
58     /**\r
59      * If the entityId can look like a host return that otherwise the string.\r
60      * @return either the host or the entityId.\r
61      */\r
62     private String getNameFromEntityId() {\r
63         EntityDescriptor sp = getSPEntityDescriptor();\r
64         \r
65         if (null == sp) {\r
66             log.debug("No relying party, nothing to display");\r
67             return null;\r
68         }\r
69 \r
70         try {\r
71             URI entityId = new URI(sp.getEntityID());\r
72             String scheme = entityId.getScheme();\r
73 \r
74             if ("http".equals(scheme) || "https".equals(scheme)) {\r
75                 return entityId.getHost(); \r
76             }\r
77         } catch (URISyntaxException e) {\r
78             // \r
79             // It wasn't an URI.  return full entityId.\r
80             //\r
81             return sp.getEntityID();\r
82         }\r
83         //\r
84         // not a URL return full entityID\r
85         //\r
86         return sp.getEntityID();\r
87     }\r
88     \r
89     /** \r
90      * look at <Uiinfo> if there and if so look for appropriate name.\r
91      * @return null or an appropriate name\r
92      */\r
93     private String getNameFromUIInfo() {\r
94         String lang = getBrowserLanguage();\r
95 \r
96         if (getSPUIInfo() != null) {\r
97             for (DisplayName name:getSPUIInfo().getDisplayNames()) {\r
98                 if (log.isDebugEnabled()){\r
99                     log.debug("Found name in UIInfo, language=" + name.getXMLLang());\r
100                 }\r
101                 if (name.getXMLLang().equals(lang)) {\r
102                     //\r
103                     // Found it\r
104                     //\r
105                     if (log.isDebugEnabled()){\r
106                         log.debug("returning name from UIInfo " + name.getName().getLocalString());\r
107                     }\r
108                     return name.getName().getLocalString();\r
109                 }\r
110             }\r
111             if (log.isDebugEnabled()){\r
112                 log.debug("No name in UIInfo");\r
113             }            \r
114         }\r
115         return null;\r
116     }\r
117 \r
118     /**\r
119      * look for an &ltAttributeConsumeService&gt and if its there look for an appropriate name.\r
120      * @return null or an appropriate name\r
121      */\r
122     private String getNameFromAttributeConsumingService(){\r
123         String lang = getBrowserLanguage();\r
124         List<RoleDescriptor> roles;\r
125         AttributeConsumingService acs = null;\r
126         EntityDescriptor sp = getSPEntityDescriptor();\r
127         \r
128         if (null == sp) {\r
129             log.warn("No relying party, nothing to display");\r
130             return null;\r
131         }\r
132 \r
133         roles = sp.getRoleDescriptors(SPSSODescriptor.DEFAULT_ELEMENT_NAME);\r
134         if (!roles.isEmpty()) {\r
135             SPSSODescriptor spssod = (SPSSODescriptor) roles.get(0);\r
136             acs = spssod.getDefaultAttributeConsumingService();\r
137         }\r
138         if (acs != null) {\r
139             for (ServiceName name:acs.getNames()) {\r
140                 LocalizedString localName = name.getName();\r
141                 if (log.isDebugEnabled()){\r
142                     log.debug("Found name in AttributeConsumingService, language=" + localName.getLanguage());\r
143                 }\r
144                 if (localName.getLanguage().equals(lang)) {\r
145                     if (log.isDebugEnabled()){\r
146                         log.debug("returning name from AttributeConsumingService " + name.getName().getLocalString());\r
147                     }\r
148                     return localName.getLocalString();\r
149                 }\r
150             }\r
151             if (log.isDebugEnabled()){\r
152                 log.debug("No name in AttributeConsumingService");\r
153             }            \r
154         }        \r
155         return null;\r
156     }\r
157     \r
158     /**\r
159      * Get the identifier for the service name as per the rules above.\r
160      * @return something sensible for display.\r
161      */\r
162     private String getServiceName() {\r
163         String result;\r
164         //\r
165         // First look for MDUI\r
166         //\r
167         if (getSPEntityDescriptor() == null) {\r
168             log.debug("No relying party, nothing to display");\r
169             return null;\r
170         }\r
171         //\r
172         // Look at <UIInfo>\r
173         //\r
174         result = getNameFromUIInfo();\r
175         if (result != null) {\r
176             return result;\r
177         }\r
178         \r
179         //\r
180         // Otherwise <AttributeConsumingService>\r
181         //\r
182         result = getNameFromAttributeConsumingService();\r
183         if (result != null) {\r
184             return result;\r
185         }\r
186         \r
187         //\r
188         // Or look at the entityName\r
189         //\r
190         return getNameFromEntityId();\r
191     }\r
192     \r
193     @Override\r
194     public int doStartTag() throws JspException {\r
195        \r
196         try {\r
197             String serviceName = getServiceName();\r
198             \r
199             if (null == serviceName) {\r
200                 BodyContent bc = getBodyContent();\r
201                 boolean written = false;\r
202                 if (null != bc) {\r
203                     JspWriter ew= bc.getEnclosingWriter();\r
204                     if (ew != null) {\r
205                         bc.writeOut(ew);\r
206                         written = true;\r
207                     }\r
208                 }\r
209                 if (!written) {\r
210                     pageContext.getOut().print(DEFAULT_VALUE);\r
211                 }\r
212             } else {\r
213                 pageContext.getOut().print(serviceName);\r
214             }\r
215         } catch (IOException e) {\r
216             log.warn("Error generating name");\r
217             throw new JspException("StartTag", e);\r
218         }\r
219         return super.doStartTag();\r
220     }\r
221 }\r