Package org.rssowl.core.model.internal.db4o

Source Code of org.rssowl.core.model.internal.db4o.DBManager

/*   **********************************************************************  **
**   Copyright notice                                                       **
**                                                                          **
**   (c) 2005-2006 RSSOwl Development Team                                  **
**   http://www.rssowl.org/                                                 **
**                                                                          **
**   All rights reserved                                                    **
**                                                                          **
**   This program and the accompanying materials are made available under   **
**   the terms of the Eclipse Public License v1.0 which accompanies this    **
**   distribution, and is available at:                                     **
**   http://www.rssowl.org/legal/epl-v10.html                               **
**                                                                          **
**   A copy is found in the file epl-v10.html and important notices to the  **
**   license from the team is found in the textfile LICENSE.txt distributed **
**   in this package.                                                       **
**                                                                          **
**   This copyright notice MUST APPEAR in all copies of the file!           **
**                                                                          **
**   Contributors:                                                          **
**     RSSOwl Development Team - initial API and implementation             **
**                                                                          **
**  **********************************************************************  */
package org.rssowl.core.model.internal.db4o;

import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.SafeRunner;
import org.rssowl.core.model.internal.Activator;
import org.rssowl.core.model.internal.preferences.Preference;
import org.rssowl.core.model.internal.types.AbstractEntity;
import org.rssowl.core.model.internal.types.BookMark;
import org.rssowl.core.model.internal.types.Feed;
import org.rssowl.core.model.internal.types.Folder;
import org.rssowl.core.model.internal.types.News;
import org.rssowl.core.model.internal.types.SearchMark;
import org.rssowl.core.model.util.LoggingSafeRunnable;

import com.db4o.Db4o;
import com.db4o.ObjectContainer;
import com.db4o.config.Configuration;
import com.db4o.config.ObjectClass;
import com.db4o.config.ObjectField;
import com.db4o.config.QueryEvaluationMode;

import java.io.File;
import java.io.IOException;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class DBManager {

  private static final String DATABASE_EXISTS_FILE_NAME = "databaseExists"; //$NON-NLS-1$
  private static DBManager fInstance;
  private ObjectContainer fObjectContainer;
  private final ReadWriteLock fLock = new ReentrantReadWriteLock();
  private final ListenerList fEntityStoreListeners = new ListenerList();

  /**
   * @return The Singleton Instance.
   */
  public static DBManager getDefault() {
    if (fInstance == null)
      fInstance = new DBManager();
    return fInstance;
  }

  /**
   * Load and initialize the contributed DataBase.
   *
   * @throws DBException In case of an error while initializing and loading the
   * contributed DataBase.
   */
  public void startup() throws DBException {
    /* Initialise */
    EventManager.getInstance();

    createDatabase();
  }

  public void addEntityStoreListener(DatabaseListener listener) {
    fEntityStoreListeners.add(listener);
  }

  private void fireDatabaseEvent(DatabaseEvent event, boolean storeOpened) {
    for (Object l : fEntityStoreListeners.getListeners()) {
      DatabaseListener listener = (DatabaseListener) l;
      if (storeOpened) {
        listener.databaseOpened(event);
      } else {
        listener.databaseClosed(event);
      }
    }
  }

  private ObjectContainer createObjectContainer(boolean dbExists) {
    //TODO We can use dbExists to configure our parameters for a more
    //efficient startup. For example, the following could be used. We'd have
    //to include a file when we need to evolve the schema or something similar
    //Db4o.configure().detectSchemaChanges(false)
    fObjectContainer = Db4o.openFile(getDBFilePath());
    fObjectContainer.ext().configure().queries().evaluationMode(QueryEvaluationMode.IMMEDIATE);
    return fObjectContainer;
  }
 
  private final String getDBFilePath() {
    String filePath = Activator.getDefault().getStateLocation().toOSString() + "/rssowl.db"; //$NON-NLS-1$
    return filePath;
  }

  private File getDBExistsFile() {
    File dir = new File(Activator.getDefault().getStateLocation().toOSString());
    File existsFile = new File(dir + DATABASE_EXISTS_FILE_NAME);
    return existsFile;
  }

  public void removeEntityStoreListener(DatabaseListener listener) {
    fEntityStoreListeners.remove(listener);
  }

  public void createDatabase() throws DBException {
    configure();
    File dbExistsFile = getDBExistsFile();
    boolean dbExists = dbExistsFile.exists();
    if (!dbExists) {
      try {
        dbExistsFile.createNewFile();
      } catch (IOException ioe) {
        throw new DBException(Activator.getDefault().createErrorStatus(
            "Error creating database", ioe)); //$NON-NLS-1$
      }
    }
   
    fObjectContainer = createObjectContainer(dbExists);
   
    fireDatabaseEvent(new DatabaseEvent(fObjectContainer, fLock), true);
  }

  private void configure() {
    Configuration globalConfig = Db4o.configure();
    globalConfig.callbacks(false);
//    globalConfig.blockSize(8);
//    globalConfig.bTreeCacheHeight(0);
//    globalConfig.bTreeNodeSize(100);
//    globalConfig.diagnostic().addListener(new DiagnosticListener() {
//      public void onDiagnostic(Diagnostic d) {
//        System.out.println(d);
//      }
//    });
    globalConfig.messageLevel(0);
    globalConfig.activationDepth(1);
    globalConfig.flushFileBuffers(false);
    globalConfig.callConstructors(true);
    globalConfig.exceptionsOnNotStorable(true);
    globalConfig.objectClass(AbstractEntity.class).objectField("fId").indexed(true); //$NON-NLS-1$
    globalConfig.objectClass(AbstractEntity.class).objectField("fId").cascadeOnActivate(true); //$NON-NLS-1$
    globalConfig.objectClass(BookMark.class).objectField("fFeedId").indexed(true); //$NON-NLS-1$
    globalConfig.objectClass(ConditionalGet.class).objectField("fLink").indexed(true); //$NON-NLS-1$
//    globalConfig.objectClass(IPerson.class).cascadeOnUpdate(true);
//    globalConfig.objectClass(IImage.class).cascadeOnUpdate(true);
//    globalConfig.objectClass(ILabel.class).cascadeOnUpdate(true);
//    globalConfig.objectClass(ICategory.class).cascadeOnUpdate(true);
//    globalConfig.objectClass(ISource.class).cascadeOnUpdate(true);
    configureFeed();
    configureNews();
    configureSearchMark();
    configureFolder();
    globalConfig.objectClass(Preference.class).cascadeOnDelete(true);
    globalConfig.objectClass(Preference.class).objectField("fKey").indexed(true); //$NON-NLS-1$
  }
 
  private void configureSearchMark() {
    ObjectClass oc = Db4o.configure().objectClass(SearchMark.class);
    oc.objectField("fSearchConditions").cascadeOnUpdate(true); //$NON-NLS-1$
  }
 
  private void configureFolder() {
    ObjectClass oc = Db4o.configure().objectClass(Folder.class);
    oc.objectField("fFolders").cascadeOnUpdate(true); //$NON-NLS-1$
    oc.objectField("fMarks").cascadeOnUpdate(true); //$NON-NLS-1$
  }

  private void configureNews() {
    ObjectClass oc = Db4o.configure().objectClass(News.class);
//    oc.maximumActivationDepth(1);
//    oc.minimumActivationDepth(0);

    oc.objectField("fTitle").cascadeOnActivate(true); //$NON-NLS-1$
   
    /* Indexes */
    oc.objectField("fLinkText").indexed(true); //$NON-NLS-1$
    oc.objectField("fGuidValue").indexed(true); //$NON-NLS-1$
   
    oc.objectField("fAttachments").cascadeOnUpdate(true); //$NON-NLS-1$
    oc.objectField("fAuthor").cascadeOnUpdate(true); //$NON-NLS-1$
    oc.objectField("fCategories").cascadeOnUpdate(true); //$NON-NLS-1$
    oc.objectField("fSource").cascadeOnUpdate(true); //$NON-NLS-1$
    oc.objectField("fLabel").cascadeOnUpdate(true); //$NON-NLS-1$
  }

  private void configureFeed() {
    ObjectClass oc = Db4o.configure().objectClass(Feed.class);
//    oc.maximumActivationDepth(1);
//    oc.minimumActivationDepth(1);
   
    ObjectField linkText = oc.objectField("fLinkText"); //$NON-NLS-1$
    linkText.indexed(true);
    linkText.cascadeOnActivate(true);
   
    oc.objectField("fTitle").cascadeOnActivate(true); //$NON-NLS-1$
   
    /* Cascade on update */
    oc.objectField("fAuthor").cascadeOnUpdate(true); //$NON-NLS-1$
    oc.objectField("fImage").cascadeOnUpdate(true); //$NON-NLS-1$
    oc.objectField("fAuthor").cascadeOnUpdate(true); //$NON-NLS-1$
    oc.objectField("fCategories").cascadeOnUpdate(true); //$NON-NLS-1$
  }

  /**
   * Shutdown the contributed Database.
   *
   * @throws DBException In case of an error while shutting down the contributed
   * DataBase.
   */
  public void shutdown() throws DBException {
    if (fObjectContainer != null)
      while (!fObjectContainer.close());
     
    fireDatabaseEvent(new DatabaseEvent(fObjectContainer, fLock), false);
  }

  public void dropDatabase() throws DBException {
    SafeRunner.run(new LoggingSafeRunnable() {
      public void run() throws Exception {
        shutdown();
        if (!new File(getDBFilePath()).delete()) {
          Activator.getDefault().logError("Failed to delete db file", null); //$NON-NLS-1$
        }
        if (!getDBExistsFile().delete()) {
          Activator.getDefault().logError("Failed to delete dbExistsFile", null); //$NON-NLS-1$
        }
      }
    });
  }

  public final ObjectContainer getObjectContainer() {
    return fObjectContainer;
  }
}
TOP

Related Classes of org.rssowl.core.model.internal.db4o.DBManager

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.