/* Copyright (C) 2006 Christian Schneider * * This file is part of Nomad. * * Nomad 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. * * Nomad 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 Nomad; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package net.sf.nmedit.test; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Dimension; import java.awt.Point; import java.awt.Rectangle; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.URISyntaxException; import java.net.URL; import java.util.ArrayList; import java.util.List; import javax.swing.AbstractAction; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JOptionPane; import javax.swing.JTabbedPane; import javax.swing.filechooser.FileFilter; import javax.swing.undo.UndoManager; import org.xml.sax.InputSource; import net.sf.nmedit.jpatch.PConnectorDescriptor; import net.sf.nmedit.jpatch.PDescriptor; import net.sf.nmedit.jpatch.PLightDescriptor; import net.sf.nmedit.jpatch.PModuleDescriptor; import net.sf.nmedit.jpatch.PParameterDescriptor; import net.sf.nmedit.jpatch.clavia.nordmodular.NM1ModuleDescriptions; import net.sf.nmedit.jpatch.clavia.nordmodular.NMPatch; import net.sf.nmedit.jpatch.history.History; import net.sf.nmedit.jpatch.transform.PTTransformationsBuillder; import net.sf.nmedit.jpatch.transform.PTTransformations; import net.sf.nmedit.jsynth.clavia.nordmodular.utils.NmUtils; import net.sf.nmedit.jtheme.clavia.nordmodular.JTNM1Context; import net.sf.nmedit.jtheme.clavia.nordmodular.JTNMPatch; import net.sf.nmedit.jtheme.clavia.nordmodular.NMStorageContext; import net.sf.nmedit.jtheme.store.DefaultStorageContext; import net.sf.nmedit.jtheme.util.RelativeClassLoader; /** * Note: add the nordmodular/data/ folder to the classpath. */ public class UITest { static JFrame frame; static JTabbedPane tabbedPane; static List<File> files = new ArrayList<File>(); static NM1ModuleDescriptions modules; static JTNM1Context uicontext; public static void main(String[] args) { files.add(new File("/Users/distrinet/Documents/patch/test.pch")); updateUI(); } private static class UITestAction extends AbstractAction { /** * */ private static final long serialVersionUID = 5875924171704911680L; public static final String FileOpen = "Open"; public static final String FileClose= "Close"; public static final String UIUpdate = "Update UI"; public static final String Exit = "Exit"; public static final String FileUndo = "Undo"; public static final String FileRedo = "Redo"; public static final String MD_SERIALIZATION = "MD Serialization"; public UITestAction(String command) { putValue(ACTION_COMMAND_KEY, command); putValue(NAME, command); } public void actionPerformed(ActionEvent e) { if (e.getActionCommand() == FileOpen) UITest.fileOpen(); else if (e.getActionCommand() == FileClose) UITest.fileClose(); else if (e.getActionCommand() == UIUpdate) UITest.updateUI(); else if (e.getActionCommand() == FileUndo) UITest.fileUndo(true); else if (e.getActionCommand() == FileRedo) UITest.fileUndo(false); else if (e.getActionCommand() == Exit) { if (JOptionPane.showConfirmDialog(frame, "Do you want to exit ?", "Exit?", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION) { System.exit(0); } } else if (e.getActionCommand() == MD_SERIALIZATION) { UITest.MD_SerializationTest(); } } } static void createFrame() { Rectangle frameBounds; if (frame != null) { frameBounds = frame.getBounds(); frame.dispose(); frame = null; } else { Dimension frameSize = new Dimension(700, 600); Dimension screen = Toolkit.getDefaultToolkit().getScreenSize(); Dimension wind = frameSize; frameBounds = new Rectangle(new Point((screen.width-wind.width)/2, (screen.height-wind.height)/2), frameSize); } // frame frame = new JFrame(UITest.class.getName()); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setBounds(frameBounds); // menu JMenuBar mnbar = new JMenuBar(); JMenu mnfile = new JMenu("File"); mnfile.add(new UITestAction(UITestAction.FileOpen)); mnfile.add(new UITestAction(UITestAction.FileClose)); mnfile.addSeparator(); mnfile.add(new UITestAction(UITestAction.UIUpdate)); mnfile.addSeparator(); mnfile.add(new UITestAction(UITestAction.Exit)); mnbar.add(mnfile); JMenu mnpatch = new JMenu("Patch"); mnpatch.add(new UITestAction(UITestAction.FileUndo)); mnpatch.add(new UITestAction(UITestAction.FileRedo)); mnbar.add(mnpatch); JMenu test = new JMenu("Test"); test.add(new UITestAction(UITestAction.MD_SERIALIZATION)); mnbar.add(test); frame.setJMenuBar(mnbar); // content tabbedPane = new JTabbedPane(); frame.getContentPane().setLayout(new BorderLayout()); frame.getContentPane().add(tabbedPane, BorderLayout.CENTER); } static JFileChooser chooser; static void fileOpen() { if (chooser == null) { chooser = new JFileChooser(); chooser.setFileFilter(new FileFilter() { @Override public boolean accept(File f) { return f.isDirectory() || (f.isFile() && f.getPath().toLowerCase().endsWith(".pch")); } @Override public String getDescription() { return "NM1 Patch File (*.pch)"; } }); chooser.setMultiSelectionEnabled(true); } if (chooser.showOpenDialog(frame) != JFileChooser.APPROVE_OPTION) return; for (File file: chooser.getSelectedFiles()) { fileOpen(file); } } static void fileOpen(File file) { if (files.contains(file)) return; if (fileOpenNoList(file)) files.add(file); } public static void MD_SerializationTest() { System.out.println("Serialization Test..."); try { ByteArrayOutputStream bout = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(bout); System.out.println("writing..."); modules.writeCache(out); out.flush(); out.close(); System.out.println("ok"); byte[] data = bout.toByteArray(); System.out.println("reading"); NM1ModuleDescriptions copy = new NM1ModuleDescriptions(modules.getModuleDescriptionsClassLoader()); copy.readCache(new ObjectInputStream(new ByteArrayInputStream(data))); System.out.println("ok"); compare(modules, copy); } catch (Exception e) { e.printStackTrace(); } } private static void compare(NM1ModuleDescriptions m1, NM1ModuleDescriptions m2) { check_true(m1.getDefinedSignals()!= null && m2.getDefinedSignals()!=null, "defined signals", m1, m2); check_true(m1.getModuleCount() == m2.getModuleCount(), "module count", m1, m2); for (PModuleDescriptor ma: m1) { PModuleDescriptor mb = m2.getModuleById(ma.getComponentId()); check_true(mb != null, "module[component-id="+ma.getComponentId()+"]", ma, mb); compare(ma, mb); } } private static void compare(PModuleDescriptor ma, PModuleDescriptor mb) { compareDescriptor(ma, mb); check_true(ma.getParameterDescriptorCount()==mb.getParameterDescriptorCount(), "parameter count", ma, mb); check_true(ma.getConnectorDescriptorCount()==mb.getConnectorDescriptorCount(), "connector count", ma, mb); check_true(ma.getLightDescriptorCount()==mb.getLightDescriptorCount(), "light count", ma, mb); for (int i=ma.getParameterDescriptorCount()-1;i>=0;i--) { PParameterDescriptor pa = ma.getParameterDescriptor(i); PParameterDescriptor pb = mb.getParameterDescriptor(i); compare(pa, pb); } for (int i=ma.getConnectorDescriptorCount()-1;i>=0;i--) { PConnectorDescriptor pa = ma.getConnectorDescriptor(i); PConnectorDescriptor pb = mb.getConnectorDescriptor(i); compare(pa, pb); } for (int i=ma.getLightDescriptorCount()-1;i>=0;i--) { PLightDescriptor pa = ma.getLightDescriptor(i); PLightDescriptor pb = mb.getLightDescriptor(i); compare(pa, pb); } } private static void compare(PLightDescriptor pa, PLightDescriptor pb) { compareDescriptor(pa, pb); } private static void compare(PConnectorDescriptor pa, PConnectorDescriptor pb) { compareDescriptor(pa, pb); } private static void compare(PParameterDescriptor pa, PParameterDescriptor pb) { compareDescriptor(pa, pb); } private static void compareDescriptor(PDescriptor pa, PDescriptor pb) { check_true(pa.getComponentId().equals(pb.getComponentId()), "component-id", pa, pb); check_true(pa.getDescriptorIndex()==pb.getDescriptorIndex(), "descriptor index", pa, pb); if (!(pa instanceof PModuleDescriptor)) { check_true(pa.getParentDescriptor()!=null, "no parent", pa); check_true(pb.getParentDescriptor()!=null, "no parent", pb); } } private static void check_true(boolean t, String msg, Object ... src) { if (!t) { StringBuilder sb = new StringBuilder(); sb.append(msg); sb.append("; source: "); int cnt = 0; for (Object o: src) { sb.append(o); if (++cnt<src.length) sb.append(", "); } throw new RuntimeException(sb.toString()); } } static boolean fileOpenNoList(File file) { InputStream in = null; NMPatch patch = null; try { in = new BufferedInputStream(new FileInputStream(file)); patch = NmUtils.parsePatch(modules, in); } catch (Exception e) { e.printStackTrace(); return false; } finally { close(in); } patch.setName(NmUtils.getPatchNameFromfileName(file)); JTNMPatch patchui; try { patchui = new JTNMPatch(uicontext, patch); } catch (Exception e) { e.printStackTrace(); return false; } tabbedPane.addTab(patch.getName(), patchui); return true; } private static void syncOpenFiles() { for (File file: files) fileOpenNoList(file); } static void fileClose() { int index = tabbedPane.getSelectedIndex(); if (index<0) return; files.remove(index); tabbedPane.removeTabAt(index); } public static void fileUndo(boolean undo) { Component c = tabbedPane.getSelectedComponent(); if (c==null) return; JTNMPatch jtpc = (JTNMPatch) c; NMPatch patch = jtpc.getPatch(); UndoManager history = patch.getUndoManager(); if (undo) history.undo(); else history.redo(); } static void updateUI() { createFrame(); // create a new frame createModuleDescriptions(); createTransformations(); createUIContext(); // create ui context syncOpenFiles(); // reopen files // show frame frame.setVisible(true); } static void createTransformations() { try { createTransformationsE(); } catch (Exception e) { e.printStackTrace(); } } static void createTransformationsE() throws Exception { InputSource is = new InputSource(new FileInputStream("./nordmodular/data/module-descriptions/transformations.xml")); PTTransformations t = PTTransformationsBuillder.build(is, modules); modules.setTransformations(t); } private static void createModuleDescriptions() { if (modules != null) return; // create them only once String modulesXml = "/module-descriptions/modules.xml"; URL moduleURL = UITest.class.getResource(modulesXml); if (moduleURL == null) { System.err.println("Resource not found: "+modulesXml); System.exit(1); } InputStream in = null; try { in = new BufferedInputStream( new FileInputStream(new File(moduleURL.toURI())) ); modules = NM1ModuleDescriptions.parse(RelativeClassLoader.fromPath(UITest.class.getClassLoader(), moduleURL), in); } catch (Exception e) { e.printStackTrace(); System.exit(1); } finally { close(in); } } static void createUIContext() { String classicThemeXml = "/classic-theme/classic-theme.xml"; URL classicThemeURL = UITest.class.getResource(classicThemeXml); ClassLoader relLoader; try { relLoader = RelativeClassLoader.fromPath(UITest.class.getClassLoader(), classicThemeURL); } catch (URISyntaxException e) { throw new RuntimeException(e); } uicontext = new JTNM1Context(null); DefaultStorageContext dsc = new NMStorageContext(uicontext, relLoader); uicontext.setStorageContext(dsc); InputStream in = null; try { in = new BufferedInputStream(classicThemeURL.openStream()); dsc.parseStore(new InputSource(in), relLoader); } catch (Exception e) { e.printStackTrace(); System.exit(1); } finally { close(in); } } // helper static void close(InputStream in) { if (in == null) return; try { in.close(); } catch (IOException e) { // ignore } } }