package org.jcon.df.work;

import org.jcon.util.setting.ReadSettingResponse;
import org.jcon.util.setting.SettingSource;
import org.jcon.df.Database;
import org.jcon.df.DatastoreServices;
import org.jcon.df.request.Filter;
import org.jcon.util.service.ContainerServices;
import org.jcon.util.service.ContainerServicesUser;

/**
 * This class defines the plugpoint interface for the setting
 * persistent source.
 *
 * @author Jack Harich
 */
public class SettingSourceImp implements
                SettingSource, ContainerServicesUser {

//---------- Private Fields ------------------------------
private String databaseName;
private DatastoreServices datastoreServices;
private ContainerServices containerServices;
private Database          database;
private DatabaseUtil      databaseUtil;

private static final String TABLE_NAME = "SysSetting";

//---------- SettingSource Implementation ----------------
/**
 * Reads the named setting and returns the result in
 * ReadValueResponse. 
 */
public ReadSettingResponse readSetting(String name) {
ReadSettingResponse response = null;
try {    
    Filter filter = new Filter();
    filter.addExpression("Name", "=", name);

    checkServices();
    Row row = databaseUtil.readRow(TABLE_NAME, filter);
    if (row != null) {
        String value = (String)row.getValue(TABLE_NAME + ".DataValue");
        response = new ReadSettingResponse(ReadSettingResponse.IN_DATABASE);
        response.setValue(value);
    } else {
        // Row not in database
        response = new ReadSettingResponse(ReadSettingResponse.NOT_IN_DATABASE);       
    }
} catch(Exception ex) {
    response = new ReadSettingResponse(ReadSettingResponse.EXCEPTION);
    response.setFailureText("Problem with reading '" + name + "'.");
    response.setFailureException(ex);
} 
return response;   
} // End method

/**
 * Adds the initial setting to storage. Returns null for
 * success or a String explaining the problem.
 */
public String addInitialSetting(String name, String initialValue) {
try {       
    Row row = new Row();
    row.setValue(TABLE_NAME + ".Name", name);
    row.setValue(TABLE_NAME + ".DataValue", initialValue);
    checkServices();
    databaseUtil.addRow(TABLE_NAME, row);
    return null; // Success
    
} catch(Exception ex) {
    return "Problem with adding '" + name + "'.\n" + ex.getMessage();
}    
} // End method

//---------- ContainerServicesUser Implementation --------
public void setContainerServices(ContainerServices services) {
    containerServices = services;
}
public String[] getContainerServicesInterests() {
    return new String[] {"DatastoreServices"};
}    
//---------- Properties ----------------------------------
//----- databaseName, required
public void setDatabaseName(String databaseName) {
    if (this.databaseName != null) throw new IllegalStateException(
        "Database name can only be set once.");
    this.databaseName = databaseName;
}
public String getDatabaseName() {
    return databaseName;
}
//---------- Public Methods ------------------------------

//---------- Private Methods -----------------------------
// This allows delayed initialization. It should be called
// before any database use.
private void checkServices() {
    if (datastoreServices == null) {
        datastoreServices = (DatastoreServices)
            containerServices.getService("DatastoreServices");

        database = datastoreServices.createDatabase("atsdr");
        databaseUtil = new DatabaseUtil(database);
    }
}
//--- Std
private static void print(String text) {
    System.out.println("SettingSourceImp" + text);
}

} // End class
