inicio Indice general clara@servidor.unam.mx

ANEXO D. Clase java CVSColmex

Archivo: CVSColmex.txt

Autor: Francisco J. Benavente

-------------------------------------------

package net.universia.rayuela.lucene.write.colmex;
import net.universia.commons.Visitor;
import net.universia.commons.dom.DOMUtils;
import net.universia.rayuela.lucene.write.CSVIndexer;
import net.universia.scorm.*;
import net.universia.scorm.types.*;
import net.universia.scorm.types.*;

import org.dom4j.Document;

import java.io.File;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

 

/**
* User: Paco
* Date: 01-jun-2004
* Time: 16:05:51
*/
public class CSVColmex implements Visitor
{

/**
*implementación de la interfaz Visitor. Este método sera llamado
*para cada una de las entradas de la tabla CSV, recibiendo como
*parametro un mapa con los valores de todas las columnas de la *tabla
*/
public void visit(Object o) throws Exception
{

// Los valores de esta entrada estan guardados como un Mapa,
// usando como claves los nombres de las columnas.
Map m = (Map) o;

// Con los valores de esta entrada, creamos una estructura LOM
Lom lom = colmex2Lom(m);

// Convertimos la estructura LOM en un documento XML
Document doc = lom.toDocument();

// Escribimos el XML en un archivo
File file = getFile(get(m, C), get(m, FOLIO));
DOMUtils.writeXML(file, doc);
}


// Nombres de las columnas en el archivo CSV
private static final String IDIOMA = "IDIOMA";
private static final String TITULO = "TITULO";
private static final String DESCRIPCION = "DESCRIPCION";
private static final String TEMA = "TEMA";
private static final String COBERTURA = "COBERTURA";
private static final String PALABRAS_CLAVE = "PALABRAS_CLAVE";
private static final String AUTOR = "AUTOR";
private static final String EDITOR = "EDITOR";
private static final String FECHA = "FECHA";
//private static final String COLABORADOR = "COLABORADOR";
private static final String FORMATO = "FORMATO";
private static final String URL = "URL";
private static final String DERECHOS = "DERECHOS";
private static final String TIPO = "TIPO";
private static final String FUENTE = "FUENTE";
private static final String AUDIENCIA = "AUDIENCIA";
private static final String FOLIO = "FOLIO";
private static final String RELACION = "RELACION";


// Valores de defecto a utilizar para determinados campos de la
// estructura LOM
private static final String DEF_INTERACTIVITYTYPE = "Expositive";
private static final String DEF_LEARNINGRESOURCETYPE = "Narrative
Text";
private static final String DEF_INTERACTIVITYLEVEL = "very low";
private static final String[] DEF_INTENDEDENDUSERROLE =
{"Learner", "Teacher", "Author"};
private static final String[] DEF_CONTEXT = {"Higher Education",
"University Postgrade", "Professional Formation" "Continuous
Formation"};
private static final String DEF_STRUCTURE = "Atomic";
private static final String DEF_VERSION = "1.0";
private static final String DEF_STATUS = "Final";
private static final String[] DEF_METADATACREATOR = {"UNAM",
"Portal Universia, S.A."};
private static final String DEF_LANGUAGE = "es_MX";
private static final String DEF_METADATASCHEME = "LOMv1.0";
private static final String DEF_REQUIREMENTTYPE = "Browser";
private static final String DEF_REQUIREMENTNAME = "Any";
private static final String DEF_ADOBEREADER = "Adobe® Reader®
(http://www.adobe.com/products/acrobat/readstep2.html)";


// Nombre de la columna que identifica el tipo de catalogo
private static final String C = "C";
// Posibles valores de la columna "C"
private static final String[] CATALOG_ID = {"F", "L", "E"};


// Valores de defecto para la estructura LOM que son dependientes
del tipo de catálogo
private static String[ ] DEF_CATALOG = {"Colecciones Mexicanas -
Archivo Franciscano", "Colecciones Mexicanas - Literatura Mexicana
del Siglo XIX", "Colecciones Mexicanas - Primeros Españoles en
México"};
private static final String[ ] DEF_AGGREGATIONLEVEL = {"3", "1",
"3"};
private static final String[ ] DEF_CONTENTPROVIDER = {"Biblioteca
Nacional de México", "DGSCA", "Espamexis"};
private static final String[ ] DEF_FORMAT = {"text/html",
"application/pdf", "text/html"};
private static final String[ ] DEF_URL = {

"http://lyncis.dgsca.unam.mx/franciscanos/cgi-bin/usuario/
imagen.cgi?campo=folio&numeroimg=0&valordebusqueda=",
null,
"http://lyncis.dgsca.unam.mx/espanoles/cgi-bin/usuario/
imagen.cgi?campo=id_documento&numeroimg=0&valordebusqueda=",


};
private static final String[] DEF_RELACION = {"Manuscritos del
siglo XVI al XIX sobre los Franciscanos en México.", "Revistas
literarias que reflejan la sociedad mexicana del siglo XIX.",
"Documentos manuscritos de la comunidad de españoles en México en
el siglo XIX."};


// Patrones de expresiones regulares utilizados para extraer la
// información relevante de los valores de determinados campos.
private static final String PATTERN_ISPARTOF =
".*(.+).*";
private static final String PATTERN_DATECREATED =
".*(.+).*";
private static final String PATTERN_SIZE =
".*(.+).*";


/**
* Método que se encarga de convertir los valores de una entrada
* de la tabla a una estructura LOM, convirtiendo apropiadamente
* los datos y añadiendo valores de defecto a otros campos de la
* estructura.
*
* @param m Los valores de la entrada de la tabla como un mapa en
* el que las claves son los nombres de las columnas
* @return la estructura Lom creada
*/
private static Lom colmex2Lom(Map m)
{


Lom lom = Lom.createLom();

// Según el catálogo (valor de la columna C) obtenemos un
// índice de array para acceder
// a los valores de defecto de este catálogo
int catId = -1;
for (int i = 0; i < CATALOG_ID.length; i++)
{

String s = CATALOG_ID[i];
if (s.equals(get(m, C)))

catId = i;


}
assert catId != -1;


// Los metadatos van en "es"
Locale locale = new Locale("es");

// La fecha de hoy
String hoy = DateFormat.getDateInstance().format(new Date());

// GENERAL
General general = lom.getGeneral();
CatalogEntry cat = general.addNewCatalogentry();
cat.getCatalog().setText(DEF_CATALOG[catId]);
cat.getEntry().add(get(m, FOLIO));
general.getTitle().add(locale, get(m, TITULO));
general.addNewDescription().add(locale, get(m, DESCRIPCION));
if (get(m, PALABRAS_CLAVE) != null)

addKeywords(general, get(m, PALABRAS_CLAVE), locale);

if (!"E".equals(get(m, C))) // En el caso de ... el TEMA

encaja mejor como Keywords que como descripción
addKeywords(general, get(m, TEMA), locale);

else

general.addNewDescription().add(locale, get(m, TEMA));

assert "SP-MX".equals(get(m, IDIOMA)) : IDIOMA + " no es 'SP-
MX', sino " + get(m, IDIOMA);
general.addNewLanguage().setText(DEF_LANGUAGE);
general.addNewCoverage().add(locale, get(m, COBERTURA));
general.getStructure().setVocabulary(DEF_STRUCTURE);

general.getAggregationlevel().setVocabulary(DEF_AGGREGATIONLEVEL[catId]);

// LIFECYCLE
LifeCycle lifecycle = lom.getLifecycle();
lifecycle.getVersion().add(DEF_VERSION);
lifecycle.getStatus().setVocabulary(DEF_STATUS);

addContributor(lifecycle.addNewContribute(), "Author", "FN",
get(m, AUTOR), null);
String date = extract(PATTERN_DATECREATED, get(m, FECHA),
true);
addContributor(lifecycle.addNewContribute(), "Publisher",
"ORG", get(m, EDITOR), date);
addContributor(lifecycle.addNewContribute(), "Content
Provider", "ORG", DEF_CONTENTPROVIDER[catId], null);

// METAMETADATA
Metametadata metametadata = lom.getMetametadata();
metametadata.setLanguage(locale.getLanguage());
Contribute contribute = metametadata.addNewContribute();
addContributors(contribute, "Creator", "ORG",
DEF_METADATACREATOR, hoy);
metametadata.addNewMetadatascheme().setText(DEF_METADATASCHEME);

// TECHNICAL
Technical technical = lom.getTechnical();
technical.addNewFormat().setText(DEF_FORMAT[catId]);
String size = extract(PATTERN_SIZE, get(m, FORMATO), false);
if (size != null)

technical.getSize().setText(size);

Location loc = technical.addNewLocation();
if ("L".equals(get(m, C)))

loc.setText(get(m, URL));

else

loc.setText(DEF_URL[catId] + get(m, FOLIO));

loc.getType().setText(Location.TYPE_URI);
Requirement req = technical.addNewRequirement();
req.setType(DEF_REQUIREMENTTYPE);
req.setName(DEF_REQUIREMENTNAME);
if (DEF_FORMAT[catId].equals("application/pdf"))

technical.getOtherplatformrequirements().add(locale,
DEF_ADOBEREADER);

// EDUCATIONAL
Educational educational = lom.getEducational();

educational.getInteractivitytype().setVocabulary(DEF_INTERACTIVITYTYPE);

assert "Texto".equalsIgnoreCase(get(m, TIPO)) ||
"text".equalsIgnoreCase(get(m, TIPO)) ||
"Coleccion".equalsIgnoreCase(get(m, TIPO)): TIPO + " no es
'Texto' ni 'Coleccion'";

educational.addNewLearningresourcetype().setVocabulary(DEF_LEARNINGRES OURCETYPE);
educational.getInteractivitylevel().setVocabulary(DEF_INTERACTIVITY LEVEL);

assert "Investigadores, docentes alumnos".equalsIgnoreCase
(get(m, AUDIENCIA)) || "Investigadores, docentes y
estudiantes".equalsIgnoreCase(get(m, AUDIENCIA))

: AUDIENCIA + " no es 'Investigadores, docentes y
alumnos'";

for (int i = 0; i < DEF_INTENDEDENDUSERROLE.length; i++)
{

String s = DEF_INTENDEDENDUSERROLE[i];
educational.addNewIntendedenduserrole().setVocabulary(s);

}
for (int i = 0; i < DEF_CONTEXT.length; i++)
{

String s = DEF_CONTEXT[i];
educational.addNewContext().setVocabulary(s);

}

// RIGHTS
Rights rights = lom.getRights();
rights.getCost().setVocabulary("no");
rights.getCopyrightandotherrestrictions().setVocabulary("yes");
rights.getDescription().add(locale, get(m, DERECHOS));

// RELATION
Relation relation = lom.addNewRelation();
relation.getKind().setVocabulary("IsPartOf");
Resource resource = relation.getResource();
resource.getDescription().add(locale, DEF_RELACION[catId] +
"(" + extract(PATTERN_ISPARTOF, get(m, RELACION), true)
+ ")");
relation = lom.addNewRelation();
relation.getKind().setVocabulary("IsBasedOn");
resource = relation.getResource();
resource.getDescription().add(locale, get(m, FUENTE));

return lom;

}


private static String extract(String pattern, String texto, boolean required)
{


return extract(pattern, texto, 1, required);


}


private static String extract(String pattern, String texto, int
grupo, boolean required)
{


Pattern p = Pattern.compile(pattern);
Matcher matcher = p.matcher(texto);
if (matcher.matches())

return matcher.group(grupo).trim();

else
{

if (required)
assert false : "La expresión regular " + pattern + "
no encaja con " + texto;
return null;

}

}


private static void addKeywords(General general, String s, Locale locale)
{

StringTokenizer st = new StringTokenizer(s, ",");
while (st.hasMoreTokens())
{

String t = st.nextToken().trim();
general.addNewKeyword().add(locale, t);

}

}
private static void addContributor(Contribute contribute, String role, String vcardKey, String entity, String date)
{

addContributors(contribute, role, vcardKey, new
String[ ]{entity}, date);

}
private static void addContributors(Contribute contribute, String role, String vcardKey, String[] array, String date)
{

contribute.getRole().setVocabulary(role);
if (date != null)
contribute.getDate().setDatetime(date);

for (int i = 0; i < array.length; i++)
contribute.addNewCentity().add(vcardKey, array[i]);

}


private static NumberFormat getNumberFormat(int numdigitos)
{


NumberFormat nf = NumberFormat.getIntegerInstance();
nf.setMinimumIntegerDigits(numdigitos);
nf.setGroupingUsed(false);
return nf;

}


private static File getFile(String prefijo, String folio)
{


int NUMDIGITOS = 7;
String SUFIJO = ".xml";

String fdir = "C:/xp/WEBS/Rayuela/WEB-
INF/RAYUELAINDEX/colmex/";

File dir = new File(fdir);
dir.mkdirs();

NumberFormat nf = getNumberFormat(NUMDIGITOS);
return new File(dir, prefijo +
nf.format(Long.parseLong(folio)) + SUFIJO);

}
// Un sencillo método privado para evitar tener que hacer casting
a String
// al obtener los valores del mapa
private static String get(Map m, String key)
{
return (String) m.get(key);

}
public static void main(String[] args) throws Exception
{

int from = 0;
int to = 999999;

// El primer parametro es el nombre del archivo CSV
String archivoCSV = args[0];
// Los restantes parámetros opcionales permiten procesar
// solamente una parte del archivo
if (args.length >= 2)
from = Integer.parseInt(args[1]);
if (args.length >= 3)
to = Integer.parseInt(args[2]);

// Esta clase, CSVColmex implementa la interfaz Visitor
// necesaria para la función visitRecords
CSVIndexer.visitRecords(archivoCSV, from, to, new
CSVColmex());

}


}