package org.chesmapper.test.util; import java.io.File; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Properties; import java.util.Set; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JList; import javax.swing.JRadioButton; import javax.swing.JSpinner; import org.chesmapper.map.alg.Algorithm; import org.chesmapper.map.alg.align3d.NoAligner; import org.chesmapper.map.alg.build3d.UseOrigStructures; import org.chesmapper.map.alg.cluster.DatasetClusterer; import org.chesmapper.map.alg.embed3d.ThreeDEmbedder; import org.chesmapper.map.data.DatasetFile; import org.chesmapper.map.data.fragments.MatchEngine; import org.chesmapper.map.dataInterface.CompoundPropertySet; import org.chesmapper.map.gui.CheSMapperWizard; import org.chesmapper.map.gui.ClusterWizardPanel; import org.chesmapper.map.gui.DatasetWizardPanel; import org.chesmapper.map.gui.EmbedWizardPanel; import org.chesmapper.map.gui.wizard.AbstractWizardPanel; import org.chesmapper.map.main.CheSMapping; import org.chesmapper.map.main.PropHandler; import org.chesmapper.map.property.PropertySetCategory; import org.chesmapper.map.property.PropertySetProvider; import org.chesmapper.map.workflow.ClustererProvider; import org.chesmapper.map.workflow.DatasetLoader; import org.chesmapper.map.workflow.EmbedderProvider; import org.chesmapper.map.workflow.MappingWorkflow; import org.chesmapper.map.workflow.MappingWorkflow.DescriptorSelection; import org.chesmapper.map.workflow.MappingWorkflow.FragmentSettings; import org.chesmapper.map.workflow.SimpleViewAlgorithmProvider; import org.chesmapper.test.WizardTest; import org.junit.Assert; import org.mg.javalib.gui.LinkButton; import org.mg.javalib.gui.Selector; import org.mg.javalib.gui.WizardPanel; import org.mg.javalib.gui.property.Property; import org.mg.javalib.gui.property.PropertyComponent; import org.mg.javalib.util.DoubleKeyHashMap; import org.mg.javalib.util.FileUtil; import org.mg.javalib.util.ListUtil; import org.mg.javalib.util.SwingUtil; import org.mg.javalib.util.ThreadUtil; public class MappingCreator { public static Set<String> tmpfiles = new HashSet<String>(); public enum Mode { StoreAndLoadProps, DirectlyUseAlgorithms, RestartWizardWithProps, ConfigureWizard; } public static class IllegalSettingException extends IllegalArgumentException { public IllegalSettingException(String msg) { super(msg); } } public static CheSMapping create(Mode mode, String dataset, DescriptorSelection feats, FragmentSettings frags, DatasetClusterer clust, ThreeDEmbedder emb, DoubleKeyHashMap<Algorithm, String, Object> algorithmProps, String mappingKey) { if (mode == Mode.StoreAndLoadProps) { applyAlgorithmProps(clust, emb, algorithmProps); return storeAndLoadProps(dataset, feats, frags, clust, emb, mappingKey); } if (mode == Mode.DirectlyUseAlgorithms) { applyAlgorithmProps(clust, emb, algorithmProps); return directlyUseAlgorithms(dataset, feats, frags, clust, emb); } if (mode == Mode.RestartWizardWithProps) return restartWizardWithProps(feats, mappingKey); if (mode == Mode.ConfigureWizard) return configureWizard(dataset, feats, frags, clust, emb, algorithmProps); else throw new IllegalArgumentException(); } private static void applyAlgorithmProps(DatasetClusterer clust, ThreeDEmbedder emb, DoubleKeyHashMap<Algorithm, String, Object> algorithmProps) { if (algorithmProps != null) for (Algorithm alg : algorithmProps.keySet1()) for (Algorithm alg2 : new Algorithm[] { clust, emb }) if (alg == alg2) { for (String prop : algorithmProps.keySet2(alg)) { boolean found = false; for (final Property p : alg.getProperties()) { if (p.getName().equals(prop)) { found = true; System.err.println("setting " + p.getName() + " of " + alg.getName() + " from " + p.getValue() + " to " + algorithmProps.get(alg, p.getName())); Assert.assertNotEquals(p.getValue(), algorithmProps.get(alg, p.getName())); p.setValue(algorithmProps.get(alg, p.getName())); } } if (!found) throw new IllegalStateException(); } } } private static void switchAdvancedSimple(WizardPanel p, boolean simple) { JButton toAdvanced = SwingTestUtil.getButton(p, "Advanced >>"); JButton toSimple = SwingTestUtil.getButton(p, "<< Simple"); JButton press = null; if (simple) press = toSimple; else press = toAdvanced; if (press != null) SwingTestUtil.clickButton(press); } private static CheSMapping configureWizard(String dataset, DescriptorSelection feats, final FragmentSettings frags, DatasetClusterer clust, ThreeDEmbedder emb, final DoubleKeyHashMap<Algorithm, String, Object> algorithmProps) { // Assert.assertNull(Settings.TOP_LEVEL_FRAsME); for (PropertySetProvider.PropertySetShortcut feat : feats.getShortcuts()) if (feat != PropertySetProvider.PropertySetShortcut.integrated) for (CompoundPropertySet set : PropertySetProvider.INSTANCE.getDescriptorSets(null, feat)) if (set.isHiddenFromGUI()) throw new IllegalSettingException("skipping wizard test - cannot use gui for hidden feature: " + set); if (new File(PropHandler.getPropertiesFile()).exists()) { new File(PropHandler.getPropertiesFile()).delete(); Assert.assertFalse(new File(PropHandler.getPropertiesFile()).exists()); PropHandler.forceReload(); } final CheSMapperWizard wwd = new CheSMapperWizard(null); while (SwingTestUtil.getOnlyVisibleFrame() == null) { System.out.println("wait for wizard to show"); ThreadUtil.sleep(50); } WizardTest.waitForLoadingDialogToClose(wwd); // ThreadUtil.sleep(20000); System.out.println("start wizard test"); JButton startButton = SwingTestUtil.getButton(wwd, "Start mapping"); JButton nextButton = SwingTestUtil.getButton(wwd, "Next"); // dataset WizardTest.selectFile((DatasetWizardPanel) wwd.getCurrentPanel(), dataset); SwingTestUtil.waitWhileBlocked(wwd, "wait while blocked, loading dataset", false); DatasetFile datasetFile = ((DatasetWizardPanel) wwd.getCurrentPanel()).getDatasetFile(); Assert.assertNotNull(datasetFile); while (!nextButton.isEnabled()) { SwingTestUtil.waitForGUI(50); System.out.println("wait fo next button"); } nextButton.doClick(); //3d Assert.assertTrue(nextButton.isEnabled()); nextButton.doClick(); //features @SuppressWarnings("unchecked") final Selector<PropertySetCategory, CompoundPropertySet> selector = (Selector<PropertySetCategory, CompoundPropertySet>) SwingTestUtil .getOnlySelector(wwd.getCurrentPanel()); selector.clearSelection(true); Assert.assertTrue(selector.getSelected() == null || selector.getSelected().length == 0); selector.setSelected(ListUtil.toArray(CompoundPropertySet.class, feats.getFilteredFeatures(datasetFile)), true); if (frags != null) { // final JList<?> l = SwingTestUtil.getOnlyList(selector); SwingUtil.invokeAndWait(new Runnable() { public void run() { selector.highlight(PropertySetProvider.INSTANCE.getStructuralFragmentCategory()); //l.setSelectedIndex(0); } }); LinkButton link = null; List<JComponent> li = SwingTestUtil.getComponents(wwd.getCurrentPanel(), LinkButton.class); for (JComponent c : li) if (((LinkButton) c).getText().matches(".*Settings for fragments.*")) { link = (LinkButton) c; break; } final LinkButton fLink = link; fLink.doAction(); SwingUtil.waitForAWTEventThread(); final JDialog d = SwingTestUtil.getOnlyVisibleDialog(wwd); Assert.assertNotNull(d); SwingUtil.invokeAndWait(new Runnable() { public void run() { JSpinner sp = SwingTestUtil.getOnlySpinner(d.getContentPane()); Assert.assertEquals(sp.getValue(), 10); sp.setValue(frags.getMinFreq()); } }); SwingUtil.invokeAndWait(new Runnable() { public void run() { JCheckBox cb = SwingTestUtil.getOnlyCheckBox(d.getContentPane()); Assert.assertTrue(cb.isSelected()); if (cb.isSelected() != frags.isSkipOmnipresent()) SwingTestUtil.clickButton(cb); } }); SwingUtil.invokeAndWait(new Runnable() { public void run() { JComboBox<?> box = SwingTestUtil.getOnlyComboBox(d.getContentPane()); Assert.assertTrue(box.getSelectedItem().toString().equals(MatchEngine.OpenBabel.toString())); if (!box.getSelectedItem().toString().equals(frags.getMatchEngine().toString())) box.setSelectedIndex(1 - box.getSelectedIndex()); Assert.assertTrue(box.getSelectedItem().toString().equals(frags.getMatchEngine().toString())); } }); JButton closeButton = SwingTestUtil.getButton(d, "Close"); SwingTestUtil.clickButton(closeButton); //((FeatureWizardPanel) wwd.getCurrentPanel()).getFragmentPropPanel(); } Assert.assertTrue(nextButton.isEnabled()); nextButton.doClick(); //clusterer && embedder LinkedHashMap<Algorithm, SimpleViewAlgorithmProvider> map = new LinkedHashMap<Algorithm, SimpleViewAlgorithmProvider>(); map.put(clust, new ClustererProvider()); map.put(emb, new EmbedderProvider()); for (final Algorithm alg : map.keySet()) { SimpleViewAlgorithmProvider prov = map.get(alg); boolean unselected = false; if (alg == prov.getYesAlgorithm() || alg == prov.getNoAlgorithm()) { switchAdvancedSimple(wwd.getCurrentPanel(), true); List<JComponent> r = SwingTestUtil.getComponents(wwd.getCurrentPanel(), JRadioButton.class); Assert.assertTrue(r.size() == 2 && ((JRadioButton) r.get(1)).getText().equals("No")); if (alg == prov.getYesAlgorithm()) SwingTestUtil.clickButton((JRadioButton) r.get(0)); else SwingTestUtil.clickButton((JRadioButton) r.get(1)); if (!nextButton.isEnabled()) { unselected = true; SwingTestUtil.clickButton((JRadioButton) r.get(1)); } } else { switchAdvancedSimple(wwd.getCurrentPanel(), false); JList<?> list = SwingTestUtil.getOnlyList(wwd.getCurrentPanel()); int idx = -1; for (int i = 0; i < list.getModel().getSize(); i++) if (list.getModel().getElementAt(i) == alg) { idx = i; break; } Assert.assertTrue(idx > 0); list.setSelectedIndex(idx); if (!nextButton.isEnabled()) { unselected = true; list.setSelectedIndex(0); } } if (unselected) System.err.println("selected " + prov.getNoAlgorithm() + " instead of " + alg + " because of no next-button disabled"); else if (alg.getProperties() != null && algorithmProps.containsKey(alg)) for (String prop : algorithmProps.keySet2(alg)) { boolean found = false; for (final Property p : alg.getProperties()) { if (p.getName().equals(prop)) { found = true; System.err.println("setting " + p.getName() + " of " + alg.getName() + " from " + p.getValue() + " to " + algorithmProps.get(alg, p.getName())); Assert.assertNotEquals(p.getValue(), algorithmProps.get(alg, p.getName())); // // this has to be done even if random is not selected, as num-feature may be too low // if (alg == Random3DEmbedder.INSTANCE && p.getName().equals("Random seed")) // //cannot be done in gui, do this directly manually // alg.getRandomSeedProperty().setValue(algorithmProps.get(alg, p.getName())); SwingUtil.invokeAndWait(new Runnable() { public void run() { PropertyComponent pc = ((AbstractWizardPanel) wwd.getCurrentPanel()) .getComponentForProperty(p); Object v = algorithmProps.get(alg, p.getName()); if (v instanceof Integer) ((JSpinner) pc).setValue((Integer) v); else throw new IllegalStateException("not yet implemented"); } }); } } if (!found) throw new IllegalStateException(); } Assert.assertTrue(nextButton.isEnabled()); nextButton.doClick(); } Assert.assertTrue(startButton.isEnabled()); SwingTestUtil.clickButton(startButton); while (wwd.isShowing()) { System.out.println("wait for wizard to close"); ThreadUtil.sleep(50); } CheSMapping mapping = wwd.getChesMapping(); return mapping; } /** * use the standard export/workflow way that stores to global props to have this settings available in the wizard */ public static CheSMapping storeAndLoadProps(String dataset, DescriptorSelection feats, FragmentSettings frags, DatasetClusterer clust, ThreeDEmbedder emb, String mappingKey) { Properties props = MappingWorkflow.createMappingWorkflow(dataset, feats, frags, clust, emb); CheSMapping mapping = MappingWorkflow.createMappingFromMappingWorkflow(props, ""); String dest = "/tmp/props" + mappingKey; if (new File(dest).exists()) System.err.println("overwriting already existing file: " + dest); FileUtil.copy(PropHandler.getPropertiesFile(), dest); System.err.println("stored props at: " + dest); tmpfiles.add(dest); return mapping; } private static CheSMapping restartWizardWithProps(DescriptorSelection feats, String mappingKey) { // Assert.assertNull(Settings.TOP_LEVEL_FRAME); for (PropertySetProvider.PropertySetShortcut feat : feats.getShortcuts()) if (feat != PropertySetProvider.PropertySetShortcut.integrated) for (CompoundPropertySet set : PropertySetProvider.INSTANCE.getDescriptorSets(null, feat)) if (set.isHiddenFromGUI()) throw new IllegalSettingException("skipping wizard test - cannot use gui for hidden feature: " + set); String dest = "/tmp/props" + mappingKey; System.err.println("use prop file from " + dest); Assert.assertTrue(new File(dest).exists()); FileUtil.robustRenameTo(dest, PropHandler.getPropertiesFile()); Assert.assertFalse(new File(dest).exists()); tmpfiles.remove(dest); PropHandler.forceReload(); final CheSMapperWizard wwd = new CheSMapperWizard(null); while (SwingTestUtil.getOnlyVisibleFrame() == null) { System.out.println("wait for wizard to show"); ThreadUtil.sleep(50); } SwingTestUtil.waitForGUI(50); // ThreadUtil.sleep(20000); System.out.println("start wizard test"); JButton startButton = SwingTestUtil.getButton(wwd, "Start mapping"); JButton nextButton = SwingTestUtil.getButton(wwd, "Next"); while (!startButton.isEnabled()) { // ThreadUtil.sleep(1000); Assert.assertTrue(nextButton.isEnabled()); while (nextButton.isEnabled()) { SwingTestUtil.clickButton(nextButton); // ThreadUtil.sleep(1000); } if (wwd.getCurrentPanel() instanceof ClusterWizardPanel || wwd.getCurrentPanel() instanceof EmbedWizardPanel) { System.err.println("unselect " + ((wwd.getCurrentPanel() instanceof ClusterWizardPanel) ? "clustering" : "embedding") + " in wizard"); JButton toggleButton = SwingTestUtil.getButton(wwd.getCurrentPanel(), "<< Simple"); if (toggleButton != null) { JList<?> list = SwingTestUtil.getOnlyList(wwd.getCurrentPanel()); Assert.assertTrue(list.getSelectedIndex() != 0); list.setSelectedIndex(0); } else { toggleButton = SwingTestUtil.getButton(wwd.getCurrentPanel(), "Advanced >>"); Assert.assertNotNull(toggleButton); JRadioButton radio = SwingTestUtil.getRadioButton(wwd.getCurrentPanel(), "No"); Assert.assertTrue(radio.isShowing()); Assert.assertFalse(radio.isSelected()); radio.doClick(); Assert.assertTrue(radio.isSelected()); } // ThreadUtil.sleep(1000); Assert.assertTrue(nextButton.isEnabled()); } else Assert.fail("not clustering or embedding panel"); } Assert.assertTrue(startButton.isEnabled()); SwingTestUtil.clickButton(startButton); while (wwd.isShowing()) { System.out.println("wait for wizard to close"); ThreadUtil.sleep(50); } // ThreadUtil.sleep(1000); CheSMapping mapping = wwd.getChesMapping(); // Settings.TOP_LEVEL_FRAME = null; return mapping; } /** * direct way */ private static CheSMapping directlyUseAlgorithms(String dataset, DescriptorSelection feats, FragmentSettings frags, DatasetClusterer clust, ThreeDEmbedder emb) { // use direct way without props, both should yield equal results // (doing this instead of comparing mapping directly because algorithms are singletons) DatasetFile d = new DatasetLoader(false).load(dataset); if (frags != null) frags.apply(d); return new CheSMapping(d, ListUtil.toArray(CompoundPropertySet.class, feats.getFilteredFeatures(d)), clust, UseOrigStructures.INSTANCE, emb, NoAligner.INSTANCE); } }