src/core/net/sf/basedb/util/extensions/manager/processor/RegisterExtensionsProcessor.java

Code
Comments
Other
Rev Date Author Line
5598 30 Mar 11 nicklas 1 /**
5598 30 Mar 11 nicklas 2   $Id$
5598 30 Mar 11 nicklas 3
5598 30 Mar 11 nicklas 4   Copyright (C) 2011 Nicklas Nordborg
5598 30 Mar 11 nicklas 5
5598 30 Mar 11 nicklas 6   This file is part of BASE - BioArray Software Environment.
5598 30 Mar 11 nicklas 7   Available at http://base.thep.lu.se/
5598 30 Mar 11 nicklas 8
5598 30 Mar 11 nicklas 9   BASE is free software; you can redistribute it and/or
5598 30 Mar 11 nicklas 10   modify it under the terms of the GNU General Public License
5598 30 Mar 11 nicklas 11   as published by the Free Software Foundation; either version 3
5598 30 Mar 11 nicklas 12   of the License, or (at your option) any later version.
5598 30 Mar 11 nicklas 13
5598 30 Mar 11 nicklas 14   BASE is distributed in the hope that it will be useful,
5598 30 Mar 11 nicklas 15   but WITHOUT ANY WARRANTY; without even the implied warranty of
5598 30 Mar 11 nicklas 16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
5598 30 Mar 11 nicklas 17   GNU General Public License for more details.
5598 30 Mar 11 nicklas 18
5598 30 Mar 11 nicklas 19   You should have received a copy of the GNU General Public License
5598 30 Mar 11 nicklas 20   along with BASE. If not, see <http://www.gnu.org/licenses/>.
5598 30 Mar 11 nicklas 21 */
5603 08 Apr 11 nicklas 22 package net.sf.basedb.util.extensions.manager.processor;
5598 30 Mar 11 nicklas 23
6030 28 Mar 12 nicklas 24 import java.io.IOException;
5598 30 Mar 11 nicklas 25 import java.io.InputStream;
5601 01 Apr 11 nicklas 26 import java.util.ArrayList;
5607 15 Apr 11 nicklas 27 import java.util.Collections;
5601 01 Apr 11 nicklas 28 import java.util.List;
5598 30 Mar 11 nicklas 29
6595 14 Nov 14 nicklas 30 import net.sf.basedb.core.plugin.About;
5598 30 Mar 11 nicklas 31 import net.sf.basedb.util.FileUtil;
6595 14 Nov 14 nicklas 32 import net.sf.basedb.util.Values;
6595 14 Nov 14 nicklas 33 import net.sf.basedb.util.extensions.ExtendedAbout;
5601 01 Apr 11 nicklas 34 import net.sf.basedb.util.extensions.Extension;
5601 01 Apr 11 nicklas 35 import net.sf.basedb.util.extensions.ExtensionPoint;
5601 01 Apr 11 nicklas 36 import net.sf.basedb.util.extensions.Registry;
5603 08 Apr 11 nicklas 37 import net.sf.basedb.util.extensions.manager.ExtensionKey;
5603 08 Apr 11 nicklas 38 import net.sf.basedb.util.extensions.manager.ExtensionPointKey;
5603 08 Apr 11 nicklas 39 import net.sf.basedb.util.extensions.manager.ExtensionsFile;
5603 08 Apr 11 nicklas 40 import net.sf.basedb.util.extensions.manager.ExtensionsFileProcessor;
5603 08 Apr 11 nicklas 41 import net.sf.basedb.util.extensions.manager.ExtensionsManager;
5603 08 Apr 11 nicklas 42 import net.sf.basedb.util.extensions.manager.FactoryParametersKey;
5603 08 Apr 11 nicklas 43 import net.sf.basedb.util.extensions.manager.ProcessResults;
5602 07 Apr 11 nicklas 44 import net.sf.basedb.util.extensions.manager.ExtensionsFile.WriteableExtensionsFile;
6595 14 Nov 14 nicklas 45 import net.sf.basedb.util.extensions.manager.Settings;
5603 08 Apr 11 nicklas 46 import net.sf.basedb.util.extensions.manager.filter.ValidAndNewOrModifiedFilter;
5598 30 Mar 11 nicklas 47 import net.sf.basedb.util.extensions.xml.XmlLoader;
5598 30 Mar 11 nicklas 48
5598 30 Mar 11 nicklas 49 /**
5598 30 Mar 11 nicklas 50   Extension file processor implementation that will load the
5598 30 Mar 11 nicklas 51   extension definitions from each file and register them with
5602 07 Apr 11 nicklas 52   the registry that is managed by the manager. This processor
5602 07 Apr 11 nicklas 53   is a two-step processer. The first step will load extension
5602 07 Apr 11 nicklas 54   definitions from the files. The second step will register the
5602 07 Apr 11 nicklas 55   loaded extension with the managers registry.
5602 07 Apr 11 nicklas 56   <p>
5602 07 Apr 11 nicklas 57   The first step is executed via the manager: 
5602 07 Apr 11 nicklas 58   {@link ExtensionsManager#processFiles(ExtensionsFileProcessor)}.
5602 07 Apr 11 nicklas 59   The second step is either automatically executed when all files
5603 08 Apr 11 nicklas 60   have been processed or executed by by calling 
5691 11 Aug 11 nicklas 61   {@link #finalizeRegistration(ExtensionsManager, boolean)}.
5603 08 Apr 11 nicklas 62   <p>
5603 08 Apr 11 nicklas 63   Note! It is recommended that this processor is paired with a 
5603 08 Apr 11 nicklas 64   {@link ValidAndNewOrModifiedFilter} since it is usually no
5603 08 Apr 11 nicklas 65   point in trying to register invalid extensions.
5598 30 Mar 11 nicklas 66
5603 08 Apr 11 nicklas 67
5598 30 Mar 11 nicklas 68   @author Nicklas
5598 30 Mar 11 nicklas 69   @since 3.0
5598 30 Mar 11 nicklas 70   @base.modified $Date$
5598 30 Mar 11 nicklas 71 */
5598 30 Mar 11 nicklas 72 public class RegisterExtensionsProcessor
5598 30 Mar 11 nicklas 73   implements ExtensionsFileProcessor
5598 30 Mar 11 nicklas 74 {
5598 30 Mar 11 nicklas 75
5598 30 Mar 11 nicklas 76   
6444 09 Apr 14 nicklas 77   private static final org.slf4j.Logger log = 
6444 09 Apr 14 nicklas 78     org.slf4j.LoggerFactory.getLogger(RegisterExtensionsProcessor.class);
5598 30 Mar 11 nicklas 79   
5598 30 Mar 11 nicklas 80   private final XmlLoader loader;
5602 07 Apr 11 nicklas 81   private final ProcessResults results;
5603 08 Apr 11 nicklas 82   private boolean delayRegistration;
5605 12 Apr 11 nicklas 83   private boolean forceUpdate;
5602 07 Apr 11 nicklas 84   private List<FileData> allData;
5603 08 Apr 11 nicklas 85
5603 08 Apr 11 nicklas 86   private int numFiles;
5603 08 Apr 11 nicklas 87   private int numError;
5603 08 Apr 11 nicklas 88   private int numRegistered;
5605 12 Apr 11 nicklas 89   private int numUnregistered;
5603 08 Apr 11 nicklas 90
5598 30 Mar 11 nicklas 91   /**
5598 30 Mar 11 nicklas 92     Create a new processor. 
5598 30 Mar 11 nicklas 93     
5598 30 Mar 11 nicklas 94     @param loader The XML loader to use when parsing the metadata
5598 30 Mar 11 nicklas 95   */
5603 08 Apr 11 nicklas 96   public RegisterExtensionsProcessor(XmlLoader loader, ProcessResults results)
5598 30 Mar 11 nicklas 97   {
5598 30 Mar 11 nicklas 98     this.loader = loader;
5602 07 Apr 11 nicklas 99     this.results = results;
5598 30 Mar 11 nicklas 100   }
5598 30 Mar 11 nicklas 101   
5598 30 Mar 11 nicklas 102   /*
5598 30 Mar 11 nicklas 103     From the ExtensionsFileProcessor interface
5598 30 Mar 11 nicklas 104     ------------------------------------------
5598 30 Mar 11 nicklas 105   */
5598 30 Mar 11 nicklas 106   @Override
5598 30 Mar 11 nicklas 107   public void begin(ExtensionsManager manager, int numFiles)
5601 01 Apr 11 nicklas 108   {
5602 07 Apr 11 nicklas 109     this.allData = new ArrayList<FileData>(numFiles);
5603 08 Apr 11 nicklas 110     this.numFiles = 0;
5603 08 Apr 11 nicklas 111     this.numError = 0;
5603 08 Apr 11 nicklas 112     this.numRegistered = 0;
5605 12 Apr 11 nicklas 113     this.numUnregistered = 0;
5601 01 Apr 11 nicklas 114   }
5598 30 Mar 11 nicklas 115
5598 30 Mar 11 nicklas 116   @Override
5603 08 Apr 11 nicklas 117   public void processFile(ExtensionsManager manager, WriteableExtensionsFile wFile)
5598 30 Mar 11 nicklas 118   {
5598 30 Mar 11 nicklas 119     InputStream in = null;
5603 08 Apr 11 nicklas 120     ExtensionsFile xtFile = wFile.getExtensionsFile();
5603 08 Apr 11 nicklas 121     
5598 30 Mar 11 nicklas 122     try
5598 30 Mar 11 nicklas 123     {
5603 08 Apr 11 nicklas 124       log.info("Loading extensions from file: " + xtFile);
5607 15 Apr 11 nicklas 125       FileData data = new FileData();
5607 15 Apr 11 nicklas 126       data.writeableFile = wFile;
5607 15 Apr 11 nicklas 127       allData.add(data);
5598 30 Mar 11 nicklas 128       in = xtFile.getXmlStream();
5601 01 Apr 11 nicklas 129       loader.loadXmlFile(in, xtFile.getName(), xtFile.getClassLoader(), true);
5606 14 Apr 11 nicklas 130       data.extensionPoints = new ArrayList<ExtensionPoint<?>>(loader.getExtensionPoints());
5606 14 Apr 11 nicklas 131       data.extensions = new ArrayList<Extension<?>>(loader.getExtensions());
6602 17 Nov 14 nicklas 132       Collections.sort(data.extensionPoints, Registry.EXTENSIONPOINT_ID_COMPARATOR);
6602 17 Nov 14 nicklas 133       Collections.sort(data.extensions, Registry.EXTENSION_ID_COMPARATOR);
5603 08 Apr 11 nicklas 134       numFiles++;
5602 07 Apr 11 nicklas 135       log.info("Loaded " + data.extensionPoints.size() + "/" + data.extensions.size() + 
5603 08 Apr 11 nicklas 136           " extensions from file: " + xtFile);
5598 30 Mar 11 nicklas 137     }
6379 13 Dec 13 nicklas 138     catch (Throwable ex)
5598 30 Mar 11 nicklas 139     {
5603 08 Apr 11 nicklas 140       wFile.setError(true);
5603 08 Apr 11 nicklas 141       numError++;
5603 08 Apr 11 nicklas 142       if (results != null)
5603 08 Apr 11 nicklas 143       {
5607 15 Apr 11 nicklas 144         results.addErrorMessage(xtFile, "Failed to load extension(s): " + ex.getMessage());
5603 08 Apr 11 nicklas 145       }
5603 08 Apr 11 nicklas 146       log.error("Failed to load extensions from file: " + xtFile, ex);
5598 30 Mar 11 nicklas 147     }
5598 30 Mar 11 nicklas 148     finally
5598 30 Mar 11 nicklas 149     {
5598 30 Mar 11 nicklas 150       FileUtil.close(in);
5598 30 Mar 11 nicklas 151     }
5598 30 Mar 11 nicklas 152   }
5598 30 Mar 11 nicklas 153   
5598 30 Mar 11 nicklas 154   @Override
5598 30 Mar 11 nicklas 155   public void done(ExtensionsManager manager)
5598 30 Mar 11 nicklas 156   {
5616 27 Apr 11 nicklas 157     if (!delayRegistration) finalizeRegistration(manager, true);
5602 07 Apr 11 nicklas 158   }
5602 07 Apr 11 nicklas 159   
5602 07 Apr 11 nicklas 160   @Override
5602 07 Apr 11 nicklas 161   public void done(ExtensionsManager manager, Throwable t)
5602 07 Apr 11 nicklas 162   {
5605 12 Apr 11 nicklas 163     if (allData != null) allData.clear();
5602 07 Apr 11 nicklas 164     allData = null;
5602 07 Apr 11 nicklas 165   }
5602 07 Apr 11 nicklas 166   // ------------------------------------------
5602 07 Apr 11 nicklas 167
5603 08 Apr 11 nicklas 168   /**
5603 08 Apr 11 nicklas 169     Set a flag to indicate if the actual registration of the found
5603 08 Apr 11 nicklas 170     extensions and extension points should be delayed or not.
5603 08 Apr 11 nicklas 171     The default is to not delay registration, which means that
5603 08 Apr 11 nicklas 172     it happend when the {@link #done(ExtensionsManager)} method is
5603 08 Apr 11 nicklas 173     called by the manager. If this flag is set the 
5691 11 Aug 11 nicklas 174     {@link #finalizeRegistration(ExtensionsManager, boolean)}
5603 08 Apr 11 nicklas 175     method must be explicitely called.
5603 08 Apr 11 nicklas 176   */
5603 08 Apr 11 nicklas 177   public void setDelayRegistration(boolean delayRegistration)
5603 08 Apr 11 nicklas 178   {
5603 08 Apr 11 nicklas 179     this.delayRegistration = delayRegistration;
5603 08 Apr 11 nicklas 180   }
5602 07 Apr 11 nicklas 181   
5603 08 Apr 11 nicklas 182   /**
5603 08 Apr 11 nicklas 183     Is the actual registration delayed or not?
5603 08 Apr 11 nicklas 184   */
5603 08 Apr 11 nicklas 185   public boolean isRegistrationDelayed()
5602 07 Apr 11 nicklas 186   {
5603 08 Apr 11 nicklas 187     return delayRegistration;
5603 08 Apr 11 nicklas 188   }
5603 08 Apr 11 nicklas 189   
5603 08 Apr 11 nicklas 190   /**
5605 12 Apr 11 nicklas 191     Set a flag to indicate if already registered extensions should
5605 12 Apr 11 nicklas 192     be re-registered or not.
5605 12 Apr 11 nicklas 193     @param forceUpdate TRUE to always re-register extensions, 
5605 12 Apr 11 nicklas 194       FALSE to only register new or updated extensions
5605 12 Apr 11 nicklas 195   */
5605 12 Apr 11 nicklas 196   public void setForceUpdate(boolean forceUpdate)
5605 12 Apr 11 nicklas 197   {
5605 12 Apr 11 nicklas 198     this.forceUpdate = forceUpdate;
5605 12 Apr 11 nicklas 199   }
5605 12 Apr 11 nicklas 200   
5605 12 Apr 11 nicklas 201   /**
5603 08 Apr 11 nicklas 202     Get the loader the processor is using for parsing xml files with
5603 08 Apr 11 nicklas 203     extension definitions.
5603 08 Apr 11 nicklas 204   */
5603 08 Apr 11 nicklas 205   public XmlLoader getXmlLoader()
5603 08 Apr 11 nicklas 206   {
5603 08 Apr 11 nicklas 207     return loader;
5603 08 Apr 11 nicklas 208   }
5603 08 Apr 11 nicklas 209   
5603 08 Apr 11 nicklas 210   public ProcessResults getProcessResults()
5603 08 Apr 11 nicklas 211   {
5603 08 Apr 11 nicklas 212     return results;
5603 08 Apr 11 nicklas 213   }
5603 08 Apr 11 nicklas 214   
5616 27 Apr 11 nicklas 215   public void finalizeRegistration(ExtensionsManager manager, boolean unregisterMissing)
5603 08 Apr 11 nicklas 216   {
5602 07 Apr 11 nicklas 217     if (allData == null) return;
5602 07 Apr 11 nicklas 218
5602 07 Apr 11 nicklas 219     Registry registry = manager.getRegistry();
5602 07 Apr 11 nicklas 220
5605 12 Apr 11 nicklas 221     // First loop -- unregister extensions and extension points that are missing
5616 27 Apr 11 nicklas 222     if (unregisterMissing)
5605 12 Apr 11 nicklas 223     {
5616 27 Apr 11 nicklas 224       log.info("Unregistering all missing extension points and extensions");
5616 27 Apr 11 nicklas 225       for (FileData data : allData)
5605 12 Apr 11 nicklas 226       {
5616 27 Apr 11 nicklas 227         WriteableExtensionsFile wFile = data.writeableFile;
5616 27 Apr 11 nicklas 228         ExtensionsFile xtFile = wFile.getExtensionsFile();
5616 27 Apr 11 nicklas 229   
5616 27 Apr 11 nicklas 230         if (!forceUpdate && (!xtFile.wasModified() || xtFile.isNew()))
5605 12 Apr 11 nicklas 231         {
5616 27 Apr 11 nicklas 232           log.debug("Skipping new or unmodified file: " + xtFile);
5616 27 Apr 11 nicklas 233           continue;
5605 12 Apr 11 nicklas 234         }
5616 27 Apr 11 nicklas 235   
5616 27 Apr 11 nicklas 236         // Unregister all extensions if the file has an error
5616 27 Apr 11 nicklas 237         if (xtFile.hasError())
5605 12 Apr 11 nicklas 238         {
5616 27 Apr 11 nicklas 239           data.extensions = Collections.emptyList();
5616 27 Apr 11 nicklas 240           data.extensionPoints = Collections.emptyList();
5605 12 Apr 11 nicklas 241         }
5605 12 Apr 11 nicklas 242         
5616 27 Apr 11 nicklas 243         try
5605 12 Apr 11 nicklas 244         {
5616 27 Apr 11 nicklas 245           wFile.open();
5616 27 Apr 11 nicklas 246           int num = 0;
5616 27 Apr 11 nicklas 247           // Extension points
6875 20 Apr 15 nicklas 248           for (ExtensionPoint<?> ep : xtFile.getObjectsOfClass(ExtensionPoint.class))
5605 12 Apr 11 nicklas 249           {
5616 27 Apr 11 nicklas 250             if (unregisterExtensionPoint(data, ep, registry))
5616 27 Apr 11 nicklas 251             {
5616 27 Apr 11 nicklas 252               num++;
5616 27 Apr 11 nicklas 253             }
5605 12 Apr 11 nicklas 254           }
5616 27 Apr 11 nicklas 255           if (num > 0 && results != null)
5616 27 Apr 11 nicklas 256           {
5616 27 Apr 11 nicklas 257             numUnregistered += num;
5616 27 Apr 11 nicklas 258             results.addMessage(xtFile, num + " extension point(s) unregistered.");
5616 27 Apr 11 nicklas 259           }
5616 27 Apr 11 nicklas 260           log.info("Unregistered " + num + " extension point(s) from file: " + xtFile);
5616 27 Apr 11 nicklas 261           
5616 27 Apr 11 nicklas 262           // Extensions
5616 27 Apr 11 nicklas 263           num = 0;
6875 20 Apr 15 nicklas 264           for (Extension<?> ext : xtFile.getObjectsOfClass(Extension.class))
5616 27 Apr 11 nicklas 265           {
5616 27 Apr 11 nicklas 266             if (unregisterExtension(data, ext, registry)) 
5616 27 Apr 11 nicklas 267             {
5616 27 Apr 11 nicklas 268               num++;
5616 27 Apr 11 nicklas 269             }
5616 27 Apr 11 nicklas 270           }
5616 27 Apr 11 nicklas 271           if (num > 0 && results != null)
5616 27 Apr 11 nicklas 272           {
5616 27 Apr 11 nicklas 273             numUnregistered += num;
5616 27 Apr 11 nicklas 274             results.addMessage(xtFile, num + " extension(s) unregistered.");
5616 27 Apr 11 nicklas 275           }
5616 27 Apr 11 nicklas 276           log.info("Unregistered " + num + " extension(s) from file: " + xtFile);
5605 12 Apr 11 nicklas 277         }
5616 27 Apr 11 nicklas 278         catch (Throwable ex)
5605 12 Apr 11 nicklas 279         {
5616 27 Apr 11 nicklas 280           log.error("Could not unregister extensions from file: " + xtFile, ex);
5605 12 Apr 11 nicklas 281         }
5616 27 Apr 11 nicklas 282         finally
5616 27 Apr 11 nicklas 283         {
5616 27 Apr 11 nicklas 284           wFile.close(); // Important! release the write lock
5616 27 Apr 11 nicklas 285         }
5605 12 Apr 11 nicklas 286       }
5605 12 Apr 11 nicklas 287     }
5605 12 Apr 11 nicklas 288     
5605 12 Apr 11 nicklas 289     // Second loop -- register extension points
5602 07 Apr 11 nicklas 290     log.info("Registering all loaded extension points");
5602 07 Apr 11 nicklas 291     for (FileData data : allData)
5601 01 Apr 11 nicklas 292     {
5602 07 Apr 11 nicklas 293       WriteableExtensionsFile wFile = data.writeableFile;
5602 07 Apr 11 nicklas 294       ExtensionsFile xtFile = wFile.getExtensionsFile();
5602 07 Apr 11 nicklas 295
5602 07 Apr 11 nicklas 296       // NOTE! Do not register files with an error
5602 07 Apr 11 nicklas 297       if (xtFile.hasError())
5601 01 Apr 11 nicklas 298       {
5602 07 Apr 11 nicklas 299         log.debug("Skipping file with error: " + xtFile);
5602 07 Apr 11 nicklas 300         continue; // with the next file
5602 07 Apr 11 nicklas 301       }
5602 07 Apr 11 nicklas 302       
5602 07 Apr 11 nicklas 303       try
5602 07 Apr 11 nicklas 304       {
5602 07 Apr 11 nicklas 305         wFile.open();
5605 12 Apr 11 nicklas 306         int num = registerExtensionPoints(data, registry, forceUpdate || xtFile.wasModified());
5603 08 Apr 11 nicklas 307         if (num > 0 && results != null)
5601 01 Apr 11 nicklas 308         {
5603 08 Apr 11 nicklas 309           results.addMessage(xtFile, num + " extension point(s) registered.");
5601 01 Apr 11 nicklas 310         }
5603 08 Apr 11 nicklas 311         log.info("Registered " + num + " extension point(s) from file: " + xtFile);
5603 08 Apr 11 nicklas 312         numRegistered += num;
5601 01 Apr 11 nicklas 313       }
5602 07 Apr 11 nicklas 314       catch (Throwable ex)
5601 01 Apr 11 nicklas 315       {
5602 07 Apr 11 nicklas 316         wFile.setError(true);
5603 08 Apr 11 nicklas 317         if (results != null)
5603 08 Apr 11 nicklas 318         {
5603 08 Apr 11 nicklas 319           results.addErrorMessage(xtFile, 
6379 13 Dec 13 nicklas 320             "Could not register extension point(s): " + ex.getClass().getName() + "; " + ex.getMessage());
5603 08 Apr 11 nicklas 321         }
5602 07 Apr 11 nicklas 322         log.error("Could not register extension points from file: " + xtFile, ex);
5602 07 Apr 11 nicklas 323       }
5602 07 Apr 11 nicklas 324       finally
5602 07 Apr 11 nicklas 325       {
5602 07 Apr 11 nicklas 326         wFile.close(); // Important! release the write lock
5602 07 Apr 11 nicklas 327       }
5602 07 Apr 11 nicklas 328     }
5602 07 Apr 11 nicklas 329     
5605 12 Apr 11 nicklas 330     // Third loop -- register extensions
5602 07 Apr 11 nicklas 331     log.info("Registering all loaded extensions");
5602 07 Apr 11 nicklas 332     for (FileData data : allData)
5602 07 Apr 11 nicklas 333     {
5602 07 Apr 11 nicklas 334       WriteableExtensionsFile wFile = data.writeableFile;
5602 07 Apr 11 nicklas 335       ExtensionsFile xtFile = wFile.getExtensionsFile();
5602 07 Apr 11 nicklas 336
5602 07 Apr 11 nicklas 337       // NOTE! Do not register files with an error
5602 07 Apr 11 nicklas 338       if (xtFile.hasError())
5602 07 Apr 11 nicklas 339       {
5602 07 Apr 11 nicklas 340         log.debug("Skipping file with error: " + xtFile);
5602 07 Apr 11 nicklas 341         continue; // with the next file
5602 07 Apr 11 nicklas 342       }
5602 07 Apr 11 nicklas 343       
5602 07 Apr 11 nicklas 344       try
5602 07 Apr 11 nicklas 345       {
5602 07 Apr 11 nicklas 346         wFile.open();
6595 14 Nov 14 nicklas 347         int num = registerExtensions(data, manager, forceUpdate || xtFile.wasModified());
5603 08 Apr 11 nicklas 348         if (num > 0 && results != null)
5601 01 Apr 11 nicklas 349         {
5603 08 Apr 11 nicklas 350           results.addMessage(xtFile, num + " extension(s) registered.");
5601 01 Apr 11 nicklas 351         }
5603 08 Apr 11 nicklas 352         log.info("Registered " + num + " extension(s) from file: " + xtFile);
5603 08 Apr 11 nicklas 353         numRegistered += num;
5601 01 Apr 11 nicklas 354       }
5602 07 Apr 11 nicklas 355       catch (Throwable ex)
5602 07 Apr 11 nicklas 356       {
5602 07 Apr 11 nicklas 357         wFile.setError(true);
5603 08 Apr 11 nicklas 358         if (results != null)
5603 08 Apr 11 nicklas 359         {
5603 08 Apr 11 nicklas 360           results.addErrorMessage(xtFile, 
6379 13 Dec 13 nicklas 361             "Could not register extension(s): " + ex.getClass().getName() + "; " + ex.getMessage());
5603 08 Apr 11 nicklas 362         }
5602 07 Apr 11 nicklas 363         log.error("Could not register extension points from file: " + xtFile, ex);
5602 07 Apr 11 nicklas 364       }
5602 07 Apr 11 nicklas 365       finally
5602 07 Apr 11 nicklas 366       {
5602 07 Apr 11 nicklas 367         wFile.close(); // Important! release the write lock
5602 07 Apr 11 nicklas 368       }
5601 01 Apr 11 nicklas 369     }
5602 07 Apr 11 nicklas 370     
5602 07 Apr 11 nicklas 371     allData.clear();
5602 07 Apr 11 nicklas 372     allData = null;
5598 30 Mar 11 nicklas 373   }
5602 07 Apr 11 nicklas 374
5603 08 Apr 11 nicklas 375   /**
5603 08 Apr 11 nicklas 376     Get the number of files that was successfully processed.
5603 08 Apr 11 nicklas 377   */
5603 08 Apr 11 nicklas 378   public int getNumFiles()
5603 08 Apr 11 nicklas 379   {
5603 08 Apr 11 nicklas 380     return numFiles;
5603 08 Apr 11 nicklas 381   }
5598 30 Mar 11 nicklas 382   
5603 08 Apr 11 nicklas 383   /**
5603 08 Apr 11 nicklas 384     Get the number of files that was had an error.
5603 08 Apr 11 nicklas 385   */
5603 08 Apr 11 nicklas 386   public int getNumError()
5603 08 Apr 11 nicklas 387   {
5603 08 Apr 11 nicklas 388     return numError;
5603 08 Apr 11 nicklas 389   }
5603 08 Apr 11 nicklas 390   
5603 08 Apr 11 nicklas 391   /**
5603 08 Apr 11 nicklas 392     Get the number of extensions + extension points that
5603 08 Apr 11 nicklas 393     was registered.
5603 08 Apr 11 nicklas 394   */
5603 08 Apr 11 nicklas 395   public int getNumRegistered()
5603 08 Apr 11 nicklas 396   {
5603 08 Apr 11 nicklas 397     return numRegistered;
5603 08 Apr 11 nicklas 398   }
5605 12 Apr 11 nicklas 399   
5605 12 Apr 11 nicklas 400   /**
5605 12 Apr 11 nicklas 401     Get the number of extensions + extension points that
5605 12 Apr 11 nicklas 402     was unregistered.
5605 12 Apr 11 nicklas 403   */
5605 12 Apr 11 nicklas 404   public int getNumUnregistered()
5605 12 Apr 11 nicklas 405   {
5605 12 Apr 11 nicklas 406     return numUnregistered;
5605 12 Apr 11 nicklas 407   }
5603 08 Apr 11 nicklas 408
5603 08 Apr 11 nicklas 409   
5605 12 Apr 11 nicklas 410   private int registerExtensionPoints(FileData data, Registry registry, boolean forceUpdate)
6030 28 Mar 12 nicklas 411     throws IOException
5601 01 Apr 11 nicklas 412   {
5602 07 Apr 11 nicklas 413     int numRegistered = 0;
5606 14 Apr 11 nicklas 414     for (ExtensionPoint<?> ep : data.extensionPoints)
5602 07 Apr 11 nicklas 415     {
5605 12 Apr 11 nicklas 416       if (forceUpdate || !registry.extensionPointIsRegistered(ep.getId()))
5602 07 Apr 11 nicklas 417       {
5607 15 Apr 11 nicklas 418         log.debug("Registering extension point: " + ep);
5602 07 Apr 11 nicklas 419         ExtensionPointKey key = new ExtensionPointKey(ep);
5602 07 Apr 11 nicklas 420         data.writeableFile.registerObject(key, ep);
5602 07 Apr 11 nicklas 421         registerFactory(data, ep.getErrorHandlerFactory());
5602 07 Apr 11 nicklas 422         registerFactory(data, ep.getRendererFactory());
6030 28 Mar 12 nicklas 423         registry.registerExtensionPoint(ep, data.writeableFile.getExtensionsFile().getClassLoader());
5602 07 Apr 11 nicklas 424         numRegistered++;
5602 07 Apr 11 nicklas 425       }
5602 07 Apr 11 nicklas 426     }
5602 07 Apr 11 nicklas 427     return numRegistered;
5601 01 Apr 11 nicklas 428   }
5602 07 Apr 11 nicklas 429   
5605 12 Apr 11 nicklas 430   /**
5605 12 Apr 11 nicklas 431     Unregister the given extension point if it is not included in the new
5605 12 Apr 11 nicklas 432     file data information. In all cases, factory metadata must be removed,
5605 12 Apr 11 nicklas 433     since we leak memory otherwise (new factory instances are always created
5605 12 Apr 11 nicklas 434     when scanning a modified file).
5605 12 Apr 11 nicklas 435     @return TRUE if the extension point is not going to be registered again
5605 12 Apr 11 nicklas 436   */
6875 20 Apr 15 nicklas 437   private boolean unregisterExtensionPoint(FileData data, ExtensionPoint<?> ep, Registry registry)
5602 07 Apr 11 nicklas 438   {
5607 15 Apr 11 nicklas 439     log.debug("Unregistering extension point: " + ep);
5605 12 Apr 11 nicklas 440     unregisterFactory(data, ep.getRendererFactory());
5605 12 Apr 11 nicklas 441     unregisterFactory(data, ep.getErrorHandlerFactory());
5605 12 Apr 11 nicklas 442     ExtensionPointKey key = new ExtensionPointKey(ep);
5605 12 Apr 11 nicklas 443     data.writeableFile.unregisterObject(key);
6602 17 Nov 14 nicklas 444     if (Collections.binarySearch(data.extensionPoints, ep, Registry.EXTENSIONPOINT_ID_COMPARATOR) < 0)
5605 12 Apr 11 nicklas 445     {
5605 12 Apr 11 nicklas 446       registry.unregisterExtensionPoint(ep.getId());
5605 12 Apr 11 nicklas 447       return true;
5605 12 Apr 11 nicklas 448     }
5605 12 Apr 11 nicklas 449     return false;
5605 12 Apr 11 nicklas 450   }
5605 12 Apr 11 nicklas 451   
6595 14 Nov 14 nicklas 452   private int registerExtensions(FileData data, ExtensionsManager manager, boolean forceUpdateOrModified)
6030 28 Mar 12 nicklas 453     throws IOException
5605 12 Apr 11 nicklas 454   {
5602 07 Apr 11 nicklas 455     int numRegistered = 0;
6595 14 Nov 14 nicklas 456     Registry registry = manager.getRegistry();
6595 14 Nov 14 nicklas 457     Settings settings = manager.getSettings();
5606 14 Apr 11 nicklas 458     for (Extension<?> ext : data.extensions)
5602 07 Apr 11 nicklas 459     {
6595 14 Nov 14 nicklas 460       boolean isNew = !registry.extensionIsRegistered(ext.getId());
6595 14 Nov 14 nicklas 461       if (forceUpdateOrModified || isNew)
5602 07 Apr 11 nicklas 462       {
5607 15 Apr 11 nicklas 463         log.debug("Registering extension: " + ext);
5602 07 Apr 11 nicklas 464         ExtensionKey key = new ExtensionKey(ext);
5602 07 Apr 11 nicklas 465         data.writeableFile.registerObject(key, ext);
5602 07 Apr 11 nicklas 466         registerFactory(data, ext.getActionFactory());
5602 07 Apr 11 nicklas 467         registerFactory(data, ext.getRendererFactory());
6030 28 Mar 12 nicklas 468         registry.registerExtension(ext, data.writeableFile.getExtensionsFile().getClassLoader());
5602 07 Apr 11 nicklas 469         numRegistered++;
6595 14 Nov 14 nicklas 470         // Check disabled="*" attribute for new extensions
6595 14 Nov 14 nicklas 471         // isNew==true also at server startup, so we must also check 'forceUpdate'
6595 14 Nov 14 nicklas 472         // since it is set when installing (forceUpdateOrModified is also set for modified files)
6595 14 Nov 14 nicklas 473         if (isNew && forceUpdate)
6595 14 Nov 14 nicklas 474         {
6595 14 Nov 14 nicklas 475           // Check if disabled="1" is set in <about>
6595 14 Nov 14 nicklas 476           About about = ext.getAbout();
6595 14 Nov 14 nicklas 477           if (about instanceof ExtendedAbout)
6595 14 Nov 14 nicklas 478           {
6595 14 Nov 14 nicklas 479             boolean disable = Values.getBoolean(((ExtendedAbout)ext.getAbout()).getAttribute("disabled"));
6595 14 Nov 14 nicklas 480             settings.enableExtension(ext.getId(), !disable);
6595 14 Nov 14 nicklas 481           }
6595 14 Nov 14 nicklas 482         }
5602 07 Apr 11 nicklas 483       }
5602 07 Apr 11 nicklas 484     }
5602 07 Apr 11 nicklas 485     return numRegistered;
5602 07 Apr 11 nicklas 486   }
5605 12 Apr 11 nicklas 487
5605 12 Apr 11 nicklas 488   /**
5605 12 Apr 11 nicklas 489     Unregister the given extension if it is not included in the new
5605 12 Apr 11 nicklas 490     file data information. In all cases, factory metadata must be removed,
5605 12 Apr 11 nicklas 491     since we leak memory otherwise (new factory instances are always created
5605 12 Apr 11 nicklas 492     when scanning a modified file).
5605 12 Apr 11 nicklas 493     @return TRUE if the extension point is not going to be registered again
5605 12 Apr 11 nicklas 494   */
6875 20 Apr 15 nicklas 495   private boolean unregisterExtension(FileData data, Extension<?> ext, Registry registry)
5605 12 Apr 11 nicklas 496   {
5607 15 Apr 11 nicklas 497     log.debug("Unregistering extension: " + ext);
5605 12 Apr 11 nicklas 498     unregisterFactory(data, ext.getRendererFactory());
5605 12 Apr 11 nicklas 499     unregisterFactory(data, ext.getActionFactory());
5605 12 Apr 11 nicklas 500     ExtensionKey key = new ExtensionKey(ext);
5605 12 Apr 11 nicklas 501     data.writeableFile.unregisterObject(key);
6602 17 Nov 14 nicklas 502     if (Collections.binarySearch(data.extensions, ext, Registry.EXTENSION_ID_COMPARATOR) < 0)
5605 12 Apr 11 nicklas 503     {
5605 12 Apr 11 nicklas 504       registry.unregisterExtension(ext.getId());
5605 12 Apr 11 nicklas 505       return true;
5605 12 Apr 11 nicklas 506     }
5605 12 Apr 11 nicklas 507     return false;
5605 12 Apr 11 nicklas 508   }
5602 07 Apr 11 nicklas 509   
5602 07 Apr 11 nicklas 510   /**
5602 07 Apr 11 nicklas 511     Register factory parameters for the given factory instance. 
5602 07 Apr 11 nicklas 512     The parameters are retreived from the {@link XmlLoader#getFactoryParameters(Object)}
5602 07 Apr 11 nicklas 513     method.
5602 07 Apr 11 nicklas 514     
5602 07 Apr 11 nicklas 515     @param data The extension file the factory was defined in
5602 07 Apr 11 nicklas 516     @param factory The factory instance (if null, no registration is done)
5602 07 Apr 11 nicklas 517   */
5602 07 Apr 11 nicklas 518   private void registerFactory(FileData data, Object factory)
5602 07 Apr 11 nicklas 519   {
5602 07 Apr 11 nicklas 520     if (factory == null) return;
5602 07 Apr 11 nicklas 521     data.writeableFile.registerMetadata(new FactoryParametersKey(factory), loader.getFactoryParameters(factory));
5602 07 Apr 11 nicklas 522   }
5598 30 Mar 11 nicklas 523
5605 12 Apr 11 nicklas 524   private void unregisterFactory(FileData data, Object factory)
5605 12 Apr 11 nicklas 525   {
5605 12 Apr 11 nicklas 526     if (factory == null) return;
5605 12 Apr 11 nicklas 527     data.writeableFile.unregisterMetadata(new FactoryParametersKey(factory));
5605 12 Apr 11 nicklas 528   }
5605 12 Apr 11 nicklas 529   
5602 07 Apr 11 nicklas 530   /**
5602 07 Apr 11 nicklas 531     Keep track of the extension points and extensions found in a file.
5602 07 Apr 11 nicklas 532   */
5602 07 Apr 11 nicklas 533   static class FileData
5601 01 Apr 11 nicklas 534   {
5602 07 Apr 11 nicklas 535     WriteableExtensionsFile writeableFile;
5606 14 Apr 11 nicklas 536     List<Extension<?>> extensions;
5606 14 Apr 11 nicklas 537     List<ExtensionPoint<?>> extensionPoints;
5601 01 Apr 11 nicklas 538   }
5598 30 Mar 11 nicklas 539
5598 30 Mar 11 nicklas 540 }