package org.jcon.df;

import org.jcon.df.column.ColumnDef;
import org.jcon.util.ArraySorter;
import org.jcon.util.DataLib;
import java.util.Hashtable;
import java.util.Vector;

/**
 * A Schema contains the entities on a logical database.
 * This allows the same schema to be on multiple physical
 * databases, such as Production, QA, Test1, Test2, etc..
 *
 * @author Jack Harich
 */
public class Schema implements java.io.Serializable {

//---------- Private Fields ------------------------------
// Key = entity name, Object = Entity
// transient for speed, loaded as needed on client
private transient Hashtable entities = new Hashtable();

private String name;    
private Vector entityNames = new Vector();
private EntitySupplier entitySupplier;

//---------- Properties ----------------------------------
public String getName() {
    return name;
}
public void setEntitySupplier(EntitySupplier entitySupplier) {
    this.entitySupplier = entitySupplier;
}
//---------- Public Methods ------------------------------
public void setEntities(Vector newEntities) {
    if (entities == null) entities = new Hashtable();
    entities.clear();
    entityNames.removeAllElements();

    for (int i = 0; i < newEntities.size(); i++) {
        Entity entity = (Entity)newEntities.elementAt(i);
        String entityName = entity.getName();
        entityNames.addElement(entityName);
        entities.put(entityName, entity);
    }
}
// Sorted
public String[] loadEntityNames() {
    return DataLib.sortStringVectorToArray(entityNames);
}
public Entity getEntity(String entityName) {
    if (entities == null) entities = new Hashtable();
    Entity entity = (Entity)entities.get(entityName);
    if (entity == null) {
        entity = entitySupplier.getEntity(name, entityName);
        entities.put(entityName, entity);
    //print(".getEntity() - got entity " + entityName + " from source");
    }
    return entity;
}
/**
 * Returns the ColumnDef type for columnID, which must be
 * of the format "EntityName.ColumnName".
 */
public String getColumnDefType(String columnID) {
    return getColumnDef(columnID).getType();
}
/**
 * Returns the ColumnDef for columnID, which must be of the
 * format "EntityName.ColumnName". Throws an
 * IllegalArgumentException if not found.
 */
public ColumnDef getColumnDef(String columnID) {
    String entityName = DataLib.getFirstDelimited(columnID, '.');
    Entity entity = getEntity(entityName);
    if (entity == null) throw new IllegalArgumentException(
        "ColumnID '" + columnID + "' is invalid since entity not found.");

    String columnName = DataLib.getLastDelimited(columnID, '.');
    ColumnDef def = entity.getColumnDef(columnName);
    if (def == null) throw new IllegalArgumentException(
        "ColumnID '" + columnID + "' is invalid since columnName not found.");

    return def;
}
//---------- Package Methods -----------------------------
void setName(String name) {
    this.name = name;
}
//---------- Private Methods -----------------------------
//--- Std
private static void print(String text) {
    System.out.println("Schema" + text);
}

} // End class



