Changeset 7430


Ignore:
Timestamp:
12/16/10 18:27:09 (9 years ago)
Author:
aivar
Message:

Added "loci.workflow" package.

Instead of having a singleton that passes images between plugins, this provides a workflow class. A workflow is built up of components, the components have named inputs and outputs which are chained together. The workflow is itself a component, so it also has named inputs and outputs.

The component and workflow can be saved to and restored from XML files (implementation uses a limited subset of simple XML). The XML for a workflow also includes the XML for its containers, which may be other workflows.

Location:
branches/maven/projects/deep-zoom-plugin/src
Files:
9 added
2 edited
1 moved

Legend:

Unmodified
Added
Removed
  • branches/maven/projects/deep-zoom-plugin/src/main/java/loci/workflow/IComponent.java

    r7425 r7430  
    1212 * @author Aivar Grislis 
    1313 */ 
    14 public interface IWorkFlowComponent { 
     14public interface IComponent { 
    1515 
    1616    /** 
     
    2727     */ 
    2828    public void setName(String name); 
     29 
     30    /** 
     31     * Saves component as XML string representation. 
     32     * 
     33     * @return 
     34     */ 
     35    String toXML(); 
     36 
     37    /** 
     38     * Restores component from XML string representation. 
     39     * 
     40     * @param xml 
     41     * @return whether successfully parsed 
     42     */ 
     43    boolean fromXML(String xml); 
    2944 
    3045    /** 
  • branches/maven/projects/deep-zoom-plugin/src/main/java/loci/workflow/IOutputListener.java

    r7425 r7430  
    1717     * Tells listener that an output image is ready. 
    1818     * 
     19     * @param name 
    1920     * @param image 
    20      * @param name 
    2121     */ 
    22     public void outputImage(ImageWrapper image, String name); 
     22    public void outputImage(String name, ImageWrapper image); 
    2323} 
  • branches/maven/projects/deep-zoom-plugin/src/main/java/loci/workflow/WorkFlow.java

    r7426 r7430  
    66package loci.workflow; 
    77 
     8import java.lang.StringBuilder; 
    89import java.util.ArrayList; 
    910import java.util.HashMap; 
     
    1920 * @author Aivar Grislis 
    2021 */ 
    21 public class WorkFlow implements IWorkFlowComponent { 
     22public class WorkFlow implements IComponent, IWorkFlow { 
     23    static final String WORKFLOW = "workflow"; 
     24    static final String NAME = "name"; 
     25    static final String COMPONENTS = "components"; 
     26    static final String COMPONENT = "component"; 
     27    static final String CHAINS = "chains"; 
     28    static final String CHAIN = "chain"; 
     29    static final String DEST = "dest"; 
     30    static final String SRC = "src"; 
     31    static final String INPUTS = "inputs"; 
     32    static final String INPUT = "input"; 
     33    static final String OUTPUTS = "outputs"; 
     34    static final String OUTPUT = "output"; 
     35 
     36    static IComponentFactory s_componentFactory; 
    2237    String m_name; 
    23     Map<String, IWorkFlowComponent> m_componentMap = new HashMap<String, IWorkFlowComponent>(); 
     38    Map<String, IComponent> m_componentMap = new HashMap<String, IComponent>(); 
    2439    List<String> m_inputNames = new ArrayList<String>(); 
    2540    List<String> m_outputNames = new ArrayList<String>(); 
    2641    List<Chain> m_chains = new ArrayList<Chain>(); 
    27     Map<String, IWorkFlowComponent> m_inputComponents = new HashMap<String, IWorkFlowComponent>(); 
     42    Map<String, IComponent> m_inputComponents = new HashMap<String, IComponent>(); 
    2843    Map<String, String> m_inputComponentNames = new HashMap<String, String>(); 
    2944    Map<String, IOutputListener> m_listeners = new HashMap<String, IOutputListener>(); 
     45    Map<String, IComponent> m_outputComponents = new HashMap<String, IComponent>(); 
     46    Map<String, String> m_outputComponentNames = new HashMap<String, String>(); 
     47    IOutputListener m_listener = new OutputListener(); 
     48    Object m_synchObject = new Object(); 
    3049 
    3150    public String getName() { 
     
    4564    } 
    4665 
    47     public void setXML(String xml) { 
    48  
    49     } 
    50  
    51     public String getXML() { 
    52         StringBuffer xml = new StringBuffer(); 
    53         xml.append("<workflow>\n"); 
    54         xml.append(" <name>"); 
    55         xml.append(getName()); 
    56         xml.append("</name>\n"); 
    57         xml.append("<components>\n"); 
    58        // for (IWorkFlowComponent component : m_componentMap.entrySet()) { 
    59  
    60        // } 
    61         xml.append("  <component>\n"); 
    62         xml.append("  </component>\n"); 
    63         xml.append("<chains>\n"); 
    64         for (Chain chain : m_chains) { 
    65             xml.append("<chain>\n"); 
    66             xml.append("<source>\n"); 
    67             xml.append(chain.getSource().getName() + '\n'); 
    68             xml.append("<image>\n"); 
    69             xml.append(chain.getSourceName() + '\n'); 
    70             xml.append("</source>\n"); 
    71             xml.append("<dest>\n"); 
    72             xml.append(chain.getDest().getName() + '\n'); 
    73             xml.append("<image>\n"); 
    74             xml.append(chain.getDestName() + '\n'); 
    75             xml.append("</image>\n"); 
    76             xml.append("</dest>\n"); 
    77             xml.append("</chain>\n"); 
    78         } 
    79         xml.append("</chains>\n"); 
    80         xml.append("</workflow>\n"); 
    81         return null; 
    82     } 
    83  
    84     public void add(IWorkFlowComponent component) { 
     66    public void setComponentFactory(IComponentFactory componentFactory) { 
     67        System.out.println("in set component factory"); 
     68        s_componentFactory = componentFactory; 
     69        if (s_componentFactory == null) { 
     70            System.out.println("its null"); 
     71        } 
     72    } 
     73 
     74    public boolean fromXML(String xml) { 
     75        boolean success = false; 
     76        XMLHelper xmlHelper = new XMLHelper(); 
     77 
     78        try { 
     79            XMLTag tag = xmlHelper.getNextTag(xml); 
     80            if (!WORKFLOW.equals(tag.getName())) { 
     81                throw new XMLException("Missing <workflow> tag"); 
     82            } 
     83            xml = tag.getContent(); 
     84            tag = xmlHelper.getNextTag(xml); 
     85            if (!NAME.equals(tag.getName())) { 
     86                throw new XMLException("Missing <name> for <workflow>"); 
     87            } 
     88            setName(tag.getContent()); 
     89            xml = tag.getRemainder(); 
     90            tag = xmlHelper.getNextTag(xml); 
     91            if (!COMPONENTS.equals(tag.getName())) { 
     92                throw new XMLException("Missing <components> for <workflow>"); 
     93            } 
     94            String componentsXML = tag.getContent(); 
     95            xml = tag.getRemainder(); 
     96            while (!componentsXML.isEmpty()) { 
     97                tag = xmlHelper.getNextTag(componentsXML); 
     98                componentsXML = tag.getRemainder(); 
     99 
     100                if (tag.getName().isEmpty()) { 
     101                    break; 
     102                } 
     103                if (!COMPONENT.equals(tag.getName())) { 
     104                    throw new XMLException("Missing <component> within <components>"); 
     105                } 
     106                String componentXML = tag.getContent(); 
     107                tag = xmlHelper.getNextTag(componentXML); 
     108                if (!NAME.equals(tag.getName())) { 
     109                    throw new XMLException("Missing <name> within <component>"); 
     110                } 
     111                System.out.println("component XML is [" + tag.getRemainder() + "]"); 
     112                if (null == s_componentFactory) { 
     113                    System.out.println("Component Factory is null"); 
     114                } 
     115                IComponent component = s_componentFactory.create(tag.getRemainder()); 
     116                add(component); 
     117            } 
     118 
     119            tag = xmlHelper.getNextTag(xml); 
     120            if (!CHAINS.equals(tag.getName())) { 
     121                throw new XMLException("Missing <chains> within <workflow>"); 
     122            } 
     123            String chainsXML = tag.getContent(); 
     124            xml = tag.getRemainder(); 
     125            while (!chainsXML.isEmpty()) { 
     126                tag = xmlHelper.getNextTag(chainsXML); 
     127                chainsXML = tag.getRemainder(); 
     128 
     129                if (tag.getName().isEmpty()) { 
     130                    break; 
     131                } 
     132                if (!CHAIN.equals(tag.getName())) { 
     133                    throw new XMLException("Missing <chain> within <chains>"); 
     134                } 
     135                String chainXML = tag.getContent(); 
     136                tag = xmlHelper.getNextTag(chainXML); 
     137                if (!SRC.equals(tag.getName())) { 
     138                    throw new XMLException("Missing <src> within <chain>"); 
     139                } 
     140                 
     141 
     142            } 
     143            success = true; 
     144        } 
     145        catch (XMLException e) { 
     146            System.out.println("XML Exception"); 
     147        } 
     148        return success; 
     149    } 
     150 
     151    public String toXML() { 
     152        StringBuilder xmlBuilder = new StringBuilder(); 
     153        XMLHelper xmlHelper = new XMLHelper(xmlBuilder); 
     154 
     155        // add workflow tag and name 
     156        xmlHelper.addTag(WORKFLOW); 
     157        xmlHelper.addTagWithContent(NAME, getName()); 
     158 
     159        // add components 
     160        xmlHelper.addTag(COMPONENTS); 
     161        for (String name: m_componentMap.keySet()) { 
     162            xmlHelper.addTag(COMPONENT); 
     163            xmlHelper.addTagWithContent(NAME, name); 
     164            xmlHelper.add(m_componentMap.get(name).toXML()); 
     165            xmlHelper.addEndTag(COMPONENT); 
     166        } 
     167        for (IComponent component: m_componentMap.values()) { 
     168            xmlHelper.addTag(COMPONENT); 
     169            xmlHelper.addTagWithContent(NAME, component.getName()); 
     170            xmlHelper.addEndTag(COMPONENT); 
     171        } 
     172        xmlHelper.addTag(COMPONENT); 
     173        xmlHelper.addEndTag(COMPONENT); 
     174        xmlHelper.addEndTag(COMPONENTS); 
     175 
     176        // add chains 
     177        xmlHelper.addTag(CHAINS); 
     178        for (Chain chain: m_chains) { 
     179            xmlHelper.addTag(CHAIN); 
     180            xmlHelper.addTag(SRC); 
     181            xmlHelper.addTagWithContent(COMPONENT, chain.getSource().getName()); 
     182            xmlHelper.addTagWithContent(NAME, chain.getSourceName()); 
     183            xmlHelper.addEndTag(SRC); 
     184            xmlHelper.addTag(DEST); 
     185            xmlHelper.addTagWithContent(COMPONENT, chain.getDest().getName()); 
     186            xmlHelper.addTagWithContent(NAME, chain.getDestName()); 
     187            xmlHelper.addEndTag(DEST); 
     188            xmlHelper.addEndTag(CHAIN); 
     189        } 
     190        xmlHelper.addEndTag(CHAINS); 
     191 
     192        // add inputs 
     193        xmlHelper.addTag(INPUTS); 
     194        for (String name : m_inputNames) { 
     195            xmlHelper.addTag(INPUT); 
     196            xmlHelper.addTagWithContent(NAME, name); 
     197            xmlHelper.addTag(DEST); 
     198            xmlHelper.addTagWithContent(COMPONENT, m_inputComponents.get(name).getName()); 
     199            xmlHelper.addTagWithContent(NAME, m_inputComponentNames.get(name)); 
     200            xmlHelper.addEndTag(SRC); 
     201            xmlHelper.addEndTag(INPUT); 
     202        } 
     203        xmlHelper.addEndTag(INPUTS); 
     204 
     205        // add outputs 
     206        xmlHelper.addTag(OUTPUTS); 
     207        for (String name : m_outputNames) { 
     208            xmlHelper.addTag(OUTPUT); 
     209            xmlHelper.addTagWithContent(NAME, name); 
     210            xmlHelper.addTag(SRC); 
     211            xmlHelper.addTagWithContent(COMPONENT, m_outputComponents.get(name).getName()); 
     212            xmlHelper.addTagWithContent(NAME, m_outputComponentNames.get(name)); 
     213            xmlHelper.addEndTag(SRC); 
     214            xmlHelper.addEndTag(OUTPUT); 
     215        } 
     216        xmlHelper.addEndTag(OUTPUTS); 
     217 
     218        // end workflow 
     219        xmlHelper.addEndTag(WORKFLOW); 
     220 
     221        return xmlBuilder.toString(); 
     222    } 
     223 
     224    public void add(IComponent component) { 
    85225        m_componentMap.put(component.getName(), component); 
    86226    } 
    87227 
    88     public void chain(IWorkFlowComponent source, IWorkFlowComponent dest) { 
     228    public void chain(IComponent source, IComponent dest) { 
    89229        chain(source, Output.DEFAULT, dest, Input.DEFAULT); 
    90230    } 
    91231 
    92     public void chain(IWorkFlowComponent source, String sourceName, IWorkFlowComponent dest) { 
     232    public void chain(IComponent source, String sourceName, IComponent dest) { 
    93233        chain(source, sourceName, dest, Input.DEFAULT); 
    94234    } 
    95235 
    96     public void chain(IWorkFlowComponent source, IWorkFlowComponent dest, String destName) { 
     236    public void chain(IComponent source, IComponent dest, String destName) { 
    97237        chain(source, Output.DEFAULT, dest, destName); 
    98238    } 
    99239 
    100     public void chain(IWorkFlowComponent source, String sourceName, IWorkFlowComponent dest, String destName) { 
     240    public void chain(IComponent source, String sourceName, IComponent dest, String destName) { 
    101241        Chain chain = new Chain(source, sourceName, dest, destName); 
    102242        m_chains.add(chain); 
    103243    } 
    104244 
    105     public void chainInput(String inName, IWorkFlowComponent dest) { 
     245    public void chainInput(IComponent dest) { 
     246        chainInput(Input.DEFAULT, dest, Input.DEFAULT); 
     247    } 
     248 
     249    public void chainInput(IComponent dest, String destName) { 
     250        chainInput(Input.DEFAULT, dest, destName); 
     251    } 
     252 
     253    public void chainInput(String inName, IComponent dest) { 
    106254        chainInput(inName, dest, Input.DEFAULT); 
    107255    } 
    108256 
    109     public void chainInput(String inName, IWorkFlowComponent dest, String destName) { 
     257    public void chainInput(String inName, IComponent dest, String destName) { 
     258        // note new input name 
    110259        m_inputNames.add(inName); 
     260 
     261        // save associated component 
    111262        m_inputComponents.put(inName, dest); 
     263 
     264        // associate dest name with input name 
    112265        m_inputComponentNames.put(inName, destName); 
    113266    } 
    114267 
    115     public void chainOutput(IWorkFlowComponent source, String outName) { 
    116         chainOutput(source, Output.DEFAULT, outName); 
    117     } 
    118  
    119     public void chainOutput(IWorkFlowComponent source, String sourceName, String outName) { 
     268    public void chainOutput(IComponent source) { 
     269        chainOutput(Output.DEFAULT, source, Output.DEFAULT); 
     270    } 
     271 
     272    public void chainOutput(IComponent source, String sourceName) { 
     273        chainOutput(Output.DEFAULT, source, sourceName); 
     274    } 
     275 
     276    public void chainOutput(String outName, IComponent source) { 
     277        chainOutput(Output.DEFAULT, source, outName); 
     278    } 
     279 
     280    public void chainOutput(String outName, IComponent source, String sourceName) { 
     281        // note new output name 
    120282        m_outputNames.add(outName); 
    121         //TODO set a listener, forwards to our listener, if any; source & sourceName might be misnomer 
     283 
     284        // save associated component 
     285        m_outputComponents.put(outName, source); 
     286 
     287        // associate source name with output name 
     288        m_outputComponentNames.put(sourceName, outName); 
     289 
     290        // listen for source name from source component 
     291        source.setOutputListener(sourceName, m_listener); 
    122292    } 
    123293     
    124294    public void input(ImageWrapper image, String name) { 
    125295        if (m_inputNames.contains(name)) { 
    126             IWorkFlowComponent dest = m_inputComponents.get(name); 
     296            IComponent dest = m_inputComponents.get(name); 
    127297            String destName = m_inputComponentNames.get(name); 
    128298            dest.input(image, destName); 
     
    133303    } 
    134304 
     305    public void setOutputListener(IOutputListener listener) { 
     306        synchronized (m_synchObject) { 
     307            setOutputListener(Output.DEFAULT, listener); 
     308        } 
     309    } 
     310 
    135311    public void setOutputListener(String name, IOutputListener listener) { 
    136         if (m_outputNames.contains(name)) { 
     312        synchronized (m_synchObject) { 
    137313            m_listeners.put(name, listener); 
    138314        } 
    139         else { 
    140             System.out.println("output name not found: " + name); 
     315    } 
     316     
     317    /** 
     318     * Listens for output images, passes them on to external listeners. 
     319     */ 
     320    private class OutputListener implements IOutputListener { 
     321 
     322        public void outputImage(String name, ImageWrapper image) { 
     323            // get output name associated with this source name 
     324            String outName = m_outputComponentNames.get(name); 
     325            IOutputListener listener = m_listeners.get(outName); 
     326            if (null != listener) { 
     327                listener.outputImage(outName, image); 
     328            } 
    141329        } 
    142330    } 
     
    146334     */ 
    147335    private class Chain { 
    148         IWorkFlowComponent m_source; 
     336        IComponent m_source; 
    149337        String m_sourceName; 
    150         IWorkFlowComponent m_dest; 
     338        IComponent m_dest; 
    151339        String m_destName; 
    152340 
    153         Chain(IWorkFlowComponent source, String sourceName, IWorkFlowComponent dest, String destName) { 
     341        Chain(IComponent source, String sourceName, IComponent dest, String destName) { 
    154342            m_source = source; 
    155343            m_sourceName = sourceName; 
     
    158346        } 
    159347 
    160         IWorkFlowComponent getSource() { 
     348        IComponent getSource() { 
    161349            return m_source; 
    162350        } 
     
    166354        } 
    167355 
    168         IWorkFlowComponent getDest() { 
     356        IComponent getDest() { 
    169357            return m_dest; 
    170358        } 
Note: See TracChangeset for help on using the changeset viewer.