1 19 20 package org.netbeans.modules.websvc.core; 21 22 import java.io.BufferedInputStream ; 23 import java.io.ByteArrayInputStream ; 24 import java.io.IOException ; 25 import java.io.InputStream ; 26 27 import java.net.ConnectException ; 28 import java.net.MalformedURLException ; 29 import java.net.URL ; 30 import java.net.URLConnection ; 31 import java.security.cert.CertificateException ; 32 import java.security.cert.X509Certificate ; 33 34 import java.text.MessageFormat ; 35 import java.util.Iterator ; 36 37 import java.util.List ; 38 import java.util.ArrayList ; 39 import javax.net.ssl.*; 40 41 import javax.swing.SwingUtilities ; 42 import org.netbeans.modules.xml.retriever.CertificationPanel; 43 import org.openide.DialogDescriptor; 44 import org.openide.DialogDisplayer; 45 import org.openide.ErrorManager; 46 47 import org.xml.sax.Attributes ; 48 import org.xml.sax.InputSource ; 49 import org.xml.sax.SAXException ; 50 import org.xml.sax.helpers.DefaultHandler ; 51 import javax.xml.parsers.SAXParser ; 52 import javax.xml.parsers.SAXParserFactory ; 53 import javax.xml.parsers.ParserConfigurationException ; 54 55 import org.openide.util.NbBundle; 56 57 58 68 public class WsdlRetriever implements Runnable { 69 70 public static final int STATUS_START = 0; 71 public static final int STATUS_CONNECTING = 1; 72 public static final int STATUS_DOWNLOADING = 2; 73 public static final int STATUS_COMPLETE = 3; 74 public static final int STATUS_FAILED = 4; 75 public static final int STATUS_TERMINATED = 5; 76 public static final int STATUS_BAD_WSDL = 6; 77 78 static final String [] STATUS_MESSAGE = { 79 NbBundle.getMessage(WsdlRetriever.class, "LBL_Ready"), NbBundle.getMessage(WsdlRetriever.class, "LBL_Connecting"), NbBundle.getMessage(WsdlRetriever.class, "LBL_Downloading"), NbBundle.getMessage(WsdlRetriever.class, "LBL_Complete"), NbBundle.getMessage(WsdlRetriever.class, "LBL_Exception"), NbBundle.getMessage(WsdlRetriever.class, "LBL_Terminated"), NbBundle.getMessage(WsdlRetriever.class, "LBL_UnknownFileType") }; 87 88 private volatile boolean shutdown; 90 private volatile int status; 91 92 private String wsdlUrlName; 94 private byte [] wsdlContent; 95 private List <SchemaInfo> schemas; 97 private String wsdlFileName; 98 private MessageReceiver receiver; 100 101 public WsdlRetriever(MessageReceiver r, String url) { 102 this.shutdown = false; 103 this.status = STATUS_START; 104 this.wsdlUrlName = url; 105 this.wsdlContent = null; 106 this.wsdlFileName = null; 107 this.schemas=null; 108 this.receiver = r; 109 } 110 111 public byte [] getWsdl() { 113 return wsdlContent; 114 } 115 116 public List <SchemaInfo> getSchemas() { 117 return schemas; 118 } 119 120 public int getState() { 121 return status; 122 } 123 124 public String getWsdlFileName() { 125 return wsdlFileName; 126 } 127 128 public String getWsdlUrl() { 129 return wsdlUrlName; 130 } 131 132 public synchronized void stopRetrieval() { 135 shutdown = true; 136 } 137 138 private URL wsdlUrl; 139 private URLConnection connection; 140 private InputStream in; 141 142 public void run() { 143 Thread.currentThread().setName("WsdlRetrieval"); 146 wsdlUrl = null; 147 connection = null; 148 in = null; 149 150 try { 151 wsdlUrlName = beautifyUrlName(wsdlUrlName); 156 wsdlUrl = new URL (wsdlUrlName); 157 setState(STATUS_CONNECTING); 158 if (wsdlUrlName.startsWith("https")) { setRetrieverTrustManager(); 160 } 161 connection = wsdlUrl.openConnection(); 162 in = connection.getInputStream(); 163 164 setState(STATUS_DOWNLOADING); 165 166 wsdlContent = downloadWsdlFileEncoded(new BufferedInputStream (in)); 168 169 WsdlInfo wsdlInfo=null; 170 if(!shutdown) { 172 wsdlInfo = getWsdlInfo(); 173 if (wsdlInfo != null) { 174 List schemaNames = wsdlInfo.getSchemaNames(); 175 if (!schemaNames.isEmpty()) { 176 schemas = new ArrayList <SchemaInfo>(); 177 Iterator it = schemaNames.iterator(); 178 while (!shutdown && it.hasNext()) { 179 String schemaName = (String )it.next(); 180 String schemaUrlName = getSchemaUrlName(wsdlUrlName,schemaName); 181 URL schemaUrl = new URL (schemaUrlName); 182 connection = schemaUrl.openConnection(); 183 in = connection.getInputStream(); 184 schemas.add(new SchemaInfo(schemaName, downloadWsdlFileEncoded(new BufferedInputStream (in)))); 185 } 186 } 187 } else { 188 throw new MalformedURLException (); 189 } 190 } 191 if (!shutdown) { 192 List serviceNames = wsdlInfo.getServiceNameList(); 194 if(serviceNames != null && serviceNames.size() > 0) { 195 wsdlFileName = wsdlUrl.getPath(); 196 int slashIndex = wsdlFileName.lastIndexOf('/'); 197 if(slashIndex != -1) { 198 wsdlFileName = wsdlFileName.substring(slashIndex+1); 199 } 200 201 if(wsdlFileName.length() == 0) { 202 wsdlFileName = (String ) serviceNames.get(0) + ".wsdl"; } else if(wsdlFileName.length() < 5 || !".wsdl".equals(wsdlFileName.substring(wsdlFileName.length()-5))) { wsdlFileName += ".wsdl"; } 206 setState(STATUS_COMPLETE); 207 } else { 208 setState(STATUS_BAD_WSDL); 210 } 211 } else { 212 setState(STATUS_TERMINATED); 213 } 214 } catch(ConnectException ex) { 215 setState(STATUS_FAILED, NbBundle.getMessage(WsdlRetriever.class, "ERR_Connection"), ex); log(ex.getMessage()); 217 } catch(MalformedURLException ex) { 218 setState(STATUS_FAILED, NbBundle.getMessage(WsdlRetriever.class, "ERR_BadUrl"), ex); log(ex.getMessage()); 220 } catch(IOException ex) { 221 setState(STATUS_FAILED, NbBundle.getMessage(WsdlRetriever.class, "ERR_IOException"), ex); log(ex.getMessage()); 223 } finally { 224 if(in != null) { 225 try { 226 in.close(); 227 } catch(IOException ex) { 228 } 229 } 230 } 231 } 232 233 244 private byte [] downloadWsdlFileEncoded(InputStream in) throws IOException { 245 ArrayList <Chunk> chunks = new ArrayList <Chunk>(); 246 final int BUF = 65536; 247 boolean eof = false; 248 byte [] data = new byte [0]; 249 250 while(!shutdown && !eof) { 251 byte [] b = new byte[BUF]; int i = 0; int l = 0; int limit = b.length; int chunksize = 0; 257 while(!shutdown && (l = in.read(b, i, limit)) != -1) { 258 limit -= l; 259 i += l; 260 chunksize += l; 261 262 if(limit == 0) { 263 break; 264 } 265 } 266 267 if(chunksize > 0) { 269 chunks.add(new Chunk(b, chunksize)); 270 } 271 272 eof = (l == -1); 273 } 274 275 if(!shutdown) { 276 int bufLen = 0; 278 Iterator <Chunk> iter = chunks.iterator(); 279 while(iter.hasNext()) { 280 bufLen += iter.next().getLength(); 281 } 282 283 data = new byte[bufLen]; 285 int index = 0; 286 iter = chunks.iterator(); 287 while(iter.hasNext()) { 288 Chunk c = iter.next(); 289 System.arraycopy(c.getData(), 0, data, index, c.getLength()); 290 index += c.getLength(); 291 } 292 } 293 294 return data; 295 } 296 297 298 public static String beautifyUrlName(String urlName) { 299 if(urlName.indexOf("://") == -1) { urlName = "http://" + urlName; } 303 304 try { 306 URL testUrl = new URL (urlName); 307 String testName = testUrl.getPath(); 308 boolean hasArguments = (testUrl.getFile().indexOf('?') != -1); 309 int slashIndex = testName.lastIndexOf('/'); 310 if(slashIndex != -1) { 311 testName = testName.substring(slashIndex+1); 312 } 313 int dotIndex = testName.lastIndexOf('.'); 314 if(dotIndex != -1) { 315 String extension = testName.substring(dotIndex+1); 316 if(!"xml".equals(extension) && !"wsdl".equals(extension) && !hasArguments) { urlName += "?WSDL"; } 319 } else if(!hasArguments) { 320 urlName = urlName + "?WSDL"; } 323 } catch(MalformedURLException ex) { 324 } 327 328 return urlName; 329 } 330 331 private String getSchemaUrlName(String wsdlUrl, String schemaName) { 332 int index = wsdlUrl.lastIndexOf("/"); if (index>=0) return wsdlUrl.substring(0,index+1)+schemaName; 334 else return null; 335 } 336 337 private void setState(int newState) { 338 status = newState; 339 log(STATUS_MESSAGE[newState]); 340 SwingUtilities.invokeLater(new MessageSender(receiver, STATUS_MESSAGE[newState])); 341 } 342 343 private void setState(int newState, String msg, Exception ex) { 344 status = newState; 345 Object [] args = new Object [] { msg, ex.getMessage()}; 346 String message = MessageFormat.format(STATUS_MESSAGE[newState], args); 347 log(message); 348 SwingUtilities.invokeLater(new MessageSender(receiver, message)); 349 } 350 351 private void log(String message) { 352 } 355 356 private static class MessageSender implements Runnable { 358 private MessageReceiver receiver; 359 private String message; 360 361 public MessageSender(MessageReceiver r, String m) { 362 receiver = r; 363 message = m; 364 } 365 366 public void run() { 367 receiver.setWsdlDownloadMessage(message); 368 } 369 } 370 371 public interface MessageReceiver { 372 public void setWsdlDownloadMessage(String m); 373 } 374 375 378 private WsdlInfo getWsdlInfo() { 379 WsdlInfo result = null; 380 381 try { 382 SAXParserFactory factory = SAXParserFactory.newInstance(); 383 factory.setNamespaceAware(true); 384 SAXParser saxParser = factory.newSAXParser(); 385 ServiceNameParser handler= new ServiceNameParser(); 386 saxParser.parse(new InputSource (new ByteArrayInputStream (wsdlContent)), handler); 387 result = new WsdlInfo(handler.getServiceNameList(),handler.getSchemaNames()); 388 } catch(ParserConfigurationException ex) { 389 } catch(SAXException ex) { 391 } catch(IOException ex) { 393 } 395 396 return result; 397 } 398 399 private static final class ServiceNameParser extends DefaultHandler { 400 401 private static final String W3C_WSDL_SCHEMA = "http://schemas.xmlsoap.org/wsdl"; private static final String W3C_WSDL_SCHEMA_SLASH = "http://schemas.xmlsoap.org/wsdl/"; 404 private List <String > serviceNameList; 405 private List <String > schemaNames; 406 407 private boolean insideSchema; 408 409 ServiceNameParser() { 410 serviceNameList = new ArrayList <String >(); 411 schemaNames = new ArrayList <String >(); 412 } 413 414 public void startElement(String uri, String localname, String qname, Attributes attributes) throws SAXException { 415 if(W3C_WSDL_SCHEMA.equals(uri) || W3C_WSDL_SCHEMA_SLASH.equals(uri)) { 416 if("service".equals(localname)) { serviceNameList.add(attributes.getValue("name")); } 419 if("types".equals(localname)) { insideSchema=true; 421 } 422 if("import".equals(localname)) { String wsdlLocation = attributes.getValue("location"); if (wsdlLocation!=null && wsdlLocation.indexOf("/")<0 && wsdlLocation.endsWith(".wsdl")) { schemaNames.add(wsdlLocation); 426 } 427 } 428 } 429 if(insideSchema && "import".equals(localname)) { String schemaLocation = attributes.getValue("schemaLocation"); if (schemaLocation!=null && schemaLocation.indexOf("/")<0 && schemaLocation.endsWith(".xsd")) { schemaNames.add(schemaLocation); 433 } 434 } 435 } 436 437 public void endElement(String uri, String localname, String qname) throws SAXException { 438 if(W3C_WSDL_SCHEMA.equals(uri) || W3C_WSDL_SCHEMA_SLASH.equals(uri)) { 439 if("types".equals(localname)) { insideSchema=false; 441 } 442 } 443 } 444 445 public List <String > getServiceNameList() { 446 return serviceNameList; 447 } 448 449 public List <String > getSchemaNames() { 450 return schemaNames; 451 } 452 } 453 454 456 private static class Chunk { 457 private int length; 458 private byte [] data; 459 460 public Chunk(byte [] d, int l) { 461 data = d; 462 length = l; 463 } 464 465 public byte [] getData() { 466 return data; 467 } 468 469 public int getLength() { 470 return length; 471 } 472 } 473 474 private static class WsdlInfo { 475 private List <String > serviceNameList; 476 private List <String > schemaNames; 477 478 WsdlInfo(List <String > serviceNameList, List <String > schemaNames) { 479 this.serviceNameList=serviceNameList; 480 this.schemaNames=schemaNames; 481 } 482 483 List <String > getSchemaNames() { 484 return schemaNames; 485 } 486 List <String > getServiceNameList() { 487 return serviceNameList; 488 } 489 } 490 491 public static class SchemaInfo { 492 private String schemaName; 493 private byte[] schemaContent; 494 495 SchemaInfo(String schemaName, byte[] schemaContent) { 496 this.schemaName=schemaName; 497 this.schemaContent=schemaContent; 498 } 499 500 public String getSchemaName() { 501 return schemaName; 502 } 503 504 public byte[] getSchemaContent() { 505 return schemaContent; 506 } 507 } 508 509 private void setRetrieverTrustManager() { 511 TrustManager[] trustAllCerts = new TrustManager[]{ 512 new X509TrustManager() { 513 public X509Certificate [] getAcceptedIssuers() { 514 return new X509Certificate [0]; 515 } 516 public void checkClientTrusted(X509Certificate [] certs, String authType) { 517 } 518 public void checkServerTrusted(X509Certificate [] certs, String authType) 519 throws CertificateException { 520 if (certs!=null) { 522 for (int i=0;i<certs.length;i++) { 523 DialogDescriptor desc = new DialogDescriptor(new CertificationPanel(certs[i]), 524 NbBundle.getMessage(WsdlRetriever.class,"TTL_CertifiedWebSite"), 525 true, 526 DialogDescriptor.YES_NO_OPTION, 527 DialogDescriptor.YES_OPTION, 528 null); 529 DialogDisplayer.getDefault().notify(desc); 530 if (!DialogDescriptor.YES_OPTION.equals(desc.getValue())) { 531 throw new CertificateException ( 532 NbBundle.getMessage(WsdlRetriever.class,"ERR_NotTrustedCertificate")); 533 } 534 } } 536 } 537 } 538 }; 539 540 541 try { 542 SSLContext sslContext = SSLContext.getInstance("SSL"); sslContext.init(null, trustAllCerts, new java.security.SecureRandom ()); 544 HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory()); 545 HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { 546 public boolean verify(String string, SSLSession sSLSession) { 547 return true; 549 } 550 }); 551 } catch (java.security.GeneralSecurityException e) { 552 ErrorManager.getDefault().notify(e); 553 } 554 555 } 556 } 557 | Popular Tags |