001/** 002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 003 * 004 * Copyright (c) 2007 Sun Microsystems Inc. All Rights Reserved 005 * 006 * The contents of this file are subject to the terms 007 * of the Common Development and Distribution License 008 * (the License). You may not use this file except in 009 * compliance with the License. 010 * 011 * You can obtain a copy of the License at 012 * https://opensso.dev.java.net/public/CDDLv1.0.html or 013 * opensso/legal/CDDLv1.0.txt 014 * See the License for the specific language governing 015 * permission and limitations under the License. 016 * 017 * When distributing Covered Code, include this CDDL 018 * Header Notice in each file and include the License file 019 * at opensso/legal/CDDLv1.0.txt. 020 * If applicable, add the following below the CDDL Header, 021 * with the fields enclosed by brackets [] replaced by 022 * your own identifying information: 023 * "Portions Copyrighted [year] [name of copyright owner]" 024 * 025 * $Id: Extension.java,v 1.2 2008/06/25 05:46:46 qcheng Exp $ 026 * Portions Copyrighted 2014 ForgeRock AS 027 */ 028 029package com.sun.identity.federation.message.common; 030 031import static org.forgerock.http.util.Uris.urlEncodeQueryParameterNameOrValue; 032 033import com.sun.identity.federation.common.FSUtils; 034import com.sun.identity.federation.common.IFSConstants; 035import com.sun.identity.shared.xml.XMLUtils; 036import java.util.ArrayList; 037import java.util.Enumeration; 038import java.util.HashMap; 039import java.util.Iterator; 040import java.util.List; 041import java.util.Map; 042import javax.servlet.http.HttpServletRequest; 043import org.w3c.dom.Document; 044import org.w3c.dom.Element; 045import org.w3c.dom.Node; 046import org.w3c.dom.NodeList; 047 048/** 049 * The class <code>Extension</code> is used to create , parse 050 * <code>Extension</code> object. 051 * 052 * @supported.all.api 053 * @deprecated since 12.0.0 054 */ 055@Deprecated 056public class Extension { 057 private List children = null; 058 private Map avpairs = null; 059 private int minorVersion = 0; 060 061 /** 062 * Constructor to create <code>Extension</code> object. 063 * 064 * @param children a list of XML <code>String</code> object. 065 * @throws FSMsgException on error. 066 */ 067 public Extension(List children) throws FSMsgException { 068 validateChildren(children); 069 this.children = children; 070 } 071 072 /** 073 * Constructor to create <code>Extension</code> object. 074 * 075 * @param element the <code>Extension</code> Element object. 076 * @throws FSMsgException on error. 077 */ 078 public Extension(Element element) throws FSMsgException { 079 if (element == null) { 080 FSUtils.debug.error("Extension.Extension: null input."); 081 throw new FSMsgException("nullInput", null); 082 } 083 String nodeName = element.getLocalName(); 084 if (!IFSConstants.EXTENSION.equals(nodeName)) { 085 FSUtils.debug.error("Extension.Extension: wrong input"); 086 throw new FSMsgException("wrongInput", null); 087 } 088 089 NodeList childNodes = element.getChildNodes(); 090 int length = childNodes.getLength(); 091 for(int i = 0; i < length; i++) { 092 Node child = childNodes.item(i); 093 if (child.getNodeType() == Node.ELEMENT_NODE) { 094 if (children == null) { 095 children = new ArrayList(); 096 } 097 children.add(XMLUtils.print(child)); 098 addToAvpairs((Element)child); 099 } 100 } 101 } 102 103 /** 104 * Constructor to create <code>Extension</code> object. Each attribute 105 * value pair will be converted to a XML string. The converted XML string 106 * has only one element. The local name of the element will be the key of 107 * the map entry and the value of the element will be the value of the map 108 * entry. Both key and value of the map entry should be a 109 * <code>String</code> object. 110 * 111 * @param avpairs attribute value pairs. 112 * @throws FSMsgException on error. 113 */ 114 public Extension(Map avpairs) throws FSMsgException { 115 setAttributeMap(avpairs); 116 } 117 118 /** 119 * Returns a list of XML <code>String</code> objects. 120 * 121 * @return a list of XML <code>String</code> objects. 122 * @see #setChildren(List) 123 */ 124 public List getChildren() { 125 return children; 126 } 127 128 /** 129 * Sets a list of XML <code>String</code> object. 130 * 131 * @param children a list of XML <code>String</code> object. 132 * @see #getChildren() 133 */ 134 public void setChildren(List children) throws FSMsgException { 135 validateChildren(children); 136 this.children = children; 137 } 138 139 /* 140 * Gets attribute value pairs. Each attribute value pair is converted from 141 * a XML string. The XML string can have only one element. The element 142 * element can't have namespace and must have a simple content. The local 143 * name of the element will be the key of the map entry and the value of 144 * the element will be the value of the map entry. Both key and value of 145 * the map entry will be a <code>String</code> object. If a XML string 146 * can't be converted, it will not be added to the map. 147 * 148 * @return an attribute value pairs. 149 */ 150 public Map getAttributeMap() { 151 if ((children == null) || (children.isEmpty())) { 152 return null; 153 } 154 155 if (avpairs != null) { 156 return avpairs; 157 } 158 for(Iterator iter = children.iterator(); iter.hasNext(); ) { 159 String xml = (String)iter.next(); 160 161 Document doc = XMLUtils.toDOMDocument(xml, FSUtils.debug); 162 if (doc == null) { 163 continue; 164 } 165 Element element = doc.getDocumentElement(); 166 addToAvpairs(element); 167 } 168 169 return avpairs; 170 } 171 172 /** 173 * Converts attribute value pairs to a list of XML <code>String</code> 174 * objects. Each attribute value pair will be converted to a XML string. 175 * The converted XML string has only one element. The local name of the 176 * element will be the key of the map entry and the value of the element 177 * will be the value of the map entry. Both key and value of the map entry 178 * should be a <code>String</code> object. 179 * 180 * @param avpairs attribute value pairs. 181 * @throws FSMsgException on error. 182 */ 183 public void setAttributeMap(Map avpairs) throws FSMsgException { 184 this.avpairs = avpairs; 185 if ((avpairs != null) && (!avpairs.isEmpty())) { 186 for(Iterator iter = avpairs.keySet().iterator(); iter.hasNext();) { 187 String key = (String)iter.next(); 188 String value = (String)avpairs.get(key); 189 String xml = IFSConstants.LEFT_ANGLE + key + 190 IFSConstants.RIGHT_ANGLE + 191 XMLUtils.escapeSpecialCharacters(value) + 192 IFSConstants.START_END_ELEMENT + key + 193 IFSConstants.RIGHT_ANGLE; 194 if (children == null) { 195 children = new ArrayList(); 196 } 197 children.add(xml); 198 } 199 } 200 } 201 202 /** 203 * Returns the <code>MinorVersion</code>. 204 * 205 * @return the <code>MinorVersion</code>. 206 * @see #setMinorVersion(int) 207 */ 208 public int getMinorVersion() { 209 return minorVersion; 210 } 211 212 /** 213 * Sets the <code>MinorVersion</code>. 214 * 215 * @param minorVersion the <code>MinorVersion</code>. 216 * @see #getMinorVersion() 217 */ 218 public void setMinorVersion(int minorVersion) { 219 this.minorVersion = minorVersion; 220 } 221 222 /** 223 * Returns a String representation of the <Code>Extension</Code> element. 224 * 225 * @return a string containing the valid XML for this element 226 * @throws FSMsgException if there is an error converting this object to 227 * a string. 228 */ 229 public String toXMLString() throws FSMsgException { 230 return this.toXMLString(true, false); 231 } 232 233 /** 234 * Creates a String representation of the <Code>Extension</Code> element. 235 * 236 * @param includeNS : Determines whether or not the namespace qualifier 237 * is prepended to the Element when converted 238 * @param declareNS : Determines whether or not the namespace is declared 239 * within the Element. 240 * @return string containing the valid XML for this element. 241 * @throws FSMsgException if there is an error. 242 */ 243 public String toXMLString(boolean includeNS, boolean declareNS) 244 throws FSMsgException { 245 246 String prefix = ""; 247 String uri = ""; 248 249 StringBuffer xml = new StringBuffer(); 250 if (includeNS) { 251 prefix = IFSConstants.LIB_PREFIX; 252 } 253 if (declareNS) { 254 if(minorVersion == IFSConstants.FF_12_PROTOCOL_MINOR_VERSION) { 255 uri = IFSConstants.LIB_12_NAMESPACE_STRING; 256 } else { 257 uri = IFSConstants.LIB_NAMESPACE_STRING; 258 } 259 } 260 xml.append(IFSConstants.LEFT_ANGLE) 261 .append(prefix) 262 .append(IFSConstants.EXTENSION) 263 .append(uri) 264 .append(IFSConstants.RIGHT_ANGLE); 265 if ((children != null) && (!children.isEmpty())) { 266 for(Iterator iter = children.iterator(); iter.hasNext();) { 267 String child = (String)iter.next(); 268 xml.append(child); 269 } 270 } 271 xml.append(IFSConstants.START_END_ELEMENT) 272 .append(prefix) 273 .append(IFSConstants.EXTENSION) 274 .append(IFSConstants.RIGHT_ANGLE); 275 276 return xml.toString(); 277 } 278 279 /** 280 * Returns <code>Extension</code> object. The object is creating by 281 * parsing the <code>HttpServletRequest</code> object. 282 * 283 * @param request the <code>HttpServletRequest</code> object. 284 * @param prefix the string that is prepended to the key of query 285 * string. 286 * @param minorVersion the <code>MinorVersion</code>. 287 * @return <code><Extension/code> object. 288 * @throws FSMsgException if there is an error creating 289 * <code>Extension</code> object. 290 */ 291 public static Extension parseURLEncodedRequest(HttpServletRequest request, 292 String prefix, int minorVersion) throws FSMsgException { 293 294 Map attrMap = null; 295 for(Enumeration e=request.getParameterNames(); e.hasMoreElements();) { 296 String paraName = (String)e.nextElement(); 297 if (paraName.startsWith(prefix)) { 298 String key = paraName.substring(prefix.length()); 299 String value = request.getParameter(paraName); 300 if (attrMap == null) { 301 attrMap = new HashMap(); 302 } 303 attrMap.put(key, value); 304 } 305 } 306 307 if (attrMap == null) { 308 return null; 309 } 310 311 Extension extension = new Extension(attrMap); 312 extension.setMinorVersion(minorVersion); 313 return extension; 314 } 315 316 /** 317 * Returns an URL Encoded String. 318 * 319 * @param prefix the string that will be prepended to the key of query 320 * string. 321 * @return a url encoded query string. 322 * @throws FSMsgException if there is an error. 323 */ 324 public String toURLEncodedQueryString(String prefix) 325 throws FSMsgException { 326 327 Map attrMap = getAttributeMap(); 328 if ((attrMap == null) || (attrMap.isEmpty())) { 329 return ""; 330 } 331 332 StringBuffer queryString = new StringBuffer(); 333 for(Iterator iter = attrMap.keySet().iterator();iter.hasNext();) { 334 String key = (String)iter.next(); 335 String value = urlEncodeQueryParameterNameOrValue((String)attrMap.get(key)); 336 key = urlEncodeQueryParameterNameOrValue(prefix + key); 337 if (queryString.length() > 0) { 338 queryString.append(IFSConstants.AMPERSAND); 339 } 340 queryString.append(key).append(IFSConstants.EQUAL_TO) 341 .append(value); 342 } 343 344 return queryString.toString(); 345 } 346 347 private void addToAvpairs(Element element) { 348 String ns = element.getNamespaceURI(); 349 if ((ns == null) && (!XMLUtils.hasElementChild(element))) { 350 String key = element.getLocalName(); 351 String value = XMLUtils.getElementValue(element); 352 if (avpairs == null) { 353 avpairs = new HashMap(); 354 } 355 avpairs.put(key, value); 356 } 357 } 358 359 private static void validateChildren(List children) throws FSMsgException { 360 if ((children != null) && (!children.isEmpty())) { 361 for(Iterator iter = children.iterator(); iter.hasNext(); ) { 362 String xml = (String)iter.next(); 363 Document doc = XMLUtils.toDOMDocument(xml, FSUtils.debug); 364 if (doc == null) { 365 FSUtils.debug.error("Extension.validateChildren: Error " 366 + "while parsing input xml string"); 367 throw new FSMsgException("parseError", null); 368 } 369 } 370 } 371 } 372}