/******************************************************************************* * Copyright (c) 2006-2010 eBay Inc. All Rights Reserved. * Licensed 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 *******************************************************************************/ package org.ebayopensource.turmeric.runtime.config.validation.verifiers; import java.io.File; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import org.apache.commons.lang.StringUtils; import org.ebayopensource.turmeric.runtime.config.validation.AbstractVerifier; import org.jaxen.JaxenException; import org.jaxen.XPath; import org.jaxen.jdom.JDOMXPath; import org.jdom.Document; import org.jdom.Element; import org.jdom.Namespace; public class WsdlVerifier extends AbstractVerifier { private static final Logger LOG = Logger.getLogger(WsdlVerifier.class.getName()); private static final String LEGACY_MARKETPLACE_NAMESPACE = "http://www.ebay.com/marketplace/services"; private static final String MARKETPLACE_NAMESPACE = "http://www.ebayopensource.org/turmeric/common/v1/types"; @Override public String getFileRegex() { return "META-INF/soa/services/wsdl/([^/]+)/([^|\\\\/:\\?\\*]+)\\.wsdl"; } @Override public void verifyHit(File hit) { LOG.fine("Verifying: " + hit); try { Document doc = xmlParse(hit); if (!validRootElement(hit, doc, "definitions", "http://schemas.xmlsoap.org/wsdl/")) { return; } Element root = doc.getRootElement(); Namespace defNs = root.getNamespace(); Namespace xsNs = findNamespace(root, "http://www.w3.org/2001/XMLSchema"); // Validate TypeLibrary namespace declarations if (xsNs != null) { Map<String, String> expectedTypes = new HashMap<String, String>(); expectedTypes.put("common-type-library", "http://www.ebayopensource.org/turmeric/common/v1/types"); validateTypeLibrarySources(hit, root, defNs, xsNs, expectedTypes); } // Validate <xs:schema> marketplace namespace declarations validateSchemaMarketplaceNamespace(hit, root, defNs, xsNs); } catch (Exception e) { LOG.log(Level.WARNING, "Unable to parse XML: " + hit, e); } } private void validateSchemaMarketplaceNamespace(File hit, Element root, Namespace defNs, Namespace xsNs) throws JaxenException { XPath expr = new JDOMXPath("//xs:schema"); expr.addNamespace("xs", xsNs.getURI()); expr.addNamespace("d", defNs.getURI()); @SuppressWarnings("unchecked") List<Element> nodes = expr.selectNodes(root); for (Element elem : nodes) { @SuppressWarnings("unchecked") List<Namespace> nslist = elem.getAdditionalNamespaces(); for (Namespace ns : nslist) { if (ns.getURI().equals(LEGACY_MARKETPLACE_NAMESPACE)) { report.violation(calculateXpathRefish(elem) + "[@xmlns:" + ns.getPrefix() + "]", "Bad marketplace namespace declaration \"%s\" use \"%s\" instead.", LEGACY_MARKETPLACE_NAMESPACE, MARKETPLACE_NAMESPACE); } } } } private void validateTypeLibrarySources(File hit, Element root, Namespace defNs, Namespace xsNs, Map<String, String> expectedTypes) throws JaxenException { XPath expr = new JDOMXPath("//xs:appinfo/d:typeLibrarySource"); expr.addNamespace("xs", xsNs.getURI()); expr.addNamespace("d", defNs.getURI()); @SuppressWarnings("unchecked") List<Element> nodes = expr.selectNodes(root); String library, libNamespace, expectedNamespace; for (Element elem : nodes) { library = elem.getAttributeValue("library"); libNamespace = elem.getAttributeValue("namespace"); expectedNamespace = expectedTypes.get(library); if (StringUtils.isNotBlank(expectedNamespace)) { // Perform specific validation report.violation(calculateXpathRefish(elem), "Bad typeLibrarySource namespace \"%s\" expected \"%s\" for library \"%s\"", libNamespace, expectedNamespace, library); continue; } // Perform basic marketplace validation on other unspecified libraries if(libNamespace.equals(LEGACY_MARKETPLACE_NAMESPACE)) { report.violation(calculateXpathRefish(elem), "Bad typeLibrarySource namespace \"%s\" expected \"%s\" for library \"%s\"", libNamespace, MARKETPLACE_NAMESPACE, library); } } } private Namespace findNamespace(Element elem, String uri) { @SuppressWarnings("unchecked") List<Namespace> nslist = elem.getAdditionalNamespaces(); for (Namespace ns : nslist) { if (ns.getURI().equals(uri)) { return ns; } } return null; } }