Changeset 5616


Ignore:
Timestamp:
Apr 27, 2011, 11:27:56 AM (10 years ago)
Author:
Nicklas Nordborg
Message:

References #1592: Unified installation procedure for plug-ins, extensions and more...

Re-organized the installation procedure. The first step will now show scan for new/updated/deleted files and present a list of options for each one (eg. install/uninstall).

We keep track of each installed extension in the settings file which should be safer since no automatic installation is done any longer.

There may still be some error handling issues, and plug-in configuration are still not installed.

Re-organized the Administrate and Extensions menus in the web client. All plug-in/extensions installation is now done from Administrate -> Plug-ins & extensions -> Overview.

Location:
trunk
Files:
6 added
8 deleted
21 edited
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/src/clients/web/net/sf/basedb/clients/web/extensions/ExtensionsControl.java

    r5615 r5616  
    3030
    3131import javax.servlet.ServletContext;
     32import javax.servlet.http.HttpServletRequest;
    3233import javax.servlet.jsp.PageContext;
    3334
     
    5960import net.sf.basedb.util.extensions.manager.ProcessResults;
    6061import net.sf.basedb.util.extensions.manager.Settings;
    61 import net.sf.basedb.util.extensions.manager.filter.DeletedFilter;
    62 import net.sf.basedb.util.extensions.manager.filter.ValidAndNewOrModifiedFilter;
     62import net.sf.basedb.util.extensions.manager.filter.InstalledFilter;
    6363import net.sf.basedb.util.extensions.manager.processor.DeleteResourcesProcessor;
     64import net.sf.basedb.util.extensions.manager.processor.DisablePluginsProcessor;
    6465import net.sf.basedb.util.extensions.manager.processor.ExtractResourcesProcessor;
    6566import net.sf.basedb.util.extensions.manager.processor.PluginInstallationProcessor;
     
    6869import net.sf.basedb.util.extensions.xml.PluginInfo;
    6970import net.sf.basedb.util.extensions.xml.XmlLoader;
     71import net.sf.basedb.util.filter.Filter;
    7072
    7173/**
     
    159161
    160162    // Install extensions
    161     lastScanResults = new ProcessResults(false, false);
     163    lastScanResults = new ProcessResults();
    162164   
    163165    // Initial scan
    164     scan(null, true, false);
     166    scan(null, null);
    165167    initialised = true;
    166168   
     
    186188 
    187189 
    188   private static ProcessResults scan(DbControl dc, boolean initialScan, boolean forceUpdate)
    189   {
    190     log.info("Starting scan: intial=" + initialScan + "; forceUpdate="+forceUpdate);
     190  private static ProcessResults scan(DbControl dc, HttpServletRequest request)
     191  {
     192    log.info("Starting scan");
    191193    String rootPath = servletContext.getContextPath();
    192194    File resourceDir = new File(servletContext.getRealPath(RESOURCES_URL));
     195    boolean initialScan = request == null;
    193196
    194197    // Collect the results from this scan
    195     ProcessResults results = new ProcessResults(!initialScan, forceUpdate);
     198    ProcessResults results = new ProcessResults();
    196199   
    197200    // File statistics
    198     int numNewFiles = 0;
    199     int numModifiedFiles = 0;
    200     int numDeletedFiles = 0;
     201    int numInstalled = 0;
     202    int numUninstalled = 0;
    201203   
    202204    // Extensions+extension points statistics
    203205    int numUnregistered = 0;
    204206    int numRegistered = 0;
    205     int numPlugins = 0;
     207    int numInstalledPlugins = 0;
     208    int numDisabledPlugins = 0;
    206209   
    207210    synchronized (manager)
     
    209212      if (!initialScan)
    210213      {
    211         log.debug("Checking for deleted files");
    212         // 1. Process files that has been deleted
    213         DeletedFilter deleted = new DeletedFilter();
     214        // 1. Process files that has been selected for uninstallation
     215        log.debug("Uninstalling extensions");
     216        UninstallFilter uninstallFilter = new UninstallFilter(request);
    214217       
    215218        // 1a. Remove resources extracted from JAR files
    216219        DeleteResourcesProcessor deleteResources = new DeleteResourcesProcessor(resourceDir, results);
    217         manager.processFiles(deleteResources, deleted);
     220        manager.processFiles(deleteResources, uninstallFilter);
    218221       
    219222        // 1b. Unregister all extensions from deleted files
    220223        UnregisterExtensionsProcessor unregister = new UnregisterExtensionsProcessor(results);
    221         manager.processFiles(unregister, deleted);
     224        manager.processFiles(unregister, uninstallFilter);
    222225        numUnregistered = unregister.getNumUnregistered();
    223226       
    224         log.debug("Processed " + unregister.getNumFiles() + " deleted files");
     227        // 1c. Mark all plug-ins as disabled
     228        DisablePluginsProcessor disablePlugins = new DisablePluginsProcessor(dc, results);
     229        manager.processFiles(disablePlugins, uninstallFilter);
     230        numDisabledPlugins = disablePlugins.getNumPlugins();
     231       
     232        // 1d. Mark files as uninstalled and remove from the manager
     233        UninstalledFileProcessor uninstall = new UninstalledFileProcessor(results);
     234        manager.processFiles(uninstall, uninstallFilter);
     235        numUninstalled = uninstall.getNumFiles();
     236        log.debug("Uninstalled " + numUninstalled + " extensions");
    225237      }
    226238     
    227       log.debug("Checking for new and updated files");
    228       // 2. Update the manager with new and modified files (skip new files for initial scan)
    229       manager.scanForNewAndUpdated(!initialScan);
    230       numNewFiles = manager.getNumNew();
    231       numModifiedFiles = manager.getNumModified();
    232       numDeletedFiles = manager.getNumDeleted();
    233       log.debug("Found " + numNewFiles + " new and " + numModifiedFiles + " modified files");
     239      // 2. Process files that has been selected for installation
     240      log.debug("Installing/updating extensions");
     241      // In the initial scan we only process already installed extensions
     242      Filter<ExtensionsFile> installFilter = initialScan ?
     243        new InstalledFilter(settings) : new InstallFilter(request);
    234244     
    235       if (initialScan || numNewFiles > 0 || numModifiedFiles > 0 || forceUpdate)
     245      // 2a. Load extension definitions
     246      WebClientRegisterExtensionsProcessor registerExtensions =
     247        new WebClientRegisterExtensionsProcessor(rootPath, rootPath + RESOURCES_URL, rootPath + SERVLET_URL, results);
     248      registerExtensions.setForceUpdate(!initialScan);
     249      if (initialScan)
    236250      {
    237         // 3. Process files that are valid and new/updated (unless forceUpdate=true)
    238         ValidAndNewOrModifiedFilter valid = new ValidAndNewOrModifiedFilter(initialScan || forceUpdate);
     251        // Filter that only load web extension points
     252        registerExtensions.getXmlLoader().setFilter(new ExtensionPointFilter("net\\.sf\\.basedb\\.clients\\.web\\..*"));
     253      }
     254      manager.processFiles(registerExtensions, installFilter);
     255
     256      // 2b. Load plug-in definitions information
     257      PluginInstallationProcessor pluginInstaller = new PluginInstallationProcessor(dc, new XmlLoader(), results);
     258      manager.processFiles(pluginInstaller, installFilter);
     259      numInstalledPlugins = pluginInstaller.getNumPlugins();
     260     
     261      // 2c. Extract web resources
     262      ExtractResourcesProcessor extractResources = new ExtractResourcesProcessor(resourceDir, Pattern.compile("resources/(.*)"), "$1", results);
     263      extractResources.setForceOverwrite(!initialScan);
     264      manager.processFiles(extractResources, installFilter);
     265
     266      // 2d. Servlets
     267      LoadServletsProcessor loadServlets = new LoadServletsProcessor(servletContext, results);
     268      manager.processFiles(loadServlets, installFilter);
    239269       
    240         // 3a. Load extension definitions
    241         WebClientRegisterExtensionsProcessor registerExtensions =
    242           new WebClientRegisterExtensionsProcessor(rootPath, rootPath + RESOURCES_URL, rootPath + SERVLET_URL, results);
    243         registerExtensions.setForceUpdate(forceUpdate);
    244         if (initialScan)
    245         {
    246           // Filter that only load web extension points
    247           registerExtensions.getXmlLoader().setFilter(new ExtensionPointFilter("net\\.sf\\.basedb\\.clients\\.web\\..*"));
    248         }
    249         manager.processFiles(registerExtensions, valid);
    250 
    251         PluginInstallationProcessor pluginInstaller = new PluginInstallationProcessor(dc, new XmlLoader(), results);
    252         manager.processFiles(pluginInstaller, valid);
    253         numPlugins = pluginInstaller.getNumPlugins();
    254        
    255         // 3b. Extract web resources
    256         ExtractResourcesProcessor extractResources = new ExtractResourcesProcessor(resourceDir, Pattern.compile("resources/(.*)"), "$1", results);
    257         extractResources.setForceOverwrite(forceUpdate);
    258         manager.processFiles(extractResources, valid);
    259 
    260         // 3c. Servlets
    261         LoadServletsProcessor loadServlets = new LoadServletsProcessor(servletContext, results);
    262         manager.processFiles(loadServlets, valid);
    263        
    264         // 3d. Actual registration of all extensions
    265         registerExtensions.finalizeRegistration(manager);
    266         numRegistered = registerExtensions.getNumRegistered();
    267       }
     270      // 2e. Actual registration of all extensions
     271      registerExtensions.finalizeRegistration(manager, !initialScan);
     272      numRegistered = registerExtensions.getNumRegistered();
    268273     
    269       // 4. Reset the 'last modifed' status of all files and generated summary per file
    270       manager.processFiles(new SetFileStatusProcessor(results));
     274      // 3. Reset the 'last modified' status of all files and generated summary per file
     275      InstalledFileProcessor install = new InstalledFileProcessor(results);
     276      manager.processFiles(install, installFilter);
     277      numInstalled = install.getNumFiles();
    271278      results.setEnded();
    272279    }
     
    274281    // Generate summary message, etc.
    275282    StringBuilder summary = new StringBuilder();
    276     if (numDeletedFiles > 0)
    277     {
    278       summary.append(numDeletedFiles).append(" deleted extension file(s) containing ");
     283    if (numInstalled > 0)
     284    {
     285      summary.append(numInstalled).append(" installed/updated extension file(s)\n");
     286      summary.append(numRegistered).append(" extension(s) registered\n");
     287    }
     288    if (numInstalledPlugins > 0)
     289    {
     290      summary.append(numInstalledPlugins).append(" plug-in(s) installed or updated\n");
     291    }
     292    if (numUninstalled > 0)
     293    {
     294      summary.append(numUninstalled).append(" uninstalled extension file(s) containing ");
    279295      summary.append(numUnregistered).append(" extension(s)\n");
    280296    }
    281     summary.append(numNewFiles).append(" new extension file(s)\n");
    282     summary.append(numModifiedFiles).append(" updated extension file(s)\n");
    283     summary.append(numRegistered).append(" extension(s) registered\n");
    284     if (numPlugins > 0)
    285     {
    286       summary.append(numPlugins).append(" plug-in(s) installed or updated\n");
     297    if (numDisabledPlugins > 0)
     298    {
     299      summary.append(numDisabledPlugins).append(" plug-in(s) have been disabled\n");
    287300    }
    288301    if (results.getNumErrorFiles() > 0)
     
    480493 
    481494  /**
    482     Perform a manual scan for new/updated/deleted extensions.
     495    Scan the managed directories for new/updated/deleted extensions.
     496    Call {@link #getFiles()} to get an updated list of files.
     497   
     498    @throws PermissionDeniedException If the logged in user doesn't
     499      have WRITE permission
     500    @return The combined number of new/modified/deleted files
     501    @since 3.0
     502  */
     503  public int scanForChanges()
     504  {
     505    return manager.scanForChanges();
     506  }
     507 
     508  /**
     509    Perform the requested actions (install/uninstall) as given
     510    in the request form.
     511   
     512    a manual scan for new/updated/deleted extensions.
    483513    If <code>forceUpdate</code> is TRUE all extensions are updated,
    484514    which means that the definitions are re-loaded and resource
     
    491521    @since 3.0
    492522  */
    493   public ProcessResults installAndUpdateExtensions(boolean forceUpdate)
     523  public ProcessResults performActions(HttpServletRequest request)
    494524  {
    495525    checkPermission(Permission.WRITE, "extensions");
    496     return scan(dc, false, forceUpdate);
     526    ProcessResults results = scan(dc, request);
     527    saveSettings();
     528    return results;
    497529  }
    498530 
  • trunk/src/clients/web/net/sf/basedb/clients/web/extensions/InstalledFileProcessor.java

    r5610 r5616  
    3232  File processor implementation that sets a final result status for each
    3333  processed file (eg. "Installed", "Updated", "Deleted", etc). It will
    34   also mark all files as processed.
     34  also mark all files as processed and installed.
    3535 
    3636  @author Nicklas
     
    3838  @base.modified $Date$
    3939*/
    40 public class SetFileStatusProcessor
     40public class InstalledFileProcessor
    4141  extends MarkAsProcessedProcessor
    4242{
    4343
    4444  private final ProcessResults results;
    45   public SetFileStatusProcessor(ProcessResults results)
     45  public InstalledFileProcessor(ProcessResults results)
    4646  {
    4747    super();
     
    7474      results.setStatus(xtFile, "Updated");
    7575    }
    76     else if (results.wasForceUpdate())
    77     {
    78       results.setStatus(xtFile, "Forced update");
    79     }
    8076    else
    8177    {
    8278      results.setStatus(xtFile, "Already installed");
    8379    }
     80    wFile.setInstalled();
    8481    super.processFile(manager, wFile);
    8582  }
  • trunk/src/clients/web/net/sf/basedb/clients/web/resources/menu.properties

    r5525 r5616  
    184184## Plug-ins menu ##
    185185###################
    186 menu.plugins  Plug-ins
    187 menu.plugins.tooltip  Administrate plug-in definitions, configurations and job agents
    188 plugintypes.title Types
     186menu.plugins  Plug-ins &amp; extensions
     187menu.plugins.tooltip  Administrate extensions, plug-in definitions, configurations and job agents
     188installedextensions.title Overview
     189installedextensions.tooltip An overview of installed extensions and plug-ins
     190plugintypes.title Plug-in types
    189191plugintypes.tooltip.1 Administrate plug-in types
    190192plugintypes.tooltip.0 You do not have permission to administrate plug-in types
    191 plugindefinitions.title Definitions
     193plugindefinitions.title Plug-in definitions
    192194plugindefinitions.tooltip.1 Administrate plug-in definitions
    193195plugindefinitions.tooltip.0 You do not have permission to administrate plug-in definitions
    194 pluginconfigurations.title  Configurations
     196pluginconfigurations.title  Plug-in configurations
    195197pluginconfigurations.tooltip.1  Administrate plugin configurations
    196198pluginconfigurations.tooltip.0  You do not have permission to administrate plugin configurations
     
    238240#####################
    239241menu.extensions Extensions
    240 installedextensions.title Installed extensions
    241 installedextensions.tooltip Display and administrate installed extensions
    242 manualscan.title  Manual scan
    243 manualscan.tooltip  Start a manual scan for new, updated and deleted extensions
    244242
    245243## Help menu ##
  • trunk/src/core/net/sf/basedb/core/Application.java

    r5615 r5616  
    3737import net.sf.basedb.util.extensions.manager.ExtensionsManager;
    3838import net.sf.basedb.util.extensions.manager.ProcessResults;
    39 import net.sf.basedb.util.extensions.manager.filter.ValidAndNewOrModifiedFilter;
     39import net.sf.basedb.util.extensions.manager.filter.InstalledFilter;
    4040import net.sf.basedb.util.extensions.manager.filter.WasProcessedFilter;
    4141import net.sf.basedb.util.extensions.manager.processor.MarkAsProcessedProcessor;
     
    569569        }
    570570       
    571         // Register and load core extensions
     571        // Register and load core extensions only
    572572        XmlLoader loader = new XmlLoader();
    573         ProcessResults results = new ProcessResults(false, false);
    574         // Filter that only load core extension points
    575573        loader.setFilter(new ExtensionPointFilter("net\\.sf\\.basedb\\.core\\..*"));
    576         xtManager.processFiles(new RegisterExtensionsProcessor(loader, results), new ValidAndNewOrModifiedFilter(false));
     574        ProcessResults results = new ProcessResults();
     575        xtManager.processFiles(new RegisterExtensionsProcessor(loader, results), new InstalledFilter(xtManager.getSettings()));
     576       
     577        // Finalize registration
    577578        xtManager.processFiles(new MarkAsProcessedProcessor(), new WasProcessedFilter(results));
    578        
     579
    579580        // Initialise log manager factory
    580581        if (logManagerFactoryDriver != null)
  • trunk/src/core/net/sf/basedb/core/PluginDefinition.java

    r5615 r5616  
    374374  }
    375375 
     376  /**
     377    Install or update the plug-in definition with information from the info
     378    object. Existing plug-ins will be updated and the disabled flag is cleared.
     379    New plug-ins are configured with additional options from the info object:
     380    <ul>
     381    <li>max-memory: Maximum memory in bytes when the plug-in is executed as an external
     382      process by a job agent
     383    <li>immediate-execution: If the plug-in is allowed to bypass the job queue.
     384    <li>everyone-use: If the plug-in should be shared with USE permission to everyone.
     385    </ul>
     386    @since 3.0
     387  */
    376388  public static PluginDefinition installOrUpdate(DbControl dc, PluginInfo info, String jarFile, ItemKey shareToEveryone)
    377389  {
     
    393405      }
    394406      dc.saveItem(plugin);
     407      plugin.info = info; // So that we can set an ID on the info object after commit.
    395408    }
    396409    plugin.setAbout(info.getAbout(), true);
    397    
     410    plugin.setDisabled(false);
    398411    return plugin;
    399    
    400     /*
    401     if (plugin != null)
    402     {
    403       pd.loadPluginInformation(null, className, true);
    404       pd.setAbout(info.getAbout(), false);
    405       dc.commit();
    406       log.info("createPluginDefinition: UPDATED [class="+className+"]");
    407     }
    408     else
    409     {
    410       pd = PluginDefinition.getNew(dc, className, null, true);
    411       pd.setAbout(info.getAbout(), false);
    412       pd.setTrusted(true);
    413       pd.setMaxMemory(Values.getLong(info.getProperty("max-memory"), null));
    414       pd.setAllowImmediateExecution(Values.getBoolean(info.getProperty("immediate-execution")));
    415       if (Values.getBoolean(info.getProperty("everyone-use")))
    416       {
    417         pd.getData().setItemKey(shareToEveryone);
    418       }
    419       dc.saveItem(pd);
    420       dc.commit();
    421         log.info("createPluginDefinition: OK [class="+className+"]");
    422       }
    423     }
    424     catch (BaseException ex)
    425     {
    426       log.error("createPluginDefinition: FAILED [class="+className+"]", ex);
    427       throw ex;
    428     }
    429     finally
    430     {
    431       if (dc != null) dc.close();
    432     }
    433     return pd;
    434     */
    435 
    436   }
     412  }
     413 
     414  private PluginInfo info;
    437415 
    438416  PluginDefinition(PluginDefinitionData pd)
     
    510488    return count > 0 || super.isUsed();
    511489  }
     490 
     491  @Override
     492  void onAfterInsert()
     493    throws BaseException
     494  {
     495    super.onAfterInsert();
     496    if (info != null) info.setInternalId(getId());
     497  }
     498
     499
    512500  /**
    513501   Get all:
  • trunk/src/core/net/sf/basedb/core/Presets.java

    r5384 r5616  
    2424import net.sf.basedb.util.XMLUtil;
    2525
     26import java.util.ArrayList;
    2627import java.util.HashMap;
    2728import java.util.Iterator;
     
    345346      }
    346347    }
     348   
     349    /**
     350      Get all keys in this preset. The returned list is a
     351      copy of the settings and are not affected by later
     352      additions or removals.
     353    */
     354    public List<String> getKeys()
     355    {
     356      return new ArrayList<String>(settings.keySet());
     357    }
    347358 
    348359  }
  • trunk/src/core/net/sf/basedb/util/extensions/manager/ExtensionsFile.java

    r5607 r5616  
    230230  }
    231231
     232  /**
     233    Is this file installed into the system or not?
     234  */
     235  public boolean isInstalled()
     236  {
     237    return file == null || manager.getSettings().isInstalledFile(file);
     238  }
     239 
    232240  /**
    233241    Check if the file was modified when the last call to
     
    666674        // Cleanup to avoid leaking memory
    667675        xtFile.allObjects.clear();
     676        xtFile.manager.unregisterAllObjects(xtFile);
     677        xtFile.objectMetadata.clear();
    668678        xtFile.jarLoader = null;
    669         xtFile.objectMetadata.clear();
    670679      }
     680    }
     681   
     682    /**
     683      Mark the file as uninstalled.
     684    */
     685    public void setUninstalled()
     686    {
     687      xtFile.manager.removeFile(xtFile.file);
     688    }
     689   
     690    /**
     691      Mark the file as installed.
     692    */
     693    public void setInstalled()
     694    {
     695      xtFile.manager.getSettings().setInstalledFile(xtFile.file);
    671696    }
    672697   
  • trunk/src/core/net/sf/basedb/util/extensions/manager/ExtensionsManager.java

    r5615 r5616  
    6565  // Directories to scan for new/deleted/modified extensions
    6666  private final Set<File> directories;
    67   // Valid extension files
     67  // Extension files
    6868  private final Map<URI, ExtensionsFile> xtFiles;
    6969  // Map objects to the file they are defined in. The key is a unique object id.
     
    7979    to store extensions.
    8080   
    81     @param registry
     81    @param registry The registry to use
     82    @param settingsFile The file were settings are stored
    8283  */
    8384  public ExtensionsManager(Registry registry, File settingsFile)
     
    9091    this.installedObjects = new HashMap<ObjectKey<?>, ExtensionsFile>();
    9192    addIgnore(settingsFile);
     93    // Add installed files
     94    for (File f : settings.getInstalledFiles())
     95    {
     96      ExtensionsFile xtFile = new ExtensionsFile(this, f);
     97      addExtensionsFile(xtFile);
     98    }
    9299  }
    93100 
     
    134141
    135142  /**
    136     Add a directory to this manager. The directory is automatically
    137     scanned for previously known files with .xml or .jar extensions
    138     which are added as extension files. To also scan for new files,
    139     call the {@link #scanForNewAndUpdated()} method.
     143    Add a directory to this manager. The directory will be monitored
     144    for extension files in the future.
    140145    <p>
    141146    This method call is ignored if the
     
    146151      not previously known to the manager
    147152  */
    148   public synchronized int addDirectory(File dir)
     153  public synchronized void addDirectory(File dir)
    149154  {
    150155    if (dir == null) throw new NullPointerException("dir");
     156    if (!dir.isDirectory()) return;
    151157    directories.add(dir);
    152     int numNew = scanForNewFiles(dir, false);
    153     return numNew;
    154158  }
    155159 
     
    169173    addExtensionsFile(xtFile);
    170174    return xtFile;
     175  }
     176 
     177  /**
     178    Remove a file from the extensions manager. This method will
     179    remove some information about the file from the manager itself,
     180    but it will not touch registered extensions, plug-ins, extracted
     181    resources, etc. The file itself is not deleted from the disk.
     182    <p>
     183    Note that if the file remains in a managed directory it will
     184    reappear in the manager if {@link #scanForChanges()} is
     185    called.
     186   
     187    @param file The file to remove (if null this method is ignored)
     188  */
     189  void removeFile(File file)
     190  {
     191    if (file == null) return;
     192    settings.setUninstalledFile(file);
     193    ExtensionsFile xtFile = xtFiles.remove(file.toURI());
     194    if (xtFile == null) return;
     195    unregisterAllObjects(xtFile);
    171196  }
    172197 
     
    196221    xtFile.validate();
    197222    xtFiles.put(xtFile.getURI(), xtFile);
    198     if (xtFile.getFile() != null)
    199     {
    200       settings.setKnownFile(xtFile.getFile());
    201     }
    202223    log.info("Added file: " + xtFile);
    203224  }
    204225 
    205226  /**
    206     Scan the managed directories for new/updated and deleted files.
    207     Files that have been deleted are simply removed from the manager.
    208     Any actions that are needed when a file has been deleted must be
    209     done before calling this method. Eg. call
    210     {@link #processFiles(ExtensionsFileProcessor)} with a processor
    211     implementation that checks {@link ExtensionsFile#exists()}.
    212 
    213     @param installAllNew TRUE to install all new files, FALSE to only install
    214       new files that are previously known according to {@link Settings#isKnownFile(File)}
    215     @return The number of new + modified files that was found
    216   */
    217   public synchronized int scanForNewAndUpdated(boolean installAllNew)
     227    Scan the managed directories for new, updated and deleted files.
     228    This method is used for gathering statistics only. To do something
     229    with the files the {@link #processFiles(ExtensionsFileProcessor)}
     230    method must be called.
     231    <p>
     232    Note! The new or modified status of files are NOT reset as a result
     233    of calling this method. The status can only be changed as a result
     234    of some processing.
     235   
     236    @return The number of new + modified + deleted files that was found
     237  */
     238  public synchronized int scanForChanges()
    218239  {
    219240    numNew = 0;
     
    222243    numUnmodified = 0;
    223244   
    224     // 1. Check all known files -- remove deleted and count modified
     245    // 1. Check and count all known files
    225246    Iterator<ExtensionsFile> it = xtFiles.values().iterator();
    226247    while (it.hasNext())
     
    230251      {
    231252        log.debug("File '" + xtFile + "' has been deleted.");
    232         unregisterAllObjects(xtFile);
    233         settings.removeKnownFile(xtFile.getFile());
    234         it.remove();
    235253        numDeleted++;
    236254      }
    237255      else if (xtFile.isNew())
    238256      {
     257        log.debug("File '" + xtFile + "' is new. Validating...");
     258        xtFile.validate();
     259        log.debug("File '" + xtFile + "' is " + (xtFile.isValid() ? "valid" : "invalid"));
    239260        numNew++;
    240261      }
     
    255276    for (File dir : directories)
    256277    {
    257       numNew += scanForNewFiles(dir, installAllNew);
    258     }
    259    
    260     settings.save();
    261    
    262     return numModified + numNew;
     278      numNew += scanForNewFiles(dir);
     279    }
     280   
     281    return numModified + numNew + numDeleted;
    263282  }
    264283 
     
    302321    Scan the given directory and add files that are new.
    303322    @param dir The directory to scan
    304     @param installAllNew TRUE to install all new files, FALSE to only install
    305       new files that are previously known according to {@link Settings#isKnownFile(File)}
    306323    @return The number of new files in the given directory
    307324  */
    308   private int scanForNewFiles(File dir, boolean installAllNew)
     325  private int scanForNewFiles(File dir)
    309326  {
    310327    int numNew = 0;
     
    339356        else
    340357        {
    341           if (installAllNew || settings.isKnownFile(file))
    342           {
    343             log.debug("Installing file: " + file);
    344             xtFile = new ExtensionsFile(this, file);
    345             addExtensionsFile(xtFile);
    346             numNew++;
    347           }
    348           else
    349           {
    350             log.debug("File '" + file + "' is an unknown file.");
    351           }
     358          log.debug("Adding file: " + file);
     359          xtFile = new ExtensionsFile(this, file);
     360          addExtensionsFile(xtFile);
     361          numNew++;
    352362        }
    353363      }
    354       log.info("Found " + numNew + " files");
     364      log.info("Found " + numNew + " new *.xml and *.jar files");
    355365    }
    356366    else
    357367    {
    358       log.info("Found no files");
    359     }
    360    
     368      log.info("Found no *.xml or *.jar files");
     369    }
    361370    return numNew;
    362371  }
  • trunk/src/core/net/sf/basedb/util/extensions/manager/ProcessResults.java

    r5603 r5616  
    3939{
    4040
    41   private final boolean manualScan;
    42   private final boolean forceUpdate;
    4341  private final long startTime;
    4442
     
    5149  /**
    5250    Create a new process results object.
    53     @param forceUpdate TRUE if the scan is forcing update of already
    54       installed extensions, FALSE otherwise
    55   */
    56   public ProcessResults(boolean manualScan, boolean forceUpdate)
    57   {
    58     this.manualScan = manualScan;
    59     this.forceUpdate = forceUpdate;
     51  */
     52  public ProcessResults()
     53  {
    6054    this.fileResults = new TreeMap<ExtensionsFile, FileResults>();
    6155    this.hasError = false;
     
    6458  }
    6559
    66   /**
    67     @return TRUE if the scan was manual, FALSE if it was automatic
    68   */
    69   public boolean wasManual()
    70   {
    71     return manualScan;
    72   }
    73 
    74   /**
    75     @return TRUE if the scan forced update of already
    76       installed extensions, FALSE otherwise
    77   */
    78   public boolean wasForceUpdate()
    79   {
    80     return forceUpdate;
    81   }
    82  
    8360  /**
    8461    Get the start time of the scan as a millisecond value.
  • trunk/src/core/net/sf/basedb/util/extensions/manager/Settings.java

    r5615 r5616  
    2929import java.io.InputStream;
    3030import java.io.OutputStream;
     31import java.util.ArrayList;
     32import java.util.List;
    3133
    3234import net.sf.basedb.core.Presets;
     
    7173  private Presets presets;
    7274  private Preset settings;
    73   private Preset knownFiles;
     75  private Preset installedFiles;
    7476  private Preset disabledExtensions;
    7577  private Preset disabledExtensionPoints;
     
    101103    }
    102104    this.settings = presets.getDefault();
    103     this.knownFiles = presets.getPreset("known-files");
     105    this.installedFiles = presets.getPreset("installed-files");
    104106    this.disabledExtensionPoints = presets.getPreset("disabled-extension-points");
    105107    this.disabledExtensions = presets.getPreset("disabled-extensions");
     
    152154  }
    153155 
    154   public boolean isKnownFile(File file)
    155   {
    156     return Values.getBoolean(knownFiles.getSetting(file.getAbsolutePath()));
    157   }
    158  
    159   public void setKnownFile(File file)
    160   {
    161     hasChanged = true;
    162     knownFiles.setSetting(file.getAbsolutePath(), "1");
    163   }
    164  
    165   public void removeKnownFile(File file)
    166   {
    167     hasChanged = true;
    168     knownFiles.setSetting(file.getAbsolutePath(), null);
    169   }
     156  /**
     157    Check if the given file is marked as installed.
     158    @since 3.0
     159  */
     160  public boolean isInstalledFile(File file)
     161  {
     162    return Values.getBoolean(installedFiles.getSetting(file.getAbsolutePath()));
     163  }
     164 
     165  /**
     166    Mark the given file as installed by the extension system.
     167    @since 3.0
     168  */
     169  public void setInstalledFile(File file)
     170  {
     171    if (file == null) return;
     172    hasChanged = true;
     173    installedFiles.setSetting(file.getAbsolutePath(), "1");
     174  }
     175 
     176  /**
     177    Mark the given file as uninstalled.
     178    @since 3.0
     179  */
     180  public void setUninstalledFile(File file)
     181  {
     182    if (file == null) return;
     183    hasChanged = true;
     184    installedFiles.setSetting(file.getAbsolutePath(), null);
     185  }
     186 
     187  /**
     188    Get a list with all files that are installed.
     189    @since 3.0
     190  */
     191  public List<File> getInstalledFiles()
     192  {
     193    List<String> paths = installedFiles.getKeys();
     194    List<File> files = new ArrayList<File>(paths.size());
     195    for (String path : paths)
     196    {
     197      files.add(new File(path));
     198    }
     199    return files;
     200  }
     201 
    170202 
    171203  /**
  • trunk/src/core/net/sf/basedb/util/extensions/manager/filter/ValidAndNewOrModifiedFilter.java

    r5607 r5616  
    4343
    4444  private final boolean allowUnmodified;
     45  private final Filter<ExtensionsFile> parent;
    4546 
    4647  /**
     
    5253  public ValidAndNewOrModifiedFilter(boolean allowUnmodified)
    5354  {
     55    this(allowUnmodified, null);
     56  }
     57 
     58  /**
     59    Create a new filter.
     60   
     61    @param allowUnmodified TRUE to allow unmodified files to
     62      pass the filter, FALSE to block them
     63    @param parent An optional parent filter that will also be checked
     64  */
     65  public ValidAndNewOrModifiedFilter(boolean allowUnmodified, Filter<ExtensionsFile> parent)
     66  {
    5467    this.allowUnmodified = allowUnmodified;
     68    this.parent = parent;
    5569  }
    5670 
     
    6276  public boolean evaluate(ExtensionsFile xtFile)
    6377  {
     78    if (parent != null && !parent.evaluate(xtFile))
     79    {
     80      return false;
     81    }
     82   
    6483    if (!xtFile.isValid() || (xtFile.hasError() && !allowUnmodified))
    6584    {
  • trunk/src/core/net/sf/basedb/util/extensions/manager/processor/PluginInstallationProcessor.java

    r5615 r5616  
    104104      int numInstalled = 0;
    105105      int numUpdated = 0;
     106      int numProcessed = 0;
    106107      if (plugins.size() > 0)
    107108      {
     
    130131            }
    131132          }
     133          numProcessed++;
    132134          wFile.registerObject(new PluginInfoKey(info), info);
    133135        }
     
    138140      if (results != null)
    139141      {
    140         if (numInstalled > 0) results.addMessage(xtFile, numInstalled + " plug-ins installed.");
    141         if (numUpdated > 0) results.addMessage(xtFile, numUpdated + " plug-ins updated.");
     142        if (numInstalled > 0) results.addMessage(xtFile, numInstalled + " plug-in(s) installed.");
     143        if (numUpdated > 0) results.addMessage(xtFile, numUpdated + " plug-in(s) updated.");
     144        if (numInstalled == 0 && numUpdated == 0 && numProcessed > 0)
     145        {
     146          results.addMessage(xtFile, numProcessed + " plug-in(s) loaded");
     147        }
    142148      }
    143       log.info("Installed/updated " + numInstalled + "/" + numUpdated + " plug-ins from file: " + xtFile);
     149      log.info("Installed/updated/processed " + numInstalled + "/" + numUpdated + "/" + numProcessed + " plug-ins from file: " + xtFile);
    144150    }
    145151    catch (Exception ex)
  • trunk/src/core/net/sf/basedb/util/extensions/manager/processor/RegisterExtensionsProcessor.java

    r5607 r5616  
    148148  public void done(ExtensionsManager manager)
    149149  {
    150     if (!delayRegistration) finalizeRegistration(manager);
     150    if (!delayRegistration) finalizeRegistration(manager, true);
    151151  }
    152152 
     
    206206  }
    207207 
    208   public void finalizeRegistration(ExtensionsManager manager)
     208  public void finalizeRegistration(ExtensionsManager manager, boolean unregisterMissing)
    209209  {
    210210    if (allData == null) return;
     
    213213
    214214    // First loop -- unregister extensions and extension points that are missing
    215     log.info("Unregistering all missing extension points and extensions");
    216     for (FileData data : allData)
    217     {
    218       WriteableExtensionsFile wFile = data.writeableFile;
    219       ExtensionsFile xtFile = wFile.getExtensionsFile();
    220 
    221       if (!forceUpdate && (!xtFile.wasModified() || xtFile.isNew()))
    222       {
    223         log.debug("Skipping new or unmodified file: " + xtFile);
    224         continue;
    225       }
    226 
    227       // Unregister all extensions if the file has an error
    228       if (xtFile.hasError())
    229       {
    230         data.extensions = Collections.emptyList();
    231         data.extensionPoints = Collections.emptyList();
    232       }
    233      
    234       try
    235       {
    236         wFile.open();
    237         int num = 0;
    238         // Extension points
    239         for (ExtensionPoint ep : xtFile.getObjectsOfClass(ExtensionPoint.class))
    240         {
    241           if (unregisterExtensionPoint(data, ep, registry))
     215    if (unregisterMissing)
     216    {
     217      log.info("Unregistering all missing extension points and extensions");
     218      for (FileData data : allData)
     219      {
     220        WriteableExtensionsFile wFile = data.writeableFile;
     221        ExtensionsFile xtFile = wFile.getExtensionsFile();
     222 
     223        if (!forceUpdate && (!xtFile.wasModified() || xtFile.isNew()))
     224        {
     225          log.debug("Skipping new or unmodified file: " + xtFile);
     226          continue;
     227        }
     228 
     229        // Unregister all extensions if the file has an error
     230        if (xtFile.hasError())
     231        {
     232          data.extensions = Collections.emptyList();
     233          data.extensionPoints = Collections.emptyList();
     234        }
     235       
     236        try
     237        {
     238          wFile.open();
     239          int num = 0;
     240          // Extension points
     241          for (ExtensionPoint ep : xtFile.getObjectsOfClass(ExtensionPoint.class))
    242242          {
    243             num++;
     243            if (unregisterExtensionPoint(data, ep, registry))
     244            {
     245              num++;
     246            }
    244247          }
    245         }
    246         if (num > 0 && results != null)
    247         {
    248           numUnregistered += num;
    249           results.addMessage(xtFile, num + " extension point(s) unregistered.");
    250         }
    251         log.info("Unregistered " + num + " extension point(s) from file: " + xtFile);
    252        
    253         // Extensions
    254         num = 0;
    255         for (Extension ext : xtFile.getObjectsOfClass(Extension.class))
    256         {
    257           if (unregisterExtension(data, ext, registry))
     248          if (num > 0 && results != null)
    258249          {
    259             num++;
     250            numUnregistered += num;
     251            results.addMessage(xtFile, num + " extension point(s) unregistered.");
    260252          }
    261         }
    262         if (num > 0 && results != null)
    263         {
    264           numUnregistered += num;
    265           results.addMessage(xtFile, num + " extension(s) unregistered.");
    266         }
    267         log.info("Unregistered " + num + " extension(s) from file: " + xtFile);
    268       }
    269       catch (Throwable ex)
    270       {
    271         log.error("Could not unregister extensions from file: " + xtFile, ex);
    272       }
    273       finally
    274       {
    275         wFile.close(); // Important! release the write lock
    276       }
    277     }
    278    
     253          log.info("Unregistered " + num + " extension point(s) from file: " + xtFile);
     254         
     255          // Extensions
     256          num = 0;
     257          for (Extension ext : xtFile.getObjectsOfClass(Extension.class))
     258          {
     259            if (unregisterExtension(data, ext, registry))
     260            {
     261              num++;
     262            }
     263          }
     264          if (num > 0 && results != null)
     265          {
     266            numUnregistered += num;
     267            results.addMessage(xtFile, num + " extension(s) unregistered.");
     268          }
     269          log.info("Unregistered " + num + " extension(s) from file: " + xtFile);
     270        }
     271        catch (Throwable ex)
     272        {
     273          log.error("Could not unregister extensions from file: " + xtFile, ex);
     274        }
     275        finally
     276        {
     277          wFile.close(); // Important! release the write lock
     278        }
     279      }
     280    }
    279281   
    280282    // Second loop -- register extension points
  • trunk/src/core/net/sf/basedb/util/extensions/xml/XmlLoader.java

    r5615 r5616  
    835835        }
    836836       
    837         // <plugin-class>
    838         String className = Values.getStringOrNull(pdTag.getChildText("plugin-class", ns));
    839        
    840         PluginInfo info = new PluginInfo(id);
    841         info.setAbout(about);
    842         info.setClassName(className);
    843        
    844         temp.add(info);
    845        
    846         // <settings>
    847         Element settingsTag = pdTag.getChild("settings", ns);
    848         if (settingsTag != null)
    849         {
    850           for (Element propertyTag : (List<Element>)settingsTag.getChildren("property", ns))
    851           {
    852             String name = propertyTag.getAttributeValue("name");
    853             String value = Values.getStringOrNull(propertyTag.getText());
    854             info.setProperty(name, value);
    855           }
    856         }
    857        
    858837        if (!verifyBaseVersion(about, false))
    859838        {
     
    866845        else
    867846        {
    868           // <action-factory>
    869           /*
    870           Element afTag = epTag.getChild("action-factory", ns);
    871           ActionFactory af = null;
    872           if (afTag != null)
     847          // <plugin-class>
     848          String className = Values.getStringOrNull(pdTag.getChildText("plugin-class", ns));
     849         
     850          PluginInfo info = new PluginInfo(id);
     851          info.setAbout(about);
     852          info.setClassName(className);
     853         
     854          temp.add(info);
     855         
     856          // <settings>
     857          Element settingsTag = pdTag.getChild("settings", ns);
     858          if (settingsTag != null)
    873859          {
    874             af = createFactory(afTag, classLoader, ActionFactory.class);
     860            for (Element propertyTag : (List<Element>)settingsTag.getChildren("property", ns))
     861            {
     862              String name = propertyTag.getAttributeValue("name");
     863              String value = Values.getStringOrNull(propertyTag.getText());
     864              info.setProperty(name, value);
     865            }
    875866          }
    876           */
    877867        }
    878868      }
  • trunk/src/test/TestAll.java

    r5523 r5616  
    140140    results.put("TestPresets", TestPresets.test_all());
    141141    results.put("TestNumberFormat", TestNumberFormat.test_all());
    142     results.put("TestExternalPluginInstaller", TestExternalPluginInstaller.test_all());
    143142    results.put("TestMetadata", TestMetadata.test_all());
    144143
  • trunk/www/admin/extensions/details.jsp

    r5615 r5616  
    162162  }
    163163
    164   function editSettings()
    165   {
    166     Main.openPopup('settings.jsp?ID=<%=ID%>', 'EditExtensionSettings', 500, 400);
    167   }
    168  
    169164  function editPlugin(pluginId)
    170165  {
     
    174169  function manualScan()
    175170  {
    176     Main.openPopup('index.jsp?ID=<%=ID%>&cmd=ManualScan', 'ManualScan', 600, 480);
     171    Main.openPopup('index.jsp?ID=<%=ID%>&cmd=ManualScan', 'ManualScan', 800, 480);
    177172  }
    178173 
     
    260255    {
    261256      %>
    262       <tbl:button
    263         onclick="editSettings()"
    264         title="Settings&hellip;"
    265         image="<%=writePermission ? "configure.png" : "configure_disabled.png" %>"
    266         tooltip="Change settings for the extension system"
    267         disabled="<%=!writePermission%>"
    268       />
    269257      <tbl:button
    270258        onclick="manualScan()"
    271         title="Manual scan&hellip;"
    272         image="<%=writePermission ? "refresh.gif" : "refresh_disabled.gif" %>"
    273         tooltip="Start a manual scan for new/updated/deleted extensions"
     259        title="Install/uninstall&hellip;"
     260        image="<%=writePermission ? "new_wizard.gif" : "new_wizard_disabled.gif" %>"
     261        tooltip="Install and uninstall extensions and plug-ins"
    274262        disabled="<%=!writePermission%>"
    275263      />
     
    539527      <table class="form" cellspacing="0">
    540528      <tr>
    541         <td class="prompt">Last scan</td>
     529        <td class="prompt">Last installation</td>
    542530        <td><%=results.hasError() ? "Failed": "Successful" %></td>
    543531      </tr>
  • trunk/www/admin/extensions/index.jsp

    r5615 r5616  
    5353    forward = "manager.jsp";
    5454  }
    55   else if ("SaveSettings".equals(cmd))
    56   {
    57     dc = sc.newDbControl();
    58     ExtensionsControl ec = ExtensionsControl.get(dc);
    59     ec.saveSettings();
    60     message = "Settings updated";
    61   }
    6255  else if ("EnableExtension".equals(cmd))
    6356  {
     
    9386  else if ("ManualScan".equals(cmd))
    9487  {
    95     forward = "manual_scan.jsp?ID=" + ID;
     88    forward = "wizard.jsp?ID=" + ID;
    9689  }
    9790  else if ("DoManualScan".equals(cmd))
     
    9992    dc = sc.newDbControl();
    10093    ExtensionsControl ec = ExtensionsControl.get(dc);
    101     boolean forceUpdate = Values.getBoolean(request.getParameter("forceUpdate"));
    102     ec.installAndUpdateExtensions(forceUpdate);
     94    ec.performActions(request);
    10395    dc.commit();
     96
    10497    redirect = "index.jsp?ID=" + ID + "&cmd=ScanResults";
    10598  }
  • trunk/www/admin/extensions/scan_results.jsp

    r5607 r5616  
    5858  Formatter timeFormatter = FormatterFactory.getDateTimeFormatter(sc);
    5959%>
    60   <base:page type="popup" title="Manual scan results">
     60  <base:page type="popup" title="Last installation results">
    6161  <base:head>
    6262  <script language="javascript">
     
    8282  <p>
    8383
    84   <h3 class="docked">Last scan results</h3>
     84  <h3 class="docked">Last installation results</h3>
    8585  <div class="boxedbottom" style="height: <%=(int)(scale*280)%>px; overflow: auto;">
    8686
     
    8888    <tr>
    8989      <td class="prompt">Status</td>
    90       <td><%=results.hasError() ? "Error" : "Success" %></td>
     90      <td colspan="3"><%=results.hasError() ? "Error" : "Success" %></td>
     91    </tr>
     92    <tr>
    9193      <td class="prompt">Started</td>
    9294      <td><%=timeFormatter.format(new Date(results.getStartTime()))%></td>
    93     </tr>
    94     <tr>
    95       <td class="prompt">Scan type</td>
    96       <td><%=results.wasManual() ? "Manual" : "Automatic" %></td>
    9795      <td class="prompt">Ended</td>
    9896      <td><%=timeFormatter.format(new Date(results.getEndTime()))%></td>
  • trunk/www/admin/extensions/tree.jsp

    r5615 r5616  
    6060  return joust;
    6161}
    62 String getJoustExtension(String parentNode, ExtensionsControl ec, Extension ext, ExtensionsFile ef, boolean inGroup)
     62String getJoustExtension(String parentNode, ExtensionsControl ec, Extension ext, ExtensionsFile ef, boolean inGroup, boolean showFile)
    6363{
    6464  String id = ext.getId();
     
    6666  String name = about == null || about.getName() == null ? id : about.getName();
    6767  if (inGroup) name = ext.getId().substring(ext.getId().indexOf(":"));
     68  if (showFile)
     69  {
     70    name += " <span class=\"itemref\">[" + ef.getName() + "]</span>";
     71  }
     72  else
     73  {
     74    name += " <span class=\"itemref\">[" + ec.getExtensionPoint(ext.getExtends()).getName() + "]</span>";
     75  }
    6876  String icon = ec.isEnabled(ext) ? "Extension" : "ExtensionDisabled";
    6977  if ((ef != null && ef.hasError()) || ec.getLastExtensionError(id) != null)
     
    173181      {
    174182        %>
    175         <%=getJoustExtension("ep", ec, ext, ec.getFileByObjectKey(new ExtensionKey(ext)), false)%>
     183        <%=getJoustExtension("ep", ec, ext, ec.getFileByObjectKey(new ExtensionKey(ext)), false, true)%>
    176184        <%
    177185      }
     
    184192    for (ExtensionsFile ef : ec.getFiles())
    185193    {
     194      if (!ef.isInstalled()) continue;
     195     
    186196      String efName = ef.getName();
    187197      String icon = ef.isJar() ? "JarFile" : "XmlFile";
     
    220230        }
    221231        %>
    222         <%=getJoustExtension(currentGroupId == null ? "file" : "group", ec, ext, ef, currentGroupId != null)%>
     232        <%=getJoustExtension(currentGroupId == null ? "file" : "group", ec, ext, ef, currentGroupId != null, false)%>
    223233        <%
    224234      }
     
    327337  }
    328338  </script>
     339  <style>
     340  .itemref {
     341    font-size: 10px;
     342    color: #777777;
     343  }
     344  </style>
    329345  </base:head>
    330346    <base:body onload="initialise()">
  • trunk/www/admin/plugindefinitions/index.jsp

    r5615 r5616  
    177177    cc.setId(0);
    178178   
    179     redirect = "select_installation_type.jsp?ID="+ID;
    180   }
    181   else if("InstallationType".equals(cmd))
    182   {
    183     //Either manually or auto installation is selected
    184     String type = request.getParameter("installationType");
    185     if ("auto".equals(type))
    186     {
    187       forward = "auto_install.jsp?ID="+ID;
    188     }
    189     else
    190     {
    191       redirect = editPage;
    192     }
    193   }
    194   /*
    195   else if("LoadPlugins".equals(cmd))
    196   {
    197     //Loads and install plugins that have been selected in auto_installer.jsp
    198     ItemContext cc = Base.getAndSetCurrentContext(sc, itemType, null, defaultContext);
    199     dc = sc.newDbControl();
    200     java.io.File pluginDir = Application.getPluginsDirectory();
    201     FileFilter jarFilter = new RegexpFileFilter(".*\\.jar", null);
    202     List<java.io.File> jarFiles = new LinkedList<java.io.File>();
    203     jarFiles.addAll(FileUtil.findFiles(pluginDir, jarFilter));
    204        
    205     List<PluginInfo> pluginInfos = new LinkedList<PluginInfo>();
    206     Map<PluginInfo, Throwable> installationResult = new LinkedHashMap<PluginInfo, Throwable>();
    207    
    208     //Get information about all plugins in jar-files that were found.
    209     for (java.io.File file : jarFiles)
    210     {
    211       try
    212       {
    213         pluginInfos.addAll(PluginInfo.loadFromJar(file));
    214       }
    215       catch (Exception ex)
    216       {}
    217     }
    218     //Load selected plugins.
    219     for (PluginInfo info : pluginInfos)
    220     {
    221       String selectedOption = request.getParameter(info.getJarPath() + ":" + info.getClassName());
    222       if (selectedOption == null) selectedOption = "";     
    223       boolean isInstalled = Values.getBoolean(request.getParameter(info.getClassName()+":isInstalled"));
    224       boolean inSameJarFile = Values.getBoolean(request.getParameter(info.getClassName()+":inSameJarFile"));
    225       boolean hasDifferentVersion = Values.getBoolean(request.getParameter(info.getClassName()+":hasDifferentVersion"));
    226       if (selectedOption.equals("plugin") || selectedOption.equals("plugin+confs"))
    227       {
    228         //The plugin doesn't exists
    229         if (!isInstalled)
    230         {
    231           PluginDefinition pd = null;
    232           try
    233           {
    234             pd = PluginDefinition.getNew(dc, info.getClassName(), info.getJarPath(), true);
    235             installationResult.put(info, null);
    236           }
    237           catch (Throwable t)
    238           {
    239             installationResult.put(info, new BaseException("Could not install: " +
    240                 info.getClassName() + " in jar:" + info.getJarPath(), t));
    241           }
    242           if (pd != null)
    243           {
    244             dc.saveItem(pd);
    245             pd.setTrusted(Values.getBoolean(request.getParameter(info.getClassName()+":trusted")));
    246             String aie = Values.getStringOrNull(request.getParameter(info.getClassName()+":immediate_execution"));
    247             pd.setAllowImmediateExecution(aie == null ?
    248               pd.getMainType() == Plugin.MainType.EXPORT : Values.getBoolean(aie));           
    249           }
    250         }
    251         //The plugin exists but in a different jar, this will change the plugin's jarpath
    252         else if (isInstalled && (!inSameJarFile || hasDifferentVersion))
    253         {
    254           try
    255           {
    256             PluginDefinition pd = PluginDefinition.getByClassName(dc, info.getClassName());
    257             pd.loadPluginInformation(info.getJarPath(), info.getClassName(), true);
    258             installationResult.put(info, null);
    259           }
    260           catch (Throwable t)
    261           {
    262             installationResult.put(info, new BaseException("Could not install: " +
    263                 info.getClassName() + " in jar:" + info.getJarPath(), t));
    264           }
    265         }
    266       }     
    267     }
    268     dc.commit();
    269    
    270     //Import selected configurations for each plugin in pluginInfos
    271     dc = sc.newDbControl();
    272     for (PluginInfo info : pluginInfos)
    273     {
    274       if (installationResult.get(info) != null) continue;
    275      
    276       List<PluginConfigInfo> configInfos = info.getConfigurations();
    277       if (configInfos != null && configInfos.size() > 0)
    278       {
    279         HashMap<Integer, Boolean> configurations = new HashMap<Integer, Boolean>();
    280         for (PluginConfigInfo cnfInfo : configInfos)
    281         {
    282           Boolean toImport = Values.getBoolean(request.getParameter(info.getClassName() + ":config:" + cnfInfo.getName()));
    283           configurations.put(cnfInfo.getOrderInXml(), toImport);
    284         }
    285         try
    286         {
    287           PluginConfigurationImporter configImporter = new PluginConfigurationImporter();
    288           configImporter.init(sc, null, null);
    289           configImporter.importPluginConfigurationsFromJar(info.getJarPath(), info.getConfigurationsPath(), configurations, false, true );
    290         }
    291         catch (Throwable t)
    292         {
    293           installationResult.put(info,
    294               new BaseException("Could not import configuration for: " +
    295               info.getClassName() + " in jar:" + info.getJarPath(), t));
    296         }
    297       }
    298     }
    299    
    300     for (Map.Entry<PluginInfo, Throwable> entry : installationResult.entrySet())
    301     {
    302       Throwable t = entry.getValue();
    303       if (t != null) t.printStackTrace();
    304     }
    305    
    306     sc.setSessionSetting("pluginwizard.installationresult", installationResult);
    307     redirect = "auto_install_result.jsp?ID=" + ID;
    308   }
    309   */
     179    redirect = editPage;
     180  }
    310181  else if ("UpdateItem".equals(cmd))
    311182  {
  • trunk/www/admin/plugintypes/edit_plugintype.jsp

    r5613 r5616  
    152152      </tr>
    153153      <tr>
    154         <td class="prompt">Jar path</td>
     154        <td class="prompt">Jar file</td>
    155155        <td><input <%=clazz%> type="text" name="jarFile"
    156156          value="<%=HTML.encodeTags(pluginType == null ? cc.getPropertyValue("jarFile") : pluginType.getJarFile())%>"
  • trunk/www/include/menu.jsp

    r5525 r5616  
    936936        style="display: none"
    937937        >
     938        <m:menuitem
     939          title="<%=menu.getString("installedextensions.title")%>"
     940          onclick="<%="Menu.openUrl('"+root+"admin/extensions/index.jsp?ID="+ID+"')"%>"
     941          tooltip="<%=menu.getString("installedextensions.tooltip")%>"
     942        />
     943        <m:menuseparator />
    938944        <m:menuitem
    939945          title="<%=menu.getString("plugintypes.title")%>"
     
    11771183    Map<String, List<MenuItemAction>> menus = new HashMap<String, List<MenuItemAction>>();
    11781184    menus.put("extensions", new LinkedList<MenuItemAction>());
     1185    int numExtensionMenues = 0;
    11791186    while (it.hasNext())
    11801187    {
     
    11951202      String menuId = entry.getKey();
    11961203      List<MenuItemAction> actions = entry.getValue();
     1204      if (actions.size() == 0) continue;
    11971205      %>
    11981206      <m:menu id="<%=menuId%>" style="display: none;">
     
    12001208      for (MenuItemAction action : actions)
    12011209      {
     1210        numExtensionMenues++;
    12021211        if (action.getType() == MenuItemAction.MenuType.SEPARATOR)
    12031212        {
     
    12371246        }
    12381247      }
    1239       if ("extensions".equals(menuId))
    1240       {
    1241         if (actions.size() > 0)
    1242         {
    1243           %>
    1244           <m:menuseparator />
    1245           <%
    1246         }
    1247         %>
    1248         <m:menuitem
    1249           title="<%=menu.getString("installedextensions.title")%>"
    1250           onclick="<%="Menu.openUrl('"+root+"admin/extensions/index.jsp?ID="+ID+"')"%>"
    1251           tooltip="<%=menu.getString("installedextensions.tooltip")%>"
    1252         />
    1253         <m:menuitem
    1254           title="<%=menu.getString("manualscan.title") + "…"%>"
    1255           onclick="<%="Main.openPopup('"+root+"admin/extensions/manual_scan.jsp?ID=" + ID + "', 'ManualScan', 500, 400);"%>"
    1256           enabled="<%=ec.hasPermission(Permission.WRITE)%>"
    1257           tooltip="<%=menu.getString("manualscan.tooltip")%>"
    1258         />
    1259         <%
    1260       }
    12611248      %>
    12621249      </m:menu>
     
    13011288        subid="extensions"
    13021289        title="<%=menu.getString("menu.extensions")%>"
     1290        visible="<%=numExtensionMenues > 0 %>"
    13031291      />
    13041292      <m:submenu
Note: See TracChangeset for help on using the changeset viewer.