[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