1 19 20 package org.netbeans.modules.autoupdate; 21 22 import java.io.UnsupportedEncodingException ; 23 import java.net.MalformedURLException ; 24 import java.net.URL ; 25 import java.net.URLEncoder ; 26 import java.text.MessageFormat ; 27 import java.text.ParseException ; 28 import java.util.StringTokenizer ; 29 import java.io.IOException ; 30 import java.io.InputStream ; 31 import java.io.InputStreamReader ; 32 import java.io.Reader ; 33 import java.net.URLConnection ; 34 import java.text.DateFormat ; 35 import java.text.SimpleDateFormat ; 36 import java.util.Collections ; 37 import java.util.Date ; 38 import java.util.MissingResourceException ; 39 import java.util.ResourceBundle ; 40 import java.util.concurrent.Callable ; 41 import java.util.logging.Level ; 42 import java.util.logging.LogRecord ; 43 import java.util.logging.Logger ; 44 import org.openide.util.NbBundle; 45 import org.openide.filesystems.FileObject; 46 import org.openide.filesystems.FileStateInvalidException; 47 import org.openide.filesystems.FileSystem; 48 import org.openide.util.Exceptions; 49 import org.openide.util.HelpCtx; 50 51 55 public class XMLAutoupdateType extends AutoupdateType { 56 57 final static String PROP_URL_SPEC = "urlSpec"; final static String PROP_URL = "URL"; 60 61 private String urlSpec; 62 private URL url; 63 64 65 private String defaultURL; 66 67 68 private static final String UPDATE_VERSION_PROP = "netbeans.autoupdate.version"; 70 71 private static final String IDE_HASH_CODE = "netbeans.hash.code"; 73 74 public static final String UPDATE_VERSION = "1.18"; 76 77 private static final String SYSPROP_COUNTRY = "netbeans.autoupdate.country"; private static final String SYSPROP_LANGUAGE = "netbeans.autoupdate.language"; private static final String SYSPROP_VARIANT = "netbeans.autoupdate.variant"; private static final String TIME_STAMP_ATTRIBUTE_NAME = "timestamp"; private static final String TIME_STAMP_FORMAT = "ss/mm/hh/dd/MM/yyyy"; 83 private static final Logger err = Logger.getLogger("org.netbeans.modules.autoupdate"); 85 86 static final long serialVersionUID = 362844553432169452L; 87 88 89 private String displayName = null; 90 91 private FileObject typeFileObject = null; 92 93 94 private String url_key; 95 96 97 private String localizingBundleName; 98 99 private boolean valid = true; 100 101 102 public XMLAutoupdateType() { 103 urlSpec = getDefaultURL (); 104 } 105 106 public XMLAutoupdateType(URL url) { 107 this.urlSpec = url.toExternalForm (); 108 } 109 110 public XMLAutoupdateType(URL url, String displayName, String url_key, Boolean enabled) { 111 this( url, displayName, null, url_key, enabled ); 112 } 113 114 public XMLAutoupdateType(URL url, String displayName, FileObject fo, String url_key, Boolean enabled) { 115 this (url, displayName, fo, url_key, enabled, null); 116 } 117 118 public XMLAutoupdateType(URL url, String displayName, FileObject fo, String url_key, Boolean enabled, String localizingBundleName) { 119 this.typeFileObject = fo; 120 this.urlSpec = url.toExternalForm (); 121 this.displayName = displayName; 122 this.url_key = url_key; 123 this.localizingBundleName = localizingBundleName; 124 125 if ( enabled != null ) 126 setEnabled( enabled.booleanValue() ); 127 } 128 129 public static XMLAutoupdateType createXMLAutoupdateType(FileObject fo) throws IOException { 130 URL url; 131 String sKey = (String )fo.getAttribute("url_key"); String remoteBundleName = (String )fo.getAttribute ("SystemFileSystem.localizingBundle"); ResourceBundle bundle = getBundleFromName (remoteBundleName); 134 if (sKey != null) { 135 String localizedValue; 136 try { 137 localizedValue = bundle.getString (sKey); 138 } catch (MissingResourceException mre) { 139 localizedValue = "http://"; } 141 url = new URL (localizedValue); 143 } else { 144 Object o = fo.getAttribute("url"); if (o instanceof String ) { 146 url = new URL ((String )o); 147 } else { 148 url = (URL )o; 149 } 150 } 151 152 Boolean en = (Boolean )fo.getAttribute("enabled"); 153 154 return new XMLAutoupdateType( url, null, fo, sKey, en, remoteBundleName ); 155 } 156 157 158 public String displayName() { 159 if (displayName == null) { 160 if (typeFileObject != null) { 161 try { 162 FileSystem fs = typeFileObject.getFileSystem(); 163 FileSystem.Status s = fs.getStatus(); 164 String x = s.annotateName("", Collections.singleton(typeFileObject)); if (!x.equals("")) { displayName = x; 167 } 168 } catch (FileStateInvalidException e) { 169 } 171 } 172 if (displayName == null) { 173 displayName = NbBundle.getBundle( Settings.class).getString("CTL_XMLAutoupdateType_Name"); 174 } 175 } 176 return displayName; 177 } 178 179 183 public String getUrlSpec () { 184 return urlSpec; 185 } 186 187 191 public void setUrlSpec (String spec) { 192 try { 193 new URL (spec); 195 } catch (MalformedURLException ex) { 196 class UserIllegalException extends IllegalArgumentException implements Callable { 197 public UserIllegalException(String s) { 198 super(s); 199 } 200 public Object call() throws Exception { 201 LogRecord r = new LogRecord (OwnLevel.USER, getMessage()); 202 return new LogRecord [] { r }; 203 } 204 } 205 206 IllegalArgumentException iae = new UserIllegalException(ex.getMessage()); 207 String msg = MessageFormat.format( 208 NbBundle.getMessage(XMLAutoupdateType.class, "FMT_EXC_BAD_URL"), new Object [] {spec} 210 ); 211 Exceptions.attachLocalizedMessage(iae, msg); 212 throw iae; 213 } 214 215 String old = this.urlSpec; 216 this.urlSpec = spec; 217 firePropertyChange (PROP_URL_SPEC, old, urlSpec); 218 } 219 220 224 public URL getURL() { 225 URL url = null; 226 try { 227 url = new URL (this.getUrlSpec()); 228 } catch (MalformedURLException ex) { 229 assert false : ex; 230 } 231 return url; 232 } 233 234 238 public void setURL(URL url) { 239 if (url != null) { 240 this.setUrlSpec (url.toExternalForm ()); 241 } else { 242 this.setUrlSpec (null); 243 } 244 } 245 246 public HelpCtx getHelpCtx () { 247 return new HelpCtx( org.netbeans.modules.autoupdate.XMLAutoupdateType.class ); 248 } 249 250 public Updates connectForUpdates() { 251 URL url = null; 252 try { 253 url = new URL (getUrlSpec()); 254 } catch (MalformedURLException ex) { 255 assert false : ex; 256 } 257 return new XMLUpdates( modifyURL (url)); 258 } 259 260 261 protected URL modifyURL (URL original) { 262 263 URL updateURL = null; 264 265 if ( System.getProperty( UPDATE_VERSION_PROP ) == null ) { 266 System.setProperty( UPDATE_VERSION_PROP, UPDATE_VERSION ); 267 } 268 269 if (System.getProperty (IDE_HASH_CODE) == null) { 270 String id = ""; try { 272 id = Settings.getShared ().getIdeIdentity (); 273 } catch (NullPointerException npe) { 274 Logger.getAnonymousLogger().warning("Property PROP_IDE_IDENTITY hasn't been initialized yet."); } 277 String prefix = NbBundle.getBundle (XMLAutoupdateType.class).getString ("URL_Prefix_Hash_Code"); System.setProperty (IDE_HASH_CODE, "".equals (id) ? prefix + "0" : prefix + id); } 280 281 try { 282 updateURL = new URL ( encode( replace( original.toString() ) ) ); 283 } 284 catch (java.net.MalformedURLException e) { 285 Exceptions.printStackTrace(e); 286 } 287 288 return updateURL; 289 290 } 291 292 295 296 protected String replace( String string ) { 297 298 setSystemProperties(); 300 301 if ( string == null ) 302 return null; 303 304 StringBuffer sb = new StringBuffer (); 305 306 int index, prevIndex; 307 index = prevIndex = 0; 308 while( ( index = string.indexOf( "{", index )) != -1 && index < string.length() - 1) { 310 if ( string.charAt( index + 1 ) == '{' || string.charAt( index + 1 ) != '$' ) { 311 ++index; 312 continue; 313 } 314 315 sb.append( string.substring( prevIndex, index ) ); 316 int endBracketIndex = string.indexOf( "}", index ); if ( endBracketIndex != -1 ) { 318 String whatToReplace = string.substring( index + 2, endBracketIndex ); 319 sb.append( getReplacement(whatToReplace) ); 320 } 321 prevIndex = endBracketIndex == -1 ? index + 2 : endBracketIndex + 1; 322 ++index; 323 } 324 325 if ( prevIndex < string.length() - 1 ) 326 sb.append( string.substring( prevIndex ) ); 327 328 return sb.toString(); 329 } 330 331 boolean isValid () { 332 return valid; 333 } 334 335 337 protected String getReplacement(String whatToReplace) { 338 return System.getProperty( whatToReplace, "" ); 339 } 340 341 protected String encode(String stringURL) { 342 String rval = stringURL; 343 int q = stringURL.indexOf('?'); 344 if(q > 0) { 345 StringBuffer buf = new StringBuffer (stringURL.substring(0, q+1)); 346 StringTokenizer st = new StringTokenizer (stringURL.substring(q + 1), "&"); 347 while(st.hasMoreTokens()) { 348 String a = st.nextToken(); 349 try { 350 int ei = a.indexOf('='); 351 if(ei < 0) { 352 buf.append(URLEncoder.encode(a, "UTF-8")); 353 } else { 354 buf.append(URLEncoder.encode(a.substring(0, ei), "UTF-8")); 355 buf.append('='); 356 String tna = a.substring(ei+1); 357 int tni = tna.indexOf("%"); 358 if( tni < 0) { 359 buf.append(URLEncoder.encode(tna, "UTF-8")); 360 } else { 361 buf.append(URLEncoder.encode(tna.substring(0, tni), "UTF-8")); 362 buf.append('%'); 363 buf.append(URLEncoder.encode(tna.substring(tni+1), "UTF-8")); 364 } 365 } 366 } catch (UnsupportedEncodingException ex) { 367 err.log (Level.INFO, ex.getMessage (), ex); 368 } 369 if (st.hasMoreTokens()) 370 buf.append('&'); 371 } 372 rval = buf.toString(); 373 } 374 375 return rval; 376 } 377 378 382 Boolean hasNewContent () { 383 InputStream is = null; 384 Date timeStamp = null; 385 try { 386 URL url = modifyURL (new URL (getUrlSpec ())); 387 err.log (Level.FINER, "Found Update Center " + getName () + "[" + url + "]"); 388 URLConnection conn = url.openConnection (); 389 is = conn.getInputStream (); 390 Reader r = new InputStreamReader (is); 391 StringBuffer sb = new StringBuffer (1024); 392 393 int c; 394 while ((c = is.read ()) != -1 && sb.length () < 1024) { 395 sb.append ((char) c); 396 } 397 err.log (Level.FINER, "Successfully checked " + url); 399 String content = sb.toString (); 400 String time = null; 401 int pos; 402 if ((pos = content.indexOf (TIME_STAMP_ATTRIBUTE_NAME)) != -1) { 403 content = content.substring (pos + TIME_STAMP_ATTRIBUTE_NAME.length () + 1 + 1); 404 if ((pos = content.indexOf ('>')) != -1) { 405 time = content.substring (0, pos - 1); 406 } 407 } 408 409 DateFormat format = new SimpleDateFormat (TIME_STAMP_FORMAT); 410 timeStamp = format.parse (time); 411 err.log (Level.FINER, "Successfully read time " + timeStamp); 413 err.log (Level.FINER, "Last Time Stamp on " + getName () + " is " + getLastTimeStamp ()); 414 415 416 } catch (MalformedURLException ex) { 417 err.log (Level.FINE, null, ex); 418 } catch (IOException ioe) { 419 err.log (Level.FINE, null, ioe); 420 } catch (ParseException ex) { 421 err.log (Level.FINE, null, ex); 422 } finally { 423 if (is != null) { 424 try { 425 is.close (); 426 } catch (IOException ex) { 427 err.log (Level.FINE, null, ex); 428 } 429 } 430 } 431 432 if (getLastTimeStamp () == null) { 433 return Boolean.TRUE; 434 } 435 436 return timeStamp == null ? null : (timeStamp.after (getLastTimeStamp ()) ? Boolean.TRUE : Boolean.FALSE); 437 438 } 439 440 441 private static ResourceBundle getOldLocalizingBundle () { 442 return NbBundle.getBundle (XMLAutoupdateType.class); 443 } 444 445 private static ResourceBundle getBundleFromName (String name) throws MissingResourceException { 446 ResourceBundle bundle = null; 447 if (name == null) { 448 bundle = getOldLocalizingBundle (); 449 } else { 450 bundle = NbBundle.getBundle (name); 451 } 452 return bundle; 453 } 454 455 private static void setSystemProperties() { 456 457 if ( System.getProperty( SYSPROP_COUNTRY, null ) == null ) { 458 System.setProperty( SYSPROP_COUNTRY, java.util.Locale.getDefault().getCountry() ); 459 } 460 if ( System.getProperty( SYSPROP_LANGUAGE, null ) == null ) { 461 System.setProperty( SYSPROP_LANGUAGE, java.util.Locale.getDefault().getLanguage() ); 462 } 463 if ( System.getProperty( SYSPROP_VARIANT, null ) == null ) { 464 System.setProperty( SYSPROP_VARIANT, java.util.Locale.getDefault().getVariant() ); 465 } 466 } 467 468 protected String getDefaultURL() { 469 if ( defaultURL == null ) { 470 ResourceBundle remoteBundle = null; 471 try { 472 remoteBundle = getBundleFromName (localizingBundleName); 473 defaultURL = url_key != null ? remoteBundle.getString( url_key ) : remoteBundle.getString( "URL_Default_N" ); 474 } catch (MissingResourceException mre) { 475 this.valid = false; 479 return null; 480 } 481 } 483 return defaultURL; 484 } 485 486 private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { 487 if (urlSpec.equals (getDefaultURL ())) { 488 out.writeObject( null ); 489 } else { 490 out.writeObject( urlSpec ); 491 } 492 out.writeObject( displayName ); 493 out.writeObject( url_key ); 494 out.writeObject( localizingBundleName ); 495 } 496 497 private void readObject(java.io.ObjectInputStream in) throws java.io.IOException , 498 ClassNotFoundException { 499 try { 500 valid = true; 502 503 Object urlObject = in.readObject(); 504 if (urlObject != null) { 505 if (urlObject instanceof URL ) { 506 urlSpec = ((URL ) urlObject).toExternalForm (); 507 } else { 508 assert urlObject instanceof String ; 509 urlSpec = (String ) urlObject; 510 } 511 } 512 513 String display = (String )in.readObject(); 514 if (display != null) 515 displayName = display; 516 517 String key = (String )in.readObject(); 518 if (key != null) 519 url_key = key; 520 521 String remoteBundleName = (String )in.readObject (); 522 if (remoteBundleName != null) { 523 localizingBundleName = remoteBundleName; 524 } 525 526 } catch (java.io.OptionalDataException ode) { 527 if ( ode.eof ) { 528 setEnabled( true ); 530 } 531 else 532 throw ode; 533 } 534 535 if (urlSpec == null) { 536 this.urlSpec = getDefaultURL (); 537 } 538 539 if (! isValid ()) { 540 setEnabled (false); 541 displayName = NbBundle.getMessage (XMLAutoupdateType.class, "XMLAutoupdateType_InvalidSetting", displayName); } 543 544 } 545 546 private static final class OwnLevel extends Level { 547 public static final Level USER = new OwnLevel("USER", 1973); 549 private OwnLevel(String s, int i) { 550 super(s, i); 551 } 552 } 554 } 555 | Popular Tags |