/* | |
* Copyright 2001-2008 The Apache Software Foundation. | |
* | |
* 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 | |
* | |
* 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. | |
* | |
*/ | |
using net.java.dev.wadl; | |
using org.apache.juddi.client.org.apache.juddi.v3.client.mapping; | |
using org.apache.juddi.v3.client.config; | |
using org.apache.juddi.v3.client.log; | |
using org.uddi.apiv3; | |
using System; | |
using System.Collections.Generic; | |
using System.Configuration; | |
using System.IO; | |
using System.Linq; | |
using System.Net; | |
using System.Text; | |
using System.Xml.Serialization; | |
namespace org.apache.juddi.v3.client.mapping | |
{ | |
/// <summary> | |
/// | |
/// This class converts a WADL document, web application description language into a | |
/// structure that more or less works within the UDDI data structures.<br><br> | |
/// <h1>Example Usage Scenario</h1> | |
/// <pre> | |
/// Application app = WADL2UDDI.parseWadl(new File("A path to your file.wadl")); | |
/// List<URL> urls = WADL2UDDI.getBaseAddresses(app); | |
/// URL url = urls.get(0); | |
/// String domain = url.getHost(); | |
/// TModel keygen = UDDIClerk.createKeyGenator("uddi:" + domain + ":keygenerator", domain, "en"); | |
/// //save the keygen | |
/// SaveTModel stm = new SaveTModel(); | |
/// stm.setAuthInfo(rootAuthToken.getAuthInfo()); | |
/// stm.getTModel().add(keygen); | |
/// properties.put("keyDomain", domain); | |
/// properties.put("businessName", domain); | |
/// properties.put("serverName", url.getHost()); | |
/// properties.put("serverPort", url.getPort()); | |
/// WADL2UDDI wadl2UDDI = new WADL2UDDI(null, new URLLocalizerDefaultImpl(), properties); | |
/// BusinessService businessServices = wadl2UDDI.createBusinessService(new QName("MyWasdl.namespace", "Servicename"), app); | |
/// Set<TModel> portTypeTModels = wadl2UDDI.createWADLPortTypeTModels(wsdlURL, app); | |
/// //Since the service depends on the tModel, we have to save the tModels first | |
/// SaveTModel tms = new SaveTModel(); | |
/// TModel[] tmodels = portTypeTModels.toArray(new TModel[0]); | |
/// for (int i = 0; i < tmodels.length; i++) { | |
/// System.out.println(tmodelPrinter.print(tmodels[i])); | |
/// tms.getTModel().add(tmodels[i]); | |
/// } | |
/// //important, you'll need to save your new tModels, or else saving the business/service may fail | |
/// publish.saveTModel(stm); | |
/// //finaly, we're ready to save all of the services defined in the WSDL | |
/// //again, we're creating a new business, if you have one already, look it up using the Inquiry getBusinessDetails | |
/// PrintUDDI<BusinessService> servicePrinter = new PrintUDDI<BusinessService>(); | |
/// System.out.println(servicePrinter.print(businessServices)); | |
/// SaveBusiness sb = new SaveBusiness(); | |
/// sb.setAuthInfo(rootAuthToken.getAuthInfo()); | |
/// BusinessEntity be = new BusinessEntity(); | |
/// be.setBusinessKey(businessServices.getBusinessKey()); | |
/// be.getName().add(new Name()); | |
/// //TODO, use some relevant here | |
/// be.getName().get(0).setValue(domain); | |
/// be.getName().get(0).setLang("en"); | |
/// be.setBusinessServices(new BusinessServices()); | |
/// be.getBusinessServices().getBusinessService().add(businessServices); | |
/// sb.getBusinessEntity().add(be); | |
/// PrintUDDI<SaveBusiness> sbp = new PrintUDDI<SaveBusiness>(); | |
/// System.out.println("Request " + sbp.print(sb)); | |
/// publish.saveBusiness(sb); | |
/// //and we're done | |
/// //Be sure to report any problems to the jUDDI JIRA bug tracker at | |
/// //https://issues.apache.org/jira/browse/JUDDI | |
/// </pre> | |
/// | |
/// @author <a href="mailto:alexoree@apache.org">Alex O'Ree</a> | |
public class WADL2UDDI | |
{ | |
private static Log log = LogFactory.getLog(typeof(WADL2UDDI)); | |
private String keyDomainURI; | |
private String businessKey; | |
private String lang; | |
private UDDIClerk clerk = null; | |
private Properties properties = null; | |
public WADL2UDDI(UDDIClerk clerk, Properties properties) | |
{ | |
this.clerk = clerk; | |
this.properties = properties; | |
if (clerk != null) | |
{ | |
if (!properties.containsKey("keyDomain")) | |
{ | |
throw new ConfigurationErrorsException("Property keyDomain is a required property when using WADL2UDDI."); | |
} | |
if (!properties.containsKey("businessKey") && !properties.containsKey("businessName")) | |
{ | |
throw new ConfigurationErrorsException("Either property businessKey, or businessName, is a required property when using WADL2UDDI."); | |
} | |
if (!properties.containsKey("nodeName")) | |
{ | |
if (properties.containsKey("serverName") && properties.containsKey("serverPort")) | |
{ | |
String nodeName = properties.getProperty("serverName") + "_" + properties.getProperty("serverPort"); | |
properties.setProperty("nodeName", nodeName); | |
} | |
else | |
{ | |
throw new ConfigurationErrorsException("Property nodeName is not defined and is a required property when using WADL2UDDI."); | |
} | |
} | |
} | |
//Obtaining values from the properties | |
this.keyDomainURI = "uddi:" + properties.getProperty("keyDomain") + ":"; | |
if (properties.containsKey(Property.BUSINESS_KEY)) | |
{ | |
this.businessKey = properties.getProperty(Property.BUSINESS_KEY); | |
} | |
else | |
{ | |
//using the BusinessKey Template, and the businessName to construct the key | |
this.businessKey = UDDIKeyConvention.getBusinessKey(properties); | |
} | |
this.lang = properties.getProperty(Property.LANG, Property.DEFAULT_LANG); | |
} | |
public HashSet<tModel> createWADLTModels(String wadlURL, application app) | |
{ | |
HashSet<tModel> tModels = new HashSet<tModel>(); | |
return tModels; | |
} | |
public HashSet<tModel> createWADLPortTypeTModels(String wadlURL, application app) | |
{ | |
HashSet<tModel> tModels = new HashSet<tModel>(); | |
// Create a tModel for each portType | |
return tModels; | |
} | |
public String getKeyDomainURI() | |
{ | |
return keyDomainURI; | |
} | |
public void setKeyDomain(String keyDomainURI) | |
{ | |
this.keyDomainURI = keyDomainURI; | |
} | |
public String getLang() | |
{ | |
return lang; | |
} | |
public void setLang(String lang) | |
{ | |
this.lang = lang; | |
} | |
private static String ContentToString(List<Object> content) | |
{ | |
StringBuilder sb = new StringBuilder(); | |
for (int i = 0; i < content.Count; i++) | |
{ | |
sb.Append(content[i].ToString()).Append(" "); | |
} | |
return sb.ToString().Trim(); | |
} | |
/** | |
* Creates a UDDI Business Service. | |
* | |
* @param serviceQName This must be specified to identify the namespace of | |
* the service, which is used to set the service uddi key | |
* @param waldDefinition | |
* @return | |
*/ | |
public businessService createBusinessService(QName serviceQName, application wadlDefinition) | |
{ | |
log.debug("Constructing Service UDDI Information for " + serviceQName); | |
businessService service = new businessService(); | |
// BusinessKey | |
service.businessKey = (businessKey); | |
// ServiceKey | |
service.serviceKey = (UDDIKeyConvention.getServiceKey(properties, serviceQName.getLocalPart())); | |
// Description | |
String serviceDescription = properties.getProperty(Property.SERVICE_DESCRIPTION, Property.DEFAULT_SERVICE_DESCRIPTION); | |
// Override with the service description from the WSDL if present | |
bool lengthwarn = false; | |
List<description> ds = new List<description>(); | |
if (wadlDefinition.doc != null) | |
{ | |
for (int i = 0; i < wadlDefinition.doc.Length; i++) | |
{ | |
String locallang = lang; | |
description description = new description(); | |
if (wadlDefinition.doc[i].lang != null) | |
{ | |
locallang = (wadlDefinition.doc[i].lang); | |
} | |
if (locallang.Length > UDDIConstants.MAX_xml_lang_length) | |
{ | |
lengthwarn = true; | |
locallang = (locallang.Substring(0, UDDIConstants.MAX_xml_lang_length - 1)); | |
} | |
StringBuilder sb = new StringBuilder(); | |
sb.Append(wadlDefinition.doc[i].title).Append(" "); | |
sb.Append(ContentToString(wadlDefinition.doc[i].Any)); | |
ds.AddRange(Common2UDDI.mapdescription(sb.ToString(), locallang)); | |
} | |
} | |
else | |
{ | |
ds.AddRange(Common2UDDI.mapdescription(serviceDescription, lang)); | |
} | |
service.description = ds.ToArray(); | |
// Service name | |
name sName = new name(); | |
sName.lang = (lang); | |
if (wadlDefinition.doc != null && wadlDefinition.doc.Length > 0) | |
{ | |
sName.Value = (wadlDefinition.doc[0].title); | |
} | |
if (sName.Value == null) | |
{ | |
sName.Value = (serviceQName.getLocalPart()); | |
} | |
service.name = new name[] { sName }; | |
categoryBag cb = new categoryBag(); | |
List<keyedReference> krs = new List<keyedReference>(); | |
String ns = serviceQName.getNamespaceURI(); | |
if (ns != null && ns != "") | |
{ | |
keyedReference namespaceReference = new keyedReference( | |
"uddi:uddi.org:xml:namespace", "uddi-org:xml:namespace", ns); | |
krs.Add(namespaceReference); | |
} | |
keyedReference serviceReference = new keyedReference( | |
"uddi:uddi.org:wadl:types", "uddi-org:wadl:types", "service"); | |
krs.Add(serviceReference); | |
keyedReference localNameReference = new keyedReference( | |
"uddi:uddi.org:xml:localname", "uddi-org:xml:localName", serviceQName.getLocalPart()); | |
krs.Add(localNameReference); | |
cb.Items = krs.ToArray(); | |
service.categoryBag = (cb); | |
if (wadlDefinition.resources != null) | |
for (int i = 0; i < wadlDefinition.resources.Length; i++) | |
{ | |
bindingTemplate bindingTemplate = createWADLBinding(serviceQName, getDocTitle(wadlDefinition.resources[i].doc), | |
new Uri(wadlDefinition.resources[i].@base), wadlDefinition.resources[i]); | |
service.bindingTemplates = new bindingTemplate[] { bindingTemplate }; | |
} | |
if (lengthwarn) | |
{ | |
log.warn("Some object descriptions are longer than the maximum allowed by UDDI and have been truncated."); | |
} | |
return service; | |
} | |
private string getDocTitle(doc[] doc) | |
{ | |
if (doc == null || doc.Length == 0 || doc[0].title == null) | |
{ | |
return "A resource base URL without a description"; | |
} | |
return (doc[0].title); | |
} | |
private string ContentToString(System.Xml.XmlNode[] xmlNode) | |
{ | |
if (xmlNode == null) return ""; | |
StringBuilder sb = new StringBuilder(); | |
for (int i = 0; i < xmlNode.Length; i++) | |
{ | |
sb.Append(xmlNode[i].Value); | |
} | |
return sb.ToString(); | |
} | |
public static List<Uri> GetBaseAddresses(application app) | |
{ | |
List<Uri> urls = new List<Uri>(); | |
if (app == null) return urls; | |
if (app.resources != null) | |
for (int i = 0; i < app.resources.Length; i++) | |
{ | |
try | |
{ | |
urls.Add(new Uri(app.resources[i].@base)); | |
} | |
catch (Exception ex) | |
{ | |
log.warn("The base URL " + app.resources[i].@base + " is invalid or could not be parsed", ex); | |
} | |
} | |
return urls; | |
} | |
protected bindingTemplate createWADLBinding(QName serviceQName, String portName, Uri serviceUrl, resources res) | |
{ | |
bindingTemplate bindingTemplate = new bindingTemplate(); | |
// Set BusinessService Key | |
bindingTemplate.serviceKey = (UDDIKeyConvention.getServiceKey(properties, serviceQName.getLocalPart())); | |
List<tModelInstanceInfo> items = new List<tModelInstanceInfo>(); | |
if (serviceUrl != null) | |
{ | |
// Set AccessPoint | |
accessPoint accessPoint = new accessPoint(); | |
accessPoint.useType = (AccessPointType.endPoint.ToString()); | |
accessPoint.Value = ((serviceUrl.ToString())); | |
bindingTemplate.Item = (accessPoint); | |
// Set Binding Key | |
String bindingKey = UDDIKeyConvention.getBindingKey(properties, serviceQName, portName, serviceUrl); | |
bindingTemplate.bindingKey = (bindingKey); | |
bindingTemplate.description = Common2UDDI.mapdescription(getDescription(res.doc), lang).ToArray(); | |
// reference wsdl:binding tModel | |
tModelInstanceInfo tModelInstanceInfoBinding = new tModelInstanceInfo(); | |
tModelInstanceInfoBinding.tModelKey = (keyDomainURI + "binding"); | |
instanceDetails id = new instanceDetails(); | |
id.instanceParms= portName ; | |
tModelInstanceInfoBinding.instanceDetails = (id); | |
tModelInstanceInfoBinding.description = Common2UDDI.mapdescription("The binding that this endpoint implements. " + bindingTemplate.description[0].Value | |
+ " The instanceParms specifies the port local name.", lang).ToArray(); | |
items.Add(tModelInstanceInfoBinding); | |
tModelInstanceInfo tModelInstanceInfoPortType = new tModelInstanceInfo(); | |
tModelInstanceInfoPortType.tModelKey = (keyDomainURI + "rest"); | |
tModelInstanceInfoPortType.description = Common2UDDI.mapdescription("The wadl:Resource:base implements.", lang).ToArray(); | |
items.Add(tModelInstanceInfoPortType); | |
} | |
bindingTemplate.tModelInstanceDetails = items.ToArray(); | |
return bindingTemplate; | |
} | |
private string getDescription(doc[] doc) | |
{ | |
if (doc == null) return "No Description."; | |
StringBuilder sb = new StringBuilder(); | |
for (int i = 0; i < doc.Length; i++) | |
{ | |
sb.Append(doc[i].title).Append(" "); | |
sb.Append(ContentToString(doc[i].Any)); | |
} | |
return sb.ToString().Trim(); | |
} | |
public const String PACKAGE = "org.apache.juddi.v3.client.mappings.wadl"; | |
/// <summary> | |
/// used to ignore SSL errors | |
/// </summary> | |
/// <param name="sender"></param> | |
/// <param name="certification"></param> | |
/// <param name="chain"></param> | |
/// <param name="sslPolicyErrors"></param> | |
/// <returns></returns> | |
public bool AcceptAllCertifications(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certification, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors) | |
{ | |
return true; | |
} | |
/** | |
* Parses a web accessible WADL file | |
* @param weburl | |
* @param username | |
* @param password | |
* @param ignoreSSLErrors if true, SSL errors are ignored | |
* @return a non-null "application" object, represeting a WADL's application root XML | |
* Sample code: | |
* <example> | |
* application app = WADL2UDDI.ParseWadl(new URL("http://server/wsdl.wsdl"), "username", "password", | |
* clerkManager.getClientConfig().isX_To_Wsdl_Ignore_SSL_Errors() ); | |
* </example> | |
*/ | |
public application ParseWadl(Uri weburl, String username, String password, bool ignoreSSLErrors) | |
{ | |
WebClient httpclient = null; | |
application unmarshal = null; | |
try | |
{ | |
String url = weburl.ToString(); | |
if (!url.ToLower().StartsWith("http")) | |
{ | |
return ParseWadl(weburl); | |
} | |
bool usessl = false; | |
int port = 80; | |
if (url.ToString().ToLower().StartsWith("https://")) | |
{ | |
port = 443; | |
usessl = true; | |
} | |
if (weburl.Port > 0) | |
{ | |
port = weburl.Port; | |
} | |
if (ignoreSSLErrors && usessl) | |
{ | |
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(AcceptAllCertifications); | |
httpclient = new WebClient(); | |
} | |
else | |
{ | |
httpclient = new WebClient(); | |
} | |
if (username != null && username.Length > 0 | |
&& password != null && password.Length > 0) | |
{ | |
httpclient.Credentials = new NetworkCredential(username, password); | |
} | |
try | |
{ | |
String wadl = httpclient.DownloadString(url); | |
XmlSerializer xs = new XmlSerializer(typeof(application)); | |
StringReader sr = new StringReader(wadl); | |
unmarshal = (application)xs.Deserialize(sr); | |
} | |
finally | |
{ | |
httpclient.Dispose(); | |
} | |
} | |
catch (Exception e) | |
{ | |
log.error("error downloading " + weburl, e); | |
} | |
finally | |
{ | |
if (httpclient != null) | |
{ | |
httpclient.Dispose(); | |
} | |
} | |
return unmarshal; | |
} | |
/// <summary> | |
/// will parse a file from the disk and parse it, returns null if an error occurs and logs it | |
/// </summary> | |
/// <param name="file"></param> | |
/// <returns></returns> | |
public static application ParseWadl(String file) | |
{ | |
try | |
{ | |
XmlSerializer xs = new XmlSerializer(typeof(application)); | |
String s = File.ReadAllText(file); | |
StringReader sr = new StringReader(s); | |
return (application)xs.Deserialize(sr); | |
} | |
catch (Exception ex) | |
{ | |
log.error("error parsing file", ex); | |
} | |
return null; | |
} | |
/// <summary> | |
/// will download a file from the network/internet and parse it, returns null if an error occurs and logs it | |
/// </summary> | |
/// <param name="file"></param> | |
/// <returns></returns> | |
public static application ParseWadl(Uri file) | |
{ | |
if (file.OriginalString.StartsWith("http")) | |
{ | |
try | |
{ | |
WebClient c = new WebClient(); | |
String content = c.DownloadString(file); | |
StringReader sr = new StringReader(content); | |
XmlSerializer xs = new XmlSerializer(typeof(application)); | |
c.Dispose(); | |
return (application)xs.Deserialize(sr); | |
} | |
catch (Exception ex) | |
{ | |
log.error("error parsing file", ex); | |
} | |
return null; | |
} | |
else | |
return ParseWadl(file.ToString()); | |
} | |
private string getDescription(List<doc> doc) | |
{ | |
StringBuilder sb = new StringBuilder(); | |
for (int i = 0; i < doc.Count; i++) | |
{ | |
sb.Append(doc[i].title).Append(" "); | |
sb.Append(ContentToString(doc[i].Any)); | |
} | |
return sb.ToString().Trim(); | |
} | |
} | |
public class QName | |
{ | |
string local; | |
string ns; | |
public QName() { } | |
public QName(string ns, string local) | |
{ | |
this.local = local; | |
this.ns = ns; | |
} | |
public string getLocalPart() | |
{ | |
return local; | |
} | |
public string getNamespaceURI() | |
{ | |
return ns; | |
} | |
} | |
} |