1 19 20 package com.sslexplorer.extensions.store; 21 22 import java.io.File ; 23 import java.io.FileFilter ; 24 import java.io.FilenameFilter ; 25 import java.io.IOException ; 26 import java.io.InputStream ; 27 import java.io.OutputStream ; 28 import java.net.MalformedURLException ; 29 import java.net.URL ; 30 import java.net.URLConnection ; 31 import java.util.ArrayList ; 32 import java.util.Calendar ; 33 import java.util.Collection ; 34 import java.util.Collections ; 35 import java.util.Comparator ; 36 import java.util.GregorianCalendar ; 37 import java.util.HashMap ; 38 import java.util.Iterator ; 39 import java.util.List ; 40 import java.util.Map ; 41 import java.util.StringTokenizer ; 42 import java.util.prefs.BackingStoreException ; 43 import java.util.prefs.Preferences ; 44 45 import javax.servlet.http.HttpServletRequest ; 46 47 import org.apache.commons.logging.Log; 48 import org.apache.commons.logging.LogFactory; 49 import org.apache.struts.action.ActionForward; 50 import org.jdom.JDOMException; 51 52 import com.sslexplorer.boot.Context; 53 import com.sslexplorer.boot.ContextHolder; 54 import com.sslexplorer.boot.RepositoryFactory; 55 import com.sslexplorer.boot.RepositoryStore; 56 import com.sslexplorer.boot.Util; 57 import com.sslexplorer.boot.VersionInfo; 58 import com.sslexplorer.core.BundleActionMessage; 59 import com.sslexplorer.core.CoreAttributeConstants; 60 import com.sslexplorer.core.CoreEvent; 61 import com.sslexplorer.core.CoreEventConstants; 62 import com.sslexplorer.core.CoreMessageResources; 63 import com.sslexplorer.core.CoreServlet; 64 import com.sslexplorer.core.CoreUtil; 65 import com.sslexplorer.core.GlobalWarning; 66 import com.sslexplorer.core.LicenseAgreement; 67 import com.sslexplorer.extensions.ExtensionBundle; 68 import com.sslexplorer.extensions.ExtensionDescriptor; 69 import com.sslexplorer.extensions.ExtensionException; 70 import com.sslexplorer.extensions.ExtensionInstaller; 71 import com.sslexplorer.extensions.ExtensionType; 72 import com.sslexplorer.extensions.ExtensionBundle.ExtensionBundleStatus; 73 import com.sslexplorer.setup.LicenseAgreementCallback; 74 import com.sslexplorer.tasks.Task; 75 import com.sslexplorer.tasks.TaskHttpServletRequest; 76 import com.sslexplorer.tasks.TaskInputStream; 77 import com.sslexplorer.tasks.TaskProgressBar; 78 import com.sslexplorer.util.ZipExtract; 79 80 90 public class ExtensionStore { 91 92 public static final String HTTP_3SP_COM_APPSTORE = "http://download.3sp.com/appstore/"; 93 private static final Log log = LogFactory.getLog(ExtensionStore.class); 94 private static final String DIRS_TO_REMOVE = "dirsToRemove"; 95 private static String currentEdition = "Community Edition"; 96 97 public static final String UPDATEABLE = "Updateable"; 98 99 102 public static final String ARCHIVE_STORE = "archives"; 103 104 107 public static final String INSTALLED_CATEGORY = "Installed"; 108 109 112 public static final String AGENT_EXTENSION_BUNDLE_ID = "sslexplorer-agent"; 113 114 118 public static final Preferences PREFS = ContextHolder.getContext().getPreferences().node("extensions"); 119 120 124 public static final Preferences STORE_PREF = PREFS.node("store"); 125 126 130 public static final Preferences VERSION_PREFS = PREFS.node("versions"); 131 132 135 public static final int CONNECT_TIMEOUT = 30000; 136 137 140 public static final int READ_TIMEOUT = 30000; 141 142 144 private File basedir; 145 private Map <String , ExtensionBundle> extensionBundles; 146 private List <ExtensionBundle> extensionBundlesList; 147 private List <ExtensionInstaller> extensionBundleInstallList; 148 private ExtensionStoreDescriptor downloadableExtensions; 149 private Calendar downloadableExtensionsLastUpdated; 150 private boolean repositoryBacked; 151 private static ExtensionStore instance; 152 154 159 public static ExtensionStore getInstance() { 160 if (instance == null) { 161 instance = new ExtensionStore(); 162 } 163 return instance; 164 } 165 166 172 176 181 public File getExtensionStoreDirectory() { 182 return basedir; 183 } 184 185 191 public boolean isRepositoryBacked() { 192 return repositoryBacked; 193 } 194 195 201 public void init(File basedir) throws IOException { 202 203 205 repositoryBacked = "true".equals(System.getProperty("sslexplorer.extensions.repositoryBacked", "true")); 207 208 this.basedir = basedir; 209 210 extensionBundles = new HashMap <String , ExtensionBundle>(); 211 extensionBundlesList = new ArrayList <ExtensionBundle>(); 212 extensionBundleInstallList = new ArrayList <ExtensionInstaller>(); 213 214 if (isRepositoryBacked()) { 215 initialiseRepository(); 216 } 217 218 try { 219 loadAll(); 220 } catch (Exception e) { 222 log.error("Failed extract extension bundles from repository.", e); 223 } 224 225 229 VersionInfo.Version sslxVersion = ContextHolder.getContext().getVersion(); 230 if (sslxVersion.getMajor() == 0 && sslxVersion.getMinor() == 2 && sslxVersion.getBuild() == 10) { 231 StringBuffer buf = new StringBuffer (); 232 for (ExtensionBundle bundle : extensionBundlesList) { 233 if (bundle.getRequiredHostVersion() == null || bundle.getRequiredHostVersion().compareTo(sslxVersion) < 0) { 234 log.warn("Extension " + bundle.getId() 235 + " has a required host version of " 236 + bundle.getRequiredHostVersion() 237 + " where as " 238 + "this version of SSL-Explorer is " 239 + sslxVersion 240 + ". This plugin will be disabled."); 241 ExtensionStoreStatusManager.systemDisableExtension(bundle.getId()); 242 if (buf.length() > 0) { 243 buf.append(","); 244 } 245 buf.append(bundle.getName()); 246 } 247 } 248 if (buf.length() > 0) { 249 CoreUtil.addMultipleGlobalWarning(GlobalWarning.MANAGEMENT_USERS, new BundleActionMessage("extensions", 250 "startup.disabledExtensions", 251 buf.toString())); 252 } 253 } 254 255 259 if (!isRepositoryBacked()) { 260 261 String dirsToRemove = STORE_PREF.get(DIRS_TO_REMOVE, ""); 262 if (!dirsToRemove.equals("")) { 263 StringTokenizer t = new StringTokenizer (dirsToRemove, ","); 264 while (t.hasMoreTokens()) { 265 File dir = new File (t.nextToken()); 266 if (dir.exists()) { 267 if (log.isInfoEnabled()) 268 log.info("Removing extension " + dir.getAbsolutePath()); 269 Util.delTree(dir); 270 } 271 } 272 STORE_PREF.remove(DIRS_TO_REMOVE); 273 } 274 275 278 File updatedExtensionsDir = getUpdatedExtensionsDirectory(); 279 File [] extensions = updatedExtensionsDir.listFiles(); 280 if (extensions != null) { 281 for (int i = 0; i < extensions.length; i++) { 282 File destDir = new File (ContextHolder.getContext().getApplicationDirectory(), extensions[i].getName()); 283 if (destDir.exists()) { 284 if (log.isInfoEnabled()) 285 log.info("Removing extension " + destDir.getAbsolutePath()); 286 if (!Util.delTree(destDir)) { 287 throw new IOException ("Failed to remove old extension " + destDir.getAbsolutePath()); 288 } 289 } 290 if (log.isInfoEnabled()) 291 log.info("Moving " + extensions[i].getAbsolutePath() + " to " + destDir.getAbsolutePath()); 292 if (!extensions[i].renameTo(destDir)) { 293 throw new IOException ("Failed to rename extension " + extensions[i].getAbsolutePath() 294 + " to " 295 + destDir.getAbsolutePath()); 296 } 297 } 298 } 299 } 300 301 addAdditionalClasspath(); 303 addAdditionalWebResource(); 304 305 313 } 316 317 320 @SuppressWarnings ("unchecked") 321 public List <ExtensionBundle> getAllAvailableExtensionBundles() { 322 List <ExtensionBundle> all = new ArrayList <ExtensionBundle>(extensionBundlesList); 323 try { 324 ExtensionStoreDescriptor descriptor = getDownloadableExtensionStoreDescriptor(downloadableExtensions != null, getWorkingVersion()); 325 if (descriptor != null && descriptor.getExtensionBundles() != null) { 326 for (Iterator itr = descriptor.getExtensionBundles().iterator(); itr.hasNext();) { 327 ExtensionBundle bundle = (ExtensionBundle) itr.next(); 328 if (!extensionBundles.containsKey(bundle.getId())) { 331 all.add(bundle); 332 } 333 } 334 } 335 } catch (Exception e) { 336 log.error("Failed to get downloadable extensions.", e); 337 } 338 Collections.sort(all); 339 return all; 340 } 341 342 348 @SuppressWarnings ("unchecked") 349 public List <ExtensionBundle> getAllAvailableExtensionBundles(String category) { 350 if (category.equals(INSTALLED_CATEGORY)){ 352 return extensionBundlesList; 353 } 354 355 List <ExtensionBundle> all = new ArrayList <ExtensionBundle>(); 356 if (category.equals(UPDATEABLE)){ 357 for (ExtensionBundle bundle : extensionBundlesList) { 358 if (bundle.isUpdateable()){ 360 all.add(bundle); 361 } 362 } 363 } 364 365 try { 366 ExtensionStoreDescriptor descriptor = getDownloadableExtensionStoreDescriptor(downloadableExtensions != null, getWorkingVersion()); 367 if (descriptor != null && descriptor.getExtensionBundles() != null) { 368 for (Iterator itr = descriptor.getExtensionBundles().iterator(); itr.hasNext();) { 369 ExtensionBundle bundle = (ExtensionBundle) itr.next(); 370 if (!extensionBundles.containsKey(bundle.getId()) && bundle.getCategory().equals(category)) { 373 all.add(bundle); 374 } 375 } 376 } 377 } catch (Exception e) { 378 log.error("Failed to get downloadable extensions.", e); 379 } 380 Collections.sort(all); 381 return all; 382 } 383 384 390 public URLConnection downloadExtension(String id, String version) throws IOException { 391 URL downloadURL = getDownloadURL(id, version); 392 if (downloadURL != null) { 393 if (log.isInfoEnabled()) 394 log.info("Downloading extension from " + downloadURL.toExternalForm()); 395 URLConnection con = downloadURL.openConnection(); 396 con.setConnectTimeout(CONNECT_TIMEOUT); 397 con.setReadTimeout(READ_TIMEOUT); 398 con.connect(); 399 return con; 400 } else { 401 throw new IOException ("No valid download location for " + id); 402 } 403 } 404 405 413 public void start() throws ExtensionException { 414 if (log.isInfoEnabled()) 415 log.info("Starting extension store. Extensions will start in the following order .. "); 416 Collections.sort(extensionBundlesList, new BundleComparator()); 417 for (ExtensionBundle bundle : extensionBundlesList) { 418 log.info(" " + bundle.getId() + " (" + bundle.getOrder() + ")"); 419 } 420 421 for (ExtensionBundle bundle : extensionBundlesList) { 422 423 ContextHolder.getContext().getBootProgressMonitor().updateMessage("Starting " + bundle.getName()); 424 ContextHolder.getContext() 425 .getBootProgressMonitor() 426 .updateProgress((int) (30 + (10 * ((float) extensionBundlesList.indexOf(bundle) / extensionBundlesList.size())))); 427 428 try { 430 if (bundle.getStatus() == ExtensionBundleStatus.ENABLED) { 431 bundle.start(); 432 } 433 } catch (Throwable t) { 434 439 log.error("Failed to start extension bundle.", t); 440 } 441 } 442 443 446 checkExtensionsForInstallation(); 447 448 451 performInstalls(ExtensionInstaller.ON_START); 452 453 } 454 455 463 public void stop() throws ExtensionException { 464 if (log.isInfoEnabled()) 465 log.info("Stopping extensions"); 466 467 470 Collections.reverse(extensionBundlesList); 472 473 ExtensionException ee = null; 474 for (ExtensionBundle bundle : extensionBundlesList) { 475 try { 476 bundle.stop(); 477 } catch (ExtensionException e) { 478 if (ee == null) { 479 ee = e; 480 } 481 log.error("Failed to stop extension bundle.", ee); 482 } 483 } 484 if (ee != null) { 485 throw ee; 486 } 487 } 488 489 497 public void activate() throws ExtensionException { 498 if (log.isInfoEnabled()) 499 log.info("Activating extension store."); 500 501 StringBuffer buf = new StringBuffer (); 502 for (ExtensionBundle bundle : extensionBundlesList) { 503 try { 504 if (bundle.getStatus() == ExtensionBundleStatus.STARTED) { 505 506 ContextHolder.getContext().getBootProgressMonitor().updateMessage("Activating " + bundle.getName()); 507 ContextHolder.getContext() 508 .getBootProgressMonitor() 509 .updateProgress((int) (65 + (10 * ((float) extensionBundlesList.indexOf(bundle) / extensionBundlesList.size())))); 510 511 bundle.activate(); 512 513 if(buf.length() != 0) 514 buf.append(","); 515 buf.append(bundle.getId()); 516 } 517 } catch (Throwable t) { 518 523 log.error("Failed to activate extension bundle.", t); 524 } 525 } 526 527 530 String [] k; 531 try { 532 k = VERSION_PREFS.keys(); 533 for (int i = 0; i < k.length; i++) { 534 if (!isExtensionBundleLoaded(k[i])) { 535 VERSION_PREFS.remove(k[i]); 536 } 537 } 538 } catch (BackingStoreException e) { 539 log.warn("Could not clean up extension versions preferences node.", e); 540 } 541 542 545 548 performInstalls(ExtensionInstaller.ON_ACTIVATE); 549 550 554 if(!buf.toString().equals(PREFS.get("lastActivatedPlugins", ""))) { 555 Util.delTree(new File (ContextHolder.getContext().getTempDirectory(), "org")); 556 } 557 PREFS.put("lastActivatedPlugins", buf.toString()); 558 559 564 try { 565 PREFS.flush(); 566 } 567 catch(BackingStoreException bse) { 568 } 569 } 570 571 574 public void resetExtensionStoreUpdate() { 575 downloadableExtensions = null; 576 } 577 578 584 public ExtensionStoreDescriptor getDownloadableExtensionStoreDescriptor(boolean connect) throws IOException , JDOMException { 585 return getDownloadableExtensionStoreDescriptor(connect, getWorkingVersion()); 586 } 587 588 595 public ExtensionStoreDescriptor getDownloadableExtensionStoreDescriptor(boolean connect, VersionInfo.Version version) throws IOException , JDOMException { 596 if (downloadableExtensions != null && downloadableExtensionsLastUpdated != null) { 597 Calendar calendar = ((Calendar ) downloadableExtensionsLastUpdated.clone()); 598 calendar.add(Calendar.DAY_OF_MONTH, 1); 599 if (new GregorianCalendar ().after(calendar)) { 600 if (log.isInfoEnabled()) 601 log.info("Downloadable extensions are out of date, will contact the update site again."); 602 downloadableExtensions = null; 603 } 604 } 605 606 if (downloadableExtensions == null && connect) { 607 URL storeURL = getStoreDownloadURL(ExtensionStore.HTTP_3SP_COM_APPSTORE, version); 608 if (storeURL != null) { 609 if (log.isInfoEnabled()) 610 log.info("Loading extension store descriptor from " + storeURL.getHost()); 611 612 downloadableExtensions = new ExtensionStoreDescriptor(storeURL); 613 downloadableExtensionsLastUpdated = new GregorianCalendar (); 614 615 for (ExtensionBundle extensionBundle : downloadableExtensions.getExtensionBundles()) { 616 try { 617 ExtensionBundle installedApp = getExtensionBundle(extensionBundle.getId()); 618 if (!installedApp.isDevExtension() && installedApp.getVersion().compareTo(extensionBundle.getVersion()) < 0) { 619 if (log.isInfoEnabled()) 620 log.info("Update found for extenions " + extensionBundle.getId()); 621 installedApp.setType(ExtensionBundle.TYPE_UPDATEABLE); 622 installedApp.setUpdateVersion(extensionBundle.getVersion()); 623 installedApp.setChanges(extensionBundle.getChanges()); 624 } 625 } catch (Exception e) { 626 } 628 } 629 630 if (log.isInfoEnabled()) 631 log.info("Extension store descriptor loaded from " + storeURL.getHost()); 632 } 633 } 634 return downloadableExtensions; 635 } 636 637 void performInstalls(String phase) { 638 for (ExtensionInstaller installer : extensionBundleInstallList) { 639 try { 640 if (log.isInfoEnabled()) { 641 log.info("Performing installer for " + installer.getBundle().getName() + " phase " + phase); 642 } 643 installer.doInstall(phase); 644 } catch (Exception e) { 645 log.warn("Installer for " + installer.getBundle().getName() + " phase " + phase + " failed.", e); 646 } 647 } 648 } 649 650 void checkExtensionsForInstallation() { 651 extensionBundleInstallList.clear(); 652 for (ExtensionBundle bundle : extensionBundlesList) { 653 if (bundle.getInstaller().getOpCount() > 0) { 654 String ver = VERSION_PREFS.get(bundle.getId(), ""); 655 if (ver.equals("") || !ver.equals(bundle.getVersion().toString())) { 656 if (ver.equals("")) { 657 log.info("Will run installer for " + bundle.getId() + " because this is its first install"); 658 } else { 659 log.info("Will run installer for " + bundle.getId() 660 + " because the last installed version " 661 + ver 662 + " has been upgraded to " 663 + bundle.getVersion().toString()); 664 } 665 extensionBundleInstallList.add(bundle.getInstaller()); 666 } 667 } 668 } 669 } 670 671 private static URL getDownloadURL(String id, String version) { 672 try { 673 String location = System.getProperty("sslexplorer.downloadableApplicationStore.location", ExtensionStore.HTTP_3SP_COM_APPSTORE); 674 location += Util.urlEncode(id) + "/" + Util.urlEncode(version) + "/" + Util.urlEncode(id) + ".zip"; 675 return new URL (location); 676 } catch (MalformedURLException murle) { 677 try { 678 String path = System.getProperty("sslexplorer.downloadableApplications.location"); 679 path = path.replaceAll("\\$\\{id\\}", id); 680 path = path.replaceAll("\\$\\{version\\}", version); 681 return new File (path).toURL(); 682 } catch (MalformedURLException e) { 683 log.error("Invalid downloadable extension location specified in system property sslexplorer.downloadableApplicationStore.location, '" + System.getProperty("sslexplorer.downloadableApplicationStore.location") 684 + "'. Must be either a URL or the file path of the store descriptor file."); 685 } 686 } 687 return null; 688 } 689 690 public static URL getStoreDownloadURL(String appStoreLocation, VersionInfo.Version version) { 691 try { 692 String location = System.getProperty("sslexplorer.downloadableApplicationStore.location", appStoreLocation); 693 location += "core/" + Util.urlEncode(version.toString()) + "/store.xml"; 694 return new URL (location); 695 } catch (MalformedURLException murle) { 696 try { 697 return new File (System.getProperty("sslexplorer.downloadableApplicationStore.location")).toURL(); 698 } catch (MalformedURLException e) { 699 log.error("Invalid downloadable extension store location specified in system property sslexplorer.downloadableApplicationStore.location, '" + System.getProperty("sslexplorer.downloadableApplicationStore.location") 700 + "'. Must be either a URL or the file path of the store descriptor file."); 701 } 702 } 703 return null; 704 } 705 706 public static URL getStoreDownloadURL(VersionInfo.Version version) { 707 return ExtensionStore.getStoreDownloadURL(ExtensionStore.HTTP_3SP_COM_APPSTORE, version); 708 } 709 710 713 public void deregisterApplicationPermissions() { 714 Util.toDo("Deregister application permissions"); 715 } 716 717 private synchronized void reloadAll() throws Exception { 718 CoreMessageResources resources = CoreServlet.getServlet().getExtensionStoreResources(); 719 for (ExtensionBundle extensionBundle : extensionBundles.values()) { 720 for (ExtensionDescriptor descriptor : extensionBundle) { 721 Collection <String > toRemove = new ArrayList <String >(); 722 723 for (Iterator itr = resources.keys(); itr.hasNext();) { 724 String key = (String ) itr.next(); 725 if (key.startsWith("application." + descriptor.getId() + ".")) { 726 toRemove.add(key); 727 } 728 } 729 730 for (Iterator itr = toRemove.iterator(); itr.hasNext();) { 731 resources.removeKey((String ) itr.next()); 732 } 733 } 734 } 735 736 extensionBundles.clear(); 737 extensionBundlesList.clear(); 738 739 loadAll(); 740 } 741 742 @SuppressWarnings ("unchecked") 743 private void loadAll() throws Exception { 744 745 if (log.isInfoEnabled()) 746 log.info("Loading applications"); 747 748 if (!basedir.exists()) { 749 basedir.mkdirs(); 750 } 751 752 loadDevExtensions(); 754 755 File [] files = basedir.listFiles(); 756 for (int index = 0; index < files.length; index++) { 757 try { 758 loadDir(files[index]); 759 } catch (Exception e) { 760 log.error("Failed to load " + files[index].getName(), e); 761 } 762 } 763 764 String descriptors = System.getProperty("sslexplorer.additionalDescriptors", ""); 765 for (StringTokenizer tokenizer = new StringTokenizer (descriptors, ","); tokenizer.hasMoreTokens();) { 767 File file = new File (tokenizer.nextToken()); 768 if (file.exists()) { 769 try { 770 loadBundle(file, false); 771 } catch (Exception e) { 772 log.error("Failed to load " + file.getAbsolutePath(), e); 773 } 774 } 775 } 776 777 Collections.sort(extensionBundlesList); 778 } 779 780 private void loadDir(File dir) throws ExtensionException { 781 if (dir.isDirectory()) { 782 File [] descriptors = dir.listFiles(new FilenameFilter () { 783 public boolean accept(File f, String filename) { 784 return filename.equals("application.xml") || filename.equals("extension.xml"); 785 } 786 }); 787 788 if (descriptors.length == 0) { 789 log.warn("Extension folder " + dir.getName() + " found with no extension.xml (or the deprecated application.xml)"); 790 return; 791 } else if (descriptors.length > 1) { 792 log.warn("Extension folder " + dir.getName() 794 + " found with too many extension.xml (or deprecated application.xml) files. Please remove one. This extensions will be ignored."); 795 return; 796 } 797 if (log.isInfoEnabled()) 798 log.info("Found application bundle " + dir.getName()); 799 800 if (descriptors[0].getName().equals("application.xml")) { 801 log.warn("DEPRECATED. Application descriptor file " + descriptors[0] 802 + " is no longer used, please use extension.xml instead."); 803 } 804 loadBundle(descriptors[0], false); 805 } 806 } 807 808 private void loadBundle(File descriptor, boolean devExtension) throws ExtensionException { 809 ExtensionBundle bundle = new ExtensionBundle(descriptor, devExtension); 810 loadBundle(bundle); 811 } 812 813 private void loadBundle(ExtensionBundle bundle) throws ExtensionException { 814 815 bundle.load(); 816 ExtensionBundle oldBundle = (ExtensionBundle) extensionBundles.get(bundle.getId()); 817 818 if (oldBundle != null && oldBundle.isDevExtension()) { 819 throw new ExtensionException(ExtensionException.CANNOT_REPLACE_DEV_EXTENSION, bundle.getId()); 820 } 821 822 bundle.setCategory(ExtensionStore.INSTALLED_CATEGORY); 823 try { 824 ExtensionBundleStatus extensionStatus = ExtensionStoreStatusManager.getExtensionStatus(bundle.getId()); 825 bundle.setStatus(extensionStatus); 826 } catch (IOException ioe) { 827 throw new ExtensionException(ExtensionException.INTERNAL_ERROR, ioe, "Failed to add bundle."); 828 } 829 830 for (ExtensionDescriptor descriptor : bundle) { 831 if (log.isInfoEnabled()) 832 log.info("Extension " + descriptor.getName() + " has been loaded"); 833 } 834 extensionBundlesList.remove(oldBundle); 835 extensionBundles.put(bundle.getId(), bundle); 836 extensionBundlesList.add(bundle); 837 } 838 839 844 public void systemDisableExtension(String bundleId) throws ExtensionException, IOException { 845 ExtensionBundle extensionBundle = getExtensionBundle(bundleId); 846 extensionBundle.setStatus(ExtensionBundle.ExtensionBundleStatus.SYSTEM_DISABLED); 847 ExtensionStoreStatusManager.systemDisableExtension(bundleId); 848 } 849 850 854 public void disableExtension(String bundleId) throws Exception { 855 ExtensionBundle extensionBundle = getExtensionBundle(bundleId); 856 extensionBundle.setStatus(ExtensionBundle.ExtensionBundleStatus.DISABLED); 857 ExtensionStoreStatusManager.disableExtension(bundleId); 858 if(extensionBundle.isContainsPlugin()) { 859 extensionBundle.setType(ExtensionBundle.TYPE_PENDING_STATE_CHANGE); 860 } 861 } 862 863 867 public void enableExtension(String bundleId) throws Exception { 868 ExtensionBundle extensionBundle = getExtensionBundle(bundleId); 869 extensionBundle.setStatus(ExtensionBundle.ExtensionBundleStatus.ENABLED); 870 ExtensionStoreStatusManager.enableExtension(bundleId); 871 if(extensionBundle.isContainsPlugin()) { 872 extensionBundle.setType(ExtensionBundle.TYPE_PENDING_STATE_CHANGE); 873 } 874 } 875 876 private static void installExtension(ExtensionBundle extensionBundle) throws IOException { 877 if (ExtensionBundle.ExtensionBundleStatus.SYSTEM_DISABLED.equals(extensionBundle.getStatus())) { 878 ExtensionStoreStatusManager.installExtension(extensionBundle.getId()); 879 extensionBundle.setStatus(ExtensionBundle.ExtensionBundleStatus.ENABLED); 880 } 881 } 882 883 886 public List <ExtensionBundle> getExtensionBundles() { 887 return extensionBundlesList; 888 } 889 890 894 public boolean isExtensionBundleLoaded(String name) { 895 return extensionBundles.containsKey(name); 896 } 897 898 901 public ExtensionDescriptor getAgentApplication() { 902 try { 903 ExtensionBundle bundle = getExtensionBundle(AGENT_EXTENSION_BUNDLE_ID); 904 return bundle != null ? (ExtensionDescriptor) bundle.getApplicationDescriptor(AGENT_EXTENSION_BUNDLE_ID) : null; 905 } catch (Exception e) { 906 log.error("Failed to get agent descriptor. Loaded?", e); 907 return null; 908 } 909 } 910 911 916 public ExtensionDescriptor getExtensionDescriptor(String id) throws Exception { 917 for (ExtensionBundle bundle : extensionBundlesList) { 918 ExtensionDescriptor descriptor = bundle.getApplicationDescriptor(id); 919 if (descriptor != null && descriptor instanceof ExtensionDescriptor) { 920 return (ExtensionDescriptor) descriptor; 921 } 922 } 923 return null; 924 } 925 926 933 public ExtensionBundle getExtensionBundle(String id) throws ExtensionException { 934 if (!extensionBundles.containsKey(id)) { 935 throw new ExtensionException(ExtensionException.INVALID_EXTENSION, id); 936 } 937 return (ExtensionBundle) extensionBundles.get(id); 938 } 939 940 945 public void reload() throws Exception { 946 if (log.isInfoEnabled()) 947 log.info("Reloading all application bundles"); 948 boolean reconnect = downloadableExtensions != null; 949 downloadableExtensions = null; 950 downloadableExtensionsLastUpdated = null; 951 deregisterApplicationPermissions(); 952 953 reloadAll(); 954 if (reconnect) { 955 getDownloadableExtensionStoreDescriptor(true); 956 } 957 } 958 959 public static VersionInfo.Version getWorkingVersion() { 960 VersionInfo.Version version = new VersionInfo.Version(System.getProperty("sslexplorer.forceVersion", ContextHolder.getContext().getVersion().toString())); 961 return version; 962 } 963 964 968 @SuppressWarnings ("unchecked") 969 public void reload(String id) throws ExtensionException { 970 if (log.isInfoEnabled()) 971 log.info("Reloading application bundle " + id); 972 if (isExtensionLoaded(id)) { 973 ExtensionBundle bundle = getExtensionBundle(id); 974 try { 975 bundle.load(); 976 } catch (ExtensionException ee) { 977 log.warn("Failed to reload extension descriptor.", ee); 978 extensionBundles.remove(id); 979 extensionBundlesList.remove(bundle); 980 throw ee; 981 } 982 } else { 983 loadDir(new File (basedir, id)); 984 } 985 Collections.sort(extensionBundlesList); 986 } 987 988 992 public File getUpdatedExtensionsDirectory() throws IOException { 993 File updatedExtensionsDir = new File (ContextHolder.getContext().getConfDirectory(), "updated-extensions"); 994 if (!updatedExtensionsDir.exists() && !updatedExtensionsDir.mkdirs()) { 995 throw new IOException ("The extension update directory " + updatedExtensionsDir.getAbsolutePath() 996 + " could not be created."); 997 } 998 return updatedExtensionsDir; 999 } 1000 1001 1010 @SuppressWarnings ("unchecked") 1011 public void removeExtensionBundle(ExtensionBundle bundle) throws Exception { 1012 if (log.isInfoEnabled()) 1013 log.info("Removing extension bundle " + bundle.getId()); 1014 boolean containsPlugin = bundle.isContainsPlugin(); 1015 try { 1016 CoreServlet.getServlet() 1017 .fireCoreEvent(new CoreEvent(this, 1018 CoreEventConstants.REMOVING_EXTENSION, 1019 bundle, 1020 null, 1021 CoreEvent.STATE_SUCCESSFUL).addAttribute(CoreAttributeConstants.EVENT_ATTR_EXTENSION_ID, 1022 bundle.getId()) 1023 .addAttribute(CoreAttributeConstants.EVENT_ATTR_EXTENSION_NAME, bundle.getName())); 1024 bundle.removeBundle(); 1025 VERSION_PREFS.remove(bundle.getId()); 1026 CoreServlet.getServlet() 1027 .fireCoreEvent(new CoreEvent(this, 1028 CoreEventConstants.REMOVE_EXTENSION, 1029 bundle, 1030 null, 1031 CoreEvent.STATE_SUCCESSFUL).addAttribute(CoreAttributeConstants.EVENT_ATTR_EXTENSION_ID, 1032 bundle.getId()) 1033 .addAttribute(CoreAttributeConstants.EVENT_ATTR_EXTENSION_NAME, bundle.getName())); 1034 if (containsPlugin) { 1035 if (!ExtensionStore.getInstance().isRepositoryBacked()) { 1036 if (log.isInfoEnabled()) 1037 log.info("Extension " + bundle.getId() + " contains plugins, deferring removal until restart."); 1038 StringBuffer toRemove = new StringBuffer (STORE_PREF.get(DIRS_TO_REMOVE, "")); 1039 if (toRemove.length() > 0) { 1040 toRemove.append(","); 1041 } 1042 toRemove.append(bundle.getBaseDir()); 1043 STORE_PREF.put(DIRS_TO_REMOVE, toRemove.toString()); 1044 } 1045 } 1046 ExtensionStoreStatusManager.removeExtension(bundle.getId()); 1047 } catch (Exception e) { 1048 CoreServlet.getServlet() 1049 .fireCoreEvent(new CoreEvent(this, CoreEventConstants.REMOVE_EXTENSION, null, null, e).addAttribute(CoreAttributeConstants.EVENT_ATTR_EXTENSION_ID, 1050 bundle.getId()) 1051 .addAttribute(CoreAttributeConstants.EVENT_ATTR_EXTENSION_NAME, bundle.getName())); 1052 1053 throw e; 1054 } finally { 1055 if (!containsPlugin) { 1056 extensionBundles.remove(bundle.getId()); 1057 extensionBundlesList.remove(bundle); 1058 if (log.isInfoEnabled()) 1059 log.info("Extension Zip file " + bundle.getId() + ".zip" + " has been deleted."); 1060 } 1061 if (ExtensionStore.getInstance().isRepositoryBacked()) { 1062 RepositoryFactory.getRepository().getStore(ExtensionStore.ARCHIVE_STORE).removeEntry(bundle.getId() + ".zip"); 1063 } 1064 Collections.sort(extensionBundlesList); 1065 } 1066 } 1067 1068 1074 public boolean isExtensionLoaded(String id) { 1075 for (Iterator i = extensionBundlesList.iterator(); i.hasNext();) { 1076 ExtensionBundle bundle = (ExtensionBundle) i.next(); 1077 if (bundle.containsApplication(id)) { 1078 return true; 1079 } 1080 } 1081 return false; 1082 } 1083 1084 1096 public ExtensionBundle installExtensionFromStore(final String id, InputStream in, HttpServletRequest request, long contentLength) 1097 throws ExtensionException { 1098 ExtensionStoreDescriptor store; 1099 try { 1100 store = getDownloadableExtensionStoreDescriptor(true); 1102 if (store == null) { 1103 throw new ExtensionException(ExtensionException.INTERNAL_ERROR, "No downloadable applications."); 1104 } 1105 1106 ExtensionBundle bundle = store.getApplicationBundle(id); 1107 if (bundle == null) { 1108 throw new ExtensionException(ExtensionException.INVALID_EXTENSION, id); 1109 } 1110 1111 Context context = ContextHolder.getContext(); 1113 if (bundle.getRequiredHostVersion() != null && bundle.getRequiredHostVersion().compareTo(context.getVersion()) > 0) { 1114 throw new ExtensionException(ExtensionException.INSUFFICIENT_SSLEXPLORER_HOST_VERSION, 1115 bundle.getId(), 1116 bundle.getRequiredHostVersion().toString()); 1117 } 1118 1119 if (bundle.getDependencies() != null) { 1121 for (String dep : bundle.getDependencies()) { 1122 if (isExtensionBundleLoaded(dep)) { 1123 ExtensionBundle current = getExtensionBundle(dep); 1124 ExtensionBundle available = store.getApplicationBundle(dep); 1125 if(available != null) { 1126 if (!current.isDevExtension() && isNewerVersionAvailable(available, current)) { 1127 if (log.isInfoEnabled()) 1128 log.info("Found a dependency (" + dep + "), that needs upgrading. " + current.getVersion().toString() + " is the current version, " + available.getVersion().toString() + " is available. Installing now"); 1129 installExtensionFromStore(current.getId(), available.getVersion().toString(), request); 1130 } 1131 } 1132 } else { 1133 try { 1134 if (log.isInfoEnabled()) 1135 log.info("Found a dependency (" + dep + "), that is not installed. Installing now"); 1136 installExtensionFromStore(dep, store.getApplicationBundle(dep).getVersion().toString(), request); 1137 } catch (Exception e) { 1138 throw new ExtensionException(ExtensionException.INTERNAL_ERROR, "Failed to install dependency " + dep); 1139 } 1140 } 1141 } 1142 } 1143 1144 Task task = (Task)request.getAttribute(TaskHttpServletRequest.ATTR_TASK); 1146 if(task != null && request.getAttribute(TaskHttpServletRequest.ATTR_TASK_PROGRESS_HANDLED_EXTERNALLY) == null) { 1147 TaskProgressBar bar = new TaskProgressBar("installExtension", 0, (int)contentLength, 0); task.clearProgressBars(); 1149 task.addProgressBar(bar); 1150 in = new TaskInputStream(bar, in); 1151 ((TaskInputStream)in).getProgressBar().setNote(new BundleActionMessage("extensions", "taskProgress.downloadExtension.note", id)); 1152 if(!task.isConfigured()) 1153 task.configured(); 1154 } 1155 1156 return installExtension(id, in); 1157 } catch (IOException jde) { 1158 throw new ExtensionException(ExtensionException.INTERNAL_ERROR, "Failed to load descriptor."); 1159 } catch (JDOMException jde) { 1160 throw new ExtensionException(ExtensionException.FAILED_TO_PARSE_DESCRIPTOR); 1161 } 1162 } 1163 1164 1174 public void installExtensionFromStore(String id, String version, HttpServletRequest request) throws IOException , ExtensionException { 1175 URLConnection connection = downloadExtension(id, version); 1176 InputStream inputStream = connection.getInputStream(); 1177 installExtensionFromStore(id, inputStream, request, connection.getContentLength()); 1178 } 1179 1180 1191 public ExtensionBundle installExtension(final String id, InputStream in) throws IOException , ExtensionException { 1192 streamToRepositoryStore(in, id); 1193 1194 try { 1195 RepositoryStore repStore = RepositoryFactory.getRepository().getStore(ARCHIVE_STORE); 1196 ZipExtract.extractZipFile(getExtensionStoreDirectory(), repStore.getEntryInputStream(id + ".zip")); 1197 reload(id); 1198 ExtensionBundle newBundle = getExtensionBundle(id); 1199 installExtension(newBundle); 1200 fireBundleEvent(CoreEventConstants.INSTALL_EXTENSION, newBundle); 1201 } catch (IOException e) { 1202 CoreServlet.getServlet().fireCoreEvent(new CoreEvent(this, 1203 CoreEventConstants.INSTALL_EXTENSION, 1204 null, 1205 null, 1206 CoreEvent.STATE_UNSUCCESSFUL).addAttribute(CoreAttributeConstants.EVENT_ATTR_EXTENSION_ID, id)); 1207 throw e; 1208 } catch (ExtensionException e) { 1209 CoreServlet.getServlet().fireCoreEvent(new CoreEvent(this, 1210 CoreEventConstants.INSTALL_EXTENSION, 1211 null, 1212 null, 1213 CoreEvent.STATE_UNSUCCESSFUL).addAttribute(CoreAttributeConstants.EVENT_ATTR_EXTENSION_ID, id)); 1214 throw e; 1215 } 1216 return getExtensionBundle(id); 1217 } 1218 1219 1232 public void licenseCheck(final ExtensionBundle newBundle, HttpServletRequest request, final ActionForward installedForward) 1233 throws Exception { 1234 1235 final RepositoryStore repStore = RepositoryFactory.getRepository().getStore(ARCHIVE_STORE); 1236 File licenseFile = newBundle.getLicenseFile(); 1238 if (licenseFile != null && licenseFile.exists()) { 1239 LicenseAgreement licenseAgreement = getLicenseAgreement(newBundle, repStore, licenseFile, installedForward); 1240 CoreUtil.requestLicenseAgreement(request.getSession(), licenseAgreement); 1241 } 1242 } 1243 1244 1254 public void postInstallExtension(final ExtensionBundle newBundle, HttpServletRequest request) throws Exception { 1255 boolean containsPlugin = newBundle.isContainsPlugin(); 1256 1257 if (containsPlugin) { 1258 CoreUtil.addMultipleGlobalWarning(GlobalWarning.MANAGEMENT_USERS, new BundleActionMessage("extensions", 1259 "extensionStore.message.pluginInstalledRestartRequired")); 1260 newBundle.setType(ExtensionBundle.TYPE_PENDING_INSTALLATION); 1261 } else { 1262 newBundle.start(); 1263 1264 if (newBundle.getInstaller() != null) { 1266 newBundle.getInstaller().doInstall(null); 1267 } 1268 1269 newBundle.activate(); 1270 } 1271 } 1272 1273 1284 public ExtensionBundle updateExtension(String id, InputStream in, HttpServletRequest request, long contentLength) throws Exception { 1285 ExtensionStoreDescriptor store; 1286 1291 1296 1297 Task task = (Task)request.getAttribute(TaskHttpServletRequest.ATTR_TASK); 1299 if(task != null && request.getAttribute(TaskHttpServletRequest.ATTR_TASK_PROGRESS_HANDLED_EXTERNALLY) == null) { 1300 TaskProgressBar bar = new TaskProgressBar("updateExtension", 0, (int)contentLength, 0); 1301 task.addProgressBar(bar); 1302 in = new TaskInputStream(bar, in); 1303 ((TaskInputStream)in).getProgressBar().setNote(new BundleActionMessage("extensions", "taskProgress.downloadExtension.note", id)); 1304 task.configured(); 1305 } 1306 1307 ExtensionBundle currentBundle = getExtensionBundle(id); 1308 if (currentBundle == null) { 1309 throw new ExtensionException(ExtensionException.INVALID_EXTENSION, id); 1310 } 1311 1312 try { 1313 return updateExtension(currentBundle, in, request); 1314 } catch (ExtensionException ee) { 1315 CoreServlet.getServlet() 1316 .fireCoreEvent(new CoreEvent(this, 1317 CoreEventConstants.UPDATE_EXTENSION, 1318 null, 1319 null, 1320 CoreEvent.STATE_SUCCESSFUL).addAttribute(CoreAttributeConstants.EVENT_ATTR_EXTENSION_ID, 1321 currentBundle.getId()) 1322 .addAttribute(CoreAttributeConstants.EVENT_ATTR_EXTENSION_NAME, currentBundle.getName()) 1323 .addAttribute(CoreAttributeConstants.EVENT_ATTR_EXTENSION_VERSION, 1324 currentBundle.getVersion().toString())); 1325 throw ee; 1326 } 1327 } 1328 1329 private ExtensionBundle updateExtension(ExtensionBundle currentBundle, InputStream in, 1330 HttpServletRequest request) throws Exception { 1331 1332 Context context = ContextHolder.getContext(); 1334 if (currentBundle.getRequiredHostVersion() != null && currentBundle.getRequiredHostVersion().compareTo(context.getVersion()) > 0) { 1335 throw new ExtensionException(ExtensionException.INSUFFICIENT_SSLEXPLORER_HOST_VERSION, 1336 currentBundle.getId(), 1337 currentBundle.getRequiredHostVersion().toString()); 1338 } 1339 1340 boolean containsPlugin = currentBundle.isContainsPlugin(); 1341 1342 try { 1344 currentBundle.removeBundle(); 1345 VERSION_PREFS.remove(currentBundle.getId()); 1346 } catch (Exception e) { 1347 throw e; 1348 } finally { 1349 if (!containsPlugin) { 1350 extensionBundles.remove(currentBundle.getId()); 1351 extensionBundlesList.remove(currentBundle); 1352 if (log.isInfoEnabled()) 1353 log.info("Extension Zip file " + currentBundle.getId() + ".zip" + " has been deleted."); 1354 } 1355 } 1356 1357 streamToRepositoryStore(in, currentBundle.getId()); 1359 RepositoryStore repStore = RepositoryFactory.getRepository().getStore(ARCHIVE_STORE); 1360 ZipExtract.extractZipFile(getExtensionStoreDirectory(), repStore.getEntryInputStream(currentBundle.getId() + ".zip")); 1361 1362 if (containsPlugin) { 1363 currentBundle.setType(ExtensionBundle.TYPE_PENDING_UPDATE); 1364 fireBundleEvent(CoreEventConstants.UPDATE_EXTENSION, currentBundle); 1365 return currentBundle; 1366 } else { 1367 reload(currentBundle.getId()); 1368 ExtensionBundle newBundle = getExtensionBundle(currentBundle.getId()); 1369 installExtension(newBundle); 1370 postInstallExtension(newBundle, request); 1371 if (newBundle.getStatus().isStartedOrActivated()) { 1372 newBundle.stop(); 1373 newBundle.start(); 1374 newBundle.activate(); 1375 } 1376 fireBundleEvent(CoreEventConstants.UPDATE_EXTENSION, newBundle); 1377 return newBundle; 1378 } 1379 } 1380 1381 1386 public static void setCurrentEdition(String currentEdition) { 1387 ExtensionStore.currentEdition = currentEdition; 1388 } 1389 1390 private LicenseAgreement getLicenseAgreement(final ExtensionBundle newBundle, final RepositoryStore repStore, 1391 final File licenseFile, final ActionForward installedForward) { 1392 return new LicenseAgreement(newBundle.getName(), licenseFile, new LicenseAgreementCallback() { 1393 public void licenseAccepted(HttpServletRequest request) { 1394 } 1396 1397 public void licenseRejected(HttpServletRequest request) { 1398 if (isRepositoryBacked()) { 1401 try { 1402 repStore.removeEntry(newBundle.getId() + ".zip"); 1403 } catch (IOException ex) { 1404 } 1405 } 1406 1407 if (newBundle.getBaseDir().exists()) { 1409 Util.delTree(newBundle.getBaseDir()); 1410 } 1411 1412 try { 1414 reload(newBundle.getId()); 1415 } catch (Exception e) { 1416 log.error("Failed to reload extension store."); 1417 } 1418 } 1419 }, installedForward); 1420 } 1421 1422 private static boolean isNewerVersionAvailable(ExtensionBundle available, ExtensionBundle current) { 1423 VersionInfo.Version v1 = new VersionInfo.Version(available.getVersion().toString()); 1424 VersionInfo.Version v2 = new VersionInfo.Version(current.getVersion().toString()); 1425 return v1.compareTo(v2) > 0; 1426 } 1427 1428 private static void streamToRepositoryStore(InputStream in, String bundleId) throws IOException { 1429 RepositoryStore repStore = RepositoryFactory.getRepository().getStore(ARCHIVE_STORE); 1430 OutputStream out = null; 1431 try { 1432 out = repStore.getEntryOutputStream(bundleId + ".zip"); 1433 Util.copy(in, out); 1434 } finally { 1435 Util.closeStream(in); 1436 Util.closeStream(out); 1437 } 1438 } 1439 1440 private void fireBundleEvent(int eventType, ExtensionBundle bundle) { 1441 String extensionType = getExtensionType(bundle); 1442 CoreServlet.getServlet() 1443 .fireCoreEvent(new CoreEvent(this, eventType, null, null, CoreEvent.STATE_SUCCESSFUL).addAttribute(CoreAttributeConstants.EVENT_ATTR_EXTENSION_ID, 1444 bundle.getId()) 1445 .addAttribute(CoreAttributeConstants.EVENT_ATTR_EXTENSION_NAME, bundle.getName()) 1446 .addAttribute(CoreAttributeConstants.EVENT_ATTR_EXTENSION_VERSION, 1447 bundle.getVersion().toString()) 1448 .addAttribute(CoreAttributeConstants.EVENT_ATTR_EXTENSION_TYPE, extensionType)); 1449 } 1450 1451 private static String getExtensionType(ExtensionBundle bundle) { 1452 for (Iterator itr = bundle.iterator(); itr.hasNext();) { 1453 ExtensionDescriptor descriptor = (ExtensionDescriptor) itr.next(); 1454 if (descriptor.getExtensionType() instanceof ExtensionType) { 1455 return descriptor.getExtensionType().getType(); 1456 } 1457 } 1458 return null; 1459 } 1460 1461 private void addAdditionalWebResource() { 1462 String additionalWebResources = System.getProperty("sslexplorer.additionalWebResourceDirectories", ""); 1464 if (additionalWebResources != null) { 1465 StringTokenizer t = new StringTokenizer (additionalWebResources, ","); 1466 while (t.hasMoreTokens()) { 1467 try { 1468 URL u = null; 1469 String dir = t.nextToken(); 1470 if (dir.endsWith("]")) { 1471 int idx = dir.indexOf('['); 1472 if (idx != -1) { 1473 dir = dir.substring(0, idx); 1474 u = new File (dir).getCanonicalFile().toURL(); 1475 log.warn("Associating additional web resource directories with plugins is no longer supported."); 1476 } 1477 } 1478 if (u == null) { 1479 u = new File (dir).getCanonicalFile().toURL(); 1480 } 1481 ContextHolder.getContext().addResourceBase(u); 1482 } catch (Exception e) { 1483 log.error("Failed to add additional web resources directory.", e); 1484 } 1485 } 1486 } 1487 } 1488 1489 private void addAdditionalClasspath() { 1490 1491 StringTokenizer t = new StringTokenizer (System.getProperty("sslexplorer.additionalClasspath", ""), ","); 1493 while (t.hasMoreTokens()) { 1494 try { 1495 String sf = t.nextToken(); 1496 File [] f = null; 1497 if (sf.endsWith("/*.jar")) { 1498 f = new File (sf.substring(0, sf.length() - 6)).listFiles(new FileFilter () { 1499 public boolean accept(File pathname) { 1500 return pathname.getName().toLowerCase().endsWith(".jar"); 1501 } 1502 }); 1503 } else { 1504 f = new File [1]; 1505 f[0] = new File (sf); 1506 } 1507 for (int j = 0; f != null && j < f.length; j++) { 1508 if (f[j].exists() && (f[j].isDirectory() || f[j].getName().toLowerCase().endsWith(".jar"))) { 1509 URL u = f[j].toURL(); 1510 ContextHolder.getContext().addContextLoaderURL(u); 1511 } 1512 } 1513 } catch (MalformedURLException murle) { 1514 log.warn("Invalid element in additional classpaths"); 1515 } 1516 1517 } 1518 } 1519 1520 private void initialiseRepository() { 1521 RepositoryStore store = RepositoryFactory.getRepository().getStore("archives"); 1522 if (basedir.exists()) { 1524 Util.delTree(basedir); 1525 } 1526 1527 basedir.mkdirs(); 1529 String [] archives = store.listEntries(); 1530 for (int i = 0; i < archives.length; i++) { 1531 if (log.isInfoEnabled()) { 1532 log.info("Extracting archive " + archives[i]); 1533 } 1534 try { 1535 ZipExtract.extractZipFile(basedir, store.getEntryInputStream(archives[i])); 1536 if (log.isInfoEnabled()) { 1537 log.info("Completed archive extraction for extension " + archives[i]); 1538 } 1539 } catch (IOException ex) { 1540 log.error("Error extracting archive for extension " + archives[i], ex); 1541 Util.delTree(new File (basedir, archives[i])); 1542 } 1543 } 1544 } 1545 1546 private void loadDevExtensions() { 1547 List <String > devExtensions = new ArrayList <String >(); 1548 String extensionList = System.getProperty("sslexplorer.devExtensions", ""); 1549 StringTokenizer t = new StringTokenizer (extensionList, ","); 1550 while (t.hasMoreTokens()) { 1551 String ext = t.nextToken(); 1552 if (ext.equalsIgnoreCase("all")) { 1553 File f = new File (System.getProperty("user.dir")).getParentFile(); 1554 File [] dirs = f.listFiles(new FileFilter () { 1555 public boolean accept(File pathname) { 1556 File f = new File (pathname, "extensions"); 1557 return f.exists() && f.isDirectory(); 1558 } 1559 }); 1560 for (int i = 0; dirs != null && i < dirs.length; i++) { 1561 devExtensions.add(dirs[i].getName()); 1562 } 1563 } else if (ext.equalsIgnoreCase("enterprise")) { 1564 File f = new File (System.getProperty("user.dir")).getParentFile(); 1565 File [] dirs = f.listFiles(new FileFilter () { 1566 public boolean accept(File pathname) { 1567 File f = new File (pathname, "extensions"); 1568 return f.exists() && f.isDirectory() && pathname.getName().indexOf("sslexplorer-enterprise-") != -1; 1569 } 1570 }); 1571 for (int i = 0; dirs != null && i < dirs.length; i++) { 1572 devExtensions.add(dirs[i].getName()); 1573 } 1574 } else if (ext.equalsIgnoreCase("community")) { 1575 File f = new File (System.getProperty("user.dir")).getParentFile(); 1576 File [] dirs = f.listFiles(new FileFilter () { 1577 public boolean accept(File pathname) { 1578 File f = new File (pathname, "extensions"); 1579 return f.exists() && f.isDirectory() && pathname.getName().indexOf("sslexplorer-community-") != -1; 1580 } 1581 }); 1582 for (int i = 0; dirs != null && i < dirs.length; i++) { 1583 devExtensions.add(dirs[i].getName()); 1584 } 1585 } else { 1586 if (ext.startsWith("!")) { 1587 devExtensions.remove(ext.substring(1)); 1588 } else { 1589 devExtensions.add(ext); 1590 } 1591 } 1592 } 1593 1594 for (Iterator it = devExtensions.iterator(); it.hasNext();) { 1595 String ext = (String ) it.next(); 1596 File d = new File (new File (System.getProperty("user.dir")).getParentFile(), ext); 1597 File extensionDir = new File (new File (d, "extensions"), d.getName()); 1598 File extensionDescriptor = new File (extensionDir, "extension.xml"); 1599 if (extensionDescriptor.exists()) { 1600 try { 1601 loadBundle(extensionDescriptor, true); 1602 } catch (Exception e) { 1603 log.error("Failed to load dev extension " + extensionDescriptor.getAbsolutePath(), e); 1604 } 1605 } 1606 } 1607 } 1608 1609 class BundleComparator implements Comparator <ExtensionBundle> { 1610 public int compare(ExtensionBundle o1, ExtensionBundle o2) { 1611 int i = new Integer (o1.getOrder()).compareTo(new Integer (o2.getOrder())); 1612 return i == 0 ? o1.getId().compareTo(o2.getId()) : i; 1613 } 1614 } 1615 1616} | Popular Tags |