Index: lutingenerator/src/java/org/codelutin/generator/models/ui/javaxml/JavaXMLParser.java diff -u /dev/null lutingenerator/src/java/org/codelutin/generator/models/ui/javaxml/JavaXMLParser.java:1.1 --- /dev/null Tue Aug 10 17:04:54 2004 +++ lutingenerator/src/java/org/codelutin/generator/models/ui/javaxml/JavaXMLParser.java Tue Aug 10 17:04:49 2004 @@ -0,0 +1,366 @@ +/* *##% +* Copyright (C) 2002, 2003 Code Lutin +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*##%*/ + +/* * +* JavaXMLParser.java +* +* Created: Aug 6, 2004 +* +* @author Benjamin Poussin +* Copyright Code Lutin +* @version $Revision: 1.1 $ +* +* Mise a jour: $Date: 2004/08/10 17:04:49 $ +* par : $Author: mazelier $ +*/ + +package org.codelutin.generator.models.ui.javaxml; + +import org.codelutin.generator.models.ui.*; +import org.codelutin.generator.models.ui.impl.*; + +import org.dom4j.Element; +import org.dom4j.Document; +import org.dom4j.io.SAXReader; +import org.dom4j.DocumentException; + +import java.util.Iterator; +import java.util.List; +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Collection; +import java.util.ArrayList; + +/** +* Parser of a xml file issue of XMLEncoder +*/ +public class JavaXMLParser { // JavaXMLParser + protected Element rootElement; + + /** + * Parses a xml file and return a uimodel + * @param file - xml file issue of XMLEncoder + * @return UIModelImpl + */ + public UIModelImpl parse(File file) throws DocumentException, MalformedURLException { + return parse(file.toURI().toURL()); + } + /** + * Parses a xml file and return a uimodel + * @param file - xml file issue of XMLEncoder + * @return UIModelImpl + */ + public UIModelImpl parse(URL url) throws DocumentException, MalformedURLException { + SAXReader reader = new SAXReader(); + Document document = reader.read(url); + + rootElement = document.getRootElement(); + UIModelImpl result = parseModel(rootElement); + return result; + } + + /** + * Returns a UIModelImpl from a element + * @param current - element root of model + * @return UIModelImpl + */ + protected UIModelImpl parseModel(Element current){ + UIModelImpl result = new UIModelImpl(); + + String version = current.attributeValue("version"); + result.setVersion(version); + + // selectionne l'unique object racine de l'arbre + Element rootElement = (Element)current.selectSingleNode("/java/object"); + UIModelObject root = parseObject(rootElement); + result.setRoot(root); + + return result; + } + + /** + * Returns a UIModelObjectImpl equivalent to current element. + * It has arguments, properties, events and children + * @param current - element to parse + * @return UIModelObjectImpl + */ + protected UIModelObjectImpl parseObject(Element current){ + + System.out.println("current " + current); + UIModelObjectImpl result = new UIModelObjectImpl(); + + String type = current.attributeValue("class"); + result.setType(type); + + UIModelArgumentsImpl arguments = parseArguments(current); + result.setArguments(arguments); + + ArrayList children = parseChildren(current); + result.setChildren(children); + + // liste des properties de l'objet courant, on est sur que le tag des properties est de la forme , ce tag est un enfant de l'objet courant + List propertiesElement = current.selectNodes("void[@property]"); + System.out.println("SIZE OF PROPERTIES : " + propertiesElement.size()); + for(Iterator i = propertiesElement.iterator(); i.hasNext();){ + Element propElement = (Element)i.next(); + UIModelProperty prop = parseProperty(propElement); + result.addProperty(prop); + } + + // liste des events de l'objet courant + // les evenements sont decrits par un tag + // addMethod sera utilisee pour decrire l'event + //sous ce tag un objet de type EventHandler avec sa methode create + // dessous on trouve l'ensemble des proprietes de l'event (source, action ...) + List eventsElement = current.selectNodes("void/object[@class=\"java.beans.EventHandler\" and @method=\"create\"]"); + System.out.println("SIZE OF EVENTS : " + eventsElement.size()); + for(Iterator i = eventsElement.iterator(); i.hasNext();){ + Element eventProp = (Element)i.next(); + UIModelEvent event = parseEvent(eventProp); + result.addEvent(event); + } + + return result; + } + + /** + * Returns UIModelArgumentsImpl equivalent to current element + * A argument can be an object or a value with a primitiv type + * @param current - element to parse + * @return UIModelArgumentsImpl + */ + protected UIModelArgumentsImpl parseArguments(Element current){ + + UIModelArgumentsImpl result = new UIModelArgumentsImpl(); + + //liste des arguments d'un propriete ou d'un objet. Ils ne sont pas des entites void mais int, double, ... (types primitfs), String + List listPrimitivElement = current.selectNodes("*[not(self::void) and not(self::object)]"); + + for(Iterator i = listPrimitivElement.iterator(); i.hasNext();){ + Element primitivElement = (Element)i.next(); + Object value = primitivElement.getData(); + result.addArgument(value); + } + + // les arguments peuvent etre aussi des objets mais dans ce cas il faut lui aussi le parser + List listObjectElement = current.selectNodes("object"); + for(Iterator i = listObjectElement.iterator(); i.hasNext();){ + + Element objectElement = (Element)i.next(); + UIModelObjectImpl value = parseObject(objectElement); + result.addArgument(value); + } + + return result; + } + + /** + * Returns UIModelPropertyImpl equivalent to current element + * A property has a name and a list of Arguments + * @param current - element to parse + * @return UIModelPropertyImpl + */ + protected UIModelPropertyImpl parseProperty(Element current){ + + // la propriete possede un nom definit par la valeur de l'attribut property + UIModelPropertyImpl result = new UIModelPropertyImpl(); + String name = current.attributeValue("property"); + result.setName(name); + + // la propriete possede aussi une liste d'arguments + UIModelArgumentsImpl arguments = parseArguments(current); + result.setArguments(arguments); + + return result; + } + + + /** + * Returns UIModelEventImpl equivalent to current element + * A event has a addMethod, source, handler, argument and an action + * @param current - element to parse + * @return UIModelEventImpl + */ + protected UIModelEventImpl parseEvent(Element current){ + UIModelEventImpl result = new UIModelEventImpl(); + + /* Modele d'un event + + + source + target + handler + arguments (attention ou ) + action + + + */ + // parfois il n'y aura pas d'arguments et il est possible que handler soit vide ! + + // recuperation de la valeur de addMethod dans le tag parent void de l'objet courant avec l'attribut method + Element addMethodElement = (Element)current.selectSingleNode("parent::void[@method]"); + result.setAddMethod(addMethodElement.getText()); + + // la source est definie pour le tag class place juste en dessous de l'objet courant + Element sourceElement = (Element)current.selectSingleNode("class"); + result.setSource(sourceElement.getText()); + + // le handler sera toujours le deuxieme element string mais le troisieme element en tout + Element handlerElement = (Element)current.selectSingleNode("string[position()=2]"); + result.setHandler(handlerElement.getText()); + + // on ne connait pas le type d'arguments (null ou string) d'ou * mais on sait que sa position sera toujours 4 ! + Element argumentsElement = (Element)current.selectSingleNode("*[position()=4]"); + result.setArgument(argumentsElement.getText()); + + // l'action est toujours de type string mais on ne peut pas vraiment determine sa position a cause de arguments : position= 4 si arguments est de type string 3 sinon mais on sait que action sera toujours en dernier position + Element actionElement = (Element)current.selectSingleNode("string[position()=last()]"); + result.setAction(actionElement.getText()); + + return result; + } + + protected ArrayList parseChildren(Element parent){ + ArrayList result = new ArrayList(); + + //liste des enfants de l'objet eput etre recuperee selon deux cas : + + // premier cas : l'objet est identifie par un id + //un enfant est un objet qui a ete ajoute par la methode add au container + // sous l'objet courant, on cherche la methode add du tag void puis on recupere l'objet se trouvant sous ce tag. L'enfant est alors identifie par un id + List childrenElement = parent.selectNodes("void[@method=\"add\"]/object"); + System.out.println("SIZE OF CHILDREN : " + childrenElement.size()); + for(Iterator i = childrenElement.iterator(); i.hasNext();){ + Element childElem = (Element)i.next(); + String id = childElem.attributeValue("idref"); + if(childElem.attributeValue("idref") != null){ + childElem = (Element)rootElement.selectSingleNode("descendant::[@id=\""+id+"\"]"); + } + UIModelObjectImpl child = parseObject(childElem); + id = childElem.attributeValue("id"); + + Element constraintElem = (Element)parent.selectSingleNode("descendant::void[@property=\"layout\"]/object[(@class)]/void[@method=\"addLayoutComponent\"]/object[1][(@idref=\""+id+"\") or (@id=\""+id+"\")]/../object[2]"); + + UIModelConstraintImpl constraint = null; + + if(constraintElem != null){ + UIModelObjectImpl constraintObject = parseObject(childElem); + constraint = new UIModelConstraintImpl(); + constraint.setValue(constraintObject); + } + + UIModelChildImpl ch = new UIModelChildImpl(); + ch.setObject(child); + ch.setConstraint(constraint); + + result.add(child); + } + return result; + } + + + /** + * Returns UIModelConstraintImpl ewuivalent to current element + * This is ths constraint of an object. It has an object value. + * @param current - element to parse + * @return UIModelConstraintImpl + */ + protected UIModelConstraintImpl parseConstraint(Element current){ + UIModelConstraintImpl result = new UIModelConstraintImpl(); + + UIModelObject value = parseObject(current); + result.setValue(value); + + return result; + + } + +} // JavaXMLParser + + +/* + // deuxieme cas : l'objet n'est pas ajoute au container selon la methode add mais lorsque la methode addLayoutComponent est appelee + if(childrenElement==null || childrenElement.size()==0){ + // l'objet possede un property layout sous laquelle se trouve la methode addLayoutComponent qui est la methode appelee lorsqu'un objet est ajoute a un container selon le layout + List childrenElem = current.selectNodes("void[@property=\"layout\"]/void[@method=\"addLayoutComponent\"]/object"); + for(Iterator i = childrenElem.iterator(); i.hasNext();){ + Element childElem = (Element)i.next(); + UIModelChild child = parseChild2(childElem); + result.addChild(child); + } + } + */ + + + + + /* + * Returns a child with its constraint if the child has been referenced by the method add + * @param current - element to parse + * @return UIModelChildImpl + *) + protected UIModelChildImpl parseChild(Element current){ + + UIModelChildImpl result = new UIModelChildImpl(); + + // recuperation de l'id de l'enfant + String id = current.attributeValue("id"); + UIModelConstraint constraint = null; + + // cas ou l'objet est deja reference sous le void de la methode add + if(id != null){ + // on est sur l'enfant, on revient sur l'element puis encore sur le parent : on est donc sur le pere de l'enfant, on va aller chercher la propriete layout puis la methode addLayoutComponent pour recuperer l'objet contrainte de l'enfant qui a le meme id que l'enfant courant + Element constraintElem = (Element)current.selectSingleNode("parent::parent::/void[@property=\"layout\"]/object[(@class)]/void[@method=\"addLayoutComponent\"]/object[(@class) and (parent::object[@idref=\""+id+"\")]"); + + constraint = parseConstraint(constraintElem); + } + + UIModelObject child = parseObject(current); + + result.setObject(child); + result.setConstraint(constraint); + + return result; + + } + + /** + * Returns a child with its constraint if the child hasn't been referenced + * by the method add + * @param current - element to parse + * @return UIModelChildImpl + *) + protected UIModelChildImpl parseChild2(Element current){ + + UIModelChildImpl result = new UIModelChildImpl(); + + // dans ce cas, l'objet n'est pas prealablement reference, il se trouve a la premiere position + Element childElem = (Element)current.selectSingleNode("object[position()=1]"); + UIModelObject child = parseObject(childElem); + + // la contrainte se trouve en deuxieme position, elle est definie par le type objet + Element constraintElem = (Element)current.selectSingleNode("object[position()=2]"); + UIModelConstraint constraint = parseConstraint(constraintElem); + + result.setObject(child); + result.setConstraint(constraint); + + return result; + } +*/