Package com.subgraph.vega.internal.model

Source Code of com.subgraph.vega.internal.model.Workspace

/*******************************************************************************
* Copyright (c) 2011 Subgraph.
* 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.eclipse.org/legal/epl-v10.html
*
* Contributors:
*     Subgraph - initial API and implementation
******************************************************************************/
package com.subgraph.vega.internal.model;

import java.io.File;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import com.db4o.ObjectContainer;
import com.db4o.ext.DatabaseFileLockedException;
import com.subgraph.vega.api.console.IConsole;
import com.subgraph.vega.api.events.EventListenerManager;
import com.subgraph.vega.api.events.NamedEventListenerManager;
import com.subgraph.vega.api.html.IHTMLParser;
import com.subgraph.vega.api.model.IModel;
import com.subgraph.vega.api.model.IModelProperties;
import com.subgraph.vega.api.model.IModelVersion;
import com.subgraph.vega.api.model.IWorkspace;
import com.subgraph.vega.api.model.IWorkspaceEntry;
import com.subgraph.vega.api.model.WorkspaceCloseEvent;
import com.subgraph.vega.api.model.WorkspaceOpenEvent;
import com.subgraph.vega.api.model.WorkspaceResetEvent;
import com.subgraph.vega.api.model.alerts.IScanAlertRepository;
import com.subgraph.vega.api.model.conditions.IHttpConditionManager;
import com.subgraph.vega.api.model.identity.IIdentityModel;
import com.subgraph.vega.api.model.macros.IHttpMacroModel;
import com.subgraph.vega.api.model.requests.IRequestLog;
import com.subgraph.vega.api.model.scope.ITargetScopeManager;
import com.subgraph.vega.api.model.tags.ITagModel;
import com.subgraph.vega.api.model.variables.IVariableModel;
import com.subgraph.vega.api.model.web.IWebModel;
import com.subgraph.vega.api.vuge.IConstants;
import com.subgraph.vega.api.xml.IXmlRepository;
import com.subgraph.vega.internal.model.alerts.ScanAlertRepository;
import com.subgraph.vega.internal.model.conditions.HttpConditionManager;
import com.subgraph.vega.internal.model.identity.IdentityModel;
import com.subgraph.vega.internal.model.macros.HttpMacroModel;
import com.subgraph.vega.internal.model.requests.RequestLog;
import com.subgraph.vega.internal.model.scope.TargetScopeManager;
import com.subgraph.vega.internal.model.tags.TagModel;
import com.subgraph.vega.internal.model.variables.VariableModel;
import com.subgraph.vega.internal.model.web.WebModel;

public class Workspace implements IWorkspace {
  private static final int BACKGROUND_COMMIT_INTERVAL = 10000;
  private final IModel model;
  private final IWorkspaceEntry workspaceEntry;
  private final NamedEventListenerManager conditionChangeManager;
  private final EventListenerManager eventManager;
  private final DatabaseConfigurationFactory configurationFactory;
  private final IConsole console;
  private final IHTMLParser htmlParser;
  private final IXmlRepository xmlRepository;
  private final WorkspaceLockStatus lockStatus;

  private IModelVersion modelVersion;
  private ITagModel tagModel;
  private IWebModel webModel;
  private IVariableModel variableModel;
  private IHttpMacroModel httpMacroModel;
  private IIdentityModel identityModel;
  private IRequestLog requestLog;
  private IScanAlertRepository scanAlerts;
  private ITargetScopeManager targetScopeManager;
  private HttpConditionManager conditionManager;

  private ObjectContainer database;
  private boolean opened;

  private final Timer backgroundCommitTimer;
  private TimerTask backgroundCommitTask;

  private WorkspaceStatus workspaceStatus;

  Workspace(IModel model, IWorkspaceEntry entry, NamedEventListenerManager conditionChangeManager, EventListenerManager eventManager,
      IConsole console, IHTMLParser htmlParser, IXmlRepository xmlRepository) {
    this.model = model;
    this.configurationFactory = new DatabaseConfigurationFactory();
    this.workspaceEntry = entry;
    this.conditionChangeManager = conditionChangeManager;
    this.eventManager = eventManager;
    this.console = console;
    this.htmlParser = htmlParser;
    this.xmlRepository = xmlRepository;
    this.lockStatus = new WorkspaceLockStatus(eventManager);
    this.backgroundCommitTimer = new Timer();
  }

  @Override
  public IModel getModel() {
    return model;
  }
 
  @Override
  public boolean open() {
    if(opened)
      throw new IllegalStateException("open() called on workspace which has already been opened.");

    database = openDatabase(getDatabaseFile());
    if(database == null)
      return false;
    opened = true;
    eventManager.fireEvent(new WorkspaceOpenEvent(this));
    backgroundCommitTask = createBackgroundCommitTask(database);
    backgroundCommitTimer.scheduleAtFixedRate(backgroundCommitTask, 0, BACKGROUND_COMMIT_INTERVAL);
    return true;
  }

  private File getDatabaseFile() {
    return new File(workspaceEntry.getPath(), "model.db");
  }

  private ObjectContainer openDatabase(final File databaseFile) {
    try {
      final String databasePath = databaseFile.getAbsolutePath();
      final boolean exists = databaseFile.exists(); // possible race condition 
      final ObjectContainer db = configurationFactory.openContainer(databasePath);
      loadModelVersion(db, !exists);
      tagModel = new TagModel(db);
      webModel = new WebModel(db);
      variableModel = new VariableModel(db);
      httpMacroModel = new HttpMacroModel(db);
      identityModel = new IdentityModel(db);
      requestLog = new RequestLog(db);
      scanAlerts = new ScanAlertRepository(db, xmlRepository);
      conditionManager = new HttpConditionManager(db, conditionChangeManager);
      targetScopeManager = new TargetScopeManager(db);
      return db;
    } catch (DatabaseFileLockedException e) {
      e.printStackTrace();
      return null;
    } catch (Exception e) {
      e.printStackTrace();
      return null;
    }
  }

  @Override
  public IModelVersion getModelVersion() {
    if (!opened) {
      throw new IllegalStateException("Must open workspace first");
    }
    return modelVersion;
  }

  @Override
  public ITagModel getTagModel() {
    if (!opened) {
      throw new IllegalStateException("Must open workspace first");
    }
    return tagModel;
  }

  @Override
  public IVariableModel getVariableModel() {
    if (!opened) {
      throw new IllegalStateException("Must open workspace first");
    }
    return variableModel;
  }

  @Override
  public IHttpMacroModel getHttpMacroModel() {
    if (!opened) {
      throw new IllegalStateException("Must open workspace first");
    }
    return httpMacroModel;
  }

  @Override
  public IIdentityModel getIdentityModel() {
    if (!opened) {
      throw new IllegalStateException("Must open workspace first");
    }
    return identityModel;
  }

  @Override
  public IWebModel getWebModel() {
    if(!opened)
      throw new IllegalStateException("Must open workspace first");
    return webModel;
  }

  @Override
  public IRequestLog getRequestLog() {
    if(!opened)
      throw new IllegalStateException("Must open workspace first");
    return requestLog;
  }

  @Override
  public IScanAlertRepository getScanAlertRepository() {
    if(!opened)
      throw new IllegalStateException("Must open workspace first");
    return scanAlerts;
  }

  @Override
  public IHttpConditionManager getHttpConditionMananger() {
    return conditionManager;
  }

  @Override
  public void close() {
    if(!opened)
      return;
    if(lockStatus.isLocked())
      throw new IllegalStateException("Cannot close locked workspace.");
    backgroundCommitTask.cancel();
    conditionManager.notifyClosed();
    database.close();
    opened = false;
    eventManager.fireEvent(new WorkspaceCloseEvent(this));
  }

  @Override
  public void setProperty(String name, Object value) {
    getProperties().setProperty(name, value);
  }

  @Override
  public void setStringProperty(String name, String value) {
    getProperties().setStringProperty(name, value);
  }

  @Override
  public void setIntegerProperty(String name, int value) {
    getProperties().setIntegerProperty(name, value);
  }

  @Override
  public Object getProperty(String name) {
    return getProperties().getProperty(name);
  }

  @Override
  public String getStringProperty(String name) {
    return getProperties().getStringProperty(name);
  }

  @Override
  public Integer getIntegerProperty(String name) {
    return getProperties().getIntegerProperty(name);
  }

  @Override
  public List<String> propertyKeys() {
    return getProperties().propertyKeys();
  }

  private IModelProperties getProperties() {
    if(workspaceStatus != null)
      return workspaceStatus.getProperties();
    synchronized(this) {
      List<WorkspaceStatus> result = database.query(WorkspaceStatus.class);
      if(result.size() == 0) {
        workspaceStatus = new WorkspaceStatus();
        database.store(workspaceStatus);
        return workspaceStatus.getProperties();
      } else if(result.size() == 1) {
        workspaceStatus =  result.get(0);
        return workspaceStatus.getProperties();
      } else {
        throw new IllegalStateException("Database corrupted, multiple WorkspaceStatus instances");
      }
    }
  }

  @Override
  public IHTMLParser getHTMLParser() {
    return htmlParser;
  }

  @Override
  public ITargetScopeManager getTargetScopeManager() {
    return targetScopeManager;
  }

  @Override
  public void consoleWrite(String output) {
    console.write(output);
  }

  @Override
  public void consoleError(String output) {
    console.error(output);
  }

  @Override
  public void lock() {
    lockStatus.lock();
  }

  @Override
  public void unlock() {
    lockStatus.unlock();
  }

  @Override
  public void reset() {
    if(lockStatus.isLocked())
      throw new IllegalStateException("Cannot reset locked workspace");

    backgroundCommitTask.cancel();
    synchronized(this) {
      conditionManager.notifyClosed();
      database.close();
      final File databaseFile = getDatabaseFile();
      if(!databaseFile.delete()) {
        // XXX
      }
      database = openDatabase(databaseFile);
      if(database != null) {
        workspaceStatus = null;
        eventManager.fireEvent(new WorkspaceResetEvent(this));
        backgroundCommitTask = createBackgroundCommitTask(database);
        backgroundCommitTimer.scheduleAtFixedRate(backgroundCommitTask, 0, BACKGROUND_COMMIT_INTERVAL);
      } else {
        eventManager.fireEvent(new WorkspaceCloseEvent(this));
      }
    }
  }

  private TimerTask createBackgroundCommitTask(final ObjectContainer db) {
    return new TimerTask() {
      @Override
      public void run() {
        if(!db.ext().isClosed()) {
          db.commit();
        }
      }
    };
  }

  private void loadModelVersion(ObjectContainer database, boolean newFile) {
    if (newFile == false) {
      final List<IModelVersion> results = database.query(IModelVersion.class);
      if (results.size() != 0) {
        modelVersion = results.get(0);
      } else {
        // reverse compatibility: Vega 1.0 beta and earlier did not have model version
        modelVersion = new ModelVersion(1, 0);
        database.store(modelVersion);
      }
    } else {
      modelVersion = new ModelVersion(IConstants.VERSION_MAJOR, IConstants.VERSION_MINOR);
      database.store(modelVersion);
    }
  }
}
TOP

Related Classes of com.subgraph.vega.internal.model.Workspace

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.