package com.fitbank.schemautils; import java.io.InputStream; import java.util.Map; import com.fitbank.serializador.xml.ExcepcionParser; import com.fitbank.util.CaseInsensitiveMap; import com.fitbank.util.Debug; import java.util.Collection; import java.util.Iterator; import java.util.LinkedList; /** * Clase Schema. * * @author FitBank */ public class Schema { private final Map tables = new CaseInsensitiveMap(); private transient final Map descriptionTables = new CaseInsensitiveMap() { @Override public boolean containsKey(Object key) { return super.containsKey(baseKey(key)); } @Override public DescriptionKey get(Object key) { return super.get(baseKey(key)); } @Override public DescriptionKey put(String key, DescriptionKey value) { return super.put(baseKey(key), value); } }; public static Schema schema; public static Schema get() { if (schema == null) { schema = load(); if (schema != null) { schema.consolidate(); } } return schema; } public static Schema schemaN; public static Schema getN() { if (schemaN == null) { schemaN = load(); } return schemaN; } public Field getField(String tableName, String fieldName) { Table table = getTables().get(tableName); if (table == null) { return null; } return table.getFields().get(fieldName); } private static Schema load() { InputStream is = Schema.class.getClassLoader().getResourceAsStream( "com/fitbank/schemautils/schema.xml"); try { return SchemaXML.parse(is); } catch (ExcepcionParser e) { Debug.error(e); return null; } } public static T baseKey(T key) { if (key instanceof String) { String keyString = (String) key; if (keyString.contains("_")) { key = (T) keyString.substring(0, keyString.indexOf('_')); } } return key; } /** * Crea un nuevo objeto Schema. */ public Schema() { } /** * Junta las tablas con sus tablas Id y setea la propiedad rootTable. */ public void consolidate() { removeIDTables(); extractDescriptionTables(); findDescriptionTable(); } private void removeIDTables() { // Juntar tablas con sus ID Iterator
tables = getTables().values().iterator(); while (tables.hasNext()) { Table table = tables.next(); String noIdName = table.getName().replaceAll("ID$", ""); if (table.getName().endsWith("ID") && getTables().containsKey( noIdName)) { Table noIdTable = getTables().get(noIdName); for (Field field : table.getFields().values()) { noIdTable.addField(field); } tables.remove(); } } // Cambiar referencias a tablas ID por la tabla normal for (Table table : getTables().values()) { String noIdName = table.getName().replaceAll("ID$", ""); for (Field field : table.getFields().values()) { Collection newTables = new LinkedList(); Iterator parentTables = field.getParentTables().iterator(); while (parentTables.hasNext()) { String parentTable = parentTables.next(); String noIdParent = parentTable.replaceAll("ID$", ""); if (getTables().containsKey(noIdParent)) { parentTables.remove(); newTables.add(noIdParent); } else if (!getTables().containsKey(parentTable)) { Debug.error("Tabla padre no encontrada: " + parentTable); parentTables.remove(); } } field.getParentTables().addAll(newTables); } } } /** * Busca la tabla raíz de todos los campos. */ private void extractDescriptionTables() { for (Table table : getTables().values()) { if (table.getName().startsWith("V")) { continue; } if (!table.getFields().containsKey("DESCRIPCION") && !table. getFields().containsKey("NOMBRE")) { continue; } DescriptionKey dk = new DescriptionKey(); dk.setTable(table.getName()); dk.getFields().addAll(table.getPrimaryKeys()); for (Field field : table.getFields().values()) { if (field.getPrimaryKey() && field.getParentTables().isEmpty()) { dk.getBaseFields().add(field.getName()); } if (field.getName().matches("(DESCRIPCION|NOMBRE)")) { dk.setDescriptionField(field.getName()); } } dk.getFields().remove("FHASTA"); dk.getBaseFields().remove("FHASTA"); if (dk.getBaseFields().size() > 1) { Debug.debug("Tabla con más de un campo principal: " + table. getName() + " => " + dk.getBaseFields()); } for (String name : dk.getBaseFields()) { if (descriptionTables.containsKey(name)) { Debug.debug("Dos tablas con el mismo campo principal: " + name + " => " + descriptionTables.get(name) + " Y " + dk); } descriptionTables.put(name, dk); } } } /** * Busca la tabla raíz de todos los campos. */ private void findDescriptionTable() { for (Table table : getTables().values()) { for (Field field : table.getFields().values()) { if (field.getParentTables().isEmpty()) { continue; } String fieldName = field.getName(); if (descriptionTables.containsKey(fieldName)) { DescriptionKey dk = descriptionTables.get(fieldName); field.setDescriptionKey(dk); } else { Debug.debug("No se encontró tabla de descripción para: " + table. getName() + "." + field.getName() + " en " + field. getParentTables()); } } } } /** * Añade una tabla a este objeto. * * @param table * Table a ser añadida */ public void addTable(Table table) { tables.put(table.getName(), table); } /** * Encuentra una tabla dado el código. * * @param code * Código de la tabla a obtener * * @return Table */ public Table findTable(int code) { for (Table t : tables.values()) { if (Integer.parseInt(t.getCode()) == code) { return t; } } return null; } public Map getTables() { return tables; } }