Package org.exist.plugin

Source Code of org.exist.plugin.PluginsManagerImpl$BH

/*
*  eXist Open Source Native XML Database
*  Copyright (C) 2010-2011 The eXist Project
*  http://exist-db.org
*  This program is free software; you can redistribute it and/or
*  modify it under the terms of the GNU Lesser General Public License
*  as published by the Free Software Foundation; either version 2
*  of the License, or (at your option) any later version.
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU Lesser General Public License for more details.
*  You should have received a copy of the GNU Lesser General Public License
*  along with this program; if not, write to the Free Software
*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*  $Id$
*/
package org.exist.plugin;

import java.io.*;
import java.lang.reflect.Constructor;
import java.net.URL;
import java.util.*;
import org.apache.log4j.Logger;
import org.exist.Database;
import org.exist.EXistException;
import org.exist.LifeCycle;
import org.exist.backup.BackupHandler;
import org.exist.backup.RestoreHandler;
import org.exist.collections.Collection;
import org.exist.config.*;
import org.exist.config.annotation.*;
import org.exist.dom.DocumentAtExist;
import org.exist.security.Permission;
import org.exist.storage.DBBroker;
import org.exist.storage.txn.TransactionManager;
import org.exist.storage.txn.Txn;
import org.exist.util.serializer.SAXSerializer;
import org.exist.xmldb.XmldbURI;
import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;

/**
* Plugins manager.
* It control search procedure, activation and de-actication (including runtime).
*
* @author <a href="mailto:shabanovd@gmail.com">Dmitriy Shabanov</a>
*
*/
@ConfigurationClass("plugin-manager")
public class PluginsManagerImpl implements Configurable, PluginsManager, LifeCycle {

  private final static Logger LOG = Logger.getLogger(PluginsManagerImpl.class);

  public final static XmldbURI COLLETION_URI = XmldbURI.SYSTEM.append("plugins");
  public final static XmldbURI CONFIG_FILE_URI = XmldbURI.create("config.xml");

  @ConfigurationFieldAsAttribute("version")
  private String version = "1.0";

  @ConfigurationFieldAsElement("plugin")
  private List<String> runPlugins = new ArrayList<String>();

//  @ConfigurationFieldAsElement("search-path")
//  private Map<String, File> placesToSearch = new LinkedHashMap<String, File>();

//  private Map<String, PluginInfo> foundClasses = new LinkedHashMap<String, PluginInfo>();
 
  private Map<String, Plug> jacks = new HashMap<String, Plug>();
 
  private Configuration configuration = null;
 
  private Collection collection;
 
  private Database db;
 
  public PluginsManagerImpl(Database db, DBBroker broker) throws ConfigurationException {
    this.db = db;
   
    //Temporary for testing
    addPlugin("org.exist.scheduler.SchedulerManager");
    addPlugin("org.exist.storage.md.MDStorageManager");
    addPlugin("org.exist.monitoring.MonitoringManager");
  }

  @Override
  public void start(DBBroker broker) throws EXistException {
        final TransactionManager transaction = db.getTransactionManager();
        Txn txn = null;

        try {
          collection = broker.getCollection(COLLETION_URI);
      if (collection == null) {
        txn = transaction.beginTransaction();
        collection = broker.getOrCreateCollection(txn, COLLETION_URI);
        if (collection == null) {return;}
          //if db corrupted it can lead to unrunnable issue
          //throw new ConfigurationException("Collection '/db/system/plugins' can't be created.");
       
        collection.setPermissions(Permission.DEFAULT_SYSTEM_SECURITY_COLLECTION_PERM);
        broker.saveCollection(txn, collection);

        transaction.commit(txn);
      }
        } catch (final Exception e) {
      transaction.abort(txn);
      e.printStackTrace();
      LOG.debug("loading configuration failed: " + e.getMessage());
    } finally {
            transaction.close(txn);
        }

        final Configuration _config_ = Configurator.parse(this, broker, collection, CONFIG_FILE_URI);
    configuration = Configurator.configure(this, _config_);
   
    //load plugins by META-INF/services/
    try {
//      File libFolder = new File(((BrokerPool)db).getConfiguration().getExistHome(), "lib");
//      File pluginsFolder = new File(libFolder, "plugins");
//      placesToSearch.put(pluginsFolder.getAbsolutePath(), pluginsFolder);
     
      for (final Class<? extends Plug> plugin : listServices(Plug.class)) {
        //System.out.println("found plugin "+plugin);
       
        try {
          final Constructor<? extends Plug> ctor = plugin.getConstructor(PluginsManager.class);
          final Plug plgn = ctor.newInstance(this);
         
          jacks.put(plugin.getName(), plgn);
        } catch (final Throwable e) {
          e.printStackTrace();
        }
      }
    } catch (final Throwable e) {
      e.printStackTrace();
    }
    //UNDERSTAND: call save?

//    try {
//      configuration.save(broker);
//    } catch (PermissionDeniedException e) {
//      //LOG?
//    }
   
    for (final Plug jack : jacks.values()) {
      if (jack instanceof LifeCycle) {
        ((LifeCycle) jack).start(broker);
      }
    }
  }
 
  @Override
  public void sync(DBBroker broker) {
    for (final Plug plugin : jacks.values()) {
      try {
        plugin.sync(broker);
      } catch (final Throwable e) {
        LOG.error(e);
      }
    }
  }

  @Override
  public void stop(DBBroker broker) throws EXistException {
    for (final Plug plugin : jacks.values()) {
      try {
        plugin.stop(broker);
      } catch (final Throwable e) {
        LOG.error(e);
      }
    }
  }
 
  public String version() {
    return version;
  }
 
  @SuppressWarnings("unchecked")
  public void addPlugin(String className) {
    //check if already run
    if (jacks.containsKey(className))
      {return;}
   
    try {
      final Class<? extends Plug> plugin = (Class<? extends Plug>) Class.forName(className);
     
      final Constructor<? extends Plug> ctor = plugin.getConstructor(PluginsManager.class);
      final Plug plgn = ctor.newInstance(this);
     
      jacks.put(plugin.getName(), plgn);

      runPlugins.add(className);
     
      //TODO: if (jack instanceof Startable) { ((Startable) jack).startUp(broker); }
    } catch (final Throwable e) {
//      e.printStackTrace();
    }
  }

  public Database getDatabase() {
    return db;
  }
 
  /*
   * Generate list of service implementations
   */
  private <S> Iterable<Class<? extends S>> listServices(Class<S> ifc) throws Exception {
    final ClassLoader ldr = Thread.currentThread().getContextClassLoader();
    final Enumeration<URL> e = ldr.getResources("META-INF/services/" + ifc.getName());
    final Set<Class<? extends S>> services = new HashSet<Class<? extends S>>();
    while (e.hasMoreElements()) {
      final URL url = e.nextElement();
      final InputStream is = url.openStream();
      try {
        final BufferedReader r = new BufferedReader(new InputStreamReader(is, "UTF-8"));
        while (true) {
          String line = r.readLine();
          if (line == null)
            {break;}
          final int comment = line.indexOf('#');
          if (comment >= 0)
            {line = line.substring(0, comment);}
          final String name = line.trim();
          if (name.length() == 0)
            {continue;}
          final Class<?> clz = Class.forName(name, true, ldr);
          final Class<? extends S> impl = clz.asSubclass(ifc);
          services.add(impl);
        }
      } finally {
        is.close();
      }
    }
    return services;
  }

  @Override
  public boolean isConfigured() {
    return configuration != null;
  }

  @Override
  public Configuration getConfiguration() {
    return configuration;
  }
 
  @Override
  public BackupHandler getBackupHandler(Logger logger) {
    return new BH(logger);
  }
 
  class BH implements BackupHandler {
    Logger LOG;
   
    public BH(Logger logger) {
      LOG = logger;
    }

    @Override
    public void backup(Collection colection, AttributesImpl attrs) {
      for (final Plug plugin : jacks.values()) {
        if (plugin instanceof BackupHandler) {
          try {
            ((BackupHandler) plugin).backup(colection, attrs);
          } catch (final Exception e) {
            LOG.error(e.getMessage(), e);
          }
        }
      }
    }

    @Override
    public void backup(Collection colection, SAXSerializer serializer) throws SAXException {
      for (final Plug plugin : jacks.values()) {
        if (plugin instanceof BackupHandler) {
          try {
            ((BackupHandler) plugin).backup(colection, serializer);
          } catch (final Exception e) {
            LOG.error(e.getMessage(), e);
          }
        }
      }
    }

    @Override
    public void backup(DocumentAtExist document, AttributesImpl attrs) {
      for (final Plug plugin : jacks.values()) {
        if (plugin instanceof BackupHandler) {
          try {
            ((BackupHandler) plugin).backup(document, attrs);
          } catch (final Exception e) {
            LOG.error(e.getMessage(), e);
          }
        }
      }
    }

    @Override
    public void backup(DocumentAtExist document, SAXSerializer serializer) throws SAXException {
      for (final Plug plugin : jacks.values()) {
        if (plugin instanceof BackupHandler) {
          try {
            ((BackupHandler) plugin).backup(document, serializer);
          } catch (final Exception e) {
            LOG.error(e.getMessage(), e);
          }
        }
      }
    }
  }

  private RestoreHandler rh = new RH();

  @Override
  public RestoreHandler getRestoreHandler() {
    return rh;
  }

  class RH implements RestoreHandler {

    @Override
    public void setDocumentLocator(Locator locator) {
      for (final Plug plugin : jacks.values()) {
        if (plugin instanceof RestoreHandler) {
          ((RestoreHandler) plugin).setDocumentLocator(locator);
        }
      }
    }

    @Override
    public void startDocument() throws SAXException {
      for (final Plug plugin : jacks.values()) {
        if (plugin instanceof RestoreHandler) {
          ((RestoreHandler) plugin).startDocument();
        }
      }
    }

    @Override
    public void endDocument() throws SAXException {
      for (final Plug plugin : jacks.values()) {
        if (plugin instanceof RestoreHandler) {
          ((RestoreHandler) plugin).endDocument();
        }
      }
    }

    @Override
    public void startPrefixMapping(String prefix, String uri) throws SAXException {
      for (final Plug plugin : jacks.values()) {
        if (plugin instanceof RestoreHandler) {
          ((RestoreHandler) plugin).startPrefixMapping(prefix, uri);
        }
      }
    }

    @Override
    public void endPrefixMapping(String prefix) throws SAXException {
      for (final Plug plugin : jacks.values()) {
        if (plugin instanceof RestoreHandler) {
          ((RestoreHandler) plugin).endPrefixMapping(prefix);
        }
      }
    }

    @Override
    public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
      for (final Plug plugin : jacks.values()) {
        if (plugin instanceof RestoreHandler) {
          ((RestoreHandler) plugin).startElement(uri, localName, qName, atts);
        }
      }
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
      for (final Plug plugin : jacks.values()) {
        if (plugin instanceof RestoreHandler) {
          ((RestoreHandler) plugin).endElement(uri, localName, qName);
        }
      }
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
      for (final Plug plugin : jacks.values()) {
        if (plugin instanceof RestoreHandler) {
          ((RestoreHandler) plugin).characters(ch, start, length);
        }
      }
    }

    @Override
    public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
      for (final Plug plugin : jacks.values()) {
        if (plugin instanceof RestoreHandler) {
          ((RestoreHandler) plugin).ignorableWhitespace(ch, start, length);
        }
      }
    }

    @Override
    public void processingInstruction(String target, String data) throws SAXException {
      for (final Plug plugin : jacks.values()) {
        if (plugin instanceof RestoreHandler) {
          ((RestoreHandler) plugin).processingInstruction(target, data);
        }
      }
    }

    @Override
    public void skippedEntity(String name) throws SAXException {
      for (final Plug plugin : jacks.values()) {
        if (plugin instanceof RestoreHandler) {
          ((RestoreHandler) plugin).skippedEntity(name);
        }
      }
    }

    @Override
    public void startCollectionRestore(Collection colection, Attributes atts) {
      for (final Plug plugin : jacks.values()) {
        if (plugin instanceof RestoreHandler) {
          ((RestoreHandler) plugin).startCollectionRestore(colection, atts);
        }
      }
    }

    @Override
    public void endCollectionRestore(Collection colection) {
      for (final Plug plugin : jacks.values()) {
        if (plugin instanceof RestoreHandler) {
          ((RestoreHandler) plugin).endCollectionRestore(colection);
        }
      }
    }

    @Override
    public void startDocumentRestore(DocumentAtExist document, Attributes atts) {
      for (final Plug plugin : jacks.values()) {
        if (plugin instanceof RestoreHandler) {
          ((RestoreHandler) plugin).startDocumentRestore(document, atts);
        }
      }
    }

    @Override
    public void endDocumentRestore(DocumentAtExist document) {
      for (final Plug plugin : jacks.values()) {
        if (plugin instanceof RestoreHandler) {
          ((RestoreHandler) plugin).endDocumentRestore(document);
        }
      }
    }
  }
}
TOP

Related Classes of org.exist.plugin.PluginsManagerImpl$BH

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.