Changeset 5615


Ignore:
Timestamp:
Apr 19, 2011, 3:42:31 PM (11 years ago)
Author:
Nicklas Nordborg
Message:

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

Added file processor for installing plug-ins as part of a scan for extensions. Trying to link information about plug-in into the tree with extensions information.

Added "disabled" property to plug-ins to make them behave more similar to extensions. There may still be synchronization issues with the in-memory information and the database information.

Changed the installation procedure somewhat to allow re-using the same code for installing plug-ins (eg. from initdb/updatedb, and scanning extensions). There are some bumps to fix yet.

Location:
trunk
Files:
7 added
23 edited

Legend:

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

    r5607 r5615  
    4242import net.sf.basedb.core.Permission;
    4343import net.sf.basedb.core.PermissionDeniedException;
     44import net.sf.basedb.core.PluginDefinition;
    4445import net.sf.basedb.core.SessionControl;
    4546import net.sf.basedb.core.plugin.GuiContext;
     
    6263import net.sf.basedb.util.extensions.manager.processor.DeleteResourcesProcessor;
    6364import net.sf.basedb.util.extensions.manager.processor.ExtractResourcesProcessor;
     65import net.sf.basedb.util.extensions.manager.processor.PluginInstallationProcessor;
    6466import net.sf.basedb.util.extensions.manager.processor.UnregisterExtensionsProcessor;
    6567import net.sf.basedb.util.extensions.xml.ExtensionPointFilter;
     68import net.sf.basedb.util.extensions.xml.PluginInfo;
     69import net.sf.basedb.util.extensions.xml.XmlLoader;
    6670
    6771/**
     
    158162   
    159163    // Initial scan
    160     scan(true, false);
     164    scan(null, true, false);
    161165    initialised = true;
    162166   
     
    182186 
    183187 
    184   private static ProcessResults scan(boolean initialScan, boolean forceUpdate)
     188  private static ProcessResults scan(DbControl dc, boolean initialScan, boolean forceUpdate)
    185189  {
    186190    log.info("Starting scan: intial=" + initialScan + "; forceUpdate="+forceUpdate);
     
    199203    int numUnregistered = 0;
    200204    int numRegistered = 0;
     205    int numPlugins = 0;
    201206   
    202207    synchronized (manager)
     
    221226     
    222227      log.debug("Checking for new and updated files");
    223       // 2. Update the manager with new and modified files
    224       manager.scanForNewAndUpdated();
     228      // 2. Update the manager with new and modified files (skip new files for initial scan)
     229      manager.scanForNewAndUpdated(!initialScan);
    225230      numNewFiles = manager.getNumNew();
    226231      numModifiedFiles = manager.getNumModified();
     
    244249        manager.processFiles(registerExtensions, valid);
    245250
     251        PluginInstallationProcessor pluginInstaller = new PluginInstallationProcessor(dc, new XmlLoader(), results);
     252        manager.processFiles(pluginInstaller, valid);
     253        numPlugins = pluginInstaller.getNumPlugins();
     254       
    246255        // 3b. Extract web resources
    247256        ExtractResourcesProcessor extractResources = new ExtractResourcesProcessor(resourceDir, Pattern.compile("resources/(.*)"), "$1", results);
     
    273282    summary.append(numModifiedFiles).append(" updated extension file(s)\n");
    274283    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");
     287    }
    275288    if (results.getNumErrorFiles() > 0)
    276289    {
     
    308321      permissions = EnumSet.of(Permission.READ);
    309322    }
    310     return new ExtensionsControl(permissions);
     323    return new ExtensionsControl(dc, permissions);
    311324  }
    312325 
     
    419432  }
    420433 
     434  private final DbControl dc;
    421435  private final Set<Permission> permissions;
    422   private ExtensionsControl(Set<Permission> permissions)
    423   {
     436  private ExtensionsControl(DbControl dc, Set<Permission> permissions)
     437  {
     438    this.dc = dc;
    424439    this.permissions = permissions;
    425440  }
     
    479494  {
    480495    checkPermission(Permission.WRITE, "extensions");
    481     return scan(false, forceUpdate);
     496    return scan(dc, false, forceUpdate);
    482497  }
    483498 
     
    673688    @return Information about the file, or null if
    674689      the object can't be found
     690    @since 3.0
    675691  */
    676692  public ExtensionsFile getFileByObjectKey(ObjectKey key)
    677693  {
    678694    return manager.getFileByObjectKey(key);
     695  }
     696 
     697  /**
     698    Get the object that was registered for the given key.
     699    @param key An object key
     700    @return The object or null if no object was found
     701    @since 3.0
     702  */
     703  public <O> O getObjectForKey(ObjectKey<O> key)
     704  {
     705    ExtensionsFile xtFile = getFileByObjectKey(key);
     706    return xtFile == null ? null : xtFile.getObjectForKey(key);
    679707  }
    680708 
     
    710738      settings.enableExtension(ext.getId(), enable);
    711739      if (enable) registry.handleEvent(AFTER_ENABLE, ep, ext);
     740    }
     741   
     742    for (PluginInfo info : file.getObjectsOfClass(PluginInfo.class))
     743    {
     744      if (info.isInstalled() && info.isDisabled() == enable)
     745      {
     746        PluginDefinition plugin = PluginDefinition.getById(dc, info.getInternalId());
     747        plugin.setDisabled(!enable);
     748      }
     749      info.setDisabled(!enable);
    712750    }
    713751  }
  • trunk/src/clients/web/web-extensions.xml

    r5609 r5615  
    3737    <url>http://base.thep.lu.se/</url>
    3838  </about>
     39 
     40  <plugin-definition
     41    id="SimpleExport">
     42    <about>
     43      <name>Table exporter</name>
     44      <description>
     45        Export all table listings in the web interface as tab-separated
     46        text files or as XML. This plugin only works from within the web
     47        client, since it depends on context and table information.
     48      </description>
     49    </about>
     50    <plugin-class>net.sf.basedb.clients.web.plugins.SimpleExport</plugin-class>
     51    <settings>
     52      <property name="everyone-use">1</property>
     53      <property name="immediate-execution">1</property>
     54    </settings>
     55  </plugin-definition>
    3956 
    4057  <extension-point
  • trunk/src/core/common-queries.xml

    r5566 r5615  
    19791979        (plg.requiresConfiguration = true AND NOT cfg.id IS NULL)
    19801980      )
     1981      AND plg.disabled = false
    19811982      GROUP BY plg.mainType
    19821983    </sql>
  • trunk/src/core/net/sf/basedb/core/Application.java

    r5608 r5615  
    555555        // TODO -- should this be moved to a utility class? Probably...
    556556        Registry xtRegistry = new Registry();
    557         java.io.File xtSettings = new java.io.File(pluginsDirectory, "settings.xml");
     557        java.io.File xtSettings = new java.io.File(userFilesDirectory, "extension-settings.xml");
    558558        xtManager = new ExtensionsManager(xtRegistry, xtSettings);
    559559       
    560560        // Add core extension points and extensions
    561561        xtManager.addURI(Application.class.getResource("/core-extensions.xml").toURI());
     562        // Add core plug-ins
     563        xtManager.addURI(Application.class.getResource("/core-plugins.xml").toURI());
    562564       
    563565        if (!Config.getBoolean("extensions.disabled"))
  • trunk/src/core/net/sf/basedb/core/Install.java

    r5613 r5615  
    691691          "net.sf.basedb.core.plugin.NonRestartable", null);
    692692     
    693       createPluginDefinitions("/core-plugins.xml", keyEveryoneUse, update);
     693      createPluginDefinitions("/core-plugins.xml", new ItemKey(keyEveryoneUse), update);
    694694     
    695695      // Plugin configurations
     
    24242424    Read plug-in definitions from the given file.
    24252425  */
    2426   private static void createPluginDefinitions(String filePath, ItemKeyData shareToEveryone, boolean update)
     2426  private static void createPluginDefinitions(String filePath, ItemKey shareToEveryone, boolean update)
    24272427  {
    24282428    DbControl dc = null;
     
    24582458    Create a {@link PluginDefinition}.
    24592459  */
    2460   private static PluginDefinition createPluginDefinition(PluginInfo info, ItemKeyData shareToEveryone)
    2461     throws BaseException
    2462   {
    2463     PluginDefinition pd = null;
     2460  private static PluginDefinition createPluginDefinition(PluginInfo info, ItemKey shareToEveryone)
     2461    throws BaseException
     2462  {
     2463    PluginDefinition plugin = null;
    24642464    DbControl dc = null;
    24652465    String className = info.getClassName();
     
    24682468     
    24692469      dc = sessionControl.newDbControl();
    2470      
    2471       try
    2472       {
    2473         pd = PluginDefinition.getByClassName(dc, className);
    2474       }
    2475       catch (ItemNotFoundException ex)
    2476       {}
    2477      
    2478       if (pd != null)
    2479       {
    2480         pd.loadPluginInformation(null, className, true);
    2481         pd.setAbout(info.getAbout(), false);
    2482         dc.commit();
     2470      plugin = PluginDefinition.installOrUpdate(dc, info, null, shareToEveryone);
     2471      boolean isNew = !plugin.isInDatabase();
     2472     
     2473      if (isNew)
     2474      {
     2475        plugin.setTrusted(true);
     2476      }
     2477      dc.commit();
     2478     
     2479      if (isNew)
     2480      {
     2481        log.info("createPluginDefinition: OK [class="+className+"]");
     2482      }
     2483      else
     2484      {
    24832485        log.info("createPluginDefinition: UPDATED [class="+className+"]");
    24842486      }
    2485       else
    2486       {
    2487         pd = PluginDefinition.getNew(dc, className, null, true);
    2488         pd.setAbout(info.getAbout(), false);
    2489         pd.setTrusted(true);
    2490         pd.setMaxMemory(Values.getLong(info.getProperty("max-memory"), null));
    2491         pd.setAllowImmediateExecution(Values.getBoolean(info.getProperty("immediate-execution")));
    2492         if (Values.getBoolean(info.getProperty("everyone-use")))
    2493         {
    2494           pd.getData().setItemKey(shareToEveryone);
    2495         }
    2496         dc.saveItem(pd);
    2497         dc.commit();
    2498         log.info("createPluginDefinition: OK [class="+className+"]");
    2499       }
    25002487    }
    25012488    catch (BaseException ex)
     
    25082495      if (dc != null) dc.close();
    25092496    }
    2510     return pd;
     2497    return plugin;
    25112498  }
    25122499
  • trunk/src/core/net/sf/basedb/core/ItemKey.java

    r5590 r5615  
    2929import net.sf.basedb.core.hibernate.TypeWrapper;
    3030
     31import java.util.EnumSet;
    3132import java.util.Map;
    3233import java.util.List;
     
    128129
    129130  /**
     131    Get a key that can be used to share items to the EVERYONE group with the
     132    given permissions.
     133    @param dc An open DbControl
     134    @param permission The permissions
     135    @return An ItemKey object
     136    @since 3.0
     137  */
     138  public static ItemKey getShareToEveryOneKey(DbControl dc, Permission permission)
     139  {
     140    Group everyone = Group.getById(dc, SystemItems.getId(Group.EVERYONE));
     141    GroupPermissions gp = new GroupPermissions();
     142    gp.setPermissions(everyone, EnumSet.of(permission));
     143    ItemKey everyoneKey = ItemKey.getNewOrExisting(dc, null, gp);
     144    return everyoneKey;
     145  }
     146 
     147  /**
    130148    Get an <code>ItemKey</code> item when you know the ID.
    131149
  • trunk/src/core/net/sf/basedb/core/PluginDefinition.java

    r5613 r5615  
    4141import net.sf.basedb.util.ClassUtil;
    4242import net.sf.basedb.util.JarClassLoader;
     43import net.sf.basedb.util.Values;
     44import net.sf.basedb.util.extensions.xml.PluginInfo;
    4345
    4446import java.util.Collection;
     
    297299        (plg.requiresConfiguration = true AND NOT cfg.id IS NULL)
    298300      )
     301      AND plg.disabled = false
    299302      GROUP BY plg.mainType
    300303    */
     
    332335   
    333336    return result;
     337  }
     338 
     339  /**
     340    Check the installation status of the given list of
     341    plug-ins.
     342    @param dc An optional DbControl (if null a new internal connection will be used)
     343    @param plugins An array with plug-in information objects
     344    @since 3.0
     345  */
     346  public static void checkInstallation(DbControl dc, Collection<PluginInfo> plugins)
     347  {
     348    if (plugins == null || plugins.size() == 0) return;
     349   
     350    org.hibernate.Session session = dc == null ? HibernateUtil.newSession() : dc.getHibernateSession();
     351    try
     352    {
     353      org.hibernate.Query query = HibernateUtil.getPredefinedQuery(session,
     354        "GET_PLUGINDEFINITION_FOR_CLASSNAME");
     355     
     356      for (PluginInfo info : plugins)
     357      {
     358        query.setString("className", info.getClassName());
     359        PluginDefinitionData plugin = HibernateUtil.loadData(PluginDefinitionData.class, query);
     360        if (plugin != null)
     361        {
     362          info.setInternalId(plugin.getId());
     363          info.setDisabled(plugin.isDisabled());
     364        }
     365      }
     366    }
     367    finally
     368    {
     369      if (dc == null)
     370      {
     371        HibernateUtil.close(session);
     372      }
     373    }
     374  }
     375 
     376  public static PluginDefinition installOrUpdate(DbControl dc, PluginInfo info, String jarFile, ItemKey shareToEveryone)
     377  {
     378    PluginDefinition plugin = null;
     379    String className = info.getClassName();
     380    try
     381    {
     382      plugin = PluginDefinition.getByClassName(dc, className);
     383      plugin.loadPluginInformation(jarFile, className, true);
     384    }
     385    catch (ItemNotFoundException ex)
     386    {
     387      plugin = PluginDefinition.getNew(dc, className, jarFile, true);
     388      plugin.setMaxMemory(Values.getLong(info.getProperty("max-memory"), null));
     389      plugin.setAllowImmediateExecution(Values.getBoolean(info.getProperty("immediate-execution")));
     390      if (Values.getBoolean(info.getProperty("everyone-use")))
     391      {
     392        plugin.setItemKey(shareToEveryone);
     393      }
     394      dc.saveItem(plugin);
     395    }
     396    plugin.setAbout(info.getAbout(), true);
     397   
     398    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
    334436  }
    335437 
     
    709811 
    710812  /**
     813    Checks if this plugin is disabled or not. A disabled plugin
     814    can't be used.
     815    @return
     816  */
     817  public boolean isDisabled()
     818  {
     819    return getData().isDisabled();
     820  }
     821 
     822  /**
     823    Disabled or enabled this plugin.
     824  */
     825  public void setDisabled(boolean disabled)
     826  {
     827    checkPermission(Permission.WRITE);
     828    getData().setDisabled(disabled);
     829  }
     830 
     831  /**
    711832    If this plugin is trusted or not. A trusted plugin is executed without any
    712833    restrictions, an untrusted have restrictions similar to an applet in a
     
    10291150  {
    10301151    checkPermission(Permission.USE);
     1152    if (isDisabled())
     1153    {
     1154      throw new PermissionDeniedException("The plugin is disabled: " + getName());
     1155    }
    10311156    return newInstance(getJarPath(), getClassName(), null, false);
    10321157  }
    1033 
    1034   /*
    1035   Plugin newInstance(String jarPath)
    1036     throws PermissionDeniedException, BaseException
    1037   {
    1038     checkPermission(Permission.USE);
    1039     return newInstance(jarPath == null ? getJarPath() : jarPath, getClassName(), false);
    1040   }
    1041   */
    10421158 
    10431159  /**
     
    10531169  {
    10541170    checkPermission(Permission.USE);
     1171    if (isDisabled())
     1172    {
     1173      throw new PermissionDeniedException("The plugin is disabled: " + getName());
     1174    }
    10551175    ClassLoader alternateClassLoader = null;
    10561176    if (clazz.getClassLoader() != this.getClass().getClassLoader())
  • trunk/src/core/net/sf/basedb/core/data/PluginDefinitionData.java

    r5595 r5615  
    288288  }
    289289 
     290  private boolean disabled;
     291  /**
     292    If the plugin is enabled or disabled.
     293    // Mapped in hibernate-properties-PluginDefinitionData.xml since annotation doesn't support a default value
     294  */
     295  public boolean isDisabled()
     296  {
     297    return disabled;
     298  }
     299  public void setDisabled(boolean disabled)
     300  {
     301    this.disabled = disabled;
     302  }
     303 
    290304  private boolean interactive;
    291305  /**
  • trunk/src/core/net/sf/basedb/util/AutoDetectFileFormat.java

    r5595 r5615  
    3535import net.sf.basedb.core.PluginConfiguration;
    3636import net.sf.basedb.core.PluginDefinition;
     37import net.sf.basedb.core.query.Expressions;
    3738import net.sf.basedb.core.query.Orders;
    3839import net.sf.basedb.core.query.Hql;
     40import net.sf.basedb.core.query.Restrictions;
    3941import net.sf.basedb.core.plugin.AutoDetectingImporter;
    4042import net.sf.basedb.core.plugin.GuiContext;
     
    105107        PluginDefinition.getQuery(context, AutoDetectingImporter.class.getName());
    106108      pluginQuery.order(Orders.asc(Hql.property("name")));
     109      pluginQuery.restrict(Restrictions.eq(Hql.property("disabled"), Expressions.parameter("isDisabled", false)));
    107110      pluginQuery.include(Include.MINE, Include.SHARED, Include.IN_PROJECT, Include.OTHERS);
    108111      pluginDefs = pluginQuery.list(dc);
  • trunk/src/core/net/sf/basedb/util/extensions/manager/ExtensionsManager.java

    r5607 r5615  
    135135  /**
    136136    Add a directory to this manager. The directory is automatically
    137     scanned for files with .xml or .jar extensions which are
    138     added as extension files. This method call is ignored if the
     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.
     140    <p>
     141    This method call is ignored if the
    139142    path is not pointing to an existing directory.
    140143   
     
    147150    if (dir == null) throw new NullPointerException("dir");
    148151    directories.add(dir);
    149     int numNew = scanForNewFiles(dir);
     152    int numNew = scanForNewFiles(dir, false);
    150153    return numNew;
    151154  }
     
    193196    xtFile.validate();
    194197    xtFiles.put(xtFile.getURI(), xtFile);
     198    if (xtFile.getFile() != null)
     199    {
     200      settings.setKnownFile(xtFile.getFile());
     201    }
    195202    log.info("Added file: " + xtFile);
    196203  }
     
    204211    implementation that checks {@link ExtensionsFile#exists()}.
    205212
     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)}
    206215    @return The number of new + modified files that was found
    207216  */
    208   public synchronized int scanForNewAndUpdated()
     217  public synchronized int scanForNewAndUpdated(boolean installAllNew)
    209218  {
    210219    numNew = 0;
     
    222231        log.debug("File '" + xtFile + "' has been deleted.");
    223232        unregisterAllObjects(xtFile);
     233        settings.removeKnownFile(xtFile.getFile());
    224234        it.remove();
    225235        numDeleted++;
     
    245255    for (File dir : directories)
    246256    {
    247       numNew += scanForNewFiles(dir);
    248     }
     257      numNew += scanForNewFiles(dir, installAllNew);
     258    }
     259   
     260    settings.save();
     261   
    249262    return numModified + numNew;
    250263  }
     
    288301  /**
    289302    Scan the given directory and add files that are new.
     303    @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)}
    290306    @return The number of new files in the given directory
    291307  */
    292   private int scanForNewFiles(File dir)
     308  private int scanForNewFiles(File dir, boolean installAllNew)
    293309  {
    294310    int numNew = 0;
     
    323339        else
    324340        {
    325           xtFile = new ExtensionsFile(this, file);
    326           addExtensionsFile(xtFile);
    327           numNew++;
     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          }
    328352        }
    329353      }
  • trunk/src/core/net/sf/basedb/util/extensions/manager/Settings.java

    r5606 r5615  
    3232import net.sf.basedb.core.Presets;
    3333import net.sf.basedb.core.Presets.Preset;
     34import net.sf.basedb.util.Values;
    3435import net.sf.basedb.util.extensions.DefaultFilter;
    3536import net.sf.basedb.util.extensions.Extension;
     
    7071  private Presets presets;
    7172  private Preset settings;
     73  private Preset knownFiles;
    7274  private Preset disabledExtensions;
    7375  private Preset disabledExtensionPoints;
     
    99101    }
    100102    this.settings = presets.getDefault();
     103    this.knownFiles = presets.getPreset("known-files");
    101104    this.disabledExtensionPoints = presets.getPreset("disabled-extension-points");
    102105    this.disabledExtensions = presets.getPreset("disabled-extensions");
     
    149152  }
    150153 
     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  }
     170 
    151171  /**
    152172    Save the settings to disk. If the settings has not been
  • trunk/src/core/net/sf/basedb/util/extensions/xml/PluginInfo.java

    r5610 r5615  
    2525import java.util.Map;
    2626
     27import net.sf.basedb.core.DbControl;
     28import net.sf.basedb.core.PluginDefinition;
    2729import net.sf.basedb.core.plugin.About;
    2830
    2931/**
     32  Object for holding information about a plug-in definition as
     33  it is loaded from the extensions definition file. This class
     34  has no effect on the actual installed plug-ins. To get
     35  more information about what is installed and what is not,
     36  call {@link PluginDefinition#checkInstallation(DbControl, java.util.Collection)}.
    3037
    3138  @author Nicklas
     
    4148  private Map<String, String> properties;
    4249 
     50  private int internalId;
     51  private boolean disabled;
     52 
     53  /**
     54    Create a new information object.
     55  */
    4356  public PluginInfo(String id)
    4457  {
     
    4659  }
    4760 
     61  /**
     62    Get the class name of the plug-in.
     63  */
     64  public String getClassName()
     65  {
     66    return className;
     67  }
    4868  public void setClassName(String className)
    4969  {
     
    5171  }
    5272 
    53   public String getClassName()
     73  /**
     74    Get information about the authors of the plug-in.
     75  */
     76  public About getAbout()
    5477  {
    55     return className;
     78    return about;
    5679  }
    57  
    5880  public void setAbout(About about)
    5981  {
    6082    this.about = about;
    61   }
    62  
    63   public About getAbout()
    64   {
    65     return about;
    6683  }
    6784 
     
    7794  }
    7895 
     96  /**
     97    Get the internal if of this plug-in. This information is
     98    only available after {@link PluginDefinition#checkInstallation(DbControl, java.util.Collection)}
     99    has been called.
     100  */
     101  public int getInternalId()
     102  {
     103    return internalId;
     104  }
     105 
     106  public void setInternalId(int internalId)
     107  {
     108    this.internalId = internalId;
     109  }
     110 
     111  /**
     112    Is this plug-in installed or not?
     113  */
     114  public boolean isInstalled()
     115  {
     116    return internalId != 0;
     117  }
     118 
     119  /**
     120    Is this plug-in enabled or not?
     121  */
     122  public boolean isDisabled()
     123  {
     124    return disabled;
     125  }
     126 
     127  public void setDisabled(boolean disabled)
     128  {
     129    this.disabled = disabled;
     130  }
    79131 
    80132}
  • trunk/src/core/net/sf/basedb/util/extensions/xml/XmlLoader.java

    r5610 r5615  
    209209  private Filter<Element> filter;
    210210  /**
    211     Set a filter that all &lt;extension-point&gt;, &lt;extension&gt;
    212     and &lt;ref&gt; tags must pass to be loaded and registered.
     211    Set a filter that all &lt;extension-point&gt;, &lt;extension&gt;,
     212    &lt;ref&gt; and &lt;plugin-definition&gt; tags must pass to be loaded
     213    and registered.
    213214    @param filter A filter or null to remove an existing filter
    214215    @since 3.0
     
    824825      log.debug("Processing plug-in definition: " + id);
    825826     
    826       // <about>
    827       AboutBean about = loadAbout(pdTag.getChild("about", ns));
    828       if (globalAbout != null)
    829       {
    830         if (about == null) about = new AboutBean();
    831         about.copy(globalAbout, false);
    832       }
    833      
    834       // <plugin-class>
    835       String className = Values.getStringOrNull(pdTag.getChildText("plugin-class", ns));
    836      
    837       PluginInfo info = new PluginInfo(id);
    838       info.setAbout(about);
    839       info.setClassName(className);
    840      
    841       temp.add(info);
    842      
    843       // <settings>
    844       Element settingsTag = pdTag.getChild("settings", ns);
    845       if (settingsTag != null)
    846       {
    847         for (Element propertyTag : (List<Element>)settingsTag.getChildren("property", ns))
    848         {
    849           String name = propertyTag.getAttributeValue("name");
    850           String value = Values.getStringOrNull(propertyTag.getText());
    851           info.setProperty(name, value);
    852         }
    853       }
    854      
    855       if (!verifyBaseVersion(about, false))
    856       {
    857         String min = about.getMinBaseVersion();
    858         String max = about.getMaxBaseVersion();
    859         log.info("Plug-in definition '" + id + "' require BASE version between " +
    860           (min == null ? "*" : min) + " and " + (max == null ? "*" : max)
    861         );
    862       }
    863       else
    864       {
    865         // <action-factory>
    866         /*
    867         Element afTag = epTag.getChild("action-factory", ns);
    868         ActionFactory af = null;
    869         if (afTag != null)
    870         {
    871           af = createFactory(afTag, classLoader, ActionFactory.class);
    872         }
    873         */
     827      if (filter == null || filter.evaluate(pdTag))
     828      {
     829        // <about>
     830        AboutBean about = loadAbout(pdTag.getChild("about", ns));
     831        if (globalAbout != null)
     832        {
     833          if (about == null) about = new AboutBean();
     834          about.copy(globalAbout, false);
     835        }
     836       
     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       
     858        if (!verifyBaseVersion(about, false))
     859        {
     860          String min = about.getMinBaseVersion();
     861          String max = about.getMaxBaseVersion();
     862          log.info("Plug-in definition '" + id + "' require BASE version between " +
     863            (min == null ? "*" : min) + " and " + (max == null ? "*" : max)
     864          );
     865        }
     866        else
     867        {
     868          // <action-factory>
     869          /*
     870          Element afTag = epTag.getChild("action-factory", ns);
     871          ActionFactory af = null;
     872          if (afTag != null)
     873          {
     874            af = createFactory(afTag, classLoader, ActionFactory.class);
     875          }
     876          */
     877        }
    874878      }
    875879    }
  • trunk/src/install/net/sf/basedb/install/Webclient.java

    r5612 r5615  
    2828import net.sf.basedb.core.Application;
    2929import net.sf.basedb.core.DbControl;
    30 import net.sf.basedb.core.Group;
    31 import net.sf.basedb.core.SystemItems;
    3230import net.sf.basedb.core.ItemKey;
    33 import net.sf.basedb.core.GroupPermissions;
    3431import net.sf.basedb.core.Permission;
    3532import net.sf.basedb.core.Client;
     
    3835import net.sf.basedb.core.BaseException;
    3936import net.sf.basedb.core.ItemNotFoundException;
    40 import net.sf.basedb.core.Version;
    41 import net.sf.basedb.core.plugin.AboutImpl;
    4237import net.sf.basedb.plugins.HelpImporter;
     38import net.sf.basedb.util.extensions.xml.PluginInfo;
     39import net.sf.basedb.util.extensions.xml.XmlLoader;
    4340
    4441import java.io.InputStream;
    4542import java.net.URL;
    46 import java.util.EnumSet;
    4743
    4844/**
     
    9995   
    10096    DbControl dc = sc.newDbControl();
    101     Group everyone = Group.getById(dc, SystemItems.getId(Group.EVERYONE));
    102     GroupPermissions gp = new GroupPermissions();
    103     gp.setPermissions(everyone, EnumSet.of(Permission.USE));
    104     ItemKey everyoneUse = ItemKey.getNewOrExisting(dc, null, gp);
     97    try
     98    {
     99      ItemKey shareToEveryone = ItemKey.getShareToEveryOneKey(dc, Permission.USE);
     100     
     101      Client client = null;
     102      try
     103      {
     104        client = Client.getByExternalId(dc, "net.sf.basedb.clients.web");
     105      }
     106      catch (ItemNotFoundException ex)
     107      {
     108        client = Client.getNew(dc, "net.sf.basedb.clients.web");
     109        client.setName("Web client");
     110        client.setDescription("The web interface to BASE");
     111        client.setItemKey(shareToEveryone);
     112        dc.saveItem(client);
     113      }
     114 
     115      String latinText = "Fusce consectetuer. Suspendisse consectetuer wisi vitae eros. Quisque sapien sapien, "+
     116        "lobortis a, congue sed, tempus vitae, sapien. Aliquam rhoncus ultricies pede. Fusce "+
     117        "gravida pharetra tellus. Nulla tortor. Donec eu enim. Vivamus blandit. Pellentesque "+
     118        "habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Mauris "+
     119        "pulvinar arcu id libero. Vestibulum pharetra. Proin id felis pharetra mauris feugiat adipiscing. "+
     120        "Cras auctor. Nullam turpis. Cras dignissim venenatis erat.<br>\n"+
     121        "[<b>The server administrator should replace this text, or remove it to disable this feature</b>]";
     122 
     123      createSetting(client, "server.about", latinText);
     124      createSetting(client, "server.admin.name", adminName);
     125      createSetting(client, "server.admin.email", adminEmail);
     126      createSetting(client, "server.forgotten.password", latinText);
     127      createSetting(client, "server.get.account", latinText);
     128      createSetting(client, "server.transferRate", Integer.toString(100 * 1024 * 1024)); // 100MB/s
     129      createSetting(client, "server.links.reportbug", "http://base.thep.lu.se/#Feedback");
     130      createSetting(client, "server.links.help", "http://base.thep.lu.se/chrome/site/doc/html/index.html");
     131      createSetting(client, "server.links.faq", "");
     132     
     133      URL fileURL = Webclient.class.getResource("/web-extensions.xml");
     134     
     135      XmlLoader loader = new XmlLoader();
     136      try
     137      {
     138        InputStream in = fileURL.openStream();
     139        loader.loadXmlFile(in, "/web-extensions.xml", null, false);
     140      }
     141      catch (Exception ex)
     142      {
     143        throw new BaseException(ex);
     144      }
     145     
     146      for (PluginInfo info : loader.getPluginDefinitions())
     147      {
     148        PluginDefinition.installOrUpdate(dc, info, null, shareToEveryone);
     149      }
     150      dc.commit();
     151      installHelpTexts(sc, client);
     152    }
     153    finally
     154    {
     155      if (dc != null) dc.close();
     156    }
    105157   
    106     Client client = null;
    107     try
    108     {
    109       client = Client.getByExternalId(dc, "net.sf.basedb.clients.web");
    110     }
    111     catch (ItemNotFoundException ex)
    112     {
    113       client = Client.getNew(dc, "net.sf.basedb.clients.web");
    114       client.setName("Web client");
    115       client.setDescription("The web interface to BASE");
    116       client.setItemKey(everyoneUse);
    117       dc.saveItem(client);
    118     }
    119 
    120     String latinText = "Fusce consectetuer. Suspendisse consectetuer wisi vitae eros. Quisque sapien sapien, "+
    121       "lobortis a, congue sed, tempus vitae, sapien. Aliquam rhoncus ultricies pede. Fusce "+
    122       "gravida pharetra tellus. Nulla tortor. Donec eu enim. Vivamus blandit. Pellentesque "+
    123       "habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Mauris "+
    124       "pulvinar arcu id libero. Vestibulum pharetra. Proin id felis pharetra mauris feugiat adipiscing. "+
    125       "Cras auctor. Nullam turpis. Cras dignissim venenatis erat.<br>\n"+
    126       "[<b>The server administrator should replace this text, or remove it to disable this feature</b>]";
    127 
    128     createSetting(client, "server.about", latinText);
    129     createSetting(client, "server.admin.name", adminName);
    130     createSetting(client, "server.admin.email", adminEmail);
    131     createSetting(client, "server.forgotten.password", latinText);
    132     createSetting(client, "server.get.account", latinText);
    133     createSetting(client, "server.transferRate", Integer.toString(100 * 1024 * 1024)); // 100MB/s
    134     createSetting(client, "server.links.reportbug", "http://base.thep.lu.se/#Feedback");
    135     createSetting(client, "server.links.help", "http://base.thep.lu.se/chrome/site/doc/html/index.html");
    136     createSetting(client, "server.links.faq", "");
    137      
    138     PluginDefinition simpleExport = null;
    139     String simpleExportClassName = "net.sf.basedb.clients.web.plugins.SimpleExport";
    140     try
    141     {
    142       simpleExport = PluginDefinition.getByClassName(dc, simpleExportClassName);
    143       simpleExport.loadPluginInformation(null, simpleExportClassName, true);
    144     }
    145     catch (ItemNotFoundException ex)
    146     {
    147       simpleExport = PluginDefinition.getNew(dc, simpleExportClassName, null, true);
    148       simpleExport.setItemKey(everyoneUse);
    149       simpleExport.setAllowImmediateExecution(true);
    150       dc.saveItem(simpleExport);
    151     }
    152    
    153     simpleExport.setAbout(
    154         new AboutImpl
    155         (
    156             "Table exporter",
    157             "Export all table listings in the web interface as tab-separated text files " +
    158             "or as XML. This plugin only works from within the web client, since it depends " +
    159             "on context and table information.",
    160             Version.getMajor() + "." + Version.getMinor() + "." + Version.getMaintenance(),
    161             "2006, Base 2 development team",
    162             null,
    163             null,
    164             "http://base.thep.lu.se"
    165           ), false);
    166    
    167     dc.commit();
    168    
    169     installHelpTexts(sc, client);
    170158  }
    171159 
  • trunk/www/admin/extensions/details.jsp

    r5607 r5615  
    2323  @version 2.0
    2424--%>
     25<%@page import="net.sf.basedb.core.PluginDefinition"%>
    2526<%@ page pageEncoding="UTF-8" session="false"
    2627  import="net.sf.basedb.core.SessionControl"
     
    4243  import="net.sf.basedb.util.extensions.manager.ExtensionPointKey"
    4344  import="net.sf.basedb.util.extensions.manager.ExtensionKey"
     45  import="net.sf.basedb.util.extensions.manager.PluginInfoKey"
    4446  import="net.sf.basedb.util.extensions.manager.FactoryParametersKey"
    4547  import="net.sf.basedb.util.extensions.manager.ProcessResults"
    4648  import="net.sf.basedb.util.extensions.manager.ProcessResults.FileResults"
     49  import="net.sf.basedb.util.extensions.xml.PluginInfo"
    4750  import="net.sf.basedb.clients.web.extensions.ExtensionsControl"
    4851  import="net.sf.basedb.clients.web.formatter.FormatterFactory"
     
    162165  {
    163166    Main.openPopup('settings.jsp?ID=<%=ID%>', 'EditExtensionSettings', 500, 400);
     167  }
     168 
     169  function editPlugin(pluginId)
     170  {
     171    Main.viewOrEditItem('<%=ID%>', 'PLUGINDEFINITION', pluginId, true);
    164172  }
    165173 
     
    351359        </tr>
    352360        </tr>
    353           <tr>
     361        <tr>
    354362          <td class="prompt">Renderer factory</td>
    355363          <td><%=displayFactory(extFile, ext.getRendererFactory())%></td>
     
    387395      }
    388396      %>
    389         <table class="form" cellspacing="0">
    390         <tr>
    391           <td class="prompt">ID</td>
    392           <td><%=ep.getId()%></td>
    393         </tr>
    394         <tr>
    395           <td class="prompt">Name</td>
    396           <td><%=HTML.encodeTags(ep.getName())%></td>
    397         </tr>
    398         <tr>
    399           <td class="prompt">File</td>
    400           <td>
     397      <table class="form" cellspacing="0">
     398      <tr>
     399        <td class="prompt">ID</td>
     400        <td><%=ep.getId()%></td>
     401      </tr>
     402      <tr>
     403        <td class="prompt">Name</td>
     404        <td><%=HTML.encodeTags(ep.getName())%></td>
     405      </tr>
     406      <tr>
     407        <td class="prompt">File</td>
     408        <td>
     409          <%
     410          if (epFile != null)
     411          {
     412            %>
     413            <a href="javascript:showFile('<%=HTML.javaScriptEncode(epFile.getName())%>')"
     414            ><%=epFile.getName()%></a>
     415            (<%=epFile.checkModified() ? "Modified" : "Up to date" %>;
     416            <%=epFile.hasError() ? "Error" : "Ok" %>)
    401417            <%
    402             if (epFile != null)
     418          }
     419          %>
     420        </td>
     421      </tr>
     422      <tr>
     423        <td class="prompt">Description</td>
     424        <td><%=HTML.niceFormat(ep.getDescription())%></td>
     425      </tr>
     426      <tr>
     427        <td class="prompt">Action class</td>
     428        <td><%=ep.getActionClass().getName()%></td>
     429      </tr>
     430      <tr>
     431        <td class="prompt">Renderer factory</td>
     432        <td><%=displayFactory(epFile, ep.getRendererFactory())%></td>
     433      </tr>
     434      <tr>
     435        <td class="prompt">Error handler factory</td>
     436        <td><%=displayFactory(epFile, ep.getErrorHandlerFactory() == null ?
     437            ec.getDefaultErrorHandlerFactory() : ep.getErrorHandlerFactory())%></td>
     438      </tr>
     439      </table>
     440      <%
     441    }
     442    %>
     443     
     444    <%
     445    if (file != null)
     446    {
     447      About about = file.getAbout();
     448      if (about == null) about = new AboutBean();
     449      %>
     450      <table class="form" cellspacing="0">
     451      <tr>
     452        <td class="prompt">File</td>
     453        <td><%=file.getName()%></td>
     454      </tr>
     455      <tr>
     456        <td class="prompt">Type</td>
     457        <td><%=file.isJar() ? "JAR file" : "XML file"%></td>
     458      </tr>
     459      <tr>
     460        <td class="prompt">Up to date</td>
     461        <td><%=file.checkModified() ? "No" : "Yes"%></td>
     462      </tr>
     463      <tr>
     464        <td class="prompt">Errors</td>
     465        <td>
     466          <%
     467          if (file.hasError())
     468          {
     469            ProcessResults results = ec.getLastScanResults();
     470            FileResults fileResults = results.getResults(file);
     471            List<String> messages = fileResults.getMessages();
     472            Throwable validationError = file.getValidationError();
     473            %>
     474            <ul style="padding-left: 20px; margin: 0px; text-align: left;" class="error">
     475            <%
     476            if (validationError != null)
    403477            {
    404478              %>
    405               <a href="javascript:showFile('<%=HTML.javaScriptEncode(epFile.getName())%>')"
    406               ><%=epFile.getName()%></a>
    407               (<%=epFile.checkModified() ? "Modified" : "Up to date" %>;
    408               <%=epFile.hasError() ? "Error" : "Ok" %>)
     479              <li><%=validationError.getClass().getSimpleName()%>: <%=HTML.niceFormat(validationError.getMessage())%>
     480              <%
     481            }
     482            for (String msg : messages)
     483            {
     484              %>
     485              <li><%=HTML.niceFormat(msg)%>
    409486              <%
    410487            }
    411488            %>
    412           </td>
    413         </tr>
    414         <tr>
    415           <td class="prompt">Description</td>
    416           <td><%=HTML.niceFormat(ep.getDescription())%></td>
    417         </tr>
    418         <tr>
    419           <td class="prompt">Action class</td>
    420           <td><%=ep.getActionClass().getName()%></td>
    421         </tr>
    422         <tr>
    423           <td class="prompt">Renderer factory</td>
    424           <td><%=displayFactory(epFile, ep.getRendererFactory())%></td>
    425         </tr>
    426         <tr>
    427           <td class="prompt">Error handler factory</td>
    428           <td><%=displayFactory(epFile, ep.getErrorHandlerFactory() == null ?
    429               ec.getDefaultErrorHandlerFactory() : ep.getErrorHandlerFactory())%></td>
    430         </tr>
    431         </table>
    432         <%
    433       }
    434       %>
    435      
    436       <%
    437       if (file != null)
    438       {
    439         About about = file.getAbout();
    440         if (about == null) about = new AboutBean();
    441         %>
    442         <table class="form" cellspacing="0">
    443         <tr>
    444           <td class="prompt">File</td>
    445           <td><%=file.getName()%></td>
    446         </tr>
    447         <tr>
    448           <td class="prompt">Type</td>
    449           <td><%=file.isJar() ? "JAR file" : "XML file"%></td>
    450         </tr>
    451         <tr>
    452           <td class="prompt">Up to date</td>
    453           <td><%=file.checkModified() ? "No" : "Yes"%></td>
    454         </tr>
    455         <tr>
    456           <td class="prompt">Errors</td>
    457           <td>
     489            </ul>
    458490            <%
    459             if (file.hasError())
    460             {
    461               ProcessResults results = ec.getLastScanResults();
    462               FileResults fileResults = results.getResults(file);
    463               List<String> messages = fileResults.getMessages();
    464               Throwable validationError = file.getValidationError();
    465               %>
    466               <ul style="padding-left: 20px; margin: 0px; text-align: left;" class="error">
    467               <%
    468               if (validationError != null)
    469               {
    470                 %>
    471                 <li><%=validationError.getClass().getSimpleName()%>: <%=HTML.niceFormat(validationError.getMessage())%>
    472                 <%
    473               }
    474               for (String msg : messages)
    475               {
    476                 %>
    477                 <li><%=HTML.niceFormat(msg)%>
    478                 <%
    479               }
    480               %>
    481               </ul>
    482               <%
    483             }
    484             else
    485             {
    486               %>
    487               No
    488               <%
    489             }
     491          }
     492          else
     493          {
    490494            %>
    491           </td>
    492         </tr>
    493         <tr>
    494           <td class="prompt">Name</td>
    495           <td><%=HTML.encodeTags(about.getName())%></td>
    496         </tr>
    497         <tr>
    498           <td class="prompt">Version</td>
    499           <td><%=HTML.encodeTags(about.getVersion())%></td>
    500         </tr>
    501         <tr>
    502           <td class="prompt">Description</td>
    503           <td><%=HTML.niceFormat(about.getDescription())%></td>
    504         </tr>
    505         <tr>
    506           <td class="prompt">Copyright</td>
    507           <td><%=HTML.encodeTags(about.getCopyright())%></td>
    508         </tr>
    509         <tr>
    510           <td class="prompt">Contact</td>
    511           <td><%=HTML.encodeTags(about.getContact())%></td>
    512         </tr>
    513         <tr>
    514           <td class="prompt">Email</td>
    515           <td><%=HTML.scanForLinks(about.getEmail(), HTML.LINK_EMAIL, "_new")%></td>
    516         </tr>
    517         <tr>
    518           <td class="prompt">Url</td>
    519           <td><%=HTML.scanForLinks(about.getUrl(), HTML.LINK_URL, "_new")%></td>
    520         </tr>
    521         </table>
    522         <%
    523       }
    524       %>
    525       <%
    526       if (ext == null && ep == null && file == null)
    527       {
    528         ProcessResults results = ec.getLastScanResults();
    529         Formatter dateTimeFormatter = FormatterFactory.getDateTimeFormatter(sc);
    530         %>
    531         <table class="form" cellspacing="0">
    532         <tr>
    533           <td class="prompt">Last scan</td>
    534           <td><%=results.hasError() ? "Failed": "Successful" %></td>
    535         </tr>
    536         <tr>
    537           <td class="prompt" style="text-align: right; font-weight: normal;">- ended</td>
    538           <td><%=dateTimeFormatter.format(new Date(results.getEndTime())) %></td>
    539         </tr>
    540         <tr>
    541           <td class="prompt" style="text-align: right; font-weight: normal;">- summary</td>
    542           <td>
    543           <%=HTML.niceFormat(results.getSummary())%></td>
    544         </tr>
    545         <tr>
    546           <td  class="prompt" style="text-align: right; font-weight: normal;"><base:icon image="bullet.gif" /></td>
    547           <td>
    548             <a href="javascript:scanResults()"
    549               title="Display detailed information about the last scan"
    550               >More details&hellip;</a>
    551           </td>
    552         </tr>
    553         </table>
    554         <%
    555       }
    556       %>
    557       </div>
     495            No
     496            <%
     497          }
     498          %>
     499        </td>
     500      </tr>
     501      <tr>
     502        <td class="prompt">Name</td>
     503        <td><%=HTML.encodeTags(about.getName())%></td>
     504      </tr>
     505      <tr>
     506        <td class="prompt">Version</td>
     507        <td><%=HTML.encodeTags(about.getVersion())%></td>
     508      </tr>
     509      <tr>
     510        <td class="prompt">Description</td>
     511        <td><%=HTML.niceFormat(about.getDescription())%></td>
     512      </tr>
     513      <tr>
     514        <td class="prompt">Copyright</td>
     515        <td><%=HTML.encodeTags(about.getCopyright())%></td>
     516      </tr>
     517      <tr>
     518        <td class="prompt">Contact</td>
     519        <td><%=HTML.encodeTags(about.getContact())%></td>
     520      </tr>
     521      <tr>
     522        <td class="prompt">Email</td>
     523        <td><%=HTML.scanForLinks(about.getEmail(), HTML.LINK_EMAIL, "_new")%></td>
     524      </tr>
     525      <tr>
     526        <td class="prompt">Url</td>
     527        <td><%=HTML.scanForLinks(about.getUrl(), HTML.LINK_URL, "_new")%></td>
     528      </tr>
     529      </table>
     530      <%
     531    }
     532    %>
     533    <%
     534    if (ext == null && ep == null && file == null)
     535    {
     536      ProcessResults results = ec.getLastScanResults();
     537      Formatter dateTimeFormatter = FormatterFactory.getDateTimeFormatter(sc);
     538      %>
     539      <table class="form" cellspacing="0">
     540      <tr>
     541        <td class="prompt">Last scan</td>
     542        <td><%=results.hasError() ? "Failed": "Successful" %></td>
     543      </tr>
     544      <tr>
     545        <td class="prompt" style="text-align: right; font-weight: normal;">- ended</td>
     546        <td><%=dateTimeFormatter.format(new Date(results.getEndTime())) %></td>
     547      </tr>
     548      <tr>
     549        <td class="prompt" style="text-align: right; font-weight: normal;">- summary</td>
     550        <td>
     551        <%=HTML.niceFormat(results.getSummary())%></td>
     552      </tr>
     553      <tr>
     554        <td  class="prompt" style="text-align: right; font-weight: normal;"><base:icon image="bullet.gif" /></td>
     555        <td>
     556          <a href="javascript:scanResults()"
     557            title="Display detailed information about the last scan"
     558            >More details&hellip;</a>
     559        </td>
     560      </tr>
     561      </table>
     562      <%
     563    }
     564    %>
     565    </div>
    558566    </base:body>
    559567  </base:page>
  • trunk/www/admin/extensions/index.jsp

    r5607 r5615  
    8787    ExtensionsControl ec = ExtensionsControl.get(dc);
    8888    ec.enableAllInFile(fileuri, enable);
     89    dc.commit();
    8990    ec.saveSettings();
    9091    redirect = "details.jsp?ID=" + ID + "&fileuri=" + HTML.urlEncode(fileuri);
     
    100101    boolean forceUpdate = Values.getBoolean(request.getParameter("forceUpdate"));
    101102    ec.installAndUpdateExtensions(forceUpdate);
     103    dc.commit();
    102104    redirect = "index.jsp?ID=" + ID + "&cmd=ScanResults";
    103105  }
  • trunk/www/admin/extensions/manager.jsp

    r5426 r5615  
    3737
    3838%>
    39 <base:page title="Installed extensions">
     39<base:page title="Installed extensions &amp; plug-ins">
    4040<base:head >
    4141  <script language="JavaScript">
  • trunk/www/admin/extensions/tree.jsp

    r5602 r5615  
    3535  import="net.sf.basedb.util.extensions.Action"
    3636  import="net.sf.basedb.util.extensions.manager.ExtensionsFile"
     37  import="net.sf.basedb.util.extensions.manager.ExtensionKey"
     38  import="net.sf.basedb.util.extensions.manager.ExtensionPointKey"
     39  import="net.sf.basedb.util.extensions.xml.PluginInfo"
    3740  import="net.sf.basedb.clients.web.extensions.ExtensionsControl"
    3841  import="net.sf.basedb.core.plugin.About"
     
    4245<%@ taglib prefix="base" uri="/WEB-INF/base.tld" %>
    4346<%!
    44 String getJoustExtensionPoint(String parentNode, ExtensionsControl ec, ExtensionPoint ep)
     47String getJoustExtensionPoint(String parentNode, ExtensionsControl ec, ExtensionPoint ep, ExtensionsFile ef)
    4548{
    4649  String id = ep.getId();
     
    4851  if (name == null) name = id;
    4952  String icon = ec.isEnabled(ep) ? "ExtensionPoint" : "ExtensionPointDisabled";
    50   ExtensionsFile f = null; //ec.getFileByExtensionId(id);
    51   if ((f != null /*&& f.hasError()*/) || ec.getLastExtensionPointError(id) != null)
     53  if ((ef != null && ef.hasError()) || ec.getLastExtensionPointError(id) != null)
    5254  {
    5355    icon = "ExtensionPointError";
     
    5860  return joust;
    5961}
    60 String getJoustExtension(String parentNode, ExtensionsControl ec, Extension ext, boolean inGroup)
     62String getJoustExtension(String parentNode, ExtensionsControl ec, Extension ext, ExtensionsFile ef, boolean inGroup)
    6163{
    6264  String id = ext.getId();
     
    6567  if (inGroup) name = ext.getId().substring(ext.getId().indexOf(":"));
    6668  String icon = ec.isEnabled(ext) ? "Extension" : "ExtensionDisabled";
    67   ExtensionsFile f = null; //ec.getFileByExtensionId(id);
    68   if ((f != null /*&& f.hasError()*/) || ec.getLastExtensionError(id) != null)
     69  if ((ef != null && ef.hasError()) || ec.getLastExtensionError(id) != null)
    6970  {
    7071    icon = "ExtensionError";
     
    8485      "'" + HTML.javaScriptEncode(name) + "', 'extensionOnClick(\"" + id + "\")', " +
    8586      "'', '" + groupId + "')";
     87  return joust;
     88}
     89String getJoustPlugin(String parentNode, ExtensionsControl ex, PluginInfo info, ExtensionsFile ef)
     90{
     91  String id = info.getClassName();
     92  About about = info.getAbout();
     93  String name = about == null || about.getName() == null ? id : about.getName();
     94  String icon = info.isDisabled() ? "PluginDisabled" : "Plugin";
     95  if ((ef != null && ef.hasError()) || !info.isInstalled())
     96  {
     97    icon = "PluginError";
     98  }
     99 
     100  String joust = "plugin = JoustMenu.addChildItem(" + parentNode +", '" + icon + "', " +
     101      "'" + HTML.javaScriptEncode(name) + "', 'pluginOnClick(\"" + id + "\")', " +
     102      "'', '" + id + "')";
    86103  return joust;
    87104}
     
    118135    IconStore.addIcon('ExtensionError', path + 'extensionerror.png', 16, 16);
    119136    IconStore.addIcon('ExtensionErrorSelected', path + 'extensionerrorselected.png', 16, 16);
     137    IconStore.addIcon('Plugin', path + 'plugin.png', 18, 16);
     138    IconStore.addIcon('PluginSelected', path + 'pluginselected.png', 18, 16);
     139    IconStore.addIcon('PluginDisabled', path + 'plugindisabled.png', 18, 16);
     140    IconStore.addIcon('PluginDisabledSelected', path + 'plugindisabledselected.png', 18, 16);
     141    IconStore.addIcon('PluginError', path + 'pluginerror.png', 18, 16);
     142    IconStore.addIcon('PluginErrorSelected', path + 'pluginerrorselected.png', 18, 16);
    120143    IconStore.addIcon('XmlFile', path + 'item.gif', 18, 16);
    121144    IconStore.addIcon('XmlFileError', path + 'itemerror.gif', 18, 16);
     
    132155    var ep;
    133156    var ext;
     157    var plugin;
    134158    <%
    135159    ExtensionsControl ec = ExtensionsControl.get(dc);
     
    143167      if (id.startsWith("net.sf.basedb.clients.web.onsave.")) parent = "editDialogs";
    144168      %>
    145       <%=getJoustExtensionPoint(parent, ec, ep)%>
     169      <%=getJoustExtensionPoint(parent, ec, ep, ec.getFileByObjectKey(new ExtensionPointKey(ep)))%>
    146170      <%
    147171      List<Extension<?>> extensions = ec.getExtensions(ep.getId());
     
    149173      {
    150174        %>
    151         <%=getJoustExtension("ep", ec, ext, false)%>
     175        <%=getJoustExtension("ep", ec, ext, ec.getFileByObjectKey(new ExtensionKey(ext)), false)%>
    152176        <%
    153177      }
     
    171195      {
    172196        %>
    173         <%=getJoustExtensionPoint("file", ec, ep)%>
     197        <%=getJoustExtensionPoint("file", ec, ep, ef)%>
    174198        <%
    175199      }
     
    196220        }
    197221        %>
    198         <%=getJoustExtension(currentGroupId == null ? "file" : "group", ec, ext, currentGroupId != null)%>
     222        <%=getJoustExtension(currentGroupId == null ? "file" : "group", ec, ext, ef, currentGroupId != null)%>
     223        <%
     224      }
     225      List<PluginInfo> plugins = ef.getObjectsOfClass(PluginInfo.class);
     226      for (PluginInfo info : plugins)
     227      {
     228        %>
     229        <%=getJoustPlugin("file", ec, info, ef)%>
    199230        <%
    200231      }
     
    281312  function extensionPointOnClick(extensionPointId)
    282313  {
    283     parent.frames['details'].location.href = 'details.jsp?ID=<%=ID%>&extensionPointId='+extensionPointId;
     314    parent.frames['details'].location.href = 'details.jsp?ID=<%=ID%>&extensionPointId='+escape(extensionPointId);
    284315  }
    285316  function extensionOnClick(extensionId)
    286317  {
    287     parent.frames['details'].location.href = 'details.jsp?ID=<%=ID%>&extensionId='+extensionId;
     318    parent.frames['details'].location.href = 'details.jsp?ID=<%=ID%>&extensionId='+escape(extensionId);
    288319  }
    289320  function fileOnClick(fileuri)
    290321  {
    291322    parent.frames['details'].location.href = 'details.jsp?ID=<%=ID%>&fileuri='+escape(fileuri);
     323  }
     324  function pluginOnClick(className)
     325  {
     326    parent.frames['details'].location.href = '../plugindefinitions/index.jsp?ID=<%=ID%>&cmd=ViewItemByClass&iframe=1&className='+escape(className);
    292327  }
    293328  </script>
  • trunk/www/admin/plugindefinitions/index.jsp

    r5595 r5615  
    5151  import="net.sf.basedb.core.query.Restrictions"
    5252  import="net.sf.basedb.util.FileUtil"
    53   import="net.sf.basedb.util.PluginInfo"
    5453  import="net.sf.basedb.util.PluginConfigInfo"
    5554  import="net.sf.basedb.util.RemovableUtil"
     
    6968  import="net.sf.basedb.core.plugin.GuiContext"
    7069  import="net.sf.basedb.util.extensions.ExtensionsInvoker"
     70  import="net.sf.basedb.util.extensions.manager.PluginInfoKey"
     71  import="net.sf.basedb.util.extensions.xml.PluginInfo"
    7172  import="net.sf.basedb.clients.web.extensions.ExtensionsControl"
    7273  import="net.sf.basedb.clients.web.extensions.JspContext"
     
    115116  +(callback == null ? "" : "&callback="+callback)
    116117  +(itemId == null ? "" : "&item_id="+itemId);
    117 final String viewPage = "view_plugin.jsp?ID="+ID;
     118final String viewPage = "view_plugin.jsp?ID="+ID+"&iframe=" + Values.getBoolean(request.getParameter("iframe"));
    118119final String editPage = "edit_plugin.jsp?ID="+ID;
    119120
     
    151152    forward = viewPage;
    152153  }
     154  else if ("ViewItemByClass".equals(cmd))
     155  {
     156    dc = sc.newDbControl();
     157    PluginDefinition plugin = PluginDefinition.getByClassName(dc, request.getParameter("className"));
     158    // Display the view page for a single item
     159    ItemContext cc = Base.getAndSetCurrentContext(sc, itemType, pageContext, defaultContext);
     160    cc.setId(plugin.getId());
     161    forward = viewPage;
     162  }
    153163  else if ("EditItem".equals(cmd))
    154164  {
     
    182192    }
    183193  }
     194  /*
    184195  else if("LoadPlugins".equals(cmd))
    185196  {
     
    296307    redirect = "auto_install_result.jsp?ID=" + ID;
    297308  }
     309  */
    298310  else if ("UpdateItem".equals(cmd))
    299311  {
     
    396408    }
    397409  }
     410  else if ("DisableItem".equals(cmd))
     411  {
     412    // Delete a single item and then return to the view page
     413    dc = sc.newDbControl();
     414    ItemContext cc = Base.getAndSetCurrentContext(sc, itemType, pageContext, defaultContext);
     415    PluginDefinition plugin = PluginDefinition.getById(dc, cc.getId());
     416    plugin.setDisabled(true);
     417    ExtensionsControl ec = ExtensionsControl.get(dc);
     418    PluginInfo info = ec.getObjectForKey(new PluginInfoKey(plugin.getClassName()));
     419    if (info != null) info.setDisabled(true);
     420    dc.commit();
     421    redirect = viewPage;
     422  }
     423  else if ("EnableItem".equals(cmd))
     424  {
     425    // Delete a single item and then return to the view page
     426    dc = sc.newDbControl();
     427    ItemContext cc = Base.getAndSetCurrentContext(sc, itemType, pageContext, defaultContext);
     428    PluginDefinition plugin = PluginDefinition.getById(dc, cc.getId());
     429    plugin.setDisabled(false);
     430    ExtensionsControl ec = ExtensionsControl.get(dc);
     431    PluginInfo info = ec.getObjectForKey(new PluginInfoKey(plugin.getClassName()));
     432    if (info != null) info.setDisabled(false);
     433    dc.commit();
     434    redirect = viewPage;
     435  }
    398436  else if ("DeleteItem".equals(cmd))
    399437  {
  • trunk/www/admin/plugindefinitions/list_plugins.jsp

    r5595 r5615  
    368368        datatype="string"
    369369        title="URL"
     370        sortable="true"
     371        filterable="true"
     372        exportable="true"
     373      />
     374      <tbl:columndef
     375        id="disabled"
     376        property="disabled"
     377        datatype="boolean"
     378        title="Disabled"
    370379        sortable="true"
    371380        filterable="true"
     
    703712                <tbl:cell column="email"><%=HTML.encodeTags(item.getEmail())%></tbl:cell>
    704713                <tbl:cell column="url"><%=HTML.encodeTags(item.getUrl())%></tbl:cell>
     714                <tbl:cell column="disabled"><%=item.isDisabled()%></tbl:cell>
    705715                <tbl:cell column="interactive"><%=item.isInteractive()%></tbl:cell>
    706716                <tbl:cell column="supportsConfigurations"><%=item.supportsConfigurations() ? "yes" : "no"%></tbl:cell>
  • trunk/www/admin/plugindefinitions/view_plugin.jsp

    r5595 r5615  
    9595%>
    9696<%
     97final boolean iFrame = Values.getBoolean(request.getParameter("iframe"));
    9798final SessionControl sc = Base.getExistingSessionControl(pageContext, true);
    9899final String ID = sc.getId();
     
    127128  try
    128129  {
    129     Plugin thePlugin = plugin.newInstance(Plugin.class, sc, null, null);
     130    if (plugin.isDisabled())
     131    {
     132      warning = "This plugin is disabled";
     133    }
     134    else
     135    {
     136      plugin.newInstance(Plugin.class, sc, null, null);
     137    }
    130138  }
    131139  catch (RuntimeException ex)
     
    136144  ExtensionsInvoker invoker = ToolbarUtil.useExtensions(jspContext);
    137145  %>
    138   <base:page title="<%=title%>">
     146  <base:page title="<%=title%>" type="<%=iFrame ? "popup" : "default" %>">
    139147  <base:head scripts="tabcontrol.js,table.js" styles="toolbar.css,headertabcontrol.css,path.css,table.css">
    140148    <ext:scripts context="<%=jspContext%>" />
     
    151159    function deleteItem()
    152160    {
    153       location.replace('index.jsp?ID=<%=ID%>&cmd=DeleteItem&item_id=<%=itemId%>');
     161      location.replace('index.jsp?ID=<%=ID%>&cmd=DeleteItem&item_id=<%=itemId%>&iframe=<%=iFrame%>');
    154162    }
    155163    function restoreItem()
    156164    {
    157       location.replace('index.jsp?ID=<%=ID%>&cmd=RestoreItem&item_id=<%=itemId%>');
     165      location.replace('index.jsp?ID=<%=ID%>&cmd=RestoreItem&item_id=<%=itemId%>&iframe=<%=iFrame%>');
    158166    }
    159167    function deleteItemPermanently()
     
    179187    function unloadPlugin()
    180188    {
    181       location.replace('index.jsp?ID=<%=ID%>&cmd=UnloadItem&item_id=<%=itemId%>');
     189      location.replace('index.jsp?ID=<%=ID%>&cmd=UnloadItem&item_id=<%=itemId%>&iframe=<%=iFrame%>');
    182190    }
    183191    function newConfiguration()
     
    192200    {
    193201      Main.viewOrEditItem('<%=ID%>', '<%=itemType.name()%>', <%=itemId%>, true, '&jobagent_id='+agentId);
     202    }
     203    function toggleDisabled()
     204    {
     205      var enable = <%=plugin.isDisabled() ? 1 : 0%>;
     206      var tree = window.parent.frames['tree'];
     207      if (tree && tree.setIcon)
     208      {
     209        var iconName = enable ? 'Plugin' : 'PluginDisabled';
     210        tree.setIcon('<%=plugin.getClassName()%>', iconName);
     211      }
     212      var cmd = enable ? 'EnableItem' : 'DisableItem';
     213      location.replace('index.jsp?ID=<%=ID%>&cmd=' + cmd + '&item_id=<%=itemId%>&iframe=<%=iFrame%>');
    194214    }
    195215    </script>
     
    197217  <base:body>
    198218    <p>
    199     <p:path>
    200       <p:pathelement title="Plugins" href="<%="index.jsp?ID="+ID%>" />
    201       <p:pathelement title="<%=HTML.encodeTags(plugin.getName())%>" />
    202     </p:path>
    203    
    204     <t:tabcontrol id="main" active="properties">
     219    <%
     220    if (!iFrame)
     221    {
     222      %>
     223      <p:path>
     224        <p:pathelement title="Plugins" href="<%="index.jsp?ID="+ID%>" />
     225        <p:pathelement title="<%=HTML.encodeTags(plugin.getName())%>" />
     226      </p:path>
     227      <%
     228    }
     229    %>
     230    <t:tabcontrol id="main" active="properties" notabs="<%=iFrame %>">
    205231    <t:tab id="properties" title="Properties">
    206232    <tbl:toolbar
     
    212238        title="Edit&hellip;"
    213239        tooltip="<%=writePermission ? "Edit this plugin" : "You do not have permission to edit this plugin"%>"
     240      />
     241      <tbl:button
     242        image="joust/plugin.png"
     243        onclick="toggleDisabled()"
     244        title="<%=plugin.isDisabled() ? "Enable" : "Disable"%>"
     245        visible="<%=writePermission%>"
     246        tooltip="Disable/enable this plugin"
    214247      />
    215248      <tbl:button
  • trunk/www/common/import/index.jsp

    r5426 r5615  
    9696      )
    9797    );
     98    pluginQuery.restrict(Restrictions.eq(Hql.property("disabled"), Expressions.parameter("isDisabled", false)));
    9899    pluginQuery.order(Orders.asc(Hql.property("name")));
    99100    pluginQuery.include(Include.MINE, Include.SHARED, Include.IN_PROJECT, Include.OTHERS);
  • trunk/www/common/plugin/index.jsp

    r5590 r5615  
    168168      )
    169169    );
     170    pluginQuery.restrict(Restrictions.eq(Hql.property("disabled"), Expressions.parameter("isDisabled", false)));
    170171    pluginQuery.order(Orders.asc(Hql.property("name")));
    171172    pluginQuery.include(Include.MINE, Include.SHARED, Include.IN_PROJECT, Include.OTHERS);
Note: See TracChangeset for help on using the changeset viewer.