Return-Path: X-Original-To: apmail-cxf-commits-archive@www.apache.org Delivered-To: apmail-cxf-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 1295E7F43 for ; Wed, 21 Dec 2011 21:54:33 +0000 (UTC) Received: (qmail 6305 invoked by uid 500); 21 Dec 2011 21:54:32 -0000 Delivered-To: apmail-cxf-commits-archive@cxf.apache.org Received: (qmail 6117 invoked by uid 500); 21 Dec 2011 21:54:32 -0000 Mailing-List: contact commits-help@cxf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cxf.apache.org Delivered-To: mailing list commits@cxf.apache.org Received: (qmail 6098 invoked by uid 99); 21 Dec 2011 21:54:32 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 21 Dec 2011 21:54:32 +0000 X-ASF-Spam-Status: No, hits=-1998.0 required=5.0 tests=ALL_TRUSTED,FB_GET_MEDS X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 21 Dec 2011 21:54:28 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id B27372388A36 for ; Wed, 21 Dec 2011 21:54:07 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1221896 [2/4] - in /cxf/sandbox/fediz: ./ fediz-core/ fediz-core/.settings/ fediz-core/src/ fediz-core/src/main/ fediz-core/src/main/java/ fediz-core/src/main/java/org/ fediz-core/src/main/java/org/apache/ fediz-core/src/main/java/org/apac... Date: Wed, 21 Dec 2011 21:54:04 -0000 To: commits@cxf.apache.org From: owulff@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20111221215407.B27372388A36@eris.apache.org> Added: cxf/sandbox/fediz/fediz-core/src/main/java/org/apache/cxf/fediz/core/util/DOMUtils.java URL: http://svn.apache.org/viewvc/cxf/sandbox/fediz/fediz-core/src/main/java/org/apache/cxf/fediz/core/util/DOMUtils.java?rev=1221896&view=auto ============================================================================== --- cxf/sandbox/fediz/fediz-core/src/main/java/org/apache/cxf/fediz/core/util/DOMUtils.java (added) +++ cxf/sandbox/fediz/fediz-core/src/main/java/org/apache/cxf/fediz/core/util/DOMUtils.java Wed Dec 21 21:53:59 2011 @@ -0,0 +1,702 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.cxf.fediz.core.util; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.WeakHashMap; + +import javax.xml.XMLConstants; +import javax.xml.namespace.QName; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; + +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.Text; + +import org.xml.sax.EntityResolver; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +/** + * Few simple utils to read DOM. This is originally from the Jakarta Commons Modeler. + * + * @author Costin Manolache + */ +public final class DOMUtils { + private static final String XMLNAMESPACE = "xmlns"; + + private static final Map DOCUMENT_BUILDERS = Collections + .synchronizedMap(new WeakHashMap()); + + private DOMUtils() { + } + + private static DocumentBuilder getBuilder() throws ParserConfigurationException { + ClassLoader loader = Thread.currentThread().getContextClassLoader(); + if (loader == null) { + loader = DOMUtils.class.getClassLoader(); + } + if (loader == null) { + return XMLUtils.getParser(); + } + DocumentBuilder builder = DOCUMENT_BUILDERS.get(loader); + if (builder == null) { + builder = XMLUtils.getParser(); + DOCUMENT_BUILDERS.put(loader, builder); + } + return builder; + } + + /** + * This function is much like getAttribute, but returns null, not "", for a nonexistent attribute. + * + * @param e + * @param attributeName + * @return + */ + public static String getAttributeValueEmptyNull(Element e, String attributeName) { + Attr node = e.getAttributeNode(attributeName); + if (node == null) { + return null; + } + return node.getValue(); + } + + /** + * Get the trimmed text content of a node or null if there is no text + */ + public static String getContent(Node n) { + String s = getRawContent(n); + if (s != null) { + s = s.trim(); + } + return s; + } + + /** + * Get the raw text content of a node or null if there is no text + */ + public static String getRawContent(Node n) { + if (n == null) { + return null; + } + StringBuilder b = null; + String s = null; + Node n1 = n.getFirstChild(); + while (n1 != null) { + if (n1.getNodeType() == Node.TEXT_NODE) { + if (b != null) { + b.append(((Text)n1).getNodeValue()); + } else if (s == null) { + s = ((Text)n1).getNodeValue(); + } else { + b = new StringBuilder(s).append(((Text)n1).getNodeValue()); + s = null; + } + } + n1 = n1.getNextSibling(); + } + if (b != null) { + return b.toString(); + } + return s; + } + + /** + * Get the first element child. + * + * @param parent lookup direct childs + * @param name name of the element. If null return the first element. + */ + public static Node getChild(Node parent, String name) { + if (parent == null) { + return null; + } + + Node first = parent.getFirstChild(); + if (first == null) { + return null; + } + + for (Node node = first; node != null; node = node.getNextSibling()) { + // System.out.println("getNode: " + name + " " + + // node.getNodeName()); + if (node.getNodeType() != Node.ELEMENT_NODE) { + continue; + } + if (name != null && name.equals(node.getNodeName())) { + return node; + } + if (name == null) { + return node; + } + } + return null; + } + + public static String getAttribute(Node element, String attName) { + NamedNodeMap attrs = element.getAttributes(); + if (attrs == null) { + return null; + } + Node attN = attrs.getNamedItem(attName); + if (attN == null) { + return null; + } + return attN.getNodeValue(); + } + + public static String getAttribute(Element element, QName attName) { + Attr attr; + if (StringUtils.isEmpty(attName.getNamespaceURI())) { + attr = element.getAttributeNode(attName.getLocalPart()); + } else { + attr = element.getAttributeNodeNS(attName.getNamespaceURI(), attName.getLocalPart()); + } + return attr == null ? null : attr.getValue(); + } + + public static void setAttribute(Node node, String attName, String val) { + NamedNodeMap attributes = node.getAttributes(); + Node attNode = node.getOwnerDocument().createAttributeNS(null, attName); + attNode.setNodeValue(val); + attributes.setNamedItem(attNode); + } + + public static void removeAttribute(Node node, String attName) { + NamedNodeMap attributes = node.getAttributes(); + attributes.removeNamedItem(attName); + } + + /** + * Set or replace the text value + */ + public static void setText(Node node, String val) { + Node chld = DOMUtils.getChild(node, Node.TEXT_NODE); + if (chld == null) { + Node textN = node.getOwnerDocument().createTextNode(val); + node.appendChild(textN); + return; + } + // change the value + chld.setNodeValue(val); + } + + /** + * Find the first direct child with a given attribute. + * + * @param parent + * @param elemName name of the element, or null for any + * @param attName attribute we're looking for + * @param attVal attribute value or null if we just want any + */ + public static Node findChildWithAtt(Node parent, String elemName, String attName, String attVal) { + + Node child = DOMUtils.getChild(parent, Node.ELEMENT_NODE); + if (attVal == null) { + while (child != null && (elemName == null || elemName.equals(child.getNodeName())) + && DOMUtils.getAttribute(child, attName) != null) { + child = getNext(child, elemName, Node.ELEMENT_NODE); + } + } else { + while (child != null && (elemName == null || elemName.equals(child.getNodeName())) + && !attVal.equals(DOMUtils.getAttribute(child, attName))) { + child = getNext(child, elemName, Node.ELEMENT_NODE); + } + } + return child; + } + + /** + * Get the first child's content ( ie it's included TEXT node ). + */ + public static String getChildContent(Node parent, String name) { + Node first = parent.getFirstChild(); + if (first == null) { + return null; + } + for (Node node = first; node != null; node = node.getNextSibling()) { + // System.out.println("getNode: " + name + " " + + // node.getNodeName()); + if (name.equals(node.getNodeName())) { + return getRawContent(node); + } + } + return null; + } + + public static QName getElementQName(Element el) { + return new QName(el.getNamespaceURI(), el.getLocalName()); + } + + /** + * Get the first direct child with a given type + */ + public static Element getFirstElement(Node parent) { + Node n = parent.getFirstChild(); + while (n != null && Node.ELEMENT_NODE != n.getNodeType()) { + n = n.getNextSibling(); + } + if (n == null) { + return null; + } + return (Element)n; + } + + public static Element getNextElement(Element el) { + Node nd = el.getNextSibling(); + while (nd != null) { + if (nd.getNodeType() == Node.ELEMENT_NODE) { + return (Element)nd; + } + nd = nd.getNextSibling(); + } + return null; + } + + /** + * Return the first element child with the specified qualified name. + * + * @param parent + * @param q + * @return + */ + public static Element getFirstChildWithName(Element parent, QName q) { + String ns = q.getNamespaceURI(); + String lp = q.getLocalPart(); + return getFirstChildWithName(parent, ns, lp); + } + + /** + * Return the first element child with the specified qualified name. + * + * @param parent + * @param ns + * @param lp + * @return + */ + public static Element getFirstChildWithName(Element parent, String ns, String lp) { + for (Node n = parent.getFirstChild(); n != null; n = n.getNextSibling()) { + if (n instanceof Element) { + Element e = (Element)n; + String ens = (e.getNamespaceURI() == null) ? "" : e.getNamespaceURI(); + if (ns.equals(ens) && lp.equals(e.getLocalName())) { + return e; + } + } + } + return null; + } + + /** + * Return child elements with specified name. + * + * @param parent + * @param ns + * @param localName + * @return + */ + public static List getChildrenWithName(Element parent, String ns, String localName) { + List r = new ArrayList(); + for (Node n = parent.getFirstChild(); n != null; n = n.getNextSibling()) { + if (n instanceof Element) { + Element e = (Element)n; + String eNs = (e.getNamespaceURI() == null) ? "" : e.getNamespaceURI(); + if (ns.equals(eNs) && localName.equals(e.getLocalName())) { + r.add(e); + } + } + } + return r; + } + + /** + * Returns all child elements with specified namespace. + * + * @param parent the element to search under + * @param ns the namespace to find elements in + * @return all child elements with specified namespace + */ + public static List getChildrenWithNamespace(Element parent, String ns) { + List r = new ArrayList(); + for (Node n = parent.getFirstChild(); n != null; n = n.getNextSibling()) { + if (n instanceof Element) { + Element e = (Element)n; + String eNs = (e.getNamespaceURI() == null) ? "" : e.getNamespaceURI(); + if (ns.equals(eNs)) { + r.add(e); + } + } + } + return r; + } + + /** + * Get the first child of the specified type. + * + * @param parent + * @param type + * @return + */ + public static Node getChild(Node parent, int type) { + Node n = parent.getFirstChild(); + while (n != null && type != n.getNodeType()) { + n = n.getNextSibling(); + } + if (n == null) { + return null; + } + return n; + } + + /** + * Get the next sibling with the same name and type + */ + public static Node getNext(Node current) { + String name = current.getNodeName(); + int type = current.getNodeType(); + return getNext(current, name, type); + } + + /** + * Return the next sibling with a given name and type + */ + public static Node getNext(Node current, String name, int type) { + Node first = current.getNextSibling(); + if (first == null) { + return null; + } + + for (Node node = first; node != null; node = node.getNextSibling()) { + + if (type >= 0 && node.getNodeType() != type) { + continue; + } + + if (name == null) { + return node; + } + if (name.equals(node.getNodeName())) { + return node; + } + } + return null; + } + + public static class NullResolver implements EntityResolver { + public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException { + return new InputSource(new StringReader("")); + } + } + + /** + * Read XML as DOM. + */ + public static Document readXml(InputStream is) throws SAXException, IOException, + ParserConfigurationException { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + + dbf.setValidating(false); + dbf.setIgnoringComments(false); + dbf.setIgnoringElementContentWhitespace(true); + dbf.setNamespaceAware(true); + // dbf.setCoalescing(true); + // dbf.setExpandEntityReferences(true); + + DocumentBuilder db = null; + db = dbf.newDocumentBuilder(); + db.setEntityResolver(new NullResolver()); + + // db.setErrorHandler( new MyErrorHandler()); + + return db.parse(is); + } + + public static Document readXml(Reader is) throws SAXException, IOException, ParserConfigurationException { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + + dbf.setValidating(false); + dbf.setIgnoringComments(false); + dbf.setIgnoringElementContentWhitespace(true); + dbf.setNamespaceAware(true); + // dbf.setCoalescing(true); + // dbf.setExpandEntityReferences(true); + + DocumentBuilder db = null; + db = dbf.newDocumentBuilder(); + db.setEntityResolver(new NullResolver()); + + // db.setErrorHandler( new MyErrorHandler()); + InputSource ips = new InputSource(is); + return db.parse(ips); + } + + public static Document readXml(StreamSource is) throws SAXException, IOException, + ParserConfigurationException { + + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + + dbf.setValidating(false); + dbf.setIgnoringComments(false); + dbf.setIgnoringElementContentWhitespace(true); + dbf.setNamespaceAware(true); + // dbf.setCoalescing(true); + // dbf.setExpandEntityReferences(true); + + DocumentBuilder db = null; + db = dbf.newDocumentBuilder(); + db.setEntityResolver(new NullResolver()); + + // db.setErrorHandler( new MyErrorHandler()); + InputSource is2 = new InputSource(); + is2.setSystemId(is.getSystemId()); + is2.setByteStream(is.getInputStream()); + is2.setCharacterStream(is.getReader()); + + return db.parse(is2); + } + + public static void writeXml(Node n, OutputStream os) throws TransformerException { + TransformerFactory tf = TransformerFactory.newInstance(); + // identity + Transformer t = tf.newTransformer(); + t.setOutputProperty(OutputKeys.INDENT, "yes"); + t.transform(new DOMSource(n), new StreamResult(os)); + } + + public static DocumentBuilder createDocumentBuilder() { + try { + return getBuilder(); + } catch (ParserConfigurationException e) { + throw new RuntimeException("Couldn't find a DOM parser.", e); + } + } + + public static Document createDocument() { + try { + return getBuilder().newDocument(); + } catch (ParserConfigurationException e) { + throw new RuntimeException("Couldn't find a DOM parser.", e); + } + } + + public static String getPrefixRecursive(Element el, String ns) { + String prefix = getPrefix(el, ns); + if (prefix == null && el.getParentNode() instanceof Element) { + prefix = getPrefixRecursive((Element)el.getParentNode(), ns); + } + return prefix; + } + + public static String getPrefix(Element el, String ns) { + NamedNodeMap atts = el.getAttributes(); + for (int i = 0; i < atts.getLength(); i++) { + Node node = atts.item(i); + String name = node.getNodeName(); + if (ns.equals(node.getNodeValue()) + && (name != null && (XMLNAMESPACE.equals(name) || name.startsWith(XMLNAMESPACE + ":")))) { + return node.getLocalName(); + } + } + return null; + } + + /** + * Get all prefixes defined, up to the root, for a namespace URI. + * + * @param element + * @param namespaceUri + * @param prefixes + */ + public static void getPrefixesRecursive(Element element, String namespaceUri, List prefixes) { + getPrefixes(element, namespaceUri, prefixes); + Node parent = element.getParentNode(); + if (parent instanceof Element) { + getPrefixesRecursive((Element)parent, namespaceUri, prefixes); + } + } + + /** + * Get all prefixes defined on this element for the specified namespace. + * + * @param element + * @param namespaceUri + * @param prefixes + */ + public static void getPrefixes(Element element, String namespaceUri, List prefixes) { + NamedNodeMap atts = element.getAttributes(); + for (int i = 0; i < atts.getLength(); i++) { + Node node = atts.item(i); + String name = node.getNodeName(); + if (namespaceUri.equals(node.getNodeValue()) + && (name != null && (XMLNAMESPACE.equals(name) || name.startsWith(XMLNAMESPACE + ":")))) { + prefixes.add(node.getPrefix()); + } + } + } + + public static String createNamespace(Element el, String ns) { + String p = "ns1"; + int i = 1; + while (getPrefix(el, ns) != null) { + p = "ns" + i; + i++; + } + addNamespacePrefix(el, ns, p); + return p; + } + + /** + * Starting from a node, find the namespace declaration for a prefix. for a matching namespace + * declaration. + * + * @param node search up from here to search for namespace definitions + * @param searchPrefix the prefix we are searching for + * @return the namespace if found. + */ + public static String getNamespace(Node node, String searchPrefix) { + + Element el; + while (!(node instanceof Element)) { + node = node.getParentNode(); + } + el = (Element)node; + + NamedNodeMap atts = el.getAttributes(); + for (int i = 0; i < atts.getLength(); i++) { + Node currentAttribute = atts.item(i); + String currentLocalName = currentAttribute.getLocalName(); + String currentPrefix = currentAttribute.getPrefix(); + if (searchPrefix.equals(currentLocalName) && XMLNAMESPACE.equals(currentPrefix)) { + return currentAttribute.getNodeValue(); + } else if (StringUtils.isEmpty(searchPrefix) && XMLNAMESPACE.equals(currentLocalName) + && StringUtils.isEmpty(currentPrefix)) { + return currentAttribute.getNodeValue(); + } + } + + Node parent = el.getParentNode(); + if (parent instanceof Element) { + return getNamespace((Element)parent, searchPrefix); + } + + return null; + } + + public static List findAllElementsByTagNameNS(Element elem, String nameSpaceURI, + String localName) { + List ret = new LinkedList(); + findAllElementsByTagNameNS(elem, nameSpaceURI, localName, ret); + return ret; + } + + private static void findAllElementsByTagNameNS(Element el, String nameSpaceURI, String localName, + List elementList) { + + if (localName.equals(el.getLocalName()) && nameSpaceURI.contains(el.getNamespaceURI())) { + elementList.add(el); + } + Element elem = getFirstElement(el); + while (elem != null) { + findAllElementsByTagNameNS(elem, nameSpaceURI, localName, elementList); + elem = getNextElement(elem); + } + } + + public static List findAllElementsByTagName(Element elem, String tagName) { + List ret = new LinkedList(); + findAllElementsByTagName(elem, tagName, ret); + return ret; + } + + private static void findAllElementsByTagName(Element el, String tagName, List elementList) { + + if (tagName.equals(el.getTagName())) { + elementList.add(el); + } + Element elem = getFirstElement(el); + while (elem != null) { + findAllElementsByTagName(elem, tagName, elementList); + elem = getNextElement(elem); + } + } + public static boolean hasElementInNS(Element el, String namespace) { + + if (namespace.equals(el.getNamespaceURI())) { + return true; + } + Element elem = getFirstElement(el); + while (elem != null) { + if (hasElementInNS(elem, namespace)) { + return true; + } + elem = getNextElement(elem); + } + return false; + } + /** + * Set a namespace/prefix on an element if it is not set already. First off, it searches for the element + * for the prefix associated with the specified namespace. If the prefix isn't null, then this is + * returned. Otherwise, it creates a new attribute using the namespace/prefix passed as parameters. + * + * @param element + * @param namespace + * @param prefix + * @return the prefix associated with the set namespace + */ + public static String setNamespace(Element element, String namespace, String prefix) { + String pre = getPrefixRecursive(element, namespace); + if (pre != null) { + return pre; + } + element.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns:" + prefix, namespace); + return prefix; + } + + /** + * Add a namespace prefix definition to an element. + * + * @param element + * @param namespaceUri + * @param prefix + */ + public static void addNamespacePrefix(Element element, String namespaceUri, String prefix) { + element.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns:" + prefix, namespaceUri); + } +} Added: cxf/sandbox/fediz/fediz-core/src/main/java/org/apache/cxf/fediz/core/util/StringUtils.java URL: http://svn.apache.org/viewvc/cxf/sandbox/fediz/fediz-core/src/main/java/org/apache/cxf/fediz/core/util/StringUtils.java?rev=1221896&view=auto ============================================================================== --- cxf/sandbox/fediz/fediz-core/src/main/java/org/apache/cxf/fediz/core/util/StringUtils.java (added) +++ cxf/sandbox/fediz/fediz-core/src/main/java/org/apache/cxf/fediz/core/util/StringUtils.java Wed Dec 21 21:53:59 2011 @@ -0,0 +1,228 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.cxf.fediz.core.util; + +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Few simple utils. This is originally from the CXF project. + */ +public final class StringUtils { + + private StringUtils() { + } + + public static String extract(String string, String startToken, String endToken) { + int start = string.indexOf(startToken) + startToken.length(); + int end = string.lastIndexOf(endToken); + + if (start == -1 || end == -1) { + return null; + } + + return string.substring(start, end); + } + + public static String wrapper(String string, String startToken, String endToken) { + StringBuilder sb = new StringBuilder(); + sb.append(startToken); + sb.append(string); + sb.append(endToken); + return sb.toString(); + } + + public static boolean isFileExist(String file) { + return new File(file).exists() && new File(file).isFile(); + } + + public static boolean isFileAbsolute(String file) { + return isFileExist(file) && new File(file).isAbsolute(); + } + + public static URL getURL(String spec) throws MalformedURLException { + try { + return new URL(spec); + } catch (MalformedURLException e) { + return new File(spec).toURI().toURL(); + } + } + + public static boolean isEmpty(String str) { + if (str != null) { + int len = str.length(); + for (int x = 0; x < len; ++x) { + if (str.charAt(x) > ' ') { + return false; + } + } + } + return true; + } + + public static boolean isEmpty(List list) { + if (list == null || list.size() == 0) { + return true; + } + if (list.size() == 1 && isEmpty(list.get(0))) { + return true; + } + return false; + } + + public static boolean isEqualUri(String uri1, String uri2) { + + if (uri1.substring(uri1.length() - 1).equals("/") && !uri2.substring(uri2.length() - 1).equals("/")) { + return uri1.substring(0, uri1.length() - 1).equals(uri2); + } else if (uri2.substring(uri2.length() - 1).equals("/") + && !uri1.substring(uri1.length() - 1).equals("/")) { + return uri2.substring(0, uri2.length() - 1).equals(uri1); + } else { + return uri1.equals(uri2); + } + } + + public static String diff(String str1, String str2) { + int index = str1.lastIndexOf(str2); + if (index > -1) { + return str1.substring(str2.length()); + } + return str1; + } + + public static List getParts(String str, String sperator) { + List ret = new ArrayList(); + List parts = Arrays.asList(str.split("/")); + for (String part : parts) { + if (!isEmpty(part)) { + ret.add(part); + } + } + return ret; + } + + public static String getFirstNotEmpty(String str, String sperator) { + List parts = Arrays.asList(str.split("/")); + for (String part : parts) { + if (!isEmpty(part)) { + return part; + } + } + return str; + } + + public static String getFirstNotEmpty(List list) { + if (isEmpty(list)) { + return null; + } + for (String item : list) { + if (!isEmpty(item)) { + return item; + } + } + return null; + } + + public static List getFound(String contents, String regex) { + if (isEmpty(regex) || isEmpty(contents)) { + return null; + } + List results = new ArrayList(); + Pattern pattern = Pattern.compile(regex, Pattern.UNICODE_CASE); + Matcher matcher = pattern.matcher(contents); + + while (matcher.find()) { + if (matcher.groupCount() > 0) { + results.add(matcher.group(1)); + } else { + results.add(matcher.group()); + } + } + return results; + } + + public static String getFirstFound(String contents, String regex) { + List founds = getFound(contents, regex); + if (isEmpty(founds)) { + return null; + } + return founds.get(0); + } + + public static String formatVersionNumber(String target) { + List found = StringUtils.getFound(target, "\\d+\\.\\d+\\.?\\d*"); + if (isEmpty(found)) { + return target; + } + return getFirstNotEmpty(found); + } + + public static String addDefaultPortIfMissing(String urlString) { + return addDefaultPortIfMissing(urlString, "80"); + } + + public static String addDefaultPortIfMissing(String urlString, String defaultPort) { + URL url = null; + try { + url = new URL(urlString); + } catch (MalformedURLException e) { + return urlString; + } + if (url.getPort() != -1) { + return urlString; + } + String regex = "http://([^/]+)"; + String found = StringUtils.getFirstFound(urlString, regex); + String replacer = "http://" + found + ":" + defaultPort; + + if (!StringUtils.isEmpty(found)) { + urlString = urlString.replaceFirst(regex, replacer); + } + return urlString; + } + + /** + * Return input string with first character in upper case. + * @param name input string. + * @return capitalized form. + */ + public static String capitalize(String name) { + if (name == null || name.length() == 0) { + return name; + } + char chars[] = name.toCharArray(); + chars[0] = Character.toUpperCase(chars[0]); + return new String(chars); + } + + public static String uncapitalize(String str) { + if (str == null || str.length() == 0) { + return str; + } + return new StringBuilder(str.length()) + .append(Character.toLowerCase(str.charAt(0))) + .append(str.substring(1)) + .toString(); + } +} Added: cxf/sandbox/fediz/fediz-core/src/main/java/org/apache/cxf/fediz/core/util/XMLUtils.java URL: http://svn.apache.org/viewvc/cxf/sandbox/fediz/fediz-core/src/main/java/org/apache/cxf/fediz/core/util/XMLUtils.java?rev=1221896&view=auto ============================================================================== --- cxf/sandbox/fediz/fediz-core/src/main/java/org/apache/cxf/fediz/core/util/XMLUtils.java (added) +++ cxf/sandbox/fediz/fediz-core/src/main/java/org/apache/cxf/fediz/core/util/XMLUtils.java Wed Dec 21 21:53:59 2011 @@ -0,0 +1,482 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.cxf.fediz.core.util; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.StringWriter; +import java.io.Writer; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.StringTokenizer; +import java.util.WeakHashMap; +import javax.xml.namespace.QName; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMResult; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.w3c.dom.Attr; +import org.w3c.dom.DOMImplementation; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.Text; +import org.w3c.dom.bootstrap.DOMImplementationRegistry; +import org.w3c.dom.ls.DOMImplementationLS; +import org.w3c.dom.ls.LSOutput; +import org.w3c.dom.ls.LSSerializer; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +/** + * Few simple utils. This is originally from the CXF project. + */ +@SuppressWarnings("PMD") +public final class XMLUtils { + + //private static final Logger LOG = LogUtils.getL7dLogger(XMLUtils.class); + + private static final Map DOCUMENT_BUILDER_FACTORIES + = Collections.synchronizedMap(new WeakHashMap()); + + private static final Map TRANSFORMER_FACTORIES + = Collections.synchronizedMap(new WeakHashMap()); + + private XMLUtils() { + } + + private static TransformerFactory getTransformerFactory() { + ClassLoader loader = Thread.currentThread().getContextClassLoader(); + if (loader == null) { + loader = XMLUtils.class.getClassLoader(); + } + if (loader == null) { + return TransformerFactory.newInstance(); + } + TransformerFactory factory = TRANSFORMER_FACTORIES.get(loader); + if (factory == null) { + factory = TransformerFactory.newInstance(); + TRANSFORMER_FACTORIES.put(loader, factory); + } + return factory; + } + private static DocumentBuilderFactory getDocumentBuilderFactory() { + ClassLoader loader = Thread.currentThread().getContextClassLoader(); + if (loader == null) { + loader = XMLUtils.class.getClassLoader(); + } + if (loader == null) { + return DocumentBuilderFactory.newInstance(); + } + DocumentBuilderFactory factory = DOCUMENT_BUILDER_FACTORIES.get(loader); + if (factory == null) { + factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); + DOCUMENT_BUILDER_FACTORIES.put(loader, factory); + } + return factory; + } + public static Transformer newTransformer() throws TransformerConfigurationException { + return getTransformerFactory().newTransformer(); + } + public static Transformer newTransformer(int indent) throws TransformerConfigurationException { + if (indent > 0) { + TransformerFactory f = TransformerFactory.newInstance(); + try { + //sun way of setting indent + f.setAttribute("indent-number", Integer.toString(indent)); + } catch (Throwable t) { + //ignore + } + return f.newTransformer(); + } + return getTransformerFactory().newTransformer(); + } + + public static DocumentBuilder getParser() throws ParserConfigurationException { + return getDocumentBuilderFactory().newDocumentBuilder(); + } + + public static Document parse(InputSource is) throws ParserConfigurationException, SAXException, + IOException { + return getParser().parse(is); + } + + public static Document parse(File is) throws ParserConfigurationException, SAXException, + IOException { + return getParser().parse(is); + } + + public static Document parse(InputStream in) throws ParserConfigurationException, SAXException, + IOException { + return getParser().parse(in); + } + + public static Document parse(String in) throws ParserConfigurationException, SAXException, IOException { + return parse(in.getBytes()); + } + + public static Document parse(byte[] in) throws ParserConfigurationException, SAXException, IOException { + if (in == null) { + return null; + } + return getParser().parse(new ByteArrayInputStream(in)); + } + + public static Document newDocument() throws ParserConfigurationException { + return getParser().newDocument(); + } + + public static void writeTo(Node node, OutputStream os) { + writeTo(new DOMSource(node), os); + } + public static void writeTo(Node node, OutputStream os, int indent) { + writeTo(new DOMSource(node), os, indent); + } + public static void writeTo(Source src, OutputStream os) { + writeTo(src, os, -1); + } + public static void writeTo(Node node, Writer os) { + writeTo(new DOMSource(node), os); + } + public static void writeTo(Node node, Writer os, int indent) { + writeTo(new DOMSource(node), os, indent); + } + public static void writeTo(Source src, Writer os) { + writeTo(src, os, -1); + } + public static void writeTo(Source src, OutputStream os, int indent) { + String enc = null; + if (src instanceof DOMSource + && ((DOMSource)src).getNode() instanceof Document) { + try { + enc = ((Document)((DOMSource)src).getNode()).getXmlEncoding(); + } catch (Exception ex) { + //ignore - not DOM level 3 + } + } + writeTo(src, os, indent, enc, "no"); + } + public static void writeTo(Source src, Writer os, int indent) { + String enc = null; + if (src instanceof DOMSource + && ((DOMSource)src).getNode() instanceof Document) { + try { + enc = ((Document)((DOMSource)src).getNode()).getXmlEncoding(); + } catch (Exception ex) { + //ignore - not DOM level 3 + } + } + writeTo(src, os, indent, enc, "no"); + } + public static void writeTo(Source src, + OutputStream os, + int indent, + String charset, + String omitXmlDecl) { + Transformer it; + try { + if (StringUtils.isEmpty(charset)) { + charset = "utf-8"; + } + + it = newTransformer(indent); + it.setOutputProperty(OutputKeys.METHOD, "xml"); + if (indent > -1) { + it.setOutputProperty(OutputKeys.INDENT, "yes"); + it.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", + Integer.toString(indent)); + } + it.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, omitXmlDecl); + it.setOutputProperty(OutputKeys.ENCODING, charset); + it.transform(src, new StreamResult(os)); + } catch (TransformerException e) { + throw new RuntimeException("Failed to configure TRaX", e); + } + } + public static void writeTo(Source src, + Writer os, + int indent, + String charset, + String omitXmlDecl) { + Transformer it; + try { + if (StringUtils.isEmpty(charset)) { + charset = "utf-8"; + } + + it = newTransformer(indent); + it.setOutputProperty(OutputKeys.METHOD, "xml"); + if (indent > -1) { + it.setOutputProperty(OutputKeys.INDENT, "yes"); + it.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", + Integer.toString(indent)); + } + it.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, omitXmlDecl); + it.setOutputProperty(OutputKeys.ENCODING, charset); + it.transform(src, new StreamResult(os)); + } catch (TransformerException e) { + throw new RuntimeException("Failed to configure TRaX", e); + } + } + public static String toString(Source source) throws TransformerException, IOException { + return toString(source, null); + } + + public static String toString(Source source, Properties props) throws TransformerException, IOException { + StringWriter bos = new StringWriter(); + StreamResult sr = new StreamResult(bos); + Transformer trans = newTransformer(); + if (props == null) { + props = new Properties(); + props.put(OutputKeys.OMIT_XML_DECLARATION, "yes"); + } + trans.setOutputProperties(props); + trans.transform(source, sr); + bos.close(); + return bos.toString(); + } + + public static String toString(Node node, int indent) { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + writeTo(node, out, indent); + return out.toString(); + } + public static String toString(Node node) { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + writeTo(node, out); + return out.toString(); + } + + public static void printDOM(Node node) { + printDOM("", node); + } + + public static void printDOM(String words, Node node) { + System.out.println(words); + System.out.println(toString(node)); + } + + public static Attr getAttribute(Element el, String attrName) { + return el.getAttributeNode(attrName); + } + + public static void replaceAttribute(Element element, String attr, String value) { + if (element.hasAttribute(attr)) { + element.removeAttribute(attr); + } + element.setAttribute(attr, value); + } + + public static boolean hasAttribute(Element element, String value) { + NamedNodeMap attributes = element.getAttributes(); + for (int i = 0; i < attributes.getLength(); i++) { + Node node = attributes.item(i); + if (value.equals(node.getNodeValue())) { + return true; + } + } + return false; + } + + public static void printAttributes(Element element) { + NamedNodeMap attributes = element.getAttributes(); + for (int i = 0; i < attributes.getLength(); i++) { + Node node = attributes.item(i); + System.err.println("## prefix=" + node.getPrefix() + " localname:" + node.getLocalName() + + " value=" + node.getNodeValue()); + } + } + + public static QName getNamespace(Map namespaces, String str, String defaultNamespace) { + String prefix = null; + String localName = null; + + StringTokenizer tokenizer = new StringTokenizer(str, ":"); + if (tokenizer.countTokens() == 2) { + prefix = tokenizer.nextToken(); + localName = tokenizer.nextToken(); + } else if (tokenizer.countTokens() == 1) { + localName = tokenizer.nextToken(); + } + + String namespceURI = defaultNamespace; + if (prefix != null) { + namespceURI = (String)namespaces.get(prefix); + } + return new QName(namespceURI, localName); + } + + public static void generateXMLFile(Element element, Writer writer) { + try { + Transformer it = newTransformer(); + + it.setOutputProperty(OutputKeys.METHOD, "xml"); + it.setOutputProperty(OutputKeys.INDENT, "yes"); + it.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); + it.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); + it.transform(new DOMSource(element), new StreamResult(writer)); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static Element createElementNS(Node node, QName name) { + return createElementNS(node.getOwnerDocument(), name.getNamespaceURI(), name.getLocalPart()); + } + + public static Element createElementNS(Document root, QName name) { + return createElementNS(root, name.getNamespaceURI(), name.getLocalPart()); + } + + public static Element createElementNS(Document root, String namespaceURI, String qualifiedName) { + return root.createElementNS(namespaceURI, qualifiedName); + } + + public static Text createTextNode(Document root, String data) { + return root.createTextNode(data); + } + + public static Text createTextNode(Node node, String data) { + return createTextNode(node.getOwnerDocument(), data); + } + + public static void removeContents(Node parent) { + Node node = parent.getFirstChild(); + while (node != null) { + parent.removeChild(node); + node = node.getNextSibling(); + } + } + + public static InputStream getInputStream(Document doc) throws Exception { + DOMImplementationLS impl = null; + DOMImplementation docImpl = doc.getImplementation(); + // Try to get the DOMImplementation from doc first before + // defaulting to the sun implementation. + if (docImpl != null && docImpl.hasFeature("LS", "3.0")) { + impl = (DOMImplementationLS)docImpl.getFeature("LS", "3.0"); + } else { + DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance(); + impl = (DOMImplementationLS)registry.getDOMImplementation("LS"); + if (impl == null) { + System.setProperty(DOMImplementationRegistry.PROPERTY, + "com.sun.org.apache.xerces.internal.dom.DOMImplementationSourceImpl"); + registry = DOMImplementationRegistry.newInstance(); + impl = (DOMImplementationLS)registry.getDOMImplementation("LS"); + } + } + LSOutput output = impl.createLSOutput(); + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + output.setByteStream(byteArrayOutputStream); + LSSerializer writer = impl.createLSSerializer(); + writer.write(doc, output); + byte[] buf = byteArrayOutputStream.toByteArray(); + return new ByteArrayInputStream(buf); + } + + public static Element fetchElementByNameAttribute(Element parent, String targetName, String nameValue) { + + List elemList = DOMUtils.findAllElementsByTagName(parent, targetName); + for (Element elem : elemList) { + if (elem.getAttribute("name").equals(nameValue)) { + return elem; + } + } + return null; + } + + public static QName getQName(String value, Node node) { + if (value == null) { + return null; + } + + int index = value.indexOf(":"); + + if (index == -1) { + return new QName(value); + } + + String prefix = value.substring(0, index); + String localName = value.substring(index + 1); + String ns = node.lookupNamespaceURI(prefix); + + if (ns == null || localName == null) { + throw new RuntimeException("Invalid QName in mapping: " + value); + } + + return new QName(ns, localName, prefix); + } + + public static Node fromSource(Source src) throws Exception { + + Transformer trans = TransformerFactory.newInstance().newTransformer(); + DOMResult res = new DOMResult(); + trans.transform(src, res); + return res.getNode(); + } + + public static QName convertStringToQName(String expandedQName) { + return convertStringToQName(expandedQName, ""); + } + + public static QName convertStringToQName(String expandedQName, String prefix) { + int ind1 = expandedQName.indexOf('{'); + if (ind1 != 0) { + return new QName(expandedQName); + } + + int ind2 = expandedQName.indexOf('}'); + if (ind2 <= ind1 + 1 || ind2 >= expandedQName.length() - 1) { + return null; + } + String ns = expandedQName.substring(ind1 + 1, ind2); + String localName = expandedQName.substring(ind2 + 1); + return new QName(ns, localName, prefix); + } + + public static Set convertStringsToQNames(List expandedQNames) { + Set dropElements = Collections.emptySet(); + if (expandedQNames != null) { + dropElements = new LinkedHashSet(expandedQNames.size()); + for (String val : expandedQNames) { + dropElements.add(XMLUtils.convertStringToQName(val)); + } + } + return dropElements; + } + +} Added: cxf/sandbox/fediz/fediz-core/src/test/java/org/apache/cxf/fediz/core/FederationProcessorTest.java URL: http://svn.apache.org/viewvc/cxf/sandbox/fediz/fediz-core/src/test/java/org/apache/cxf/fediz/core/FederationProcessorTest.java?rev=1221896&view=auto ============================================================================== --- cxf/sandbox/fediz/fediz-core/src/test/java/org/apache/cxf/fediz/core/FederationProcessorTest.java (added) +++ cxf/sandbox/fediz/fediz-core/src/test/java/org/apache/cxf/fediz/core/FederationProcessorTest.java Wed Dec 21 21:53:59 2011 @@ -0,0 +1,152 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.cxf.fediz.core; + +import java.io.BufferedReader; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +import org.apache.cxf.fediz.core.FederationConfiguration; +import org.apache.cxf.fediz.core.FederationConstants; +import org.apache.cxf.fediz.core.FederationProcessor; +import org.apache.cxf.fediz.core.FederationProcessorImpl; +import org.apache.cxf.fediz.core.FederationRequest; +import org.apache.cxf.fediz.core.FederationResponse; +import org.junit.BeforeClass; + +import junit.framework.Assert; + +import static org.apache.cxf.fediz.core.FederationConstants.DEFAULT_ROLE_URI; + +public class FederationProcessorTest { + + private static final String TEST_OTHER_ISSUER = "ZFS IDP DEV"; + private static final String TEST_USER = "alice"; + private static final String TEST_TRUSTSTORE_FILE = "stsstore.jks"; + private static final String TEST_TRUSTSTORE_PASSWORD = "stsspass"; + private static final String TEST_RSTR_ISSUER = "DoubleItSTSIssuer"; + private static final String TEST_CERT_CONSTRAINT = ".*CN=www.sts.com.*"; + + + private static String sRSTR = null; + + @BeforeClass + public static void readWResult() { + InputStream is = null; + try { + is = FederationProcessorTest.class.getResourceAsStream("/RSTR.xml"); + if (is == null) { + throw new FileNotFoundException("Failed to get RSTR.xml"); + } + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is)); + StringBuilder stringBuilder = new StringBuilder(); + String line = null; + while ((line = bufferedReader.readLine()) != null) { + stringBuilder.append(line + "\n"); + } + bufferedReader.close(); + sRSTR = stringBuilder.toString(); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (is != null) { + try { + is.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + Assert.assertNotNull("RSTR resource null", sRSTR); + + } + + @org.junit.Test + public void validateSAML2Token() { + + FederationRequest wfReq = new FederationRequest(); + wfReq.setWa(FederationConstants.ACTION_SIGNIN); + wfReq.setWresult(sRSTR); + + FederationConfiguration config = new FederationConfiguration(); + config.setTrustedIssuer(TEST_CERT_CONSTRAINT); + config.setRoleDelimiter(";"); + config.setRoleURI(FederationConstants.DEFAULT_ROLE_URI); + config.setTrustStoreFile(TEST_TRUSTSTORE_FILE); + config.setTrustStorePassword(TEST_TRUSTSTORE_PASSWORD); + config.setDetectReplayedTokens(false); + + FederationProcessor wfProc = new FederationProcessorImpl(); + FederationResponse wfRes = wfProc.processRequest(wfReq, config); + Assert.assertEquals("Principal name wrong", TEST_USER, wfRes.getUsername()); + Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer()); + } + + + @org.junit.Test + public void validateSAML2TokenWithWrongIssuer() { + + FederationRequest wfReq = new FederationRequest(); + wfReq.setWa(FederationConstants.ACTION_SIGNIN); + wfReq.setWresult(sRSTR); + + FederationConfiguration config = new FederationConfiguration(); + config.setTrustedIssuer(TEST_OTHER_ISSUER); + config.setRoleDelimiter(";"); + config.setRoleURI(FederationConstants.DEFAULT_ROLE_URI); + config.setTrustStoreFile(TEST_TRUSTSTORE_FILE); + config.setTrustStorePassword(TEST_TRUSTSTORE_PASSWORD); + config.setDetectReplayedTokens(false); + + FederationProcessor wfProc = new FederationProcessorImpl(); + try { + wfProc.processRequest(wfReq, config); + Assert.fail("Processing must fail because of wrong issuer configured"); + } + catch (RuntimeException ex) { + Assert.assertEquals("Exception expected", "Issuer '" + TEST_RSTR_ISSUER + "' not trusted", ex.getMessage()); + } + } + + @org.junit.Test + public void validateSAML2TokenForRoles() { + + FederationRequest wfReq = new FederationRequest(); + wfReq.setWa(FederationConstants.ACTION_SIGNIN); + wfReq.setWresult(sRSTR); + + FederationConfiguration config = new FederationConfiguration(); + config.setTrustedIssuer(TEST_CERT_CONSTRAINT); + config.setRoleDelimiter(";"); + config.setRoleURI(DEFAULT_ROLE_URI); + config.setTrustStoreFile(TEST_TRUSTSTORE_FILE); + config.setTrustStorePassword(TEST_TRUSTSTORE_PASSWORD); + config.setDetectReplayedTokens(false); + + FederationProcessor wfProc = new FederationProcessorImpl(); + FederationResponse wfRes = wfProc.processRequest(wfReq, config); + Assert.assertEquals("Principal name wrong", TEST_USER, wfRes.getUsername()); + Assert.assertEquals("Issuer wrong", TEST_RSTR_ISSUER, wfRes.getIssuer()); + Assert.assertEquals("One role must be found", 1, wfRes.getRoles().size()); + } + + + +} Added: cxf/sandbox/fediz/fediz-core/src/test/resources/RSTR.formatted.xml URL: http://svn.apache.org/viewvc/cxf/sandbox/fediz/fediz-core/src/test/resources/RSTR.formatted.xml?rev=1221896&view=auto ============================================================================== --- cxf/sandbox/fediz/fediz-core/src/test/resources/RSTR.formatted.xml (added) +++ cxf/sandbox/fediz/fediz-core/src/test/resources/RSTR.formatted.xml Wed Dec 21 21:53:59 2011 @@ -0,0 +1,107 @@ + + + + + http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0 + + + + DoubleItSTSIssuer + + + + + + + + + + + + + 3BwoTotMyMTFt40DCmi0ayEdnko= + + + bXSIwaG+e2hDdpdDkciR3pjLbbpCLD/XwS+CezMygN/w2g1trgyaIlfkUvyAXVyk5ULJH9s+fFuecPgRm2n2JePm8Up2oZ0+vAJ6fvwQxbhhpuGz8j+OkVr11rGMjpVo1tFSVQNlq183blHVjjDQhGBl7TvoKAZsSGnhzoHclEY= + + + + MIID5jCCA0+gAwIBAgIJAPahVdM2UPibMA0GCSqGSIb3DQEBBQUAMIGpMQswCQYDVQQGEwJVUzERMA8GA1UECBMITWFyeWxhbmQxEjAQBgNVBAcTCUJhbHRpbW9yZTEpMCcGA1UEChMgU2FtcGxlIFNUUyAtLSBOT1QgRk9SIFBST0RVQ1RJT04xFjAUBgNVBAsTDUlUIERlcGFydG1lbnQxFDASBgNVBAMTC3d3dy5zdHMuY29tMRowGAYJKoZIhvcNAQkBFgtzdHNAc3RzLmNvbTAeFw0xMTAyMDkxODM4MTNaFw0yMTAyMDYxODM4MTNaMIGpMQswCQYDVQQGEwJVUzERMA8GA1UECBMITWFyeWxhbmQxEjAQBgNVBAcTCUJhbHRpbW9yZTEpMCcGA1UEChMgU2FtcGxlIFNUUyAtLSBOT1QgRk9SIFBST0RVQ1RJT04xFjAUBgNVBAsTDUlUIERlcGFydG1lbnQxFDASBgNVBAMTC3d3dy5zdHMuY29tMRowGAYJKoZIhvcNAQkBFgtzdHNAc3RzLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAo+f8gs4WcteLdSPWPm8+ciyEz7zVmA7kcCGFQQvlO0smxRViWJ1x+yniT5Uu86UrAQjxRJyANBomQrirfE7KPrnCm6iVOsGDEntuIZAf7DFPnrv5p++jAZQuR3vm4ZHXFOFTXmI+/FD5AqLfNi17xiTxZCDYyDdD39CNFTrB2PkCAwEAAaOCARIwggEOMB0GA1UdDgQWBBRa0A38holQIbJMFW7m5ZSw+iVDHDCB3gYDVR0jBIHWMIHTgBRa0A38holQIbJMFW7m5ZSw+iVDHKGBr6SBrDCBqTELMAkGA1UEBhMCVVMxETAPBgNVBAgTCE1hcnlsYW5kMRIwEAYDVQQHEwlCYWx0aW1vcmUxKTAnBgNVBA oTIFNhbXBsZSBTVFMgLS0gTk9UIEZPUiBQUk9EVUNUSU9OMRYwFAYDVQQLEw1JVCBEZXBhcnRtZW50MRQwEgYDVQQDEwt3d3cuc3RzLmNvbTEaMBgGCSqGSIb3DQEJARYLc3RzQHN0cy5jb22CCQD2oVXTNlD4mzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBACp9yK1I9r++pyFT0yrcaV1m1Sub6urJH+GxQLBaTnTsaPLuzq2gIsJHpwk5XggB+IDe69iKKeb74Vt8aOe5usIWVASgi9ckqCwdfTqYu6KG9BlezqHZdExnIG2v/cD/3NkKr7O/a7DjlbE6FZ4G1nrOfVJkjmeAa6txtYm1Dm/f + + + + + + alice + + + + + http://localhost:8080/wsfedhelloworld/ + + + + + + Alice + + + + Smith + + + + alice@mycompany.org + + + + User + + + + + + + + #_93FDCC53AC1D5AE3EB131849544559910 + + + + + _93FDCC53AC1D5AE3EB131849544559910 + + + + + http://localhost:8080/wsfedhelloworld/ + + + + 2011-10-13T08:44:05.608Z + 2011-10-13T08:49:05.608Z + + + \ No newline at end of file Added: cxf/sandbox/fediz/fediz-core/src/test/resources/RSTR.xml URL: http://svn.apache.org/viewvc/cxf/sandbox/fediz/fediz-core/src/test/resources/RSTR.xml?rev=1221896&view=auto ============================================================================== --- cxf/sandbox/fediz/fediz-core/src/test/resources/RSTR.xml (added) +++ cxf/sandbox/fediz/fediz-core/src/test/resources/RSTR.xml Wed Dec 21 21:53:59 2011 @@ -0,0 +1,3 @@ + + +http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0DoubleItSTSIssuer3BwoTotMyMTFt40DCmi0ayEdnko=bXSIwaG+e2hDdpdDkciR3pjLbbpCLD/XwS+CezMygN/w2g1trgyaIlfkUvyAXVyk5ULJH9s+fFuecPgRm2n2JePm8Up2oZ0+vAJ6fvwQxbhhpuGz8j+OkVr11rGMjpVo1tFSVQNlq183blHVjjDQhGBl7TvoKAZsSGnhzoHclEY=MIID5jCCA0+gAwIBAgIJAPahVdM2UPibMA0GCSqGSIb3DQEBBQUAMIGpMQswCQYDVQQGEwJVUzERMA8GA1UECBMITWFyeWxhbmQxEjAQBg NVBAcTCUJhbHRpbW9yZTEpMCcGA1UEChMgU2FtcGxlIFNUUyAtLSBOT1QgRk9SIFBST0RVQ1RJT04xFjAUBgNVBAsTDUlUIERlcGFydG1lbnQxFDASBgNVBAMTC3d3dy5zdHMuY29tMRowGAYJKoZIhvcNAQkBFgtzdHNAc3RzLmNvbTAeFw0xMTAyMDkxODM4MTNaFw0yMTAyMDYxODM4MTNaMIGpMQswCQYDVQQGEwJVUzERMA8GA1UECBMITWFyeWxhbmQxEjAQBgNVBAcTCUJhbHRpbW9yZTEpMCcGA1UEChMgU2FtcGxlIFNUUyAtLSBOT1QgRk9SIFBST0RVQ1RJT04xFjAUBgNVBAsTDUlUIERlcGFydG1lbnQxFDASBgNVBAMTC3d3dy5zdHMuY29tMRowGAYJKoZIhvcNAQkBFgtzdHNAc3RzLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAo+f8gs4WcteLdSPWPm8+ciyEz7zVmA7kcCGFQQvlO0smxRViWJ1x+yniT5Uu86UrAQjxRJyANBomQrirfE7KPrnCm6iVOsGDEntuIZAf7DFPnrv5p++jAZQuR3vm4ZHXFOFTXmI+/FD5AqLfNi17xiTxZCDYyDdD39CNFTrB2PkCAwEAAaOCARIwggEOMB0GA1UdDgQWBBRa0A38holQIbJMFW7m5ZSw+iVDHDCB3gYDVR0jBIHWMIHTgBRa0A38holQIbJMFW7m5ZSw+iVDHKGBr6SBrDCBqTELMAkGA1UEBhMCVVMxETAPBgNVBAgTCE1hcnlsYW5kMRIwEAYDVQQHEwlCYWx0aW1vcmUxKTAnBgNVBAoTIFNhbXBsZSBTVFMgLS0gTk9UIEZPUiBQUk9EVUNUSU9OMRYwFAYDVQQLEw1JVCBEZXBhcnRtZW50MRQwEgYDVQQDEwt3d3cuc3RzLmNvbTEaMBgGCSqGSIb3DQEJARYLc3R zQHN0cy5jb22CCQD2oVXTNlD4mzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBACp9yK1I9r++pyFT0yrcaV1m1Sub6urJH+GxQLBaTnTsaPLuzq2gIsJHpwk5XggB+IDe69iKKeb74Vt8aOe5usIWVASgi9ckqCwdfTqYu6KG9BlezqHZdExnIG2v/cD/3NkKr7O/a7DjlbE6FZ4G1nrOfVJkjmeAa6txtYm1Dm/falicehttp://localhost:8080/wsfedhelloworld/AliceSmithalice@mycompany.orgUser#_93FDCC53AC1D5AE3EB131849544559910_93FDCC53AC1D5AE3EB131849544559910http://localhost:8080/wsfedhelloworld/2011-10-13T08:44:05.608Z2011-10-13T08:49:05.608Z \ No newline at end of file Added: cxf/sandbox/fediz/fediz-core/src/test/resources/RSTR_old.xml URL: http://svn.apache.org/viewvc/cxf/sandbox/fediz/fediz-core/src/test/resources/RSTR_old.xml?rev=1221896&view=auto ============================================================================== --- cxf/sandbox/fediz/fediz-core/src/test/resources/RSTR_old.xml (added) +++ cxf/sandbox/fediz/fediz-core/src/test/resources/RSTR_old.xml Wed Dec 21 21:53:59 2011 @@ -0,0 +1,3 @@ + + +2011-09-15T13:18:59.140Z2011-09-15T14:18:59.140Z
http://ws-ubuntu-talend.z.ch.zurich.com:8080/wsfedhelloworld/secure/test.html
ZFS IDP LABWozRF8Ml1jrUFlzMktNb1Aj28jvX+Giy2qhSqcGtStQ=FdlwgcqSw+VgUT98/48DvZbHguQZTndW1GM/ctKrWok8kuWP8Vmmt9Qa1ts1QnWe6Sv07du+jDA9shHE/mxctC97T/dgraQwggPe4X4/RhNYiRD8w5pKY3hiVI1mFrnRUEg/rEcyQiCXQhcE6YL2V+asO+RpU0YW34AgRWdgJLI=MIIC1zCCAkCgAwIBAgICAj0wDQYJKoZIhvcNAQEFBQAwgaYxCzAJBgNVBAYTAkNIMQ8wDQYDVQQIEwZ adXJpY2gxGTAXBgNVBAcTEFp1cmljaCBJbnN1cmFuY2UxGjAYBgNVBAoTEVN3aXNzIERhdGEgQ2VudGVyMQwwCgYDVQQLEwNJTkcxGDAWBgNVBAMTD1NEQyBJbnRlcm5hbCBDQTEnMCUGCSqGSIb3DQEJARYYY2hyX25ldHNlY3VyZUB6dXJpY2guY29tMB4XDTA5MTIyODE2MTMwOFoXDTExMTIyODE2MTMwOFowgZ4xCzAJBgNVBAYTAkNIMQ8wDQYDVQQIEwZadXJpY2gxDzANBgNVBAcTBlp1cmljaDEhMB8GA1UEChMYWnVyaWNoIEluc3VyYW5jZSBDb21wYW55MRMwEQYDVQQLEwpJU1AgRXVyb3BlMQwwCgYDVQQDEwNTVFMxJzAlBgkqhkiG9w0BCQEWGGNocl9uZXRzZWN1cmVAenVyaWNoLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAxLcHLtMzqstcDeIozxMethzbDunN+ZINWpW8ui5EbkuduwB4q9Um6zARnHe+ECfcaDkzBge+INgl4MSmHxWW79lFYSwIwH+8RcLpgZKabmX9G9EKeNW0T5tJjauzumU2Pc8Q66NiTa2hr/aNlRZzWUtz9UM4AL+V2GSwXNDYrakCAwEAAaMaMBgwCQYDVR0TBAIwADALBgNVHQ8EBAMCBaAwDQYJKoZIhvcNAQEFBQADgYEAo+uaHVi02v7Pch1ispD5kQNCMgMJoXgGYGM/xuLlIIpz7785L+fp7j8F//aCXUSjj+4juAOCKe+vwc0/Ij9WDjhH10fruzTOHtOiCDyp1dzb9fwlug+zzGUvL07CJZY+ZDetqYJUHIq4F56bAe65d+S445I254uttRslM8D0DFU=Johnhttp://ws-ubuntu-talend.z.ch.zurich.com:8080/wsfedhelloworld/secure/test.htmlJohnDoe5/5/1955555-555-5555john@gh.comContosoAir54545454gold_1020637e-0ce4-4312-bd91-4adc38f47c0b_1020637e-0ce4-4312-bd91-4adc38f47c0burn:oasis:names:tc:SAML:2.0:assertionhttp://docs.oasis-open.org/ws-sx/ws-trust/200512/Issuehttp://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer
\ No newline at end of file Added: cxf/sandbox/fediz/fediz-core/src/test/resources/logging.properties URL: http://svn.apache.org/viewvc/cxf/sandbox/fediz/fediz-core/src/test/resources/logging.properties?rev=1221896&view=auto ============================================================================== --- cxf/sandbox/fediz/fediz-core/src/test/resources/logging.properties (added) +++ cxf/sandbox/fediz/fediz-core/src/test/resources/logging.properties Wed Dec 21 21:53:59 2011 @@ -0,0 +1,54 @@ +############################################################ +# Default Logging Configuration File +# +# You can use a different file by specifying a filename +# with the java.util.logging.config.file system property. +# For example java -Djava.util.logging.config.file=myfile +############################################################ + +############################################################ +# Global properties +############################################################ + +# "handlers" specifies a comma separated list of log Handler +# classes. These handlers will be installed during VM startup. +# Note that these classes must be on the system classpath. +# By default we only configure a ConsoleHandler, which will only +# show messages at the WARNING and above levels. +handlers= java.util.logging.ConsoleHandler +#handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler + +# Default global logging level. +# This specifies which kinds of events are logged across +# all loggers. For any given facility this global level +# can be overridden by a facility specific level +# Note that the ConsoleHandler also has a separate level +# setting to limit messages printed to the console. +.level= INFO + +############################################################ +# Handler specific properties. +# Describes specific configuration info for Handlers. +############################################################ + +# default file output is in user's home directory. +java.util.logging.FileHandler.pattern = %h/java%u.log +java.util.logging.FileHandler.limit = 50000 +java.util.logging.FileHandler.count = 1 +java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter + +# Limit the message that are printed on the console to WARNING and above. +java.util.logging.ConsoleHandler.level = FINEST +java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter + + +############################################################ +# Facility specific properties. +# Provides extra control for each logger. +############################################################ + +# For example, set the com.xyz.foo logger to only log SEVERE +# messages: +#com.xyz.foo.level = SEVERE +org.apache.ws.security.level = FINEST +org.apache.cxf.fediz.level = FINEST Added: cxf/sandbox/fediz/fediz-core/src/test/resources/signature.properties URL: http://svn.apache.org/viewvc/cxf/sandbox/fediz/fediz-core/src/test/resources/signature.properties?rev=1221896&view=auto ============================================================================== --- cxf/sandbox/fediz/fediz-core/src/test/resources/signature.properties (added) +++ cxf/sandbox/fediz/fediz-core/src/test/resources/signature.properties Wed Dec 21 21:53:59 2011 @@ -0,0 +1,6 @@ +org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin +org.apache.ws.security.crypto.merlin.keystore.type=jks +org.apache.ws.security.crypto.merlin.keystore.password=changeit +#org.apache.ws.security.crypto.merlin.keystore.alias=notneeded +org.apache.ws.security.crypto.merlin.keystore.file=sdcinternal.jks + Added: cxf/sandbox/fediz/fediz-core/src/test/resources/stsstore.jks URL: http://svn.apache.org/viewvc/cxf/sandbox/fediz/fediz-core/src/test/resources/stsstore.jks?rev=1221896&view=auto ============================================================================== Binary file - no diff available. Propchange: cxf/sandbox/fediz/fediz-core/src/test/resources/stsstore.jks ------------------------------------------------------------------------------ svn:mime-type = application/octet-stream Added: cxf/sandbox/fediz/fediz-idp-sts/pom.xml URL: http://svn.apache.org/viewvc/cxf/sandbox/fediz/fediz-idp-sts/pom.xml?rev=1221896&view=auto ============================================================================== --- cxf/sandbox/fediz/fediz-idp-sts/pom.xml (added) +++ cxf/sandbox/fediz/fediz-idp-sts/pom.xml Wed Dec 21 21:53:59 2011 @@ -0,0 +1,93 @@ + + + + 4.0.0 + + org.apache.cxf.fediz + fediz + 0.6-SNAPSHOT + + fediz-idp-sts + WS Federation IDP STS + war + + + 2.5.1 + UTF-8 + + + + + org.apache.cxf + cxf-rt-transports-http + ${cxf.version} + + + org.apache.cxf + cxf-rt-frontend-jaxws + ${cxf.version} + + + org.apache.cxf + cxf-rt-ws-policy + ${cxf.version} + + + org.apache.cxf.services.sts + cxf-services-sts-core + ${cxf.version} + + + + + + + + + + + + org.codehaus.mojo + tomcat-maven-plugin + 1.1 + + myTomcat + http://localhost:9080/manager/text + /${project.build.finalName} + + + + + fedizidpsts + + + Added: cxf/sandbox/fediz/fediz-idp-sts/src/main/java/org/apache/cxf/fediz/service/sts/FileClaimsHandler.java URL: http://svn.apache.org/viewvc/cxf/sandbox/fediz/fediz-idp-sts/src/main/java/org/apache/cxf/fediz/service/sts/FileClaimsHandler.java?rev=1221896&view=auto ============================================================================== --- cxf/sandbox/fediz/fediz-idp-sts/src/main/java/org/apache/cxf/fediz/service/sts/FileClaimsHandler.java (added) +++ cxf/sandbox/fediz/fediz-idp-sts/src/main/java/org/apache/cxf/fediz/service/sts/FileClaimsHandler.java Wed Dec 21 21:53:59 2011 @@ -0,0 +1,95 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.cxf.fediz.service.sts; + +import java.net.URI; +import java.security.Principal; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import javax.xml.ws.WebServiceContext; + +import org.apache.cxf.sts.claims.Claim; +import org.apache.cxf.sts.claims.ClaimCollection; +import org.apache.cxf.sts.claims.ClaimTypes; +import org.apache.cxf.sts.claims.ClaimsHandler; +import org.apache.cxf.sts.claims.RequestClaim; +import org.apache.cxf.sts.claims.RequestClaimCollection; + +/** + * A custom ClaimsHandler implementation for use in the tests. + */ +public class FileClaimsHandler implements ClaimsHandler { + + public static final URI ROLE = + URI.create("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role"); + + private Map> userClaims = null; + + public void setUserClaims(Map> userClaims) { + this.userClaims = userClaims; + } + + public Map> getUserClaims() { + return userClaims; + } + + @Override + public ClaimCollection retrieveClaimValues(Principal principal, RequestClaimCollection claims, WebServiceContext context, String realm) { + + if (getUserClaims() == null) { + return new ClaimCollection(); + } + + Map claimMap = getUserClaims().get(principal.getName()); + if (claimMap == null || claimMap.size() == 0) { + return new ClaimCollection(); + } + + if (claims != null && claims.size() > 0) { + ClaimCollection claimCollection = new ClaimCollection(); + for (RequestClaim requestClaim : claims) { + String claimValue = claimMap.get(requestClaim.getClaimType().toString()); + if (claimValue != null) { + Claim claim = new Claim(); + claim.setClaimType(requestClaim.getClaimType()); + claim.setIssuer("Test Issuer"); + claim.setOriginalIssuer("Original Issuer"); + claim.setValue(claimValue); + claimCollection.add(claim); + } + } + return claimCollection; + } + return null; + } + + @Override + public List getSupportedClaimTypes() { + ArrayList list = new ArrayList(); + list.add(ClaimTypes.EMAILADDRESS); + list.add(ClaimTypes.LASTNAME); + list.add(ClaimTypes.FIRSTNAME); + list.add(ROLE); + return list; + } + + + +}