Parsing the attributes using xml dom parser.

This commit is contained in:
lavrovdv 2012-03-14 09:25:15 +04:00
parent 26e959c3d0
commit 4b454e1e2e
2 changed files with 53 additions and 39 deletions

View File

@ -21,6 +21,8 @@ package org.jasig.cas.client.util;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
@ -28,6 +30,10 @@ import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
@ -171,4 +177,27 @@ public final class XmlUtils {
return builder.toString();
}
/**
* Retrieve the child nodes from xml string, for a specific element.
*
* @param xmlAsString the xml response
* @param tagName the element to look for
* @return the {@link org.w3c.dom.NodeList NodeList} containing the child nodes.
* @throws ParserConfigurationException
* @throws IOException
* @throws SAXException
*/
public static NodeList getNodeListForElements(final String xmlAsString, final String tagName)
throws ParserConfigurationException,
IOException,
SAXException {
final DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
final InputSource inStream = new InputSource();
inStream.setCharacterStream(new StringReader(xmlAsString));
final Document document = documentBuilder.parse(inStream);
return document.getElementsByTagName(tagName).item(0).getChildNodes();
}
}

View File

@ -26,14 +26,10 @@ import org.jasig.cas.client.proxy.ProxyGrantingTicketStorage;
import org.jasig.cas.client.proxy.ProxyRetriever;
import org.jasig.cas.client.util.CommonUtils;
import org.jasig.cas.client.util.XmlUtils;
import org.w3c.dom.NodeList;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
@ -115,6 +111,11 @@ public class Cas20ServiceTicketValidator extends AbstractCasProtocolUrlBasedTick
* <cas:attribute2>value</cas:attribute2>
* </cas:attributes>
* <p>
*
* Attributes look like following also parsed correctly:
* &lt;cas:attributes&gt;&lt;cas:attribute1&gt;value&lt;/cas:attribute1&gt;&lt;cas:attribute2&gt;value&lt;/cas:attribute2&gt;&lt;/cas:attributes&gt;
* <p>
*
* This code is here merely for sample/demonstration purposes for those wishing to modify the CAS2 protocol. You'll
* probably want a more robust implementation or to use SAML 1.1
*
@ -122,45 +123,29 @@ public class Cas20ServiceTicketValidator extends AbstractCasProtocolUrlBasedTick
* @return the map of attributes.
*/
protected Map<String,Object> extractCustomAttributes(final String xml) {
final int pos1 = xml.indexOf("<cas:attributes>");
final int pos2 = xml.indexOf("</cas:attributes>");
if (pos1 == -1) {
if (!xml.contains("<cas:attributes>")) {
return Collections.emptyMap();
}
final String attributesText = xml.substring(pos1+16, pos2);
final Map<String,Object> attributes = new HashMap<String,Object>();
final BufferedReader br = new BufferedReader(new StringReader(attributesText));
String line;
final List<String> attributeNames = new ArrayList<String>();
try {
while ((line = br.readLine()) != null) {
final String trimmedLine = line.trim();
if (trimmedLine.length() > 0) {
final int leftPos = trimmedLine.indexOf(":");
final int rightPos = trimmedLine.indexOf(">");
attributeNames.add(trimmedLine.substring(leftPos+1, rightPos));
}
}
br.close();
} catch (final IOException e) {
//ignore
}
for (final String name : attributeNames) {
final List<String> values = XmlUtils.getTextForElements(xml, name);
final Map<String, Object> attributes = new HashMap<String, Object>();
if (values.size() == 1) {
attributes.put(name, values.get(0));
} else {
attributes.put(name, values);
try {
NodeList nodeList = XmlUtils.getNodeListForElements(xml,"cas:attributes");
for (int i = 0; i < nodeList.getLength(); i++) {
final String nodeName = nodeList.item(i).getNodeName();
final int beginIndex = nodeName.indexOf(":") + 1;
final int endIndex = nodeList.item(i).getNodeName().length();
final String attributeName = nodeName.substring(beginIndex, endIndex); // remove the "cas:" prefix from node name
final Object attributeValue = nodeList.item(i).getTextContent();
attributes.put(attributeName, attributeValue);
}
}
return attributes;
return attributes;
} catch (Exception e) {
return Collections.emptyMap();
}
}
/**