Snippet: Reparar contenido XML

Mon Mar 02 12:51:22 CET 2015       Sergio Raposo Vargas       Código - Snippet, OpenCms, Programación

Es muy habitual en OpenCms que al modificar un XSD de un recurso, los ya existente de dicho tipo generen algún error de xml mal formado. Para arreglar el problema OpenCms nos ofrece una herramienta para Reparar Contenido disponible en la vista de Administración:

Vista Administración -> Herramientas de contenido -> Reparar Contenidos XML

En este artículo vamos a ver como lanzar el proceso de reparación desde código:

//Parametrizacion
boolean forceRepair = true;
//Tipo de recurso a reparar
int resourceTypeId = OpenCms.getResourceManager().getResourceType("RESOURCETYPE_NAME").getTypeId();
CmsResourceFilter filter = CmsResourceFilter.IGNORE_EXPIRATION.addRequireType(resourceTypeId);
String path = CmsResource.getFolderPath(rootPath);
//Obtenemos la lista de recursos a reparar
List<CmsResource> resources = cmsObject.readResources(path, filter, recursivo);
//Creamos el objeto que va a reparar los contenidos
CmsXmlEntityResolver resolver = new CmsXmlEntityResolver(cmsObject);
//Recorremos todos los recursos
Iterator<CmsResource> i = resources.iterator();
int count = 0;
while (i.hasNext()) {    
    count++;
    CmsResource res = i.next();
    try {
        CmsFile file = cmsObject.readFile(res);
        CmsXmlContent xmlContent = CmsXmlContentFactory.unmarshal(cmsObject, file);
        boolean fixFile = forceRepair;
        if (!fixFile) {
            try {
                xmlContent.validateXmlStructure(resolver);
            } catch (CmsXmlException e) {
                fixFile = true;
            }
        }
        if (fixFile) {
            //Si hay que arreglar, bloqueamos el recurso
            CmsLock lock = cmsObject.getLock(res);
            boolean isLocked = false;
            boolean canWrite = false;
            if (lock.isNullLock()) {                
                cmsObject.lockResource(cmsObject.getSitePath(res));
                isLocked = true;
                canWrite = true;
            } else if (lock.isOwnedBy(cmsObject.getRequestContext().getCurrentUser())) {                
                canWrite = true;
            }
            if (canWrite) {                                
                xmlContent.setAutoCorrectionEnabled(true);
                //Corregimos el xml
                xmlContent.correctXmlStructure(cmsObject);
                file.setContents(xmlContent.marshal());                
                // escribe los mapeos y asigna las categorías de los campos tipo OpenCmsCategory
                file = xmlContent.getHandler().prepareForWrite(cmsObject, xmlContent, file);                
                //Reescribimos el contenido
                cmsObject.writeFile(file);
            } else {
                //No es posible editar el recurso
                System.out.println(count+" -> "+res.getRootPath()+" -> ERROR: No se ha podido editar el recurso");                        
            }
            if (isLocked) {
                //Desbloqueamos
                cmsObject.unlockResource(cmsObject.getSitePath(res));
            }
            if (canWrite) {
                //Recurso corregido
                System.out.println(count+" -> "+res.getRootPath()+" -> OK");
            }
        } else {
            //Nada que hacer, nos saltamos el recurso
            println(count+" -> "+res.getRootPath()+" -> Sin errores");
        }
    } catch (CmsException e) {
        //Se ha producido un error, lo mostramos en el log
        e.printStackTrace()
    }
}

Si os fijáis tan solo tenemos que sacar una lista de recursos y ejecutar un par de métodos que hacen el proceso de reparar. Este script, no solo repara el XML sino que también arregla los mapeos de propiedades y el mapeo de url para páginas de detalle.

 Snippet, Código, Reparar Xml