package org.jcon.df;

import org.jcon.util.GenLib;
import org.jcon.util.lock.LockPool;
import org.jcon.df.request.Performer;
import org.jcon.df.request.PerformerPool;
import org.jcon.df.request.Request;
import org.jcon.df.request.RequestServices;
import org.jcon.df.request.Translator;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.RemoteException;
import java.sql.Connection;
import java.sql.Statement;
import java.util.Vector;

/**
 * Provides a Database with those services which must be
 * performed on the server, such as mutator and transaction
 * requests. In progress.... ***
 *
 * @author Jack Harich
 */
public class DatabaseServer { //extends UnicastRemoteObject
    //implements DatabaseServerRemote, java.io.Serializable {

//---------- Private Fields ------------------------------
private String       dbName;
private Schema       schema;
private Translator   translator;
private Connector    connector;

private RequestServices requestServices = new RequestServices();
private PerformerPool   performerPool = new PerformerPool();
private Integrity       integrity = new Integrity();

//---------- Initialization ------------------------------
public DatabaseServer() throws RemoteException {
    super();
    performerPool.setRequestServices(requestServices);
    performerPool.setIntegrity(integrity);
}
//---------- DatabaseServerRemote Implementation ---------
public synchronized Object performTransaction(Vector requests) throws RemoteException {
    // *** Will probably remove this method ***
    return null;
}
// *** NO LONGER CALLED, DONE BY PERFORMER
/** public synchronized Object performRequest(Request request) throws RemoteException {

String sql = "#Empty#";
try{
    //print(".performRequest() - On Server");

    // DUPECODE with Database.preformRequest()
    // Configure request
    request.clearFailureData();
    request.setRequestServices(requestServices);

    // Perform request
    requestServices.prepareResources();
    request.perform();
    requestServices.releaseResources();

} catch(Exception ex) {
    GenLib.exception("DatabaseServer.performRequest()",
        "Cannot perform request. SQL = \n" + sql, ex);
    if (request.getFailureText() == null) {
        request.setFailureText("Database request failure due to exception.");
    }
    if (request.getFailureException() == null) {
        request.setFailureException(ex);
    }
} finally {
    connector.releaseConnection();
}
return request; // Client will cast to Request type
} */ // End method

public Entity getEntity(String schemaName,
    String entityName) throws RemoteException {

    return schema.getEntity(entityName);
}
//---------- Properties ----------------------------------
public void setDatabaseName(String dbName) {
    this.dbName = dbName;
}
public void setConnector(Connector connector) {
    this.connector = connector;
    requestServices.setConnector(connector);
}
public void setSchema(Schema schema) {
    this.schema = schema;
    integrity.setSchema(schema);
    requestServices.setSchema(schema);

    // Prepare entityLockPool with proxies
    // We could later use Entity for instance if needed
    LockPool lockPool = new LockPool();
    String[] names = schema.loadEntityNames();
    for (int i = 0; i < names.length; i++) {
        String name = new String(names[i]);
        //print(".setSchema() - Adding lock proxy " + name);
        // Note the object is irrelevant but must be unique
        lockPool.add((Object)name, new Object());
    }
    requestServices.setEntityLockPool(lockPool);
}
public void setTranslator(Translator translator) {
    this.translator = translator;
    requestServices.setTranslator(translator);
}
//---------- Public Methods ------------------------------
public synchronized Performer checkOutPerformer() {
    return performerPool.checkOut();
}
/** public synchronized void checkInPerformer(Performer performer) {
    performerPool.checkIn(performer);
} */
//---------- Private Methods -----------------------------

//--- Std
private static void print(String text) {
    System.out.println("DatabaseServer" + text);
}

} // End class
