diff --git a/src/main/java/plugins/fab/trackmanager/TrackManager.java b/src/main/java/plugins/fab/trackmanager/TrackManager.java index 8679f64056e00015057645ac9f9017e570ab7595..c4b7814350a38f72eaefd6b1fb3125003d634114 100644 --- a/src/main/java/plugins/fab/trackmanager/TrackManager.java +++ b/src/main/java/plugins/fab/trackmanager/TrackManager.java @@ -766,7 +766,6 @@ public class TrackManager extends PluginActionable private void loadTracks() { - JFileChooser chooser = new JFileChooser(); chooser.setDialogTitle("Select track.xml file."); @@ -784,102 +783,102 @@ public class TrackManager extends PluginActionable preferences.put("path", chooser.getCurrentDirectory().getAbsolutePath()); - File file = chooser.getSelectedFile(); + try + { + final List<TrackGroup> groups = loadTracks(chooser.getSelectedFile().getAbsolutePath()); - Document document = XMLUtil.loadDocument(file); + // add group to swimming pool + for (TrackGroup group : groups) + { + SwimmingObject so = new SwimmingObject(group); + Icy.getMainInterface().getSwimmingPool().add(so); + } - if (document == null) - { - MessageDialog.showDialog("Invalid track file: no document to open", MessageDialog.ERROR_MESSAGE); - return; + trackPool.fireTrackEditorProcessorChange(); } - - Element versionElement = XMLUtil.getElement(document.getDocumentElement(), "trackfile"); - if (versionElement == null) + catch (IllegalArgumentException ex) { - MessageDialog.showDialog("Invalid track file: the tag trackfile is missing.", MessageDialog.ERROR_MESSAGE); + MessageDialog.showDialog(ex.getMessage(), MessageDialog.ERROR_MESSAGE); return; } + } - ArrayList<Element> trackGroupElementList = XMLUtil.getElements(document.getDocumentElement(), "trackgroup"); + public static List<TrackGroup> loadTracks(String path) throws IllegalArgumentException + { + final Document document = XMLUtil.loadDocument(path, false); + return loadTracks(document); + } - for (Element trackGroupElement : trackGroupElementList) - { + public static List<TrackGroup> loadTracks(Document document) throws IllegalArgumentException + { + if (document == null) + throw new IllegalArgumentException("Invalid track file !"); + + final Element rootElement = document.getDocumentElement(); + + if (XMLUtil.getElement(rootElement, "trackfile") == null) + throw new IllegalArgumentException("Invalid track file: the tag trackfile is missing."); - ArrayList<Element> trackSegmentElementList = XMLUtil.getElements(trackGroupElement); - TrackGroup trackGroup = new TrackGroup(null); - String groupDescription = XMLUtil.getAttributeValue(trackGroupElement, "description", "no description"); - trackGroup.setDescription(groupDescription); + final List<TrackGroup> result = new ArrayList<>(); + + for (Element trackGroupElement : XMLUtil.getElements(rootElement, "trackgroup")) + { + // create track group + final TrackGroup trackGroup = new TrackGroup(null); + trackGroup.setDescription(XMLUtil.getAttributeValue(trackGroupElement, "description", "no description")); - for (Element trackSegmentElement : trackSegmentElementList) + for (Element trackSegmentElement : XMLUtil.getElements(trackGroupElement)) { + // create track segment + final TrackSegment trackSegment = new TrackSegment(); + final int id = XMLUtil.getAttributeIntValue(trackSegmentElement, "id", -1); - TrackSegment trackSegment = new TrackSegment(); - int id = XMLUtil.getAttributeIntValue(trackSegmentElement, "id", -1); if (id == -1) trackSegment.generateId(); else trackSegment.setId(id); - // trackSegment.setId( Integer.parseInt( trackSegmentElement.getAttribute("id") ) ); - ArrayList<Element> detectionElementList = XMLUtil.getElements(trackSegmentElement); - - for (Element detectionElement : detectionElementList) + for (Element detectionElement : XMLUtil.getElements(trackSegmentElement)) { + // create detection + final Detection detection = Detection.createDetection(XMLUtil.getAttributeValue(detectionElement, + "classname", "plugins.nchenouard.spot.Detection")); - String className = XMLUtil.getAttributeValue(detectionElement, "classname", - "plugins.nchenouard.spot.Detection"); - - Detection detection = Detection.createDetection(className); - + // load it detection.loadFromXML(detectionElement); - + // add to track segement trackSegment.addDetection(detection); } + // add track segment to track group trackGroup.addTrackSegment(trackSegment); } - - SwimmingObject so = new SwimmingObject(trackGroup); - Icy.getMainInterface().getSwimmingPool().add(so); - + + // add track group to result + result.add(trackGroup); } - // load links. - - ArrayList<Element> linkList = XMLUtil.getElements(document.getDocumentElement(), "linklist"); + // get links + for (Element linkListElement : XMLUtil.getElements(rootElement, "linklist")) { - for (Element linkListElement : linkList) + for (Element link : XMLUtil.getElements(linkListElement)) { - ArrayList<Element> trackSegmentElementList = XMLUtil.getElements(linkListElement); - for (Element link : trackSegmentElementList) - { - int idFrom = XMLUtil.getAttributeIntValue(link, "from", -1); - int idTo = XMLUtil.getAttributeIntValue(link, "to", -1); - - TrackSegment from = TrackSegment.getTrackSegmentById(idFrom); - TrackSegment to = TrackSegment.getTrackSegmentById(idTo); - - // System.out.println( "track from: " + idFrom + " "+ from ); - // System.out.println( "track to: " + idTo + " "+ to ); + final int idFrom = XMLUtil.getAttributeIntValue(link, "from", -1); + final int idTo = XMLUtil.getAttributeIntValue(link, "to", -1); - // System.out.println( "Checking null... "); + final TrackSegment from = TrackSegment.getTrackSegmentById(idFrom); + final TrackSegment to = TrackSegment.getTrackSegmentById(idTo); - if (from != null && to != null) - { - // System.out.println("TrackManager : from : " + from + " to " + to ); - trackPool.createLink(from, to); - } - } + if (from != null && to != null) + TrackPool.createLink(result, from, to); } } - trackPool.fireTrackEditorProcessorChange(); + return result; } private void loadTracksFromTrackMate() { - JFileChooser chooser = new JFileChooser(); chooser.setDialogTitle("Import TrackMate xml track file."); @@ -897,81 +896,86 @@ public class TrackManager extends PluginActionable preferences.put("path", chooser.getCurrentDirectory().getAbsolutePath()); - File file = chooser.getSelectedFile(); + try + { + final List<TrackGroup> groups = loadTracksFromTrackMate(chooser.getSelectedFile().getAbsolutePath()); - Document document = XMLUtil.loadDocument(file); + // add group to swimming pool + for (TrackGroup group : groups) + { + SwimmingObject so = new SwimmingObject(group); + Icy.getMainInterface().getSwimmingPool().add(so); + } - if (document == null) + trackPool.fireTrackEditorProcessorChange(); + } + catch (IllegalArgumentException ex) { - MessageDialog.showDialog("Invalid track file: no document to open", MessageDialog.ERROR_MESSAGE); + MessageDialog.showDialog(ex.getMessage(), MessageDialog.ERROR_MESSAGE); return; } + } + + public static List<TrackGroup> loadTracksFromTrackMate(String path) + { + final Document document = XMLUtil.loadDocument(path, false); + return loadTracksFromTrackMate(document); + } + + public static List<TrackGroup> loadTracksFromTrackMate(Document document) throws IllegalArgumentException + { + if (document == null) + throw new IllegalArgumentException("Invalid track file !"); final Element trackNode = XMLUtil.getElement(document.getDocumentElement().getParentNode(), "Tracks"); if (trackNode == null) - { - MessageDialog.showDialog( - "Unsupported version of TrackMate XML file !\nTry to use the Icy XML export in TrackMate instead and directly load it with 'TrackManager-->File->Load...' command.", - MessageDialog.ERROR_MESSAGE); - return; - } + throw new IllegalArgumentException( + "Unsupported version of TrackMate XML file !\nTry to use the Icy XML export in TrackMate instead and directly load it with 'TrackManager-->File->Load...' command."); - String unit = XMLUtil.getAttributeValue(trackNode, "spaceUnits", "pixel"); + final List<TrackGroup> result = new ArrayList<>(); + final String unit = XMLUtil.getAttributeValue(trackNode, "spaceUnits", "pixel"); double unitMultiplicator = 1; if (unit == "micron") unitMultiplicator = 0.000001d; - ArrayList<Element> trackElementList = XMLUtil.getElements(document.getDocumentElement().getParentNode(), - "Tracks"); - - // XMLUtil.getAttribute( trackElementList , attribute) - // trackElementList - - for (Element trackElement : trackElementList) + for (Element trackElement : XMLUtil.getElements(document.getDocumentElement().getParentNode(), "Tracks")) { + // create track group + final TrackGroup trackGroup = new TrackGroup(null); + trackGroup.setDescription(XMLUtil.getAttributeValue(trackElement, "description", "no description")); - ArrayList<Element> trackSegmentElementList = XMLUtil.getElements(trackElement); - TrackGroup trackGroup = new TrackGroup(null); - String groupDescription = XMLUtil.getAttributeValue(trackElement, "description", "no description"); - trackGroup.setDescription(groupDescription); - - for (Element trackSegmentElement : trackSegmentElementList) // particle tag + for (Element trackSegmentElement : XMLUtil.getElements(trackElement)) { + // create track segment + final TrackSegment trackSegment = new TrackSegment(); - TrackSegment trackSegment = new TrackSegment(); - int id = XMLUtil.getAttributeIntValue(trackSegmentElement, "id", -1); + final int id = XMLUtil.getAttributeIntValue(trackSegmentElement, "id", -1); if (id == -1) - { trackSegment.generateId(); - } else - { trackSegment.setId(id); - } - - ArrayList<Element> detectionElementList = XMLUtil.getElements(trackSegmentElement); - for (Element detectionElement : detectionElementList) + for (Element detectionElement : XMLUtil.getElements(trackSegmentElement)) { + // create detection + final Detection detection = Detection.createDetection("plugins.nchenouard.spot.Detection"); - Detection detection = Detection.createDetection("plugins.nchenouard.spot.Detection"); - + // load it detection.loadFromXML(detectionElement); - + // add to track segment trackSegment.addDetection(detection); - } + // add track segment to group trackGroup.addTrackSegment(trackSegment); } - - SwimmingObject so = new SwimmingObject(trackGroup); - Icy.getMainInterface().getSwimmingPool().add(so); - + + // add track group to result + result.add(trackGroup); } - trackPool.fireTrackEditorProcessorChange(); + return result; } private void debug() @@ -991,7 +995,6 @@ public class TrackManager extends PluginActionable private void saveTracks() { - JFileChooser chooser = new JFileChooser(); chooser.setDialogTitle("Select track.xml file."); chooser.setFileFilter(new FileNameExtensionFilter("XML track file", "xml")); @@ -1008,30 +1011,41 @@ public class TrackManager extends PluginActionable preferences.put("path", chooser.getCurrentDirectory().getAbsolutePath()); - File file = chooser.getSelectedFile(); + saveTracks(chooser.getSelectedFile().getAbsolutePath(), trackPool.getTrackGroupList()); + } - file = new File(FileUtil.setExtension(file.getAbsolutePath(), ".xml")); + public static void saveTracks(String path, List<TrackGroup> groups) + { + // get file + final File file = new File(FileUtil.setExtension(path, ".xml")); + // generate document + final Document document = saveTracks(groups); + // save it + XMLUtil.saveDocument(document, file); + } - Document document = XMLUtil.createDocument(true); + public static Document saveTracks(List<TrackGroup> groups) + { + final Document result = XMLUtil.createDocument(true); + final Element rootElement = result.getDocumentElement(); - Element versionElement = XMLUtil.addElement(document.getDocumentElement(), "trackfile"); + final Element versionElement = XMLUtil.addElement(rootElement, "trackfile"); versionElement.setAttribute("version", "1"); - for (TrackGroup trackGroup : trackPool.getTrackGroupList()) + for (TrackGroup trackGroup : groups) { - Element trackGroupElement = XMLUtil.addElement(document.getDocumentElement(), "trackgroup"); + final Element trackGroupElement = XMLUtil.addElement(rootElement, "trackgroup"); trackGroupElement.setAttribute("description", trackGroup.getDescription()); for (TrackSegment trackSegment : trackGroup.getTrackSegmentList()) { - Element trackElement = XMLUtil.addElement(trackGroupElement, "track"); + final Element trackElement = XMLUtil.addElement(trackGroupElement, "track"); trackElement.setAttribute("id", "" + trackSegment.getId()); - // System.out.println("Saving track : id : " + trackSegment.getId() ); - for (Detection detection : trackSegment.getDetectionList()) { - Element detectionElement = XMLUtil.addElement(trackElement, "detection"); + final Element detectionElement = XMLUtil.addElement(trackElement, "detection"); + detectionElement.setAttribute("classname", detection.getClass().getName()); // detectionElement.setAttribute( "x", ""+detection.x ); // detectionElement.setAttribute( "y", ""+detection.y ); @@ -1039,27 +1053,20 @@ public class TrackManager extends PluginActionable // detectionElement.setAttribute( "t", ""+detection.t ); detection.saveToXML(detectionElement); } - } - } // save links - - Element linklistElement = XMLUtil.addElement(document.getDocumentElement(), "linklist"); - for (Link link : trackPool.getLinks()) + final Element linklistElement = XMLUtil.addElement(rootElement, "linklist"); + for (Link link : TrackPool.getLinks(groups)) { - Element trackElement = XMLUtil.addElement(linklistElement, "link"); + final Element trackElement = XMLUtil.addElement(linklistElement, "link"); trackElement.setAttribute("from", "" + link.getStartSegment().getId()); trackElement.setAttribute("to", "" + link.getEndSegment().getId()); - // System.out.println("saving link."); - // System.out.println("from Id: " + link.getStartSegment().getId() ); - // System.out.println("to Id: " + link.getEndSegment().getId() ); } - XMLUtil.saveDocument(document, file); - + return result; } /** diff --git a/src/main/java/plugins/fab/trackmanager/TrackPool.java b/src/main/java/plugins/fab/trackmanager/TrackPool.java index 09c319a8f20d1dac15f255f37380637b889248e9..5df0025e7412a8d36c90a22c0e9d8e908b1dd8ae 100644 --- a/src/main/java/plugins/fab/trackmanager/TrackPool.java +++ b/src/main/java/plugins/fab/trackmanager/TrackPool.java @@ -86,26 +86,39 @@ public class TrackPool fireTrackEditorProcessorChange(); } + public static boolean linkExists(List<Link> links, TrackSegment start, TrackSegment end) + { + // check if the link already exists + for (Link link : links) + if ((link.start == start) && (link.end == end)) + return true; + + return false; + } + + public static boolean isLinkExists(List<TrackGroup> groups, TrackSegment start, TrackSegment end) + { + return linkExists(getLinks(groups), start, end); + } + public boolean isLinkExists(TrackSegment start, TrackSegment end) { - for (Link link : getLinks()) // check if the link already exists. + return linkExists(getLinks(), start, end); + } + + public static void createLink(List<TrackGroup> groups, TrackSegment start, TrackSegment end) + { + if (!isLinkExists(groups, start, end)) { - if (link.start == start && link.end == end) - { - return true; - } + start.nextList.add(end); + end.previousList.add(start); } - return false; } public void createLink(TrackSegment start, TrackSegment end) { - boolean alreadyExist = false; - alreadyExist = isLinkExists(start, end); - - if (!alreadyExist) + if (!isLinkExists(start, end)) { - // System.out.println("create a new link."); start.nextList.add(end); end.previousList.add(start); } @@ -539,6 +552,18 @@ public class TrackPool return linkarray; } + public static List<Link> getLinks(List<TrackGroup> groups) + { + final List<Link> result = new ArrayList<Link>(); + final List<TrackSegment> segments = getTrackSegmentList(groups); + + for (TrackSegment segment : segments) + for (int i = 0; i < segment.nextList.size(); i++) + result.add(new Link(segment, segment.nextList.get(i))); + + return result; + } + // FIXME: put a WeakReference in here private Sequence displaySequence = null; @@ -597,6 +622,19 @@ public class TrackPool return tePainter; } + /** + * @return the pool of tracksegment of all the trackgroup + */ + public static List<TrackSegment> getTrackSegmentList(List<TrackGroup> groups) + { + final List<TrackSegment> result = new ArrayList<TrackSegment>(); + + for (TrackGroup group : groups) + result.addAll(group.getTrackSegmentList()); + + return result; + } + /** * @return the pool of tracksegment of all the trackgroup */ @@ -876,14 +914,12 @@ public class TrackPool if (result.getObject() instanceof TrackGroup) { - // remove track id stored in tracksemgent.idhashmap - TrackGroup tg = (TrackGroup) result.getObject(); + final TrackGroup tg = (TrackGroup) result.getObject(); + + // remove track segment from hash map for (TrackSegment ts : tg.getTrackSegmentList()) - { - TrackSegment.idHashMapList.remove(ts); - } + ts.removeId(); } - } /** diff --git a/src/main/java/plugins/fab/trackmanager/TrackSegment.java b/src/main/java/plugins/fab/trackmanager/TrackSegment.java index 7c44bffb7c8af7e749f094ae447795ec9927909a..72ca4e2c13c1c332ba32a0998b8db43a6cc84af3 100644 --- a/src/main/java/plugins/fab/trackmanager/TrackSegment.java +++ b/src/main/java/plugins/fab/trackmanager/TrackSegment.java @@ -18,6 +18,8 @@ */ package plugins.fab.trackmanager; +import java.lang.ref.Reference; +import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -35,8 +37,8 @@ import plugins.nchenouard.spot.Detection; public class TrackSegment implements Cloneable { - protected static Map<TrackSegment, Integer> idHashMapList = new HashMap<TrackSegment, Integer>(); // 1-1 hashmap. - protected static Map<Integer, TrackSegment> idKeyHashMapList = new HashMap<Integer, TrackSegment>(); // 1-1 hashmap. + // better to use weak reference in the map + protected static Map<Integer, Reference<TrackSegment>> idKeyHashMapList = new HashMap<Integer, Reference<TrackSegment>>(); // 1-1 hashmap. List<Detection> detectionList = new ArrayList<Detection>(); List<TrackSegment> previousList = new ArrayList<TrackSegment>(); @@ -46,9 +48,19 @@ public class TrackSegment implements Cloneable public static TrackSegment getTrackSegmentById(int id) { + final Integer iid = Integer.valueOf(id); + synchronized (idKeyHashMapList) { - return idKeyHashMapList.get(Integer.valueOf(id)); + final Reference<TrackSegment> ref = idKeyHashMapList.get(iid); + + // null ? --> can remove it from the hashmap + if (ref.get() == null) + { + idKeyHashMapList.remove(iid); + } + + return ref.get(); } } @@ -104,11 +116,7 @@ public class TrackSegment implements Cloneable { synchronized (idKeyHashMapList) { - synchronized (idHashMapList) - { - idKeyHashMapList.remove(Integer.valueOf(id)); - idHashMapList.remove(this); - } + idKeyHashMapList.remove(Integer.valueOf(id)); } } @@ -124,22 +132,17 @@ public class TrackSegment implements Cloneable synchronized (idKeyHashMapList) { - synchronized (idHashMapList) + while (true) { - while (true) - { - final Integer key = Integer.valueOf(Random.nextInt()); - - // available ? - if (idKeyHashMapList.get(key) == null) - { - idHashMapList.put(this, key); - idKeyHashMapList.put(key, this); + final Integer key = Integer.valueOf(Random.nextInt()); - this.id = key.intValue(); + // available ? + if (idKeyHashMapList.get(key) == null) + { + idKeyHashMapList.put(key, new WeakReference<TrackSegment>(this)); + id = key.intValue(); - return; - } + return; } } } @@ -151,19 +154,14 @@ public class TrackSegment implements Cloneable synchronized (idKeyHashMapList) { - synchronized (idHashMapList) + // available ? + if (idKeyHashMapList.get(key) == null) { - // available ? - if (idKeyHashMapList.get(key) == null) - { - idHashMapList.put(this, key); - idKeyHashMapList.put(key, this); - - this.id = key.intValue(); - } - else - System.out.println("track id already loaded"); + idKeyHashMapList.put(key, new WeakReference<TrackSegment>(this)); + this.id = key.intValue(); } + else + System.out.println("track id already loaded"); } } diff --git a/src/main/java/plugins/fab/trackmanager/blocks/LoadTracksFromXML.java b/src/main/java/plugins/fab/trackmanager/blocks/LoadTracksFromXML.java new file mode 100644 index 0000000000000000000000000000000000000000..0b30ee1078540ec2ddf43618c8f945e0e8dd3e46 --- /dev/null +++ b/src/main/java/plugins/fab/trackmanager/blocks/LoadTracksFromXML.java @@ -0,0 +1,74 @@ +package plugins.fab.trackmanager.blocks; + +import java.io.File; +import java.util.List; + +import icy.plugin.abstract_.Plugin; +import icy.plugin.interface_.PluginBundled; +import icy.plugin.interface_.PluginLibrary; +import plugins.adufour.blocks.tools.roi.ROIBlock; +import plugins.adufour.blocks.util.VarList; +import plugins.adufour.vars.lang.Var; +import plugins.adufour.vars.lang.VarInteger; +import plugins.adufour.vars.lang.VarMutable; +import plugins.fab.trackmanager.TrackGroup; +import plugins.fab.trackmanager.TrackManager; + +/** + * Block to load a set of ROI from a file + * + * @author Stephane + */ +public class LoadTracksFromXML extends Plugin implements ROIBlock, PluginLibrary, PluginBundled +{ + final VarMutable file = new VarMutable("XML file", null) + { + @Override + public boolean isAssignableFrom(@SuppressWarnings("rawtypes") Var source) + { + return (String.class == source.getType()) || (File.class == source.getType()); + } + }; + final VarInteger groupIndex = new VarInteger("Group index", 0); + final Var<TrackGroup> tracks = new Var<TrackGroup>("Track group", new TrackGroup(null)); + + @Override + public void run() + { + final Object obj = file.getValue(); + if (obj == null) + return; + + final File f; + + if (obj instanceof String) + f = new File((String) obj); + else + f = (File) obj; + + // load track groups from file + final List<TrackGroup> groups = TrackManager.loadTracks(f.getAbsolutePath()); + // set result + tracks.setValue(groups.get(groupIndex.getValue().intValue())); + } + + @Override + public void declareInput(VarList inputMap) + { + inputMap.add("file", file); + inputMap.add("groupIndex", groupIndex); + } + + @Override + public void declareOutput(VarList outputMap) + { + outputMap.add("tracks", tracks); + + } + + @Override + public String getMainPluginClassName() + { + return TrackManager.class.getName(); + } +} diff --git a/src/main/java/plugins/fab/trackmanager/blocks/SaveTracksToXML.java b/src/main/java/plugins/fab/trackmanager/blocks/SaveTracksToXML.java new file mode 100644 index 0000000000000000000000000000000000000000..c35bb0a76544a344c43633fd59db856824af7d7e --- /dev/null +++ b/src/main/java/plugins/fab/trackmanager/blocks/SaveTracksToXML.java @@ -0,0 +1,74 @@ +package plugins.fab.trackmanager.blocks; + +import java.io.File; + +import icy.plugin.abstract_.Plugin; +import icy.plugin.interface_.PluginBundled; +import icy.plugin.interface_.PluginLibrary; +import icy.type.collection.CollectionUtil; +import plugins.adufour.blocks.tools.roi.ROIBlock; +import plugins.adufour.blocks.util.VarList; +import plugins.adufour.vars.lang.Var; +import plugins.adufour.vars.lang.VarMutable; +import plugins.fab.trackmanager.TrackGroup; +import plugins.fab.trackmanager.TrackManager; + +/** + * Block to save a set of ROI to a file + * + * @author Stephane + */ +public class SaveTracksToXML extends Plugin implements ROIBlock, PluginLibrary, PluginBundled +{ + final Var<TrackGroup> tracks = new Var<TrackGroup>("Track group", new TrackGroup(null)); + final VarMutable file = new VarMutable("XML file", null) + { + @Override + public boolean isAssignableFrom(@SuppressWarnings("rawtypes") Var source) + { + return (String.class == source.getType()) || (File.class == source.getType()); + } + }; + + @Override + public void run() + { + final TrackGroup group = tracks.getValue(); + // nothing to do + if (group == null) + return; + + final Object obj = file.getValue(); + if (obj == null) + return; + + final File f; + + if (obj instanceof String) + f = new File((String) obj); + else + f = (File) obj; + + // save tracks into file + TrackManager.saveTracks(f.getAbsolutePath(), CollectionUtil.createArrayList(group)); + } + + @Override + public void declareInput(VarList inputMap) + { + inputMap.add("tracks", tracks); + inputMap.add("file", file); + } + + @Override + public void declareOutput(VarList outputMap) + { + // + } + + @Override + public String getMainPluginClassName() + { + return TrackManager.class.getName(); + } +}