Changeset 5598


Ignore:
Timestamp:
Mar 30, 2011, 11:44:57 AM (10 years ago)
Author:
Nicklas Nordborg
Message:

References #1593: Extension system for the core API

The first step towards a core extension system. It is still very rudimentary and will only read the core-extensions.xml file at startup. No support yet for other extensions or automatic updates. The web client extension system has not been touched yet but this should be merged with the core extensions.

The next step is to define an extension point for #1582 and try to implement a HDFS extension. This should help to get things going before starting to move the web part into this.

Location:
trunk/src/core
Files:
7 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/core/net/sf/basedb/core/Application.java

    r5595 r5598  
    3434import net.sf.basedb.util.RegexpFileFilter;
    3535import net.sf.basedb.util.StaticCache;
     36import net.sf.basedb.util.extensions.Registry;
     37import net.sf.basedb.util.extensions.manager.ExtensionsFile;
     38import net.sf.basedb.util.extensions.manager.ExtensionsManager;
     39import net.sf.basedb.util.extensions.manager.RegisterExtensionsProcessor;
     40import net.sf.basedb.util.extensions.xml.ExtensionPointFilter;
     41import net.sf.basedb.util.extensions.xml.XmlLoader;
    3642import net.sf.basedb.util.timer.Scheduler;
    3743import net.sf.basedb.util.uri.ConnectionManagerRegistry;
     
    5763import java.sql.SQLException;
    5864
     65import org.jdom.Element;
     66
    5967
    6068/**
     
    198206  */
    199207  private static ConnectionManagerRegistry connectionManagerRegistry;
     208 
     209  /**
     210    Manager for the extensions system.
     211  */
     212  private static ExtensionsManager xtManager;
    200213 
    201214  /**
     
    526539        RawDataTypes.initPlatforms();
    527540 
     541        // Initialize extensions system
     542        // TODO -- should this be moved to a utility class? Probably...
     543        Registry xtRegistry = new Registry();
     544        xtManager = new ExtensionsManager(xtRegistry);
     545       
     546        // Add core extension points and extensions
     547        ExtensionsFile core = new ExtensionsFile(Application.class.getResource("/core-extensions.xml").toURI());
     548        xtManager.addExtensionsFile(core);
     549       
     550        // Add plugins directory to the manager
     551        //xtManager.addDirectory(pluginsDirectory);
     552       
     553        // Register and load core extensions
     554        XmlLoader loader = new XmlLoader();
     555        // Filter that only load core extension points
     556        loader.setFilter(new ExtensionPointFilter("net\\.sf\\.basedb\\.core\\..*"));
     557        xtManager.processFiles(new RegisterExtensionsProcessor(loader));
     558           
    528559        // Initialise log manager factory
    529560        if (logManagerFactoryDriver != null)
  • trunk/src/core/net/sf/basedb/util/extensions/ExtensionsInvoker.java

    r5486 r5598  
    2323
    2424import java.util.Collection;
     25import java.util.Iterator;
    2526
    2627/**
     
    5253*/
    5354public class ExtensionsInvoker<A extends Action>
     55  implements Iterable<A>
    5456{
    5557
     
    179181    }
    180182  }
     183
     184  @Override
     185  public Iterator<A> iterator()
     186  {
     187    return iterate();
     188  }
    181189}
  • trunk/src/core/net/sf/basedb/util/extensions/xml/XmlLoader.java

    r5519 r5598  
    5757import net.sf.basedb.util.extensions.Registry;
    5858import net.sf.basedb.util.extensions.RendererFactory;
     59import net.sf.basedb.util.filter.Filter;
    5960
    6061/**
     
    124125public class XmlLoader
    125126{
     127  private static final org.apache.log4j.Logger log =
     128    org.apache.log4j.LogManager.getLogger("net.sf.basedb.util.extensions.xml.XmlLoader");
    126129
    127130  /**
     
    153156  // The last document that was validated
    154157  private Document validatedDom;
     158 
     159  // The name of the last document
     160  private String lastName;
    155161 
    156162  /**
     
    193199  {
    194200    if (converters != null) converters.clear();
     201  }
     202 
     203  private Filter<Element> filter;
     204  /**
     205    Set a filter that all &lt;extension-point&gt;, &lt;extension&gt;
     206    and &lt;ref&gt; tags must pass to be loaded and registered.
     207    @param filter A filter or null to remove an existing filter
     208    @since 3.0
     209  */
     210  public void setFilter(Filter<Element> filter)
     211  {
     212    this.filter = filter;
    195213  }
    196214 
     
    253271    validatedDom = null;
    254272    validatedDom = loadDocument(xmlFile, filename);
     273    lastName = filename;
    255274    About globalAbout = loadGlobalAbout(validatedDom);
    256275    return globalAbout;
     
    424443    throws IOException, JDOMException
    425444  {
     445    log.debug("Validating file: " + filename);
    426446    return XMLUtil.getSchemaValidatedXML(xmlFile, filename, namespace, schemaFileURL);
    427447  }
     
    469489      IllegalAccessException, InstantiationException
    470490  {
     491    log.debug("Loading extension points from file: " + lastName);
    471492    int numLoaded = 0;
    472493    List<ExtensionPoint<Action>> temp = new LinkedList<ExtensionPoint<Action>>();
     
    499520   
    500521    List<Element> epTags = root.getChildren("extension-point", ns);
     522    log.debug("Found " + epTags.size() + " extension point(s) in file: " + lastName);
    501523    for (Element epTag : epTags)
    502524    {
    503       ExtensionPointBean<Action> extensionPoint = new ExtensionPointBean<Action>();
    504       temp.add(extensionPoint);
    505       numLoaded++;
    506  
    507       // Set ID (required)
    508525      String id = Values.getStringOrNull(epTag.getAttributeValue("id"));
    509526      if (idBase != null) id = idBase + id;
    510       extensionPoint.setId(id);
     527
     528      log.debug("Processing extension point: " + id);
    511529     
    512       // Set Name and Description (optional)
    513       extensionPoint.setName(Values.getStringOrNull(epTag.getChildText("name", ns)));
    514       extensionPoint.setDescription(Values.getStringOrNull(epTag.getChildText("description", ns)));
    515      
    516       // Load and set Action class (required)
    517       String actionClassName = Values.getStringOrNull(epTag.getChildText("action-class", ns));
    518       Class actionClass =
    519         ClassUtil.checkAndLoadClass(classLoader, actionClassName, false, Action.class);
    520       extensionPoint.setActionClass(actionClass);
    521      
    522       // Load and set RendererFactory (optional)
    523       Element rfTag = epTag.getChild("renderer-factory", ns);
    524       if (rfTag != null)
    525       {
    526         RendererFactory rf = createFactory(rfTag, classLoader, RendererFactory.class);
    527         extensionPoint.setRendererFactory(rf);
    528         extensionPoint.setAllowRendererOverrider(
    529           Values.getBoolean(rfTag.getAttributeValue("override")));
    530       }
    531      
    532       Element ehfTag = epTag.getChild("error-handler-factory", ns);
    533       if (ehfTag != null)
    534       {
    535         ErrorHandlerFactory ehf = createFactory(ehfTag, classLoader, ErrorHandlerFactory.class);
    536         extensionPoint.setErrorHandlerFactory(ehf);
     530      if (filter == null || filter.evaluate(epTag))
     531      {
     532        ExtensionPointBean<Action> extensionPoint = new ExtensionPointBean<Action>();
     533        temp.add(extensionPoint);
     534        numLoaded++;
     535   
     536        // Set ID (required)
     537        extensionPoint.setId(id);
     538       
     539        // Set Name and Description (optional)
     540        extensionPoint.setName(Values.getStringOrNull(epTag.getChildText("name", ns)));
     541        extensionPoint.setDescription(Values.getStringOrNull(epTag.getChildText("description", ns)));
     542       
     543        // Load and set Action class (required)
     544        String actionClassName = Values.getStringOrNull(epTag.getChildText("action-class", ns));
     545        Class actionClass =
     546          ClassUtil.checkAndLoadClass(classLoader, actionClassName, false, Action.class);
     547        extensionPoint.setActionClass(actionClass);
     548       
     549        // Load and set RendererFactory (optional)
     550        Element rfTag = epTag.getChild("renderer-factory", ns);
     551        if (rfTag != null)
     552        {
     553          RendererFactory rf = createFactory(rfTag, classLoader, RendererFactory.class);
     554          extensionPoint.setRendererFactory(rf);
     555          extensionPoint.setAllowRendererOverrider(
     556            Values.getBoolean(rfTag.getAttributeValue("override")));
     557        }
     558       
     559        Element ehfTag = epTag.getChild("error-handler-factory", ns);
     560        if (ehfTag != null)
     561        {
     562          ErrorHandlerFactory ehf = createFactory(ehfTag, classLoader, ErrorHandlerFactory.class);
     563          extensionPoint.setErrorHandlerFactory(ehf);
     564        }
    537565      }
    538566    }
     
    550578      IllegalAccessException, InstantiationException
    551579  {
     580    log.debug("Loading extensions from file: " + lastName);
    552581    int numLoaded = 0;
    553582    List<Extension<Action>> temp = new LinkedList<Extension<Action>>();
     
    589618
    590619    List<Element> epTags = root.getChildren("extension", ns);
     620    log.debug("Found " + epTags.size() + " extension(s) in file: " + lastName);
    591621    for (Element epTag : epTags)
    592622    {
    593       // <index>
    594       float defaultIndex = Values.getFloat(epTag.getChildText("index", ns), 999.0f);
    595 
    596623      // id
    597624      String id = Values.getStringOrNull(epTag.getAttributeValue("id"));
    598625      if (idBase != null) id = idBase + id;
    599 
    600       // <about>
    601       AboutBean about = loadAbout(epTag.getChild("about", ns));
    602       if (globalAbout != null)
    603       {
    604         if (about == null) about = new AboutBean();
    605         about.copy(globalAbout, false);
    606       }
    607 
    608       // <action-factory>
    609       Element afTag = epTag.getChild("action-factory", ns);
    610       ActionFactory af = null;
    611       if (afTag != null)
    612       {
    613         af = createFactory(afTag, classLoader, ActionFactory.class);
    614       }
    615    
    616       // <renderer-factory>
    617       Element rfTag = epTag.getChild("renderer-factory", ns);
    618       RendererFactory rf = null;
    619       if (rfTag != null)
    620       {
    621         rf = createFactory(rfTag, classLoader, RendererFactory.class);
    622       }
     626      log.debug("Processing extension: " + id);
     627     
     628      // <index>
     629      float defaultIndex = Values.getFloat(epTag.getChildText("index", ns), 999.0f);
    623630     
    624631      // Pick up the extension points + index
     
    629636      if (epId != null)
    630637      {
    631         extensionPoints.add(epId);
    632         indexes.add(defaultIndex);
    633       }
     638        if (filter == null || filter.evaluate(epTag))
     639        {
     640          extensionPoints.add(epId);
     641          indexes.add(defaultIndex);
     642        }
     643      }
     644     
    634645      // Then... any <extends>/<ref> subtags
    635646      Element extendsTag = epTag.getChild("extends", ns);
     
    638649        for (Element refTag : (List<Element>)extendsTag.getChildren("ref", ns))
    639650        {
    640           epId = Values.getStringOrNull(refTag.getText());
    641           if (epId != null)
     651          if (filter == null || filter.evaluate(refTag))
    642652          {
    643             extensionPoints.add(epId);
    644             indexes.add(Values.getFloat(refTag.getAttributeValue("index"), defaultIndex));
     653            epId = Values.getStringOrNull(refTag.getText());
     654            if (epId != null)
     655            {
     656              extensionPoints.add(epId);
     657              indexes.add(Values.getFloat(refTag.getAttributeValue("index"), defaultIndex));
     658            }
    645659          }
    646660        }
    647661      }
     662
     663      // Any extension points remaining after filtering?
     664      if (extensionPoints.size() > 0)
     665      {
     666 
     667        // <about>
     668        AboutBean about = loadAbout(epTag.getChild("about", ns));
     669        if (globalAbout != null)
     670        {
     671          if (about == null) about = new AboutBean();
     672          about.copy(globalAbout, false);
     673        }
     674 
     675        // <action-factory>
     676        Element afTag = epTag.getChild("action-factory", ns);
     677        ActionFactory af = null;
     678        if (afTag != null)
     679        {
     680          af = createFactory(afTag, classLoader, ActionFactory.class);
     681        }
    648682     
    649       String commonIdPrefix = null;
    650       if (extensionPoints.size() > 1)
    651       {
    652         // We need to calculate the common id prefix for the extension points
    653         // so that we can create unique extension id:s
    654         commonIdPrefix = StringUtil.getCommonPrefix(extensionPoints);
    655       }
    656      
    657      
    658       for (int i = 0; i < extensionPoints.size(); ++i)
    659       {
    660         epId = extensionPoints.get(i);
    661         float index = indexes.get(i);
    662         ExtensionBean<Action> ext = new ExtensionBean<Action>();
    663         temp.add(ext);
    664         numLoaded++;
     683        // <renderer-factory>
     684        Element rfTag = epTag.getChild("renderer-factory", ns);
     685        RendererFactory rf = null;
     686        if (rfTag != null)
     687        {
     688          rf = createFactory(rfTag, classLoader, RendererFactory.class);
     689        }
    665690       
    666         String thisId = id;
    667         if (commonIdPrefix != null)
    668         {
    669           thisId += ":" + epId.substring(commonIdPrefix.length());
     691        String commonIdPrefix = null;
     692        if (extensionPoints.size() > 1)
     693        {
     694          // We need to calculate the common id prefix for the extension points
     695          // so that we can create unique extension id:s
     696          commonIdPrefix = StringUtil.getCommonPrefix(extensionPoints);
    670697        }
    671698       
    672         ext.setId(thisId);
    673         ext.setExtends(epId);
    674         ext.setIndex(index);
    675         ext.setAbout(about);
    676         ext.setActionFactory(af);
    677         ext.setRendererFactory(rf);
     699        for (int i = 0; i < extensionPoints.size(); ++i)
     700        {
     701          epId = extensionPoints.get(i);
     702          float index = indexes.get(i);
     703          ExtensionBean<Action> ext = new ExtensionBean<Action>();
     704          temp.add(ext);
     705          numLoaded++;
     706         
     707          String thisId = id;
     708          if (commonIdPrefix != null)
     709          {
     710            thisId += ":" + epId.substring(commonIdPrefix.length());
     711          }
     712         
     713          ext.setId(thisId);
     714          ext.setExtends(epId);
     715          ext.setIndex(index);
     716          ext.setAbout(about);
     717          ext.setActionFactory(af);
     718          ext.setRendererFactory(rf);
     719        }
    678720      }
    679721    }
Note: See TracChangeset for help on using the changeset viewer.