Commit 43613ffa authored by Guillaume Chomat's avatar Guillaume Chomat
Browse files

implemented the observer/observable model

parent 9a79923f
......@@ -249,7 +249,7 @@
<para>Cete exemple trés complet présente la majorité des éléments pouvant définir une transformation dans l'environement Transmorpher.</para>
<para>Transmorpher s'apuie, dans la compostion de transformations, sur trois notions importantes:</para>
<itemizedlist>
<listitem><para>Process : composant appliquant une transformation au flux de données XML en entrée</para></listitem>
<listitem><para>Process : composant appliquant une transformation au flux de données XML en entrée.</para></listitem>
<listitem><para>Channel : composant connectant les process entre eux.</para></listitem>
<listitem><para>Port : composant servant à connecter les channels entre process. Un port est lié a un et un seul process.</para></listitem>
</itemizedlist>
......@@ -261,10 +261,8 @@
</imageobject>
</mediaobject>
</figure>
</section>
</section>
</section>
</section>
<section><title>FlowComposer</title>
......@@ -272,28 +270,26 @@
<section><title>Composants graphiques</title>
<para>Aujourd'hui, le nombres de process définissables par le transmorpher sont au nombre de 8. Le nombre de channel est lui de 5.</para>
<para>Pour tous ces composants, une charte graphique a été établie. Cette charte devra donc être respecté pour l'affichage des composants.</para>
<para>Aujourd'hui, le nombres d'éléments définissables par le transmorpher sont au nombre de huit. Le nombre de channel est lui de cinq.</para>
<para>Pour tous ces éléments, une charte graphique a été établie. Cette charte devra donc être respecté pour l'affichage des composants.</para>
<section><title>Generate et Serialize</title>
<itemizedlist>
<listitem>
<para>Generate : à partir d'une source XML, elle permet de générer et d'initier un flux XML. Ces composants n'ont pas d'entrées et une seule sortie.</para>
<para>Le Generate est un élément qui n'a aucune entrée et une sortie. Cet élément permet, à partir d'une source XML, de générer, d'initier un flux XML.</para>
<para>Il existe un seul type de Generate : le type readfile.</para>
<figure>
<title >Charte graphique du Generate</title>
<title>Charte graphique du Generate</title>
<mediaobject>
<imageobject>
<imagedata fileref="generate.png" format="PNG"/>
</imageobject>
</mediaobject>
</figure>
</listitem>
<listitem>
<para>Serialize : </para>
<para>Le Serialize est un élément qui a une entrée mais aucune sortie. Cet élément permet d'écrire l'entrée dans un fichier.</para>
<figure>
<title>Charte graphique du Serialize</title>
<mediaobject>
......@@ -302,36 +298,105 @@
</imageobject>
</mediaobject>
</figure>
</listitem>
</itemizedlist>
</section>
<section><title>Merge et Dispatch</title>
<para></para>
<itemizedlist>
<listitem>
<para>Un Merge est un élément qui peut avoir N entrées mais une seule sortie.</para>
<para>L'implémentation basic du Merge dans transmorpher permet de concaténer des flux XML en un.</para>
<figure>
<title>Charte graphique du Merge</title>
<mediaobject>
<imageobject>
<imagedata fileref="generate.png" format="PNG"/>
</imageobject>
</mediaobject>
</figure>
</listitem>
<listitem>
<para>Le Dispatch est un élément qui peut avoir une entrée et N sorties. Transmorpher fournit une impléméntation basic d'un Dispatche qui permet de copier l'netrée sur les différentes sorties.</para>
<figure>
<title>Charte graphique du Dispatch</title>
<mediaobject>
<imageobject>
<imagedata fileref="serialize.png" format="PNG"/>
</imageobject>
</mediaobject>
</figure>
</listitem>
</itemizedlist>
</section>
<section><title>Apply...</title>
<para></para>
<section><title>Process Externe</title>
<para>L' ApplyExternal est un élément qui peut avoir N entrées et N sortie. Il est identifié par son type.</para>
<para>Cet élément permet d'appliquer aux entrées un programme de transformation non spécifiques à Transmorpher.</para>
<para>Le seul type pris en compte, actuellement, dans Transmorpher est XSLT.</para>
<figure>
<title>Charte graphique de L'ApplyExternal</title>
<mediaobject>
<imageobject>
<imagedata fileref="generate.png" format="PNG"/>
</imageobject>
</mediaobject>
</figure>
</section>
<section><title>Channels</title>
<para>Les channels seront représentées par des simples traits entre ports.</para>
<section><title>Query</title>
<para>Un des requis fondamental des applications de Transformation est la capacité à selectionner une partie de documents XML pour être après transformée.</para>
<para>L' ApplyQuery est un élément qui peut avoir une entrée et une sortie.</para>
<para>Cet élément permet d'appliquer à l'entrée une requête. La sortie est le résultat de cette transformation.</para>
<figure>
<title>Charte graphique de L'ApplyQuery</title>
<mediaobject>
<imageobject>
<imagedata fileref="generate.png" format="PNG"/>
</imageobject>
</mediaobject>
</figure>
</section>
<section><title>Ruleset</title>
<section><title>Process</title>
<para>Les ports des process seront représentés....</para>
<para>Transmorpher fournit une collection de régles (correspondant à des templates XSLT) trés simple à utiliser et facile à analyser.</para>
<para>L'ApplyRuleset est un élément qui peut avoir une entrée et une sortie.</para>
<para>Cet élément permet d'appliquer à l'entrée un ensemble de règles. La sortie est le résultat de cette transformation.</para>
<figure>
<title>Charte graphique de L'ApplyRuleset</title>
<mediaobject>
<imageobject>
<imagedata fileref="generate.png" format="PNG"/>
</imageobject>
</mediaobject>
</figure>
</section>
<section><title>Process</title>
<para>Le Process est une notion importante dans Transmorpher. Un Process définit un ensemble de transformation à l'aide des éléments définis dans cette section.</para>
<para>Tout process peut être appeler à l'aide de l'élément ApplyProcess.</para>
<para>Un ApplyProcess peut avoir N entrées et N sorties.</para>
<figure>
<title>Charte graphique de L'ApplyProcess</title>
<mediaobject>
<imageobject>
<imagedata fileref="generate.png" format="PNG"/>
</imageobject>
</mediaobject>
</figure>
</section>
<section><title>Channels</title>
<para>Les channels seront représentées par des simples traits entre ports.</para>
</section>
</section>
......
/**
* $Id: FCConstants.java,v 1.5 2002-06-03 17:19:30 gchomat Exp $
* $Id: FCConstants.java,v 1.6 2002-06-10 09:47:41 gchomat Exp $
*
* Transmorpher
*
......@@ -58,8 +58,8 @@ public class FCConstants{
public static final Object[] MERGETYPE = new Object[]{"concat"};
public static final Object[] DISPATCHTYPE = new Object[]{"broadcast"};
public static final Object[] SERIALIZETYPE = new Object[]{"writeFile"};
public static final Object[] GENERATETYPE = new Object[]{"readFile"};
public static final Object[] SERIALIZETYPE = new Object[]{"writefile"};
public static final Object[] GENERATETYPE = new Object[]{"readfile"};
public static final Object[] APPLYQUERYTYPE = new Object[]{"tmq"};
public static final Object[] APPLYEXTERNALTYPE= new Object[]{"xslt"};
......
/**
* $Id: FCProcessFactory.java,v 1.8 2002-06-06 08:43:39 gchomat Exp $
* $Id: FCProcessFactory.java,v 1.9 2002-06-10 09:47:42 gchomat Exp $
*
* Transmorpher
*
......@@ -34,14 +34,13 @@ package fr.fluxmedia.flowcomposer;
import java.util.Iterator;
import java.util.*;
import com.jgraph.JGraph;
import com.jgraph.graph.*;
import fr.fluxmedia.transmorpher.Files.*;
import fr.fluxmedia.transmorpher.Graph.*;
import fr.fluxmedia.transmorpher.Graph.Process;
public class FCProcessFactory implements ProcessFactory{
public class FCProcessFactory implements ProcessFactory,Observer{
// The list of all process create with this factory
protected ArrayList listProcess ;
......@@ -52,8 +51,11 @@ public class FCProcessFactory implements ProcessFactory{
//The list of class coresponding of type.
protected static Hashtable listType;
public FCProcessFactory(){
protected FlowComposer flowcomposer;
public FCProcessFactory( FlowComposer flowcomposer){
this.flowcomposer = flowcomposer;
listProcess = new ArrayList();
listType = new Hashtable();
initFactory();
......@@ -71,12 +73,12 @@ public class FCProcessFactory implements ProcessFactory{
listType.put("standardOutput", (Object)"fr.fluxmedia.transmorpher.Graph.Serialize");
}
public JGraph createProcess(Object userObject) throws FCException{
public ProcessGraph createProcess(Object userObject) throws FCException{
if(userObject != null)
{
GraphModel model = new ProcessGraphModel();
JGraph process = new ProcessGraph(model,null,userObject);
ProcessGraph process = new ProcessGraph(model,null,userObject);
if(userObject instanceof MainProcess)
{
......@@ -85,22 +87,24 @@ public class FCProcessFactory implements ProcessFactory{
throw new SingleMainProcessException("single main");
}
else
mainProcess = (ProcessGraph)process;
mainProcess = process;
}
listProcess.add(process);
((Process)userObject).addObserver(process);
return process;
}
else return null;
}
public boolean validateProcess(Object process){
// not yet implemented
return true;
}
public JGraph getProcess(String index){
public ProcessGraph getProcess(String index){
Iterator it = getAllProcess().iterator();
String processName;
......@@ -150,4 +154,32 @@ public class FCProcessFactory implements ProcessFactory{
}
}
public void update(Observable observable, Object arg){
if(observable instanceof Transmorpher)
{
if(arg instanceof Process)
{
ProcessGraph process ;
try{
process = createProcess(arg);
}
catch(SingleMainProcessException e)
{
Alert.show(null,e.getMessage(),"WARNING",1);
return;
}
catch(FCException e)
{
return;
}
flowcomposer.createProcess(process);
}
}
}
}
......@@ -41,16 +41,16 @@ public class PortProcessRenderer extends VertexRenderer {
if (bordercolor != null) {
g.setColor(bordercolor);
g2.setStroke(new BasicStroke(b));
drawApplyProcess(g,d,b);
drawPortProcess(g,d,b);
}
if (selected) {
g2.setStroke(GraphConstants.SELECTION_STROKE);
g.setColor(graph.getHighlightColor());
drawApplyProcess(g,d,b);
drawPortProcess(g,d,b);
}
}
private void drawApplyProcess(Graphics g,Dimension d , int b ) {
private void drawPortProcess(Graphics g,Dimension d , int b ) {
g.drawRect(b-1, b-1,d.width-b, d.height-b);
}
......
......@@ -16,6 +16,7 @@ import java.awt.*;
public class PortProcessView extends VertexView{
public static PortProcessRenderer renderer = new PortProcessRenderer();
public PortProcessView(Object cell, JGraph graph, CellMapper cm) {
......
/**
* $Id: ProcessFactory.java,v 1.4 2002-06-03 17:19:30 gchomat Exp $
* $Id: ProcessFactory.java,v 1.5 2002-06-10 09:47:42 gchomat Exp $
*
* Transmorpher
*
......@@ -31,18 +31,17 @@
package fr.fluxmedia.flowcomposer;
import com.jgraph.JGraph;
import com.jgraph.graph.*;
import java.util.*;
public interface ProcessFactory{
public JGraph createProcess(Object userObject) throws FCException;
public ProcessGraph createProcess(Object userObject) throws FCException;
public boolean validateProcess(Object process);
public JGraph getProcess(String index);
public ProcessGraph getProcess(String index);
public List getAllProcess();
......
/**
* $Id: ProcessGraph.java,v 1.19 2002-06-06 09:49:55 frederic Exp $
* $Id: ProcessGraph.java,v 1.20 2002-06-10 09:47:42 gchomat Exp $
*
* Transmorpher
*
......@@ -40,6 +40,7 @@ import java.io.*;
import javax.swing.*;
import javax.swing.undo.UndoManager;
import fr.fluxmedia.transmorpher.Graph.Transmorpher;
import fr.fluxmedia.transmorpher.Graph.Process;
import fr.fluxmedia.transmorpher.Graph.Call;
import fr.fluxmedia.transmorpher.Files.*;
......@@ -58,6 +59,8 @@ public class ProcessGraph extends JGraph implements Comparator, Observer{
static Dimension boundsCube = new Dimension(70,70);
static Dimension boundsPort = new Dimension(15,15);
static Dimension boundsPortCell = new Dimension(30,30);
/** boundsRect define the dimension of a rectangle form composant such as ApplyProcess, Serialize,...
* ie: this composant are included in rectangle boxe
*/
......@@ -118,6 +121,13 @@ public class ProcessGraph extends JGraph implements Comparator, Observer{
return super.toString();
}
public String getName(){
if(userObject instanceof Process){
return ((Process)userObject).getName();
}
return "";
}
/**
......@@ -165,11 +175,18 @@ public class ProcessGraph extends JGraph implements Comparator, Observer{
/** interface Observer*/
public void update(Observable o, Object arg){
public void update(Observable observable, Object arg){
if(observable instanceof Process)
{
if(arg instanceof Call)
{
System.out.println("new call created ");
addVertex(arg,new Point(10,10),FCConstants.DISPATCH);
}
}
}
/** implementation insertion sort */
public boolean inferieur(Object o1, Object o2) {
......@@ -495,6 +512,47 @@ public class ProcessGraph extends JGraph implements Comparator, Observer{
}
*/
/**
create a channel in the graph.
*/
public void createChannel(){}
/**
create a call in the graph.
*/
/* public void createCall(int type, Object[] parameters, Point position){
call = FCProcessFactory.createCall(type,parameters);
if(userObject != null && userObject instanceof Transformation)
((Transformation)userObject).addCall(call);
else
{
// traitement erreur
}
addVertex(call, position,FCConstants.MERGE);
}*/
/**
remove a channel in the graph.
*/
public void removeChannel(){}
/**
remove a call in the graph.
*/
public void removeCall(){}
/**
* add a Cell to the Graph
public void updateProcess() {
if (pCell!=null) {
GraphView v = getView();
......@@ -506,7 +564,7 @@ public class ProcessGraph extends JGraph implements Comparator, Observer{
attributes.put(cellView,map);
v.edit(attributes);}
}
*/
/** add a Cell to the Graph
*
......@@ -549,16 +607,22 @@ public class ProcessGraph extends JGraph implements Comparator, Observer{
case FCConstants.APPLYEXTERNAL :
cell = new ApplyExternalCell(userObject);
bounds = new Rectangle(point,boundsRect);
//addCell(cell,viewMap,bounds);
Map map = GraphConstants.createMap();
GraphConstants.setBounds(map, bounds);
GraphConstants.setOpaque(map, false);
GraphConstants.setBorderColor(map, Color.black);
GraphConstants.setForeground(map, Color.white);
GraphConstants.setBackground(map, Color.lightGray);
viewMap.put(cell, map);
break;
addCell(cell,viewMap,bounds);
Call call = (Call)userObject;
if(call.getType().equals("xslt")){
addPort(cell,viewMap,FCConstants.PORTINPUT);
addPort(cell,viewMap,FCConstants.PORTOUTPUT);
}
/*Map map = GraphConstants.createMap();
GraphConstants.setBounds(map, bounds);
GraphConstants.setOpaque(map, false);
GraphConstants.setBorderColor(map, Color.black);
GraphConstants.setForeground(map, Color.white);
GraphConstants.setBackground(map, Color.lightGray);
viewMap.put(cell, map);*/
break;
case FCConstants.APPLYPROCESS :
cell = new ApplyProcessCell(userObject);
bounds = new Rectangle(point,boundsRect);
......@@ -579,30 +643,48 @@ public class ProcessGraph extends JGraph implements Comparator, Observer{
addPort(cell,viewMap,FCConstants.PORTOUTPUT);
break;
case FCConstants.PORTPROCESS :
Rectangle r = getBounds();
cell = new PortProcessCell(userObject);
pCell=cell;
bounds = new Rectangle(new Point(0,0),new Dimension(70,70));
bounds = new Rectangle(point,boundsCube);
addCell(cell,viewMap,bounds);
break;
addPort(cell,viewMap,FCConstants.PORTOUTPUT);
break;
default: System.out.println("pas de vertex correspondant la string : FlowComposerGraph+meth addCell");break;
}
getModel().insert(new Object[]{cell}, null, null, viewMap);
FlowComposer.editing=true;
updateProcess();
// updateProcess();
}
public void addCell(DefaultGraphCell cell,Map viewMap, Rectangle bounds) {
Map map = GraphConstants.createMap();
GraphConstants.setBounds(map, bounds);
if(cell instanceof PortProcessCell){
GraphConstants.setMoveable(map, false);
GraphConstants.setSizeable(map, false);
}
GraphConstants.setBounds(map, bounds);
GraphConstants.setOpaque(map, false);
GraphConstants.setBorderColor(map, Color.black);
viewMap.put(cell, map);
viewMap.put(cell, map);
}
public void createPort(int type)
{
if(getSelectionCount()==0)
{
addVertex(null,new Point(0,100),FCConstants.PORTPROCESS);
}
else
{
Map map = GraphConstants.createMap();
}
}
public void addPort(DefaultGraphCell cell,Map viewMap, int type) {
int index;
fr.fluxmedia.transmorpher.Graph.Port port=null;
......@@ -610,20 +692,24 @@ public class ProcessGraph extends JGraph implements Comparator, Observer{
Map map = GraphConstants.createMap();
// Call call = (Call)cell.getUserObject();
Call call = (Call)cell.getUserObject();
switch (type) {
case FCConstants.PORTINPUT :
GraphConstants.setOffset(map, new Point(0,(int) (u/2)));
// index = (call.inPorts().length()==0)?0:call.inPorts().length()-1;
// port = new fr.fluxmedia.transmorpher.Graph.Port(null,call,index);
// call.inPorts().addPort(port);
break;
if(call!=null){
index = (call.inPorts().length()==0)?0:call.inPorts().length()-1;
port = new fr.fluxmedia.transmorpher.Graph.Port(null,call,index);
call.inPorts().addPort(port);
}
break;
case FCConstants.PORTOUTPUT :
GraphConstants.setOffset(map, new Point(u,(int) (u/2)));
// index = (call.outPorts().length()==0)?0:call.outPorts().length()-1;
// port = new fr.fluxmedia.transmorpher.Graph.Port(null,call,index);
// call.outPorts().addPort(port);
break;
if(call!=null){
index = (call.outPorts().length()==0)?0:call.outPorts().length()-1;
port = new fr.fluxmedia.transmorpher.Graph.Port(null,call,index);
call.outPorts().addPort(port);
}
break;
default : System.out.println("type de port inconnu : meth addPort");
}
PortCell pc = new PortCell("",type);
......