[Castore-commits] OutputDocumentGenerator.java NONE 1.1

Céline BENOIT cbenoit at adullact1.hosting.cri74.org
Mer 22 Mar 15:06:40 CET 2006


Update of /cvsroot/castore/castore-core/src/java/fr/emn/castor/documents/metier/textes/retro/generator
In directory adullact1:/tmp/cvs-serv6343/src/java/fr/emn/castor/documents/metier/textes/retro/generator

Added Files:
	OutputDocumentGenerator.java 
Log Message:
déplacement du fichier 

--- NEW FILE: OutputDocumentGenerator.java ---
/*
 * $Id: OutputDocumentGenerator.java,v 1.1 2006/03/22 14:06:38 cbenoit Exp $
 *
 * Plateforme CASTORE
 * CeCILL Copyright (C) 2005-2006 by EMN
 * Made by Stéphane Bouchet, Xerox
 * Web site = http://www.emn.fr/castore
 * Contact = Cédric Dumas, e-mail = Cedric.Dumas at emn.fr
 *
 * Version 1.0 (1er mars 2005)
 *
 * Ce logiciel est un programme informatique servant à créer une plateforme
 * open-source de bibliothèque numérique XML pour Conserver, Valoriser et
 * Diffuser le patrimoine documentaire de votre institut.
 *
 * Ce logiciel est régi par la licence CeCILL soumise au droit français et
 * respectant les principes de diffusion des logiciels libres. Vous pouvez
 * utiliser, modifier et/ou redistribuer ce programme sous les conditions de la
 * licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA sur le site
 * "http://www.cecill.info". En contrepartie de l'accessibilité au code source
 * et des droits de copie, de modification et de redistribution accordés par
 * cette licence, il n'est offert aux utilisateurs qu'une garantie limitée. Pour
 * les mêmes raisons, seule une responsabilité restreinte pèse sur l'auteur du
 * programme, le titulaire des droits patrimoniaux et les concédants successifs.
 * A cet égard l'attention de l'utilisateur est attirée sur les risques associés
 * au chargement, à l'utilisation, à la modification et/ou au développement et à
 * la reproduction du logiciel par l'utilisateur étant donné sa spécificité de
 * logiciel libre, qui peut le rendre complexe à manipuler et qui le réserve
 * donc à des développeurs et des professionnels avertis possédant des
 * connaissances informatiques approfondies. Les utilisateurs sont donc invités
 * à charger et tester l'adéquation du logiciel à leurs besoins dans des
 * conditions permettant d'assurer la sécurité de leurs systèmes et ou de leurs
 * données et, plus généralement, à l'utiliser et l'exploiter dans les mêmes
 * conditions de sécurité. Le fait que vous puissiez accéder à cet en-tête
 * signifie que vous avez pris connaissance de la licence CeCILL, et que vous en
 * avez accepté les termes.
 *
 */
package fr.emn.castor.documents.metier.textes.retro.generator;

import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdom.Content;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.Namespace;
import org.jdom.Text;

import fr.emn.castor.documents.metier.textes.retro.flatxmlrawdata.FlatXmlRawData;
import fr.emn.castor.documents.metier.textes.retro.flatxmlrawdata.FxrdElement;
import fr.emn.castor.documents.metier.textes.retro.flatxmlrawdata.InlineElement;
import fr.emn.castor.documents.metier.textes.retro.flatxmlrawdata.LayoutElement;
import fr.emn.castor.documents.metier.textes.retro.flatxmlrawdata.OutputParagraphElement;
import fr.emn.castor.documents.metier.textes.retro.flatxmlrawdata.ParagraphComponent;
import fr.emn.castor.documents.metier.textes.retro.flatxmlrawdata.ParagraphElement;
import fr.emn.castor.documents.metier.textes.retro.flatxmlrawdata.TextElement;
import fr.emn.castor.documents.metier.textes.retro.pointtopointschema.PointToPointSchema;
import fr.emn.castor.documents.metier.textes.retro.pointtopointschema.PpsElement;

/**
 * @author  rdelambe  Generate the final output DOM tree
 */
public class OutputDocumentGenerator {

    /** le logger.*/
    private static Log logger = LogFactory
        .getLog(OutputDocumentGenerator.class);

    /**
     * Default constructor
     */
    public OutputDocumentGenerator() {
    }

    /**
     * Constructor
     * 
     * @param theInputFilePath
     * @param theOutputFilePath 
     * @param thePpsFilePath
     * @param theCatalogPath
     *  
     */
    public OutputDocumentGenerator(String theInputFilePath,
            String theOutputFilePath, String thePpsFilePath) {
        inputFilePath = theInputFilePath;
        outputFilePath = theOutputFilePath;
        ppsFilePath = thePpsFilePath;
    }

    /**
     * Class members
     */

    // the input file path
    protected String inputFilePath = "";

    /** the output file path */
    protected String outputFilePath = "";

    /** the PointToPointSchema file path */
    protected String ppsFilePath = "";

    /** the final outputDocument */
    protected Document outputDocument = null;

    /** the point to point schema */
    private PointToPointSchema pps = null;

    // getters / setters
    /**
     * @return  Returns the inputFilePath.
     */
    public String getInputFilePath() {
        return inputFilePath;
    }

    /**
     * @return  Returns the outputFilePath.
     */
    public String getOutputFilePath() {
        return outputFilePath;
    }

    /**
     * @return  Returns the ppsFilePath.
     */
    public String getPpsFilePath() {
        return ppsFilePath;
    }

    /**
     * @param inputFilePath  The inputFilePath to set.
     */
    public void setInputFilePath(String theFilePath) {
        inputFilePath = theFilePath;
    }

    /**
     * @param outputFilePath  The outputFilePath to set.
     */
    public void setOutputFilePath(String theFilePath) {
        outputFilePath = theFilePath;
    }

    /**
     * @param ppsFilePath  The ppsFilePath to set.
     */
    public void setPpsFilePath(String theFilePath) {
        ppsFilePath = theFilePath;
    }

    /**
     * generate the final output document
     * 
     * @return the document
     */
    public Document generate() {

        FlatXmlRawData inputDocument = new FlatXmlRawData();

        try {
            // Load the PointToPointSchema
            pps = new PointToPointSchema(ppsFilePath);
            pps.load();
        } catch (Error e) {
            logger.error(ERROR_UNKNOWN + " while loading Pps");
            e.printStackTrace();
        }

        try {
            // Load the input document
            inputDocument = new FlatXmlRawData(inputFilePath);
            inputDocument.load();
        } catch (Error e) {
            logger.error(ERROR_UNKNOWN + " while loading input document");
            e.printStackTrace();
        }

        try {

            // Get root element outputDocument which has the same name as the
            // root element of inputDocument
            String rootName = inputDocument.getRootElement();
            Element root = new Element(rootName);
            root.setNamespace(Namespace.getNamespace(inputDocument
                .getTargetNamespace()));
            outputDocument = new Document(root);

            //allPleList = 
            // Deal with the document
            boolean insert = traiterElements(
                inputDocument.getFxrdElements(), root, FLAG_FC, true);

            if (!insert)
                logger.error(ERROR_VALIDITY);

            return outputDocument;
        } catch (Error e) {
            logger.error(ERROR_UNKNOWN);
            e.printStackTrace();
            return null;
        }
    }

    /**
     * Treatment method
     * 
     * @param ple
     *            a vector of FxrdElements
     * @param e
     *            the last inserted element in the output tree
     * @param c
     *            a flag: FS = following sibling, FC = following child
     * @param hl
     *            a boolean: if true, try to insert at a higher level
     * @return true if ok, false otherwise
     */
    public boolean traiterElements(
            Vector pleList, Element e, String c, boolean hl) {
        int tpe = 0;
        Element lite = e;
        FxrdElement ple;
        do {
            ple = (FxrdElement) pleList.get(tpe);
            boolean insert = traiterElement(ple, lite, c, hl);
            if (insert) {
                tpe = tpe + 1;
            } else {
                do {
                    ((FxrdElement) pleList.get(tpe)).Reset();
                    tpe = tpe - 1;
                } while (tpe != -1
                        & ((FxrdElement) pleList.get(tpe)).getEp() == true);
            }
            if (tpe != -1 & tpe != pleList.size()) {
                // Préparer le traitement ou retraitement de l'élément d'index tpe
                ple = (FxrdElement) pleList.get(tpe);
                c = FLAG_FS;
                //  L'élément inséré en dernier est 
                //  - soit la racine, 
                //  - soit l'élément inséré lors du traitement de l'élément d'avant le prochain à traiter               
                if (tpe == 0) {
                    lite = lite.getDocument().getRootElement();
                } else {
                    lite = ((FxrdElement) pleList.get(tpe - 1)).getTe();
                }

                // Retraitement
                if (!insert) {
                    ple.getTe().detach();
                }
            }
        } while (tpe != -1 & tpe != pleList.size());

        /*  Le traitement a pu s'arréter pour deux raisons :
         |  - On est remonté jusqu'à la racine : Le document n'a pu être rendu valide
         |  - On a traité tous les éléménts : Le document a été rendu valide */

        if (tpe == -1) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * Treatment method
     * 
     * @param ple
     *            a vector of FxrdElements
     * @param i
     *            integer telling us which item of the ple list to deal with
     * @param e
     *            the last inserted element in the output tree
     * @param c
     *            a flag: FS = following sibling, FC = following child
     * @param hl
     *            a boolean: if true, try to insert at a higher level
     * @return true if ok, false otherwise
     */
    public boolean traiterElement(
            FxrdElement ple, Element e, String c, boolean hl) {
        InsertReturn para;
        boolean insert;

        if (ple instanceof ParagraphElement) {
            para = traiterParagraphElement((ParagraphElement) ple, e, c, hl);
            return para.insert;
        } else {
            insert = traiterLayoutElement((LayoutElement) ple, e, c, hl);
            return insert;
        }
    }

    /**
     * Treatment method for ParagraphElements
     * 
     * @param pleList
     *            a vector of FxrdElements
     * @param i
     *            integer telling us which item of the ple list to deal with
     * @param e
     *            the last inserted element in the output tree
     * @param c
     *            a flag: FS = following sibling, FC = following child
     * @param hl
     *            a boolean: if true, try to insert at a higher level
     * @param ePrime
     *            the inserted element            
     * @return true if ok, false otherwise
     */
    public InsertReturn traiterParagraphElement(
            ParagraphElement pe, Element e, String c, boolean hl) {

        boolean insert = false;
        Element ePrime = null;

        Vector opeList = pe.getOutputParagraphElements();
        Vector pcList = pe.getParagraphComponents();

        int tpope = pe.getLpope() + 1;
        while (!insert & tpope != opeList.size()) {
            OutputParagraphElement ope = (OutputParagraphElement) opeList
                .get(tpope);
            String p = ope.getName();
            String ce = ope.getContainerElement();

            Element pElement = new Element(p);

            if (ce != null) {
                // insert p element into ce element
                Element ceElement = new Element(ce);
                ceElement.addContent(pElement);
                ePrime = ceElement;
            } else {
                ePrime = pElement;
            }

            // Try to insert the element
            insert = insertElement(ePrime, e, c, hl);
            pe.setLpope(pe.getLpope() + 1);

            if (!insert) {
                tpope = pe.getLpope() + 1;
            } else {
                // insert content into paragraph
                AddContent(pElement, pcList);
                pe.setTe(pElement);
            }
        }

        if (!insert) {
            // No element coming from the ParagraphElement list fits
            // try an element from the target schema            
            InsertReturn insertReturn;
            insertReturn = insertParagraphElementFromSchema(
                pe, e, c, opeList, hl);
            insert = insertReturn.insert;
            ePrime = insertReturn.element;

            if (insert) {
                // insert content into paragraph
                AddContent(ePrime, pcList);
                pe.setTe(ePrime);
            }
        }

        InsertReturn insertReturn = new InsertReturn(insert, ePrime);
        return insertReturn;
    }

    public void AddContent(Element e, Vector pcList) {
        Content pc = null;

        // Insert the content of a paragraph (elements of the pcList) in the element e
        for (int i = 0; i < pcList.size(); i++) {
            Object paragraphComponent = (ParagraphComponent) pcList.get(i);

            if (paragraphComponent instanceof TextElement) {
                String t = ((TextElement) paragraphComponent).getValue();
                pc = new Text(t);
                e.addContent(pc);
            } else {
                InlineElement inlineElement = (InlineElement) paragraphComponent;
                Element outputInlineElement = (Element) inlineElement
                    .getOutputInlineElement().clone();
                // Try to insert the inline element into the current paragraph
                boolean insert;
                if (i == 0) {
                    // Try to insert as first Child
                    insert = insertElement(
                        outputInlineElement, e, FLAG_FC, false);
                } else {
                    // Try to insert as following sibling of last insert paragraph component (element or text)                  
                    insert = insertElement(
                        outputInlineElement, pc, FLAG_FS, false);
                }

                if (!insert) {
                    // Insert the substitute texte in the current paragraph
                    String t = inlineElement.getSubstituteText();
                    pc = new Text(t);
                    e.addContent(pc);
                } else {
                    pc = outputInlineElement;
                }
            }
        }
    }

    /**
     * Treatment method for LayoutElements
     * 
     * @param ple
     *            a vector of FxrdElements
     * @param i
     *            integer telling us which item of the ple list to deal with
     * @param e
     *            the last inserted element in the output tree
     * @param c
     *            a flag: FS = following sibling, FC = following child
     * @param hl
     *            a boolean: if true, try to insert at a higher level
     * @return true if ok, false otherwise
     */
    public boolean traiterLayoutElement(
            LayoutElement le, Element e, String c, boolean hl) {

        boolean insert = false;

        if (!le.getPole()) {
            Element ole = (Element) le.getOutputLayoutElement();

            // Create the root layout element
            Element ePrime = (Element) ole.clone();
            ePrime.removeContent();

            insert = insertElement(ePrime, e, c, hl);

            if (insert) {
                insert = insertOutputLayoutSubElements(ole, ePrime);
                if (insert) {
                    le.setTe(ePrime);
                }
            }
            le.setPole(true);
        }
        if (!insert) {
            insert = traiterElements(
                le.getSubstituteParagraphElements(), e, c, false);
            if (insert) {
                FxrdElement lastSubstituteParagraphElements = (FxrdElement) le
                    .getSubstituteParagraphElements().lastElement();
                le.setTe(lastSubstituteParagraphElements.getTe());
            }
            le.setEp(true);
        }

        return insert;
    }

    /**
     * insert element in outputDocument
     * 
     * @param ePrime
     *            the element to be inserted as last child or son of e
     * @param e
     *            the last inserted element
     * @param c
     *            a flag: FS = following sibling, FC = following child
     * @param hl
     *            a boolean: if true, try to insert at a higher level
     * @return
     */
    private boolean insertElement(
            Element ePrime, Content e, String c, boolean hl) {

        boolean insert = false;
        if (e == null || (e.getParentElement() == null && c.equals(FLAG_FS)))
            return insert;

        PpsElement fatherElement = null;
        PpsElement eElem = null;

        // Can ePrime be inserted as a sibling of e ?
        boolean canEPrimeBeSiblingOfE = false;
        String eName;

        if (e instanceof Element)
            eName = ((Element) e).getName();
        else
            eName = PointToPointSchema.TEXT_NAME;

        if (c.equals(FLAG_FS)) {
            fatherElement = pps.getElement(e.getParentElement().getName());
            canEPrimeBeSiblingOfE = fatherElement
                .isAllowedFollowingSiblingOfChild(eName, ePrime.getName());
        }

        // Can ePrime be inserted as a child of e ?
        boolean canEPrimeBeChildOfE = true;
        if (c.equals(FLAG_FC)) {
            eElem = pps.getElement(eName);
            canEPrimeBeChildOfE = eElem
                .isAllowedFirstChild(ePrime.getName());
        }

        if ((c.equals(FLAG_FS) && canEPrimeBeSiblingOfE)
                || (c.equals(FLAG_FC) && canEPrimeBeChildOfE)) {

            if (c.equals(FLAG_FS)) {
                // insert ePrime as sibling of e
                e.getParentElement().addContent(ePrime);
            } else {
                // insert ePrime as child of e
                ((Element) e).addContent(ePrime);
            }
            insert = true;
        } else {
            if (hl) {
                // Try to insert less deeply in tree
                if (c.equals(FLAG_FC)) {
                    // Check if e can be empty, if so, try ton insert ePrime as
                    // sibling of e
                    if (eElem.getCanEmptyContent()) {
                        insert = insertElement(ePrime, e, FLAG_FS, hl);
                    }
                } else {
                    // Check if e is a last valid sibling of its father element,
                    // if so try to insert ePrime as a sibling of e's father
                    if (fatherElement.isAllowedLastChild(eName)) {
                        insert = insertElement(ePrime, (Element) e
                            .getParentElement(), FLAG_FS, hl);
                    }
                }
            }
        }
        return insert;
    }

    /**
     * Try to insert a paragraph element containing t text as last son or
     * sibling of e (depending on c flag)
     * 
     * @param t
     *            text contained in the paragraph
     * @param e
     *            last inserted element
     * @param c
     *            a flag: FS = following sibling, FC = following child
     * @param theOpeList
     * @param hl
     *            a boolean: if true, try to insert at a higher level
     * @param ePrime
     *            the inserted element
     * @return
     */
    private InsertReturn insertParagraphElementFromSchema(
            ParagraphElement pe, Element e, String c, Vector theOpeList,
            boolean hl) {

        boolean insert = false;
        Element ePrime = null;
        if (pe.ParagraphElementsFromSchema == null) {
            PpsElement eElem = pps.getElement(e.getName());
            PpsElement fatherElem = pps.getElement(e
                .getParentElement().getName());
            if (c.equals(FLAG_FS)) {
                pe.ParagraphElementsFromSchema = fatherElem
                    .getAllowedFollowingSiblingsOfChild(e.getName());
            } else {
                // c=FC
                pe.ParagraphElementsFromSchema = eElem
                    .getAllowedFirstChildren();
            }
            pe.setIpefs(pe.ParagraphElementsFromSchema.iterator());
        }
        Iterator iter = pe.getIpefs();
        while (!insert & iter.hasNext()) {
            PpsElement ePrimeElem = (PpsElement) iter.next();
            ePrime = new Element(ePrimeElem.getName());

            if (ePrimeElem.isParagraph()) {
                insert = insertElement(ePrime, e, c, hl);
            }
        }
        InsertReturn insertReturn = new InsertReturn(insert, ePrime);
        return insertReturn;
    }

    private boolean insertOutputLayoutSubElements(Element olse, Element e) {
        boolean insert = true;
        InsertReturn insertReturn;

        String c = "";

        List olseChildList = olse.getChildren();
        Element ePrime = null;

        for (int i = 0; i < olseChildList.size(); i++) {

            Element olseChild = (Element) olseChildList.get(i);
            String n = olseChild.getName();

            if (i == 0) {
                c = FLAG_FC;
            } else {
                c = FLAG_FS;
            }

            if (n.equals(FlatXmlRawData.PARAGRAPH_ELEMENT)) {
                ParagraphElement paraElemEPrime = new ParagraphElement();
                paraElemEPrime.load(olseChild);

                insertReturn = traiterParagraphElement(
                    paraElemEPrime, e, c, false);
                insert = insertReturn.insert;
                ePrime = insertReturn.element;

                if (!insert)
                    break;
            } else {
                // Duplicate node olseChild with function importNode 
                // in order to be able to insert it into the output document 
                // ePrime = (Element) outputDocument.importNode(olseChild, false);
                ePrime = (Element) olseChild.clone();
                ePrime.removeContent();

                if (c.equals(FLAG_FC)) {
                    // insert ePrime as first child of e
                    e.addContent(ePrime);
                } else {
                    // insert ePrime as following sibling of e                  
                    e.getParentElement().addContent(ePrime);
                }
                // recurse
                insertOutputLayoutSubElements(olseChild, ePrime);
            }
            e = ePrime;
        }

        return insert;
    }

    /**
     * Class constants
     *  
     */
    // Following child
    private static final String FLAG_FC = "FC";

    // Following sibling
    private static final String FLAG_FS = "FS";

    private static final String ERROR_VALIDITY = "La mise en validité a échoué";

    private static final String ERROR_UNKNOWN = "Unknown error";

    /**
     */
    public Element TEXT = new Element(PointToPointSchema.TEXT_NAME);

    /*private static final String ERROR_LOADING_PPS = "Error while loading PointToPointSchema file";

     private static final String ERROR_LOADING_INPUT = "Error while loading input document";

     private static final String ERROR_INITIALIZING_OUTPUT = "Error while initializing output document";

     private static final String ERROR_GENERATING_OUTPUT = "Error while generating output document";*/
}




Plus d'informations sur la liste de diffusion Castore-commits