diff --git a/build_src.xml b/build_src.xml
new file mode 100644
index 0000000..b5a4d2d
--- /dev/null
+++ b/build_src.xml
@@ -0,0 +1,101 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/eu/engys/application/AbstractApplication.java b/src/eu/engys/application/AbstractApplication.java
new file mode 100644
index 0000000..b8c087f
--- /dev/null
+++ b/src/eu/engys/application/AbstractApplication.java
@@ -0,0 +1,252 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.application;
+
+import static eu.engys.launcher.StartUpMonitor.close;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.GraphicsDevice;
+import java.awt.Image;
+import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.util.Arrays;
+
+import javax.swing.AbstractAction;
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import javax.swing.JFrame;
+import javax.swing.JMenuItem;
+import javax.swing.JPanel;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import eu.engys.core.Arguments;
+import eu.engys.core.OpenFOAMEnvironment;
+import eu.engys.core.controller.Controller;
+import eu.engys.core.presentation.ActionContainer;
+import eu.engys.core.presentation.ActionManager;
+import eu.engys.core.project.Model;
+import eu.engys.gui.AboutWindow;
+import eu.engys.gui.GlassPane;
+import eu.engys.gui.PreferencesDialog;
+import eu.engys.gui.events.EventManager;
+import eu.engys.gui.view.View;
+import eu.engys.gui.view3D.View3DEventListener;
+import eu.engys.util.ui.ResourcesUtil;
+import eu.engys.util.ui.UiUtil;
+
+public abstract class AbstractApplication implements Application, ActionContainer {
+
+ private static final Logger logger = LoggerFactory.getLogger(AbstractApplication.class);
+
+ protected JFrame frame;
+ public View view;
+ protected Model model;
+ public Controller controller;
+ protected View3DEventListener view3dListener;
+
+ public AbstractApplication(Model model, View view, Controller controller) {
+ this.model = model;
+ this.view = view;
+ this.controller = controller;
+ }
+
+ @Override
+ public JFrame getFrame() {
+ return frame;
+ }
+
+ @Override
+ public boolean isDemo() {
+ return false;
+ }
+
+ @Override
+ public void checkVersion() {
+ }
+
+ @Override
+ public void run() {
+ initFrame();
+ frame.setVisible(true);
+ trySettingOpenFoamFolder();
+
+ if (Arguments.stlFiles != null) {
+ if (Arguments.baseDir != null) {
+ ActionManager.getInstance().invoke("application.open");
+ } else {
+ ActionManager.getInstance().invoke("application.create");
+ }
+ } else {
+ if (Arguments.baseDir != null) {
+ controller.openCase(Arguments.baseDir);
+ } else {
+ view.showStartupDialog(this);
+ }
+ }
+ close();
+ }
+
+ protected void trySettingOpenFoamFolder() {
+ OpenFOAMEnvironment.trySettingOpenFoamFolder(frame);
+ }
+
+ @Override
+ public void initFrame() {
+ view.layoutComponents();
+ frame = new JFrame(getTitle()) {
+ @Override
+ public void dispose() {
+ EventManager.unregisterAllEventSubscriptions();
+ super.dispose();
+ }
+
+ /**
+ * This method fixes the Synthetica laf bug that causes incorrect
+ * fullscreen window size on secondary monitor.
+ */
+ @Override
+ public void setMaximizedBounds(Rectangle bounds) {
+ GraphicsDevice currentFrame = getGraphicsConfiguration().getDevice();
+ if (UiUtil.isSecondaryScreen(currentFrame) && getExtendedState() == JFrame.NORMAL) {
+ super.setMaximizedBounds(UiUtil.getCurrentScreenSize(frame));
+ } else {
+ super.setMaximizedBounds(bounds);
+ }
+ }
+ };
+ view.setProgressMonitorParent(frame);
+
+ Dimension preferredDimension = UiUtil.getPreferredScreenSize();
+ logger.info("Set dimendions to {}", preferredDimension);
+ frame.setSize(preferredDimension);
+ frame.setLocationRelativeTo(null);
+
+ UiUtil.center(frame);
+
+ frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+
+ frame.setIconImages(Arrays.asList(new Image[] { ((ImageIcon) getSmallIcon()).getImage(), ((ImageIcon) getBigIcon()).getImage() }));
+
+ frame.addWindowListener(new WindowAdapter() {
+ @Override
+ public void windowClosing(WindowEvent e) {
+ ActionManager.getInstance().invoke("application.exit");
+ }
+ });
+ frame.setName("MainFrame");
+ frame.getRootPane().updateUI();
+ frame.setJMenuBar(view.getMenuBar());
+
+ frame.getContentPane().setLayout(new BorderLayout());
+ frame.getContentPane().add(view, BorderLayout.CENTER);
+ frame.getContentPane().add(view.getStatusBar(), BorderLayout.SOUTH);
+
+ GlassPane glassPane = new GlassPane();
+ frame.setGlassPane(glassPane);
+ glassPane.setVisible(false);
+
+
+ customizeGUIFrame(view);
+ }
+
+ public View getView() {
+ return view;
+ }
+
+ public Model getModel() {
+ return model;
+ }
+
+ public abstract String getTitle();
+
+ protected abstract void customizeGUIFrame(View view);
+
+ protected void addPreferencesItem(final View view) {
+ JMenuItem preferencesItem = new JMenuItem(new AbstractAction("Preferences", PREFERENCES_ICON) {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ new PreferencesDialog(isOS(), hasParaview(), hasFieldView(), hasEnsight(), hasSolverPreferences(), model.getDefaults().getDictDataFolder()).show();
+ }
+ });
+ preferencesItem.setName("Application Preferences");
+ view.getMenuBar().getEditMenu().add(preferencesItem);
+ }
+
+ protected abstract boolean hasParaview();
+
+ protected abstract boolean hasFieldView();
+
+ protected abstract boolean hasEnsight();
+
+ protected boolean hasSolverPreferences() {
+ return true;
+ }
+
+ protected boolean isOS() {
+ return false;
+ }
+
+ protected void addHelpItem(final View view) {
+ view.getMenuBar().getHelpMenu().add(new AbstractAction("About", INFO_ICON) {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ new AboutWindow(getMediumIcon(), getBannerIcon());
+ }
+ });
+ }
+
+
+ @Override
+ public JPanel createAdPanel() {
+ return new JPanel();
+ }
+
+ @Override
+ public JPanel createVersionPanel() {
+ return new JPanel();
+ }
+
+ /**
+ * RESOURCES
+ */
+
+ public static final Icon PREFERENCES_ICON = ResourcesUtil.getIcon("preferences.icon");
+ public static final Icon LICENSE_ICON = ResourcesUtil.getIcon("license.icon");
+ public static final Icon INFO_ICON = ResourcesUtil.getIcon("info.icon");
+ public static final Icon PDF_ICON = ResourcesUtil.getIcon("file.pdf");
+ public static final Icon FOLDER_ICON = ResourcesUtil.getIcon("application.open.icon");
+
+ public static final Icon SMALL_LOGO = ResourcesUtil.getIcon("engys.logo");
+ public static final Icon BIG_LOGO = ResourcesUtil.getIcon("engys.logo.big");
+ public static final Icon MEDIUM_LOGO = ResourcesUtil.getIcon("engys.logo.medium");
+ public static final Icon FULL_LOGO = ResourcesUtil.getIcon("engys.logo.full");
+}
diff --git a/src/eu/engys/application/AdPanel.java b/src/eu/engys/application/AdPanel.java
new file mode 100644
index 0000000..ecba263
--- /dev/null
+++ b/src/eu/engys/application/AdPanel.java
@@ -0,0 +1,133 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.application;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.FlowLayout;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import javax.swing.AbstractAction;
+import javax.swing.BorderFactory;
+import javax.swing.Icon;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+
+import eu.engys.util.Symbols;
+import eu.engys.util.Util;
+import eu.engys.util.ui.ResourcesUtil;
+import eu.engys.util.ui.UiUtil;
+
+public class AdPanel extends JPanel {
+
+ private static final String ENGYS = "ENGYS" + Symbols.REGISTERED;
+
+ public static final Icon FAQ = ResourcesUtil.getIcon("helyxos.faq");
+ public static final Icon ENGYS_PRODUCTS = ResourcesUtil.getIcon("helyxos.products");
+ public static final Icon HELYX_BOX = ResourcesUtil.getIcon("helyxos.helyx.box");
+ public static final Icon HELYX_OS_BOX = ResourcesUtil.getIcon("helyxos.helyxos.box");
+ public static final Icon ELEMENTS_BOX = ResourcesUtil.getIcon("helyxos.elements.box");
+ public static final Icon FULL_LOGO = ResourcesUtil.getIcon("engys.logo.full");
+
+ public AdPanel() {
+ super(new BorderLayout());
+ layoutComponents();
+
+ setBorder(BorderFactory.createTitledBorder(ENGYS + " products"));
+ }
+
+ private void layoutComponents() {
+ createCentralPanel();
+ createSouthPanel();
+ }
+
+ private void createCentralPanel() {
+ JPanel productsPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
+ productsPanel.add(new JLabel(HELYX_BOX));
+ productsPanel.add(new JLabel(HELYX_OS_BOX));
+ productsPanel.add(new JLabel(ELEMENTS_BOX));
+
+ add(productsPanel, BorderLayout.CENTER);
+ }
+
+ private void createSouthPanel() {
+ JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
+ buttonsPanel.add(createShowImageButton("FAQ", FAQ));
+ buttonsPanel.add(createShowImageButton("Products Comparison", ENGYS_PRODUCTS));
+ buttonsPanel.add(createOpenEngysSiteButton());
+
+ JPanel southPanel = new JPanel(new GridLayout(2, 1));
+ southPanel.add(new JLabel(FULL_LOGO, JLabel.CENTER));
+ southPanel.add(buttonsPanel);
+
+ add(southPanel, BorderLayout.SOUTH);
+
+ }
+
+ private JButton createShowImageButton(final String title, final Icon image) {
+ return new JButton(new AbstractAction(title) {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ JDialog dialog = new JDialog(UiUtil.getActiveWindow(), title);
+ dialog.setModal(true);
+ dialog.setSize(1000, 600);
+ dialog.setLocationRelativeTo(null);
+ dialog.getContentPane().setLayout(new BorderLayout());
+
+ JLabel label = new JLabel(image);
+ label.setBackground(Color.WHITE);
+
+ JScrollPane jsp = new JScrollPane(label);
+ jsp.setOpaque(false);
+ jsp.getViewport().setOpaque(false);
+ jsp.getVerticalScrollBar().setUnitIncrement(20);
+ dialog.getContentPane().add(jsp, BorderLayout.CENTER);
+
+ dialog.setVisible(true);
+ }
+ });
+ }
+
+ private JButton createOpenEngysSiteButton() {
+ return new JButton(new AbstractAction(ENGYS + " Website") {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ try {
+ Util.openWebpage(new URL("http://www.engys.com"));
+ } catch (MalformedURLException e1) {
+ e1.printStackTrace();
+ }
+ }
+ });
+ }
+}
diff --git a/src/eu/engys/application/Application.java b/src/eu/engys/application/Application.java
new file mode 100644
index 0000000..41278b3
--- /dev/null
+++ b/src/eu/engys/application/Application.java
@@ -0,0 +1,53 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.application;
+
+import javax.swing.Icon;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+
+public interface Application extends Runnable {
+
+ public JFrame getFrame();
+ public void initFrame();
+
+ public abstract String getTitle();
+
+ public abstract Icon getSmallIcon();
+ public abstract Icon getMediumIcon();
+ public abstract Icon getBigIcon();
+ public abstract Icon getFullLogo();
+
+ public abstract Icon getBannerIcon();
+ public abstract Icon getBgIcon();
+
+ public abstract JPanel createAdPanel();
+ public abstract JPanel createVersionPanel();
+
+ public void checkVersion();
+
+}
diff --git a/src/eu/engys/application/ApplicationEventListener.java b/src/eu/engys/application/ApplicationEventListener.java
new file mode 100644
index 0000000..21dec04
--- /dev/null
+++ b/src/eu/engys/application/ApplicationEventListener.java
@@ -0,0 +1,51 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.application;
+
+import java.io.File;
+
+import eu.engys.core.project.CaseParameters;
+import eu.engys.gui.events.EventManager.GenericEventListener;
+
+public interface ApplicationEventListener extends GenericEventListener {
+
+ void createCase(CaseParameters params);
+
+ void openCase(File file);
+
+ void saveCase(File file);
+
+ void setupMesh();
+
+ void runMesh();
+
+ void setupCase();
+
+ void runCase();
+
+
+}
diff --git a/src/eu/engys/application/Batch.java b/src/eu/engys/application/Batch.java
new file mode 100644
index 0000000..66e8147
--- /dev/null
+++ b/src/eu/engys/application/Batch.java
@@ -0,0 +1,35 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.application;
+
+
+public interface Batch extends Runnable {
+
+ public abstract String getTitle();
+
+}
+
diff --git a/src/eu/engys/application/HELYXOS.java b/src/eu/engys/application/HELYXOS.java
new file mode 100644
index 0000000..3e70ead
--- /dev/null
+++ b/src/eu/engys/application/HELYXOS.java
@@ -0,0 +1,217 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.application;
+
+import java.awt.Color;
+import java.awt.FlowLayout;
+import java.awt.Font;
+import java.awt.event.ActionEvent;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import javax.swing.AbstractAction;
+import javax.swing.BorderFactory;
+import javax.swing.Icon;
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.inject.Inject;
+
+import eu.engys.core.OpenFOAMEnvironment;
+import eu.engys.core.controller.Controller;
+import eu.engys.core.presentation.Action;
+import eu.engys.core.presentation.ActionManager;
+import eu.engys.core.project.Model;
+import eu.engys.core.project.zero.patches.BoundaryType;
+import eu.engys.gui.view.View;
+import eu.engys.util.ApplicationInfo;
+import eu.engys.util.Symbols;
+import eu.engys.util.Util;
+import eu.engys.util.VersionChecker;
+import eu.engys.util.VersionChecker.VersionType;
+import eu.engys.util.ui.ResourcesUtil;
+
+public class HELYXOS extends AbstractApplication {
+
+ private static final Logger logger = LoggerFactory.getLogger(HELYXOS.class);
+ private static final String DISCLAIMER = "This offering is not approved or endorsed by OpenCFD" + Symbols.COPYRIGHT + " Limited, the producer of the OPENFOAM" + Symbols.COPYRIGHT + " software and owner of the OPENFOAM" + Symbols.COPYRIGHT + " and OpenCFD" + Symbols.COPYRIGHT + " trade marks.";
+
+ private JLabel versionLabel;
+ private JButton versionButton;
+
+ @Inject
+ public HELYXOS(Model model, View view, Controller controller) {
+ super(model, view, controller);
+ ActionManager.getInstance().parseActions(this);
+
+ BoundaryType.registerBoundaryType(BoundaryType.PATCH);
+ BoundaryType.registerBoundaryType(BoundaryType.WALL);
+ BoundaryType.registerBoundaryType(BoundaryType.EMPTY);
+ BoundaryType.registerBoundaryType(BoundaryType.CYCLIC_AMI);
+ BoundaryType.registerBoundaryType(BoundaryType.CYCLIC);
+ BoundaryType.registerBoundaryType(BoundaryType.SYMMETRY_PLANE);
+ BoundaryType.registerBoundaryType(BoundaryType.SYMMETRY);
+ BoundaryType.registerBoundaryType(BoundaryType.WEDGE);
+ }
+
+ @Override
+ public String getTitle() {
+ return ApplicationInfo.getName() + " - powered by " + ApplicationInfo.getVendor() + Symbols.REGISTERED;
+ }
+
+ @Override
+ protected void customizeGUIFrame(final View view) {
+ addPreferencesItem(view);
+ addHelpItem(view);
+ addSupportItem(view);
+ }
+
+ @Override
+ protected void trySettingOpenFoamFolder() {
+ OpenFOAMEnvironment.trySettingOpenFoamFolderOS(frame);
+ }
+
+ private void addSupportItem(final View view) {
+ view.getMenuBar().getHelpMenu().add(new AbstractAction("Support", INFO_ICON) {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ showSupportWindow();
+ }
+ });
+ }
+
+ @Action(key = "application.support.window")
+ public void showSupportWindow() {
+ new SupportWindow(getMediumIcon(), getBannerIcon(), DISCLAIMER);
+ }
+
+ @Override
+ public void checkVersion() {
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ VersionType versionType = VersionChecker.isNewVersionAvailable();
+ if (versionType.isUpdated()) {
+ versionLabel.setText("Your version is up to date!");
+ versionLabel.setForeground(Color.GREEN.darker());
+ versionButton.setVisible(false);
+ } else if (versionType.isOld()) {
+ versionLabel.setText("Version " + VersionChecker.getOnlineVersion() + " is available for download!");
+ versionLabel.setForeground(Color.RED);
+ versionButton.setVisible(true);
+ } else if (versionType.isNotAvailable()) {
+ versionLabel.setText("Version not available!");
+ versionButton.setVisible(false);
+ }
+ }
+ }).start();
+ }
+
+ @Override
+ public JPanel createAdPanel() {
+ return new AdPanel();
+ }
+
+ @Override
+ public JPanel createVersionPanel() {
+ JPanel panel = new JPanel(new FlowLayout());
+ panel.add(versionLabel = new JLabel("Checking for updates..."));
+ versionLabel.setFont(new Font(versionLabel.getFont().getFontName(), Font.BOLD, versionLabel.getFont().getSize()));
+
+ panel.add(versionButton = new JButton(new AbstractAction("Download") {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ String downloadPage = ApplicationInfo.getSite() + "/files";
+ try {
+ Util.openWebpage(new URL(downloadPage));
+ } catch (MalformedURLException e1) {
+ logger.error("Cannot open " + downloadPage);
+ }
+ }
+ }));
+ versionButton.setVisible(false);
+ panel.setBorder(BorderFactory.createTitledBorder("Version"));
+ return panel;
+ }
+
+ @Override
+ protected boolean isOS() {
+ return true;
+ }
+
+ @Override
+ protected boolean hasParaview() {
+ return true;
+ }
+
+ @Override
+ protected boolean hasFieldView() {
+ return false;
+ }
+
+ @Override
+ protected boolean hasEnsight() {
+ return false;
+ }
+
+ @Override
+ public Icon getSmallIcon() {
+ return SMALL_LOGO;
+ }
+
+ @Override
+ public Icon getBigIcon() {
+ return BIG_LOGO;
+ }
+
+ @Override
+ public Icon getBannerIcon() {
+ return BANNER;
+ }
+
+ @Override
+ public Icon getBgIcon() {
+ return STARTUP_BACKGROUND;
+ }
+
+ @Override
+ public Icon getMediumIcon() {
+ return MEDIUM_LOGO;
+ }
+
+ @Override
+ public Icon getFullLogo() {
+ return null;
+ }
+
+ public static final Icon BANNER = ResourcesUtil.getIcon("helyxos.banner");
+ public static final Icon STARTUP_BACKGROUND = ResourcesUtil.getIcon("helyxos.startup");
+
+}
diff --git a/src/eu/engys/application/SupportWindow.java b/src/eu/engys/application/SupportWindow.java
new file mode 100644
index 0000000..946395d
--- /dev/null
+++ b/src/eu/engys/application/SupportWindow.java
@@ -0,0 +1,198 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.application;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.FlowLayout;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.RenderingHints;
+import java.awt.event.ActionEvent;
+
+import javax.swing.AbstractAction;
+import javax.swing.BorderFactory;
+import javax.swing.Icon;
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextPane;
+import javax.swing.JWindow;
+import javax.swing.text.SimpleAttributeSet;
+import javax.swing.text.StyleConstants;
+import javax.swing.text.StyledDocument;
+
+import eu.engys.util.ApplicationInfo;
+import eu.engys.util.Symbols;
+import eu.engys.util.ui.UiUtil;
+
+public class SupportWindow {
+
+ private static final String MESSAGE = "If you require technical assistance with HELYX-OS and OPENFOAM" + Symbols.COPYRIGHT + ", ENGYS offers a dedicated user support package. For more information please contact ";
+ private static final String SUBJECT = "HELYX-OS%20Info%20Request";
+ private final String disclaimer;
+
+ private JWindow window;
+ private final Icon vendorIcon;
+ private final Icon applicationIcon;
+
+ public SupportWindow(Icon vendorIcon, Icon applicationIcon, String disclaimer) {
+ this.vendorIcon = vendorIcon;
+ this.applicationIcon = applicationIcon;
+ this.disclaimer = disclaimer;
+ createWindow();
+ }
+
+ private void createWindow() {
+ window = new JWindow(UiUtil.getActiveWindow());
+ window.getContentPane().setLayout(new BorderLayout());
+ window.getContentPane().add(createMainPanel(), BorderLayout.CENTER);
+ window.setSize(420, 320);
+ window.setLocationRelativeTo(null);
+ window.setVisible(true);
+ }
+
+ private JPanel createMainPanel() {
+ JPanel mainPanel = new JPanel(new BorderLayout());
+ mainPanel.setBackground(Color.WHITE);
+ mainPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
+ mainPanel.add(createNorthPanel(), BorderLayout.NORTH);
+ mainPanel.add(createCenterPanel(), BorderLayout.CENTER);
+ mainPanel.add(createCloseButtonPanel(), BorderLayout.SOUTH);
+ return mainPanel;
+ }
+
+ private JPanel createNorthPanel() {
+ JPanel panel = new JPanel(new BorderLayout());
+ panel.setBackground(Color.WHITE);
+ panel.add(getImage(vendorIcon), BorderLayout.WEST);
+ panel.add(getImage(applicationIcon), BorderLayout.CENTER);
+ panel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
+ return panel;
+ }
+
+ private JLabel getImage(Icon imageIcon) {
+ JLabel label = new JLabel(imageIcon);
+ label.setOpaque(true);
+ label.setBackground(Color.WHITE);
+ return label;
+ }
+
+ private JPanel createCloseButtonPanel() {
+ JPanel panel = new JPanel(new FlowLayout());
+ panel.setBackground(Color.WHITE);
+ panel.add(new JButton(new AbstractAction("Close") {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ window.dispose();
+ }
+ }));
+ return panel;
+ }
+
+ private JPanel createCenterPanel() {
+ JLabel vers = center("" + ApplicationInfo.getVersion() + "", 20f, Color.BLACK);
+ JLabel copy = left("" + ApplicationInfo.getCopyright() + "", 10f, Color.BLACK);
+
+ JPanel infoPanel = new JPanel(new GridBagLayout());
+ infoPanel.setBackground(Color.WHITE);
+ infoPanel.add(vers, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(30, 10, 0, 10), 0, 0));
+ infoPanel.add(copy, new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 10, 30, 10), 0, 0));
+
+ JTextPane textPane = createTextPane();
+ JScrollPane scrollPane = new JScrollPane(textPane);
+
+ JPanel textPanePanel = new JPanel(new BorderLayout());
+ textPanePanel.setBackground(Color.WHITE);
+ textPanePanel.add(scrollPane, BorderLayout.CENTER);
+ textPanePanel.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10));
+
+ JPanel mainPanel = new JPanel(new BorderLayout());
+ mainPanel.add(infoPanel, BorderLayout.NORTH);
+ mainPanel.add(textPanePanel, BorderLayout.CENTER);
+ return mainPanel;
+ }
+
+ private JTextPane createTextPane() {
+ JTextPane textPane = new JTextPane();
+ textPane.setText(MESSAGE + ApplicationInfo.getMail() + ".\n\n" + disclaimer);
+ StyledDocument doc = textPane.getStyledDocument();
+ SimpleAttributeSet center = new SimpleAttributeSet();
+ StyleConstants.setAlignment(center, StyleConstants.ALIGN_LEFT);
+ doc.setParagraphAttributes(0, doc.getLength(), center, false);
+ textPane.setCaretPosition(0);
+ return textPane;
+ }
+
+ private JButton createMailButton() {
+ final JButton button = new JButton(new AbstractAction(ApplicationInfo.getMail()) {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ // MailManagerSupport.mail(TO, SUBJECT);
+ }
+ });
+ button.setForeground(Color.BLUE);
+ return button;
+ }
+
+ private JLabel center(String text, float size, Color color) {
+ JLabel label = new JLabel(text) {
+ @Override
+ public void paintComponent(Graphics g) {
+ Graphics2D graphics2d = (Graphics2D) g;
+ graphics2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ super.paintComponent(g);
+ }
+ };
+ label.setAlignmentX(JLabel.CENTER_ALIGNMENT);
+ label.setHorizontalAlignment(JLabel.CENTER);
+ label.setFont(label.getFont().deriveFont(size));
+ label.setForeground(color);
+ return label;
+ }
+
+ private JLabel left(String text, float size, Color color) {
+ JLabel label = new JLabel(text) {
+ @Override
+ public void paintComponent(Graphics g) {
+ Graphics2D graphics2d = (Graphics2D) g;
+ graphics2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ super.paintComponent(g);
+ }
+ };
+ label.setAlignmentX(JLabel.LEFT_ALIGNMENT);
+ label.setHorizontalAlignment(JLabel.LEFT);
+ label.setFont(label.getFont().deriveFont(size));
+ label.setForeground(color);
+ return label;
+ }
+}
diff --git a/src/eu/engys/application/modules/HELYXOSModule.java b/src/eu/engys/application/modules/HELYXOSModule.java
new file mode 100644
index 0000000..68a9b81
--- /dev/null
+++ b/src/eu/engys/application/modules/HELYXOSModule.java
@@ -0,0 +1,285 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.application.modules;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Singleton;
+import com.google.inject.multibindings.Multibinder;
+import com.google.inject.name.Names;
+
+import eu.engys.application.Application;
+import eu.engys.application.HELYXOS;
+import eu.engys.core.Arguments;
+import eu.engys.core.controller.Controller;
+import eu.engys.core.controller.HelyxOSController;
+import eu.engys.core.controller.ScriptFactory;
+import eu.engys.core.modules.ApplicationModule;
+import eu.engys.core.modules.boundaryconditions.BoundaryTypePanel;
+import eu.engys.core.project.DefaultProjectReader;
+import eu.engys.core.project.DefaultProjectWriter;
+import eu.engys.core.project.Model;
+import eu.engys.core.project.NullProjectReader;
+import eu.engys.core.project.NullProjectWriter;
+import eu.engys.core.project.ProjectReader;
+import eu.engys.core.project.ProjectWriter;
+import eu.engys.core.project.defaults.Defaults;
+import eu.engys.core.project.defaults.DictDataFolder;
+import eu.engys.core.project.defaults.JarDictDataFolder;
+import eu.engys.core.project.geometry.factory.DefaultGeometryFactory;
+import eu.engys.core.project.geometry.factory.GeometryFactory;
+import eu.engys.core.project.materials.MaterialsReader;
+import eu.engys.core.project.materials.MaterialsWriter;
+import eu.engys.core.project.state.Table15;
+import eu.engys.core.project.system.fieldmanipulationfunctionobjects.FieldManipulationFunctionObjectType;
+import eu.engys.core.project.system.monitoringfunctionobjects.MonitoringFunctionObjectType;
+import eu.engys.core.project.zero.cellzones.CellZoneType;
+import eu.engys.core.project.zero.cellzones.CellZonesBuilder;
+import eu.engys.core.project.zero.fields.Initialisations;
+import eu.engys.gui.Actions;
+import eu.engys.gui.GUIPanel;
+import eu.engys.gui.StandardScriptFactory;
+import eu.engys.gui.casesetup.CaseSetup;
+import eu.engys.gui.casesetup.CaseSetup3DElement;
+import eu.engys.gui.casesetup.CaseSetupElement;
+import eu.engys.gui.casesetup.RuntimeControlsPanel;
+import eu.engys.gui.casesetup.actions.StandardCaseSetupActions;
+import eu.engys.gui.casesetup.boundaryconditions.BoundaryConditionsPanel;
+import eu.engys.gui.casesetup.boundaryconditions.panels.CyclicSettingsPanel;
+import eu.engys.gui.casesetup.boundaryconditions.panels.StandardCyclicAMISettingsPanel;
+import eu.engys.gui.casesetup.boundaryconditions.panels.patch.PatchSettingsPanel;
+import eu.engys.gui.casesetup.boundaryconditions.panels.wall.StandardWallSettingsPanel;
+import eu.engys.gui.casesetup.cellzones.CellZonesPanel;
+import eu.engys.gui.casesetup.cellzones.StandardCellZonesBuilder;
+import eu.engys.gui.casesetup.cellzones.mrf.StandardMRF;
+import eu.engys.gui.casesetup.cellzones.porous.StandardPorous;
+import eu.engys.gui.casesetup.cellzones.thermal.StandardThermal;
+import eu.engys.gui.casesetup.fields.StandardFieldsInitialisationPanel;
+import eu.engys.gui.casesetup.fields.StandardInitialisations;
+import eu.engys.gui.casesetup.materials.CompressibleMaterialsPanel;
+import eu.engys.gui.casesetup.materials.IncompressibleMaterialsPanel;
+import eu.engys.gui.casesetup.materials.StandardCompressibleMaterialsPanel;
+import eu.engys.gui.casesetup.materials.StandardIncompressibleMaterialsPanel;
+import eu.engys.gui.casesetup.materials.StandardMaterialsReader;
+import eu.engys.gui.casesetup.materials.StandardMaterialsWriter;
+import eu.engys.gui.casesetup.materials.panels.MaterialsDatabasePanel;
+import eu.engys.gui.casesetup.materials.panels.MaterialsPanel;
+import eu.engys.gui.casesetup.run.StandardTable15;
+import eu.engys.gui.casesetup.schemes.NumericalSchemesPanel;
+import eu.engys.gui.casesetup.solution.StandardSolutionModellingPanel;
+import eu.engys.gui.casesetup.solver.SolverSettingsPanel;
+import eu.engys.gui.custom.CustomNodePanel;
+import eu.engys.gui.mesh.Mesh;
+import eu.engys.gui.mesh.Mesh3DElement;
+import eu.engys.gui.mesh.MeshElement;
+import eu.engys.gui.mesh.actions.StandardMeshActions;
+import eu.engys.gui.mesh.panels.DefaultBoundaryMeshPanel;
+import eu.engys.gui.mesh.panels.DefaultMeshAdvancedOptionsPanel;
+import eu.engys.gui.mesh.panels.MaterialPointsPanel;
+import eu.engys.gui.mesh.panels.SolverBoundaryMeshPanel;
+import eu.engys.gui.mesh.panels.StandardBaseMeshPanel;
+import eu.engys.gui.mesh.panels.StandardFeatureLinesPanel;
+import eu.engys.gui.mesh.panels.StandardGeometryPanel;
+import eu.engys.gui.mesh.panels.StandardMeshAdvancedOptionsPanel;
+import eu.engys.gui.solver.DefaultRunOptionsPanel;
+import eu.engys.gui.solver.Solver;
+import eu.engys.gui.solver.Solver3DElement;
+import eu.engys.gui.solver.SolverElement;
+import eu.engys.gui.solver.SolverRuntimeControlsPanel;
+import eu.engys.gui.solver.actions.StandardSolverActions;
+import eu.engys.gui.solver.postprocessing.panels.residuals.ResidualsPanel;
+import eu.engys.gui.view.View;
+import eu.engys.gui.view.View3DElement;
+import eu.engys.gui.view.ViewElement;
+import eu.engys.gui.view3D.CanvasPanel;
+import eu.engys.gui.view3D.Controller3D;
+import eu.engys.gui.view3D.Geometry3DController;
+import eu.engys.gui.view3D.Mesh3DController;
+import eu.engys.gui.view3D.fallback.FallbackGeometry3DController;
+import eu.engys.gui.view3D.fallback.FallbackMesh3DController;
+import eu.engys.gui.view3D.fallback.FallbackView3D;
+import eu.engys.gui.view3D.widget.Widget;
+import eu.engys.launcher.ApplicationLauncher;
+import eu.engys.launcher.HELYXOSLauncher;
+import eu.engys.standardVOF.StandardVOFModule;
+import eu.engys.util.VTKSettings;
+import eu.engys.util.plaf.HelyxOSLookAndFeel;
+import eu.engys.util.plaf.ILookAndFeel;
+import eu.engys.util.progress.ProgressMonitor;
+import eu.engys.util.progress.ProgressMonitorImpl;
+import eu.engys.vtk.VTKEmptyView3D;
+import eu.engys.vtk.VTKGeometry3DController;
+import eu.engys.vtk.VTKMesh3DController;
+import eu.engys.vtk.VTKView3D;
+import eu.engys.vtk.WidgetPanel;
+
+public class HELYXOSModule extends AbstractModule {
+
+ @Override
+ protected void configure() {
+ configureApp();
+ configureMVC();
+ configureModules();
+ configure3D();
+ configurePanels();
+ configureBoundaryConditions();
+ configureCellZones();
+ configureFunctionObjects();
+ }
+
+ protected void configureApp() {
+ bind(ILookAndFeel.class).to(HelyxOSLookAndFeel.class).in(Singleton.class);
+ bind(ApplicationLauncher.class).to(HELYXOSLauncher.class).in(Singleton.class);
+ bind(String.class).annotatedWith(Names.named("Application")).toInstance("HELYX-OS");
+ bind(Application.class).to(HELYXOS.class).in(Singleton.class);
+ }
+
+ private void configureMVC() {
+ bind(DictDataFolder.class).to(JarDictDataFolder.class).in(Singleton.class);
+ bind(Defaults.class).in(Singleton.class);
+ bind(Model.class).in(Singleton.class);
+ bind(View.class).in(Singleton.class);
+ bind(Controller.class).to(HelyxOSController.class).in(Singleton.class);
+ bind(ProgressMonitor.class).to(ProgressMonitorImpl.class).in(Singleton.class);
+
+ bind(Initialisations.class).to(StandardInitialisations.class).in(Singleton.class);
+
+ bind(ProjectWriter.class).to(DefaultProjectWriter.class);
+ bind(ProjectReader.class).to(DefaultProjectReader.class);
+ bind(ProjectWriter.class).annotatedWith(CaseSetup.class).to(NullProjectWriter.class);
+ bind(ProjectReader.class).annotatedWith(CaseSetup.class).to(NullProjectReader.class);
+
+ bind(CellZonesBuilder.class).to(StandardCellZonesBuilder.class);
+
+ bind(MaterialsReader.class).to(StandardMaterialsReader.class);
+ bind(MaterialsWriter.class).to(StandardMaterialsWriter.class);
+ bind(CompressibleMaterialsPanel.class).to(StandardCompressibleMaterialsPanel.class);
+
+ bind(Table15.class).to(StandardTable15.class).in(Singleton.class);
+ bind(ScriptFactory.class).to(StandardScriptFactory.class).in(Singleton.class);
+ }
+
+ private void configureModules() {
+ Multibinder applicationModules = Multibinder.newSetBinder(binder(), ApplicationModule.class);
+ applicationModules.addBinding().to(StandardVOFModule.class).in(Singleton.class);
+ }
+
+ protected void configure3D() {
+ bind(WidgetPanel.class).in(Singleton.class);
+ if (!VTKSettings.librariesAreLoaded()) {
+ VTKSettings.LoadAllNativeLibraries();
+ }
+ if (VTKSettings.librariesAreLoaded()) {
+ if (Arguments.no3D) {
+ bind(CanvasPanel.class).to(VTKEmptyView3D.class).in(Singleton.class);
+ } else {
+ bind(CanvasPanel.class).to(VTKView3D.class).in(Singleton.class);
+ }
+ bind(Geometry3DController.class).to(VTKGeometry3DController.class).in(Singleton.class);
+ bind(Mesh3DController.class).to(VTKMesh3DController.class).in(Singleton.class);
+ } else {
+ bind(CanvasPanel.class).to(FallbackView3D.class).in(Singleton.class);
+ bind(Geometry3DController.class).to(FallbackGeometry3DController.class).in(Singleton.class);
+ bind(Mesh3DController.class).to(FallbackMesh3DController.class).in(Singleton.class);
+ }
+
+ Multibinder controllers = Multibinder.newSetBinder(binder(), Controller3D.class);
+ controllers.addBinding().to(Geometry3DController.class).in(Singleton.class);
+ controllers.addBinding().to(Mesh3DController.class).in(Singleton.class);
+
+ Multibinder.newSetBinder(binder(), Widget.class);
+ }
+
+ private void configurePanels() {
+ bind(String.class).annotatedWith(Mesh.class).toInstance("Mesh");
+ bind(String.class).annotatedWith(CaseSetup.class).toInstance("Case Setup");
+ bind(String.class).annotatedWith(Solver.class).toInstance("Solver");
+
+ bind(View3DElement.class).annotatedWith(Mesh.class).to(Mesh3DElement.class);
+ bind(View3DElement.class).annotatedWith(CaseSetup.class).to(CaseSetup3DElement.class);
+ bind(View3DElement.class).annotatedWith(Solver.class).to(Solver3DElement.class);
+
+ bind(Actions.class).annotatedWith(Mesh.class).to(StandardMeshActions.class).in(Singleton.class);
+ bind(Actions.class).annotatedWith(CaseSetup.class).to(StandardCaseSetupActions.class).in(Singleton.class);
+ bind(Actions.class).annotatedWith(Solver.class).to(StandardSolverActions.class).in(Singleton.class);
+
+ bind(GeometryFactory.class).to(DefaultGeometryFactory.class);
+ bind(DefaultMeshAdvancedOptionsPanel.class).to(StandardMeshAdvancedOptionsPanel.class);
+
+ bind(MaterialsDatabasePanel.class).in(Singleton.class);
+ bind(CompressibleMaterialsPanel.class).to(StandardCompressibleMaterialsPanel.class);
+ bind(IncompressibleMaterialsPanel.class).to(StandardIncompressibleMaterialsPanel.class);
+
+ Multibinder binder = Multibinder.newSetBinder(binder(), ViewElement.class);
+ binder.addBinding().to(MeshElement.class).in(Singleton.class);
+ binder.addBinding().to(CaseSetupElement.class).in(Singleton.class);
+ binder.addBinding().to(SolverElement.class).in(Singleton.class);
+
+ Multibinder panelsMesh = Multibinder.newSetBinder(binder(), GUIPanel.class, Mesh.class);
+ panelsMesh.addBinding().to(StandardBaseMeshPanel.class).in(Singleton.class);
+ panelsMesh.addBinding().to(StandardGeometryPanel.class).in(Singleton.class);
+ panelsMesh.addBinding().to(StandardFeatureLinesPanel.class).in(Singleton.class);
+ panelsMesh.addBinding().to(MaterialPointsPanel.class).in(Singleton.class);
+ panelsMesh.addBinding().to(DefaultBoundaryMeshPanel.class).in(Singleton.class);
+ panelsMesh.addBinding().to(CustomNodePanel.class).in(Singleton.class);
+
+ Multibinder panelsCaseSetup = Multibinder.newSetBinder(binder(), GUIPanel.class, CaseSetup.class);
+ panelsCaseSetup.addBinding().to(StandardSolutionModellingPanel.class).in(Singleton.class);
+ panelsCaseSetup.addBinding().to(MaterialsPanel.class).in(Singleton.class);
+ panelsCaseSetup.addBinding().to(BoundaryConditionsPanel.class).in(Singleton.class);
+ panelsCaseSetup.addBinding().to(CellZonesPanel.class).in(Singleton.class);
+ panelsCaseSetup.addBinding().to(NumericalSchemesPanel.class).in(Singleton.class);
+ panelsCaseSetup.addBinding().to(SolverSettingsPanel.class).in(Singleton.class);
+ panelsCaseSetup.addBinding().to(RuntimeControlsPanel.class).in(Singleton.class);
+ panelsCaseSetup.addBinding().to(StandardFieldsInitialisationPanel.class).in(Singleton.class);
+ panelsCaseSetup.addBinding().to(CustomNodePanel.class).in(Singleton.class);
+
+ Multibinder panelsSolver = Multibinder.newSetBinder(binder(), GUIPanel.class, Solver.class);
+ panelsSolver.addBinding().to(DefaultRunOptionsPanel.class).in(Singleton.class);
+ panelsSolver.addBinding().to(SolverRuntimeControlsPanel.class).in(Singleton.class);
+ panelsSolver.addBinding().to(ResidualsPanel.class).in(Singleton.class);
+ panelsSolver.addBinding().to(SolverBoundaryMeshPanel.class).in(Singleton.class);
+ }
+
+ private void configureBoundaryConditions() {
+ Multibinder bcMultibinder = Multibinder.newSetBinder(binder(), BoundaryTypePanel.class);
+ bcMultibinder.addBinding().to(PatchSettingsPanel.class).in(Singleton.class);
+ bcMultibinder.addBinding().to(StandardWallSettingsPanel.class).in(Singleton.class);
+ bcMultibinder.addBinding().to(CyclicSettingsPanel.class).in(Singleton.class);
+ bcMultibinder.addBinding().to(StandardCyclicAMISettingsPanel.class).in(Singleton.class);
+ }
+
+ private void configureCellZones() {
+ Multibinder zonesMultibinder = Multibinder.newSetBinder(binder(), CellZoneType.class);
+ zonesMultibinder.addBinding().to(StandardMRF.class).in(Singleton.class);
+ zonesMultibinder.addBinding().to(StandardPorous.class).in(Singleton.class);
+ zonesMultibinder.addBinding().to(StandardThermal.class).in(Singleton.class);
+ }
+
+ private void configureFunctionObjects() {
+ Multibinder.newSetBinder(binder(), FieldManipulationFunctionObjectType.class);
+ Multibinder.newSetBinder(binder(), MonitoringFunctionObjectType.class);
+ }
+}
diff --git a/src/eu/engys/core/Arguments.java b/src/eu/engys/core/Arguments.java
new file mode 100644
index 0000000..90ca5a5
--- /dev/null
+++ b/src/eu/engys/core/Arguments.java
@@ -0,0 +1,232 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.core;
+
+import java.io.File;
+import java.io.FilenameFilter;
+
+import org.apache.log4j.Level;
+
+import eu.engys.util.ApplicationInfo;
+import eu.engys.util.Util;
+
+public class Arguments {
+
+ private static final String LINE = " ********************************";
+ private static final String TAB = " ";
+
+ public enum CaseType {
+ SERIAL, PARALLEL
+ }
+
+ public static boolean verbose = false;
+ public static boolean no3D = false;
+ public static boolean load3Dmesh = true;
+ public static boolean load3Dgeometry = true;
+ public static Level logLevel = Level.ERROR;
+
+ public static File baseDir = null;
+
+ public static boolean mesh = false;
+ public static boolean run = false;
+ public static boolean setup = false;
+ public static boolean all = false;
+ public static boolean initialise = false;
+
+ public static boolean server = false;
+ public static CaseType caseType = null;
+ public static File[] stlFiles = null;
+// public static long timeout = -1L;
+
+ private static final String OPTION_V = "-v";
+ private static final String OPTION_VV = "-V";
+ private static final String OPTION_HELP = "-help";
+ private static final String OPTION_NO3D = "-no3D";
+ private static final String OPTION_CASE = "-case";
+
+ public static final String OPTION_MESH = "-mesh";
+ public static final String OPTION_RUN = "-run";
+ public static final String OPTION_SETUP = "-setup";
+ public static final String OPTION_ALL = "-all";
+ public static final String OPTION_INITIALISE = "-initialise";
+
+ private static final String OPTION_SERVER = "-server"; /* INTERNAL */
+ private static final String OPTION_IMPORT = "-import"; /* INTERNAL */
+ private static final String OPTION_NOMESH = "-no3Dmesh"; /* INTERNAL */
+ private static final String OPTION_NOGEOM = "-no3DGeom"; /* INTERNAL */
+// private static final String OPTION_CORE = "-core"; /* INTERNAL */
+// private static final String OPTION_TIMEOUT = "-timeout"; /* INTERNAL */
+
+ public static void init(final String[] argv) {
+ for (int i = 0; i < argv.length; i++) {
+ final String arg = argv[i];
+
+ if (arg.charAt(0) == '-') {
+ switch (arg) {
+ case OPTION_V: logLevel = Level.INFO; verbose = true; break;
+ case OPTION_VV: logLevel = Level.DEBUG; verbose = true; break;
+ case OPTION_NO3D: no3D = true; break;
+
+ case OPTION_CASE:
+ if (i == argv.length - 1) {
+ fatal("Missing case folder");
+ printUsage();
+ exit(-1);
+ }
+ String baseDirPath = argv[++i];
+ final File baseDir = new File(baseDirPath);
+ if (!baseDir.exists()) {
+ warning("Case Folder \"" + baseDir.getAbsolutePath() + "\" Does Not Exist!");
+ } else {
+ Arguments.baseDir = baseDir;
+ }
+ break;
+
+ case OPTION_MESH: mesh = true; break;
+ case OPTION_RUN: run = true; break;
+ case OPTION_SETUP: setup = true; break;
+ case OPTION_ALL: all = true; break;
+ case OPTION_INITIALISE: initialise = true; break;
+ case OPTION_SERVER: server = true; break;
+
+ case OPTION_NOGEOM: load3Dgeometry = false; break;
+ case OPTION_NOMESH: load3Dmesh = false; break;
+
+ case OPTION_IMPORT:
+ if (i == argv.length - 1) {
+ fatal("Missing import folder");
+ printUsage();
+ exit(-1);
+ }
+ String importPath = argv[++i];
+ final File importFolder = new File(importPath);
+ if (!importFolder.exists()) {
+ fatal("Import Folder Does Not Exist!");
+ exit(-1);
+ } else if (importFolder.isFile()) {
+ String name = importFolder.getName();
+ if (name.endsWith("stl") || name.endsWith("STL")) {
+ Arguments.stlFiles = new File[]{importFolder};
+ } else {
+ fatal("Import Folder Does Not Exist!");
+ exit(-1);
+ }
+ } else {
+ File[] stls = importFolder.listFiles(new FilenameFilter() {
+ @Override
+ public boolean accept(File dir, String name) {
+ return name.endsWith("stl") || name.endsWith("STL");
+ }
+ });
+ if (stls.length == 0) {
+ fatal("No files to import!");
+ exit(-1);
+ } else {
+ Arguments.stlFiles = stls;
+ }
+ }
+ break;
+ case OPTION_HELP:
+ printUsage();
+ exit(0);
+ break;
+ default:
+ fatal("Unknown Option " + arg);
+ printUsage();
+ exit(0);
+ break;
+ }
+ }
+ }
+ checkCase();
+ }
+
+ private static void checkCase() {
+ if (hasCommand()) {
+ if (Arguments.baseDir == null) {
+ fatal("Missing case folder");
+ printUsage();
+ exit(-1);
+ }
+ }
+ }
+
+ private static void fatal(String msg) {
+ System.err.println();
+ System.err.println(LINE);
+ System.err.println(" " + TAB + "FATAL ERROR:");
+ System.err.println(" " + TAB + TAB + msg);
+ System.err.println(LINE);
+ }
+
+ private static void warning(String msg) {
+ System.err.println();
+ System.err.println(LINE);
+ System.err.println(" " + TAB+"WARNING:");
+ System.err.println(" " + TAB + TAB + msg);
+ System.err.println(TAB+LINE);
+ }
+
+ private static void exit(int status) {
+ System.exit(status);
+ }
+
+ private static void printUsage() {
+
+ System.err.println(" USAGE");
+ System.err.println(" -----------------------------------------------------");
+ if (Util.isWindows())
+ System.err.println(" "+ApplicationInfo.getName()+".bat ["+OPTION_V+"] ["+OPTION_VV+"] [-case ] [command] ");
+ else
+ System.err.println(" "+ApplicationInfo.getName()+".sh ["+OPTION_V+"] ["+OPTION_VV+"] [-case ] [command] ");
+
+ System.err.println();
+ System.err.println(" Options:");
+ System.err.println(" " + Util.padWithSpaces(OPTION_HELP, 12) + " Print this help screen.");
+ System.err.println(" " + Util.padWithSpaces(OPTION_V, 12) + " The verbose output.");
+ System.err.println(" " + Util.padWithSpaces(OPTION_VV, 12) + " The very verbose output.");
+ System.err.println(" " + Util.padWithSpaces(OPTION_CASE, 12) + " Specify the case directory for the application.");
+ System.err.println(" " + Util.padWithSpaces(OPTION_NO3D, 12) + " Does not display 3D window.");
+ System.err.println();
+ System.err.println(" Commands:");
+ System.err.println(" " + Util.padWithSpaces(OPTION_MESH, 12) + " Launch mesh creation according to system/snappyHexMeshDict.");
+ System.err.println(" " + Util.padWithSpaces(OPTION_SETUP, 12) + " Setup the cfd case according to system/caseSetupDict.");
+ System.err.println(" " + Util.padWithSpaces(OPTION_INITIALISE, 12) + " Initialise the fields according to system/caseSetupDict.");
+ System.err.println(" " + Util.padWithSpaces(OPTION_RUN, 12) + " Launch the solver.");
+ System.err.println(" " + Util.padWithSpaces(OPTION_ALL, 12) + " Launch mesh + setup + run.");
+ System.err.println(" -----------------------------------------------------");
+ }
+
+ public static boolean isBatch() {
+ return Arguments.server || hasCommand();
+ }
+
+ private static boolean hasCommand() {
+ return Arguments.mesh || Arguments.setup || Arguments.run || Arguments.all || Arguments.initialise;
+ }
+
+}
diff --git a/src/eu/engys/core/LoggerUtil.java b/src/eu/engys/core/LoggerUtil.java
new file mode 100644
index 0000000..3e9eec8
--- /dev/null
+++ b/src/eu/engys/core/LoggerUtil.java
@@ -0,0 +1,153 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.core;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.log4j.ConsoleAppender;
+import org.apache.log4j.FileAppender;
+import org.apache.log4j.Layout;
+import org.apache.log4j.Level;
+import org.apache.log4j.PatternLayout;
+import org.apache.log4j.Priority;
+import org.apache.log4j.spi.LoggingEvent;
+
+import eu.engys.util.Symbols;
+import eu.engys.util.Util;
+
+public class LoggerUtil {
+
+ public static void initLogger() {
+ if (Util.isWindows()) {
+ initNormalLogger();
+ } else {
+ initColorLogger();
+ }
+ }
+
+ private static void initColorLogger() {
+ org.apache.log4j.Logger.getRootLogger().addAppender(new ColorConsoleAppender(new PatternLayout("%6r - %-30.30t - %-5p %-30.30c{1} %x - %m%n")));
+ org.apache.log4j.Logger.getRootLogger().setLevel(Arguments.logLevel);
+ }
+
+ private static void initNormalLogger() {
+ org.apache.log4j.Logger.getRootLogger().addAppender(new ConsoleAppender(new PatternLayout("%6r - %-30.30t - %-5p %-30.30c{1} %x - %m%n")));
+ org.apache.log4j.Logger.getRootLogger().setLevel(Arguments.logLevel);
+ }
+
+ public static void initFlatLogger() {
+ org.apache.log4j.Logger.getRootLogger().addAppender(new ConsoleAppender(new PatternLayout("%-5p %m%n")));
+ org.apache.log4j.Logger.getRootLogger().setLevel(Arguments.logLevel);
+ }
+
+ public static void initTestLogger() {
+ org.apache.log4j.Logger.getRootLogger().addAppender(new ConsoleAppender(new PatternLayout("%r [%t] %p %c %x - %m%n")));
+ org.apache.log4j.Logger.getRootLogger().setLevel(Level.INFO);
+ }
+
+ public static void initTestLogger(Level level) {
+ org.apache.log4j.Logger.getRootLogger().addAppender(new ConsoleAppender(new PatternLayout("%r [%t] %p %c %x - %m%n")));
+ org.apache.log4j.Logger.getRootLogger().setLevel(level);
+ }
+
+ public static void initFileLogger(String file, Level level) throws IOException {
+ org.apache.log4j.Logger.getRootLogger().removeAllAppenders();
+ org.apache.log4j.Logger.getRootLogger().addAppender(new FileAppender(new PatternLayout("%r [%t] %p %c %x - %m%n"), file, false));
+ org.apache.log4j.Logger.getRootLogger().setLevel(level);
+ }
+
+ private static final String LOG_FILE_NAME = "log";
+ private static final String TXT_EXT = ".txt";
+
+ public static void redirectLog(File tempDirectory) {
+ File log = new File(tempDirectory, LOG_FILE_NAME + TXT_EXT);
+ try {
+ initFileLogger(log.getAbsolutePath(), Level.DEBUG);
+ } catch (Exception e) {
+ System.out.println("ERROR : Unable to open logger file!");
+ System.exit(-1);
+ }
+ }
+
+ static class ColorConsoleAppender extends ConsoleAppender {
+ private static final int NORMAL = 0;
+ private static final int BRIGHT = 1;
+ // private static final int FOREGROUND_BLACK = 30;
+ private static final int FOREGROUND_RED = 31;
+ private static final int FOREGROUND_GREEN = 32;
+ private static final int FOREGROUND_YELLOW = 33;
+ private static final int FOREGROUND_BLUE = 34;
+ // private static final int FOREGROUND_MAGENTA = 35;
+ private static final int FOREGROUND_CYAN = 36;
+ // private static final int FOREGROUND_WHITE = 37;
+
+ private static final String PREFIX = Symbols.ESC + "[";
+ private static final String SUFFIX = "m";
+ private static final char SEPARATOR = ';';
+ private static final String END_COLOUR = PREFIX + SUFFIX;
+
+ private static final String FATAL_COLOUR = PREFIX + BRIGHT + SEPARATOR + FOREGROUND_RED + SUFFIX;
+ private static final String ERROR_COLOUR = PREFIX + NORMAL + SEPARATOR + FOREGROUND_RED + SUFFIX;
+ private static final String WARN_COLOUR = PREFIX + NORMAL + SEPARATOR + FOREGROUND_YELLOW + SUFFIX;
+ private static final String INFO_COLOUR = PREFIX + NORMAL + SEPARATOR + FOREGROUND_GREEN + SUFFIX;
+ private static final String DEBUG_COLOUR = PREFIX + NORMAL + SEPARATOR + FOREGROUND_CYAN + SUFFIX;
+ private static final String TRACE_COLOUR = PREFIX + NORMAL + SEPARATOR + FOREGROUND_BLUE + SUFFIX;
+
+ public ColorConsoleAppender(Layout layout) {
+ super(layout);
+ }
+
+ @Override
+ protected void subAppend(LoggingEvent event) {
+ this.qw.write(getColour(event.getLevel()));
+ super.subAppend(event);
+ this.qw.write(END_COLOUR);
+
+ if (this.immediateFlush) {
+ this.qw.flush();
+ }
+ }
+
+ private String getColour(Level level) {
+ switch (level.toInt()) {
+ case Priority.FATAL_INT:
+ return FATAL_COLOUR;
+ case Priority.ERROR_INT:
+ return ERROR_COLOUR;
+ case Priority.WARN_INT:
+ return WARN_COLOUR;
+ case Priority.INFO_INT:
+ return INFO_COLOUR;
+ case Priority.DEBUG_INT:
+ return DEBUG_COLOUR;
+ default:
+ return TRACE_COLOUR;
+ }
+ }
+ }
+}
diff --git a/src/eu/engys/core/OpenFOAMEnvironment.java b/src/eu/engys/core/OpenFOAMEnvironment.java
new file mode 100644
index 0000000..ca14fd9
--- /dev/null
+++ b/src/eu/engys/core/OpenFOAMEnvironment.java
@@ -0,0 +1,417 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core;
+
+import static eu.engys.core.project.openFOAMProject.LOG;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.net.URISyntaxException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.swing.JFrame;
+
+import org.apache.commons.exec.CommandLine;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import eu.engys.core.controller.ScriptBuilder;
+import eu.engys.core.executor.Executor;
+import eu.engys.core.executor.JavaExecutor;
+import eu.engys.core.project.Model;
+import eu.engys.util.PrefUtil;
+import eu.engys.util.Util;
+import eu.engys.util.ui.UiUtil;
+
+public class OpenFOAMEnvironment {
+
+ private static final Logger logger = LoggerFactory.getLogger(OpenFOAMEnvironment.class);
+
+ private static final String[] VARIABLES_TO_UNSET = new String[] { "LD_LIBRARY_PATH", "WM_COMPILER", "WM_PROJECT_VERSION", "WM_THIRDPARTY_VERSION", "ParaView_MAJOR", "ParaView_VERSION", "WM_MPLIB", "FOAM_MPI" };
+
+ public static void loadEnvironment(ScriptBuilder sb) {
+ cleanEnvironment(sb);
+ sb.newLine();
+ if (Util.isWindowsScriptStyle()) {
+ sb.append("call \"%ENV_LOADER%\"");
+ } else {
+ sb.append("export ParaView_VERSION=$PV_VERSION");
+ sb.append("export FOAM_INST_DIR=$VENDOR_HOME");
+ sb.append(". $ENV_LOADER");
+ sb.newLine();
+ sb.append("set -e");
+ sb.append("set -o pipefail");
+ }
+ sb.newLine();
+ }
+
+ public static void cleanEnvironment(ScriptBuilder sb) {
+ for (String var : VARIABLES_TO_UNSET) {
+ if (Util.isWindowsScriptStyle()) {
+ sb.append("set " + var + "=");
+ } else {
+ sb.append("unset " + var);
+ }
+ }
+ }
+
+ public static void printVariables(ScriptBuilder sb) {
+ if (Util.isWindowsScriptStyle()) {
+ sb.append("echo \"Case : %CASE%\"");
+ sb.append("echo \"Procs : %NP%\"");
+ sb.append("echo \"Log : %LOG%\"");
+ sb.append("echo \"Env : %ENV_LOADER%\"");
+ sb.append("echo \"MachineFile : %MACHINEFILE%\"");
+ sb.append("echo \"Solver : %SOLVER%\"");
+ } else {
+ sb.append("echo \"Case : $CASE\"");
+ sb.append("echo \"Procs : $NP\"");
+ sb.append("echo \"Log : $LOG\"");
+ sb.append("echo \"Env : $ENV_LOADER\"");
+ sb.append("echo \"Vendor : $VENDOR_HOME\"");
+ sb.append("echo \"Paraview : $PV_VERSION\"");
+ sb.append("echo \"MachineFile : $MACHINEFILE\"");
+ sb.append("echo \"Solver : $SOLVER\"");
+ }
+ sb.newLine();
+ }
+
+ public static Map getEnvironment(Model model) {
+ return getEnvironment(model, "");
+ }
+
+// public static Map getEnvironment(Model model, File baseDir) {
+// return getEnvironment(model, baseDir, null, null);
+// }
+
+ public static Map getEnvironment(Model model, String logFileName) {
+ return getEnvironment(model, model.getProject().getBaseDir(), logFileName, null);
+ }
+
+ public static Map getEnvironment(Model model, File baseDir, String logFileName) {
+ return getEnvironment(model, baseDir, logFileName, null);
+ }
+
+ public static Map getEnvironment(Model model, String logFileName, String option) {
+ return getEnvironment(model, model.getProject().getBaseDir(), logFileName, option);
+ }
+
+ private static Map getEnvironment(Model model, File baseDir, String logFileName, String option) {
+ Map map = new HashMap<>();
+
+ Path hostfilePath = Paths.get(model.getProject().getBaseDir().getAbsolutePath()).resolve(model.getSolverModel().getHostfilePath());
+
+ map.put("CASE", baseDir.getAbsolutePath());
+
+ map.put("NP", String.valueOf(model.getProject().getProcessors()));
+
+ map.put("SOLVER", model.getState().getSolver().getName());
+
+ if (logFileName != null) {
+ map.put("LOG", Paths.get(model.getProject().getBaseDir().getAbsolutePath(), LOG, logFileName).toString());
+ }
+
+ map.put("VENDOR_HOME", getVendorHome().getAbsolutePath());
+
+ map.put("PV_VERSION", getParaviewVersion());
+
+ map.put("ENV_LOADER", getEnvLoader().getAbsolutePath());
+
+ if (option != null) {
+ JavaExecutor executor = Executor.jvm("eu.engys.launcher.Launcher", option, "-V");
+ executor.inFolder(baseDir);
+
+ CommandLine cmdLine = executor.getCommandLine();
+ map.put("APPLICATION", cmdLine.toString());
+ }
+
+ // DPC
+ if (model.getSolverModel().isQueue()) {
+ map.put("MACHINEFILE", "-machinefile " + System.getenv("HOSTFILE"));
+ } else {
+ map.put("MACHINEFILE", model.getSolverModel().getMultiMachine() ? "-machinefile " + hostfilePath : "");
+ }
+
+ return map;
+ }
+
+ public static Map getTestEnvironment() {
+ Map map = new HashMap<>();
+ map.put("VENDOR_HOME", getVendorHome().getAbsolutePath());
+ map.put("ENV_LOADER", getEnvLoader().getAbsolutePath());
+ return map;
+ }
+
+ public static void printHeader(ScriptBuilder sb, String header) {
+ if (Util.isWindowsScriptStyle()) {
+ sb.append("@echo off");
+ } else {
+ sb.append("#!/bin/bash");
+ }
+ sb.append(getHeaderDelimiter(header.length()));
+ sb.append(getHeaderTitle(header));
+ sb.append(getHeaderDelimiter(header.length()));
+ sb.newLine();
+ }
+
+ private static String getHeaderTitle(String header) {
+ StringBuilder sb = new StringBuilder("echo \"");
+ sb.append("*");
+ sb.append(" ");
+ sb.append(" ");
+ sb.append(" ");
+ sb.append(" ");
+ sb.append(header);
+ sb.append(" ");
+ sb.append(" ");
+ sb.append(" ");
+ sb.append(" ");
+ sb.append("*");
+ sb.append("\"");
+ return sb.toString();
+ }
+
+ private static String getHeaderDelimiter(int headerLength) {
+ StringBuilder sb = new StringBuilder("echo \"");
+ for (int i = 0; i < headerLength + 10; i++) {
+ sb.append("*");
+ }
+ sb.append("\"");
+ return sb.toString();
+ }
+
+ /*
+ * Other
+ */
+
+ public static void trySettingOpenFoamFolder(JFrame frame) {
+ if (!OpenFOAMEnvironment.isEnvironementLoaded()) {
+ File[] openFoamDir = getOpenFoamDir();
+ if (Util.isVarArgsNotNullAndOfSize(1, openFoamDir)) {
+ PrefUtil.setOpenFoamEntry(openFoamDir[0]);
+ logger.info("Environment set to {}", PrefUtil.getOpenFoamEntry());
+ } else {
+ UiUtil.showCoreEnvironmentNotLoadedWarning(frame);
+ }
+ }
+ }
+
+ public static void trySettingOpenFoamFolderOS(JFrame frame) {
+ if (!OpenFOAMEnvironment.isEnvironementLoaded()) {
+ File[] openFoamDir = null;
+ if (Util.isUnix()) {
+ openFoamDir = getOpenFoamDirOS_onUnix();
+ } else {
+ openFoamDir = getOpenFoamDir();
+ }
+ if (Util.isVarArgsNotNullAndOfSize(1, openFoamDir)) {
+ PrefUtil.setOpenFoamEntry(openFoamDir[0]);
+ logger.info("Environment set to {}", PrefUtil.getOpenFoamEntry());
+ } else {
+ UiUtil.showCoreEnvironmentNotLoadedWarning(frame);
+ }
+ }
+ }
+
+ public static void trySettingParaviewExecutable() {
+ if (!OpenFOAMEnvironment.isParaviewPathSet() && OpenFOAMEnvironment.isEnvironementLoaded()) {
+ File paraviewExecutable = getParaViewExecutablePath();
+ if (paraviewExecutable != null) {
+ PrefUtil.setParaViewEntry(paraviewExecutable);
+ logger.info("ParaView path set to {}", PrefUtil.getParaViewEntry());
+ } else {
+ logger.warn("ParaView path NOT set");
+ }
+ }
+ }
+
+ public static File[] getOpenFoamDir() {
+ File[] openFoamFolders = new File[0];
+ String jarPath = "";
+ try {
+ jarPath = new File(OpenFOAMEnvironment.class.getProtectionDomain().getCodeSource().getLocation().toURI()).getAbsolutePath();
+ File vendorHome = Paths.get(jarPath).getParent().getParent().getParent().getParent().toFile();
+ logger.info("Check for valid OpenFOAM folder in {}", vendorHome);
+ openFoamFolders = vendorHome.listFiles(new FileFilter() {
+
+ @Override
+ public boolean accept(File file) {
+ return file.isDirectory() && file.getName().startsWith("OpenFOAM");
+ }
+ });
+ } catch (URISyntaxException e) {
+ logger.error("JarPath {}", jarPath);
+ }
+ return openFoamFolders;
+ }
+
+ private static File getParaViewExecutablePath() {
+ File[] paraviewFolders = new File[0];
+ File[] thirdPartyDirs = getThirdPartyDir();
+ if (Util.isVarArgsNotNullAndOfSize(1, thirdPartyDirs)) {
+ File thirdPartyDir = thirdPartyDirs[0];
+ logger.info("Check for valid ParaView folder in {}", thirdPartyDir);
+ paraviewFolders = thirdPartyDir.listFiles(new FileFilter() {
+ @Override
+ public boolean accept(File file) {
+ return file.isDirectory() && file.getName().startsWith("ParaView");
+ }
+ });
+ }
+ if (Util.isVarArgsNotNull(paraviewFolders)) {
+ for (File pvFolder : paraviewFolders) {
+ File pvExecutable = Paths.get(pvFolder.getAbsolutePath(), "platforms", "linux64Gcc", "bin", "paraview").toFile();
+ if (pvExecutable.exists()) {
+ return pvExecutable;
+ }
+ }
+ }
+ return null;
+ }
+
+ private static File[] getThirdPartyDir() {
+ File[] openFoamFolders = getOpenFoamDir();
+ File[] thirdPartyFolders = new File[0];
+ if (Util.isVarArgsNotNullAndOfSize(1, openFoamFolders)) {
+ File vendorHome = getOpenFoamDir()[0].getParentFile();
+ logger.info("Check for valid ThirdParty folder in {}", vendorHome);
+ thirdPartyFolders = vendorHome.listFiles(new FileFilter() {
+ @Override
+ public boolean accept(File file) {
+ return file.isDirectory() && file.getName().startsWith("ThirdParty");
+ }
+ });
+ }
+ return thirdPartyFolders;
+ }
+
+ private static File[] getOpenFoamDirOS_onUnix() {
+ File[] openFoamFolders = new File[0];
+ File optFolder = new File("/opt");
+ logger.info("Check for valid OpenFOAM folder in {}", optFolder);
+ openFoamFolders = optFolder.listFiles(new FileFilter() {
+
+ @Override
+ public boolean accept(File file) {
+ boolean isDir = file.isDirectory();
+ String fileName = file.getName();
+ boolean ubuntuNameCheck = fileName.startsWith("openfoam");
+ boolean fedoraNameCheck = fileName.startsWith("OpenFOAM") && !fileName.contains("ParaView") && !fileName.contains("scotch");
+ boolean suseNameCheck = fileName.startsWith("OpenFOAM") && !fileName.contains("ParaView") && !fileName.contains("scotch");
+ return isDir && (ubuntuNameCheck || fedoraNameCheck || suseNameCheck);
+ }
+ });
+ return openFoamFolders;
+ }
+
+ public static File[] getDocumentationDir() {
+ File[] documentationFolders = new File[0];
+ String jarPath = "";
+ try {
+ jarPath = new File(OpenFOAMEnvironment.class.getProtectionDomain().getCodeSource().getLocation().toURI()).getAbsolutePath();
+ File vendorHome = Paths.get(jarPath).getParent().getParent().getParent().getParent().toFile();
+ logger.info("Check for valid documentation folder in {}", vendorHome);
+ documentationFolders = vendorHome.listFiles(new FileFilter() {
+
+ @Override
+ public boolean accept(File file) {
+ return file.isDirectory() && file.getName().equals("doc");
+ }
+ });
+ } catch (URISyntaxException e) {
+ logger.error("JarPath {}", jarPath);
+ }
+ return documentationFolders;
+ }
+
+ public static boolean isEnvironementLoaded() {
+ File openFoamDir = PrefUtil.getOpenFoamEntry();
+ if (openFoamDir == null || !openFoamDir.exists() || !openFoamDir.isDirectory()) {
+ return false;
+ }
+ return true;
+ }
+
+ public static boolean isParaviewPathSet() {
+ File paraView = PrefUtil.getParaViewEntry();
+ if (paraView == null || !paraView.exists() || !paraView.isFile() || !paraView.canExecute()) {
+ return false;
+ }
+ return true;
+ }
+
+ public static boolean isFieldViewPathSet() {
+ File fieldView = PrefUtil.getFieldViewEntry();
+ if (fieldView == null || !fieldView.exists() || !fieldView.isFile() || !fieldView.canExecute()) {
+ return false;
+ }
+ return true;
+ }
+
+ public static boolean isEnSightPathSet() {
+ File enSight = PrefUtil.getEnsightEntry();
+ if (enSight == null || !enSight.exists() || !enSight.isFile() || !enSight.canExecute()) {
+ return false;
+ }
+ return true;
+ }
+
+ private static File getEnvLoader() {
+ File openFoamEntry = PrefUtil.getOpenFoamEntry();
+ if (openFoamEntry != null) {
+ if (Util.isWindowsScriptStyle()) {
+ return openFoamEntry.toPath().resolve("etc").resolve("batchrc.bat").toFile();
+ } else {
+ return openFoamEntry.toPath().resolve("etc").resolve("bashrc").toFile();
+ }
+ }
+ return new File("");
+ }
+
+ public static File getVendorHome() {
+ File openFoamEntry = PrefUtil.getOpenFoamEntry();
+ if (openFoamEntry != null) {
+ return openFoamEntry.getParentFile();
+ }
+ return new File("");
+ }
+
+ public static String getParaviewVersion() {
+ File pvHome = PrefUtil.getParaViewEntry();
+ if (pvHome != null && pvHome.exists()) {
+ String name = pvHome.getName();
+ if (name.startsWith("ParaView-")) {
+ String version = name.substring("ParaView-".length());
+ return version;
+ }
+ }
+ return "";
+ }
+
+}
diff --git a/src/eu/engys/core/controller/AbstractController.java b/src/eu/engys/core/controller/AbstractController.java
new file mode 100644
index 0000000..9c322da
--- /dev/null
+++ b/src/eu/engys/core/controller/AbstractController.java
@@ -0,0 +1,541 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.controller;
+
+import java.io.File;
+import java.rmi.RemoteException;
+import java.util.Set;
+
+import javax.swing.Icon;
+import javax.swing.JOptionPane;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import eu.engys.core.Arguments;
+import eu.engys.core.controller.actions.CommandException;
+import eu.engys.core.controller.actions.DeleteMesh;
+import eu.engys.core.modules.ApplicationModule;
+import eu.engys.core.presentation.Action;
+import eu.engys.core.presentation.ActionContainer;
+import eu.engys.core.presentation.ActionManager;
+import eu.engys.core.project.CaseParameters;
+import eu.engys.core.project.InvalidProjectException;
+import eu.engys.core.project.Model;
+import eu.engys.core.project.Project200To210Converter;
+import eu.engys.core.project.ProjectFolderAnalyzer;
+import eu.engys.core.project.ProjectReader;
+import eu.engys.core.project.ProjectWriter;
+import eu.engys.core.project.SolverState;
+import eu.engys.core.project.openFOAMProject;
+import eu.engys.core.project.system.monitoringfunctionobjects.ParserView;
+import eu.engys.core.project.zero.cellzones.CellZonesBuilder;
+import eu.engys.util.ApplicationInfo;
+import eu.engys.util.PrefUtil;
+import eu.engys.util.filechooser.AbstractFileChooser.ReturnValue;
+import eu.engys.util.filechooser.HelyxFileChooser;
+import eu.engys.util.filechooser.util.SelectionMode;
+import eu.engys.util.progress.ProgressMonitor;
+import eu.engys.util.ui.ExecUtil;
+import eu.engys.util.ui.ResourcesUtil;
+import eu.engys.util.ui.UiUtil;
+
+public abstract class AbstractController implements Controller, ActionContainer {
+
+ public static final String STOP_SOLVER = "Stop Solver";
+ public static final String KILL_SOLVER = "Kill Solver";
+
+ public static final String STOP_EXECUTION = "Stop Execution";
+ public static final String KILL_PROCESS = "Kill Process";
+
+ public static final String STOP_FIELDS_INITIALISATION = "Stop Fields Initialisation";
+ public static final String STOP_MESH_GENERATOR = "Stop Mesh Generator";
+
+ public static final String CANCEL = "Cancel";
+ public static final String CONTINUE_IN_BATCH = "Continue in Batch";
+
+ private static final Icon EXIT_BIG_ICON = ResourcesUtil.getIcon("application.exit.big.icon");
+ private static final String EXIT_LABEL = ResourcesUtil.getString("application.exit.label");
+ private static final Logger logger = LoggerFactory.getLogger(Controller.class);
+
+ protected final Model model;
+ protected final Set modules;
+ protected final ProjectReader reader;
+ protected final ProjectWriter writer;
+ protected final ProgressMonitor monitor;
+ protected final ScriptFactory scriptFactory;
+ protected ControllerListener listener;
+ protected CellZonesBuilder cellZonesBuilder;
+
+ public AbstractController(Model model, Set modules, ProjectReader reader, ProjectWriter writer, CellZonesBuilder cellZonesBuilder, ProgressMonitor monitor, ScriptFactory scriptFactory) {
+ this.cellZonesBuilder = cellZonesBuilder;
+ logger.info("Loading {}", getClass().getSimpleName());
+ this.model = model;
+ this.modules = modules;
+ this.reader = reader;
+ this.writer = writer;
+ this.monitor = monitor;
+ this.scriptFactory = scriptFactory;
+ }
+
+ /*
+ * NEW CASE
+ */
+
+ @Override
+ public void createCase(CaseParameters params) {
+ if (params != null) {
+ newCaseInAThread(params);
+ }
+ }
+
+ private void newCaseInAThread(final CaseParameters params) {
+ monitor.setTotal(10);
+ monitor.start(String.format("Creating %s", params), false, new Runnable() {
+ @Override
+ public void run() {
+ create(params);
+ PrefUtil.putFile(PrefUtil.WORK_DIR, model.getProject().getBaseDir().getParentFile());
+ monitor.end();
+ }
+ });
+ }
+
+ @Override
+ public void create(final CaseParameters params) {
+ if (listener != null) {
+ listener.beforeNewCase();
+ }
+ clearModel();
+ writer.create(params);
+ if (listener != null) {
+ listener.afterNewCase();
+ }
+ }
+
+ /*
+ * OPEN
+ */
+
+ @Override
+ public void openCase(File file) {
+ if (file == null) {
+ file = fileToOpenOrNull();
+ }
+ if (file != null) {
+ ActionManager.getInstance().invoke("application.startup.hide");
+ openInAThread(file);
+ }
+ Arguments.load3Dgeometry = true;
+ Arguments.load3Dmesh = true;
+ }
+
+ private File fileToOpenOrNull() {
+ final File[] openFile = new File[1];
+ Runnable r = new Runnable() {
+ @Override
+ public void run() {
+ File workDir = PrefUtil.getWorkDir(PrefUtil.WORK_DIR);
+ HelyxFileChooser fileChooser = new HelyxFileChooser(workDir.getAbsolutePath());
+ fileChooser.setTitle("Open");
+ fileChooser.setSelectionMode(SelectionMode.DIRS_AND_ARCHIVES);
+
+ View3DOptions options = new View3DOptions();
+ ReturnValue returnValue = fileChooser.showOpenDialog(options);
+ if (returnValue.isApprove()) {
+ File selectedCase = fileChooser.getSelectedFile();
+ if (isSuitable(selectedCase)) {
+ PrefUtil.putFile(PrefUtil.WORK_DIR, selectedCase.getParentFile());
+ Arguments.load3Dgeometry = true;
+ Arguments.load3Dmesh = options.loadMesh();
+ openFile[0] = selectedCase;
+ return;
+ }
+ JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), selectedCase + "\n appears not to be a valid case folder", "File System Error", JOptionPane.ERROR_MESSAGE);
+ }
+ openFile[0] = null;
+ return;
+ }
+ };
+ ExecUtil.invokeAndWait(r);
+ return openFile[0];
+ }
+
+ private void openInAThread(final File file) {
+ monitor.setTotal(10);
+ monitor.start("Open " + file.getName(), false, new Runnable() {
+ @Override
+ public void run() {
+ open(file);
+ monitor.end();
+ }
+ });
+ }
+
+ @Override
+ public void open(File file) {
+ final File baseDir = file.isAbsolute() ? file : file.getAbsoluteFile();
+ logger.debug("OPEN file {}", baseDir.getAbsolutePath());
+ if (listener != null) {
+ listener.beforeLoadCase();
+ }
+ clearModel();
+
+ model.setProject(openFOAMProject.createProject(baseDir, monitor));
+
+ new Project200To210Converter(model.getProject(), cellZonesBuilder).convert();
+
+ _read();
+
+ if (listener != null) {
+ listener.afterLoadCase();
+ }
+
+ logger.debug("OPEN file {} done.", baseDir.getName());
+ }
+
+ @Override
+ public void reopen(OpenOptions options) {
+ File baseDir = model.getProject().getBaseDir();
+ int np = model.getProject().getProcessors();
+ boolean parallel = model.getProject().isParallel();
+
+ logger.debug("REOPEN file {} with option {}", baseDir.getAbsolutePath(), options);
+ if (listener != null) {
+ listener.beforeReopenCase();
+ }
+
+ if (options == OpenOptions.MESH_ONLY) {
+ reader.readMesh();
+ if (listener != null) {
+ listener.afterReopenCase();
+ }
+ return;
+ }
+ clearModel();
+
+ switch (options) {
+ case SERIAL:
+ model.setProject(openFOAMProject.newSerialProject(baseDir));
+ break;
+ case PARALLEL:
+ model.setProject(openFOAMProject.newParallelProject(baseDir));
+ break;
+ case CHECK_FOLDER:
+ model.setProject(openFOAMProject.createProject(baseDir, monitor));
+ break;
+ case CURRENT_SETTINGS:
+ model.setProject(parallel ? openFOAMProject.newParallelProject(baseDir, np) : openFOAMProject.newSerialProject(baseDir));
+ break;
+ case MESH_ONLY:
+ break;
+ default:
+ break;
+ }
+
+ reader.read();
+
+ if (listener != null) {
+ listener.afterReopenCase();
+ }
+ logger.debug("Open file {} done.", baseDir.getName());
+ }
+
+ private void _read() {
+ try {
+ reader.read();
+ } catch (InvalidProjectException e) {
+ logger.error(e.getMessage());
+ JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), e.getMessage(), "Project error", JOptionPane.ERROR_MESSAGE);
+ clearModel();
+ }
+ }
+
+ @Override
+ public void reopenCase(final OpenOptions options) {
+ monitor.start("Reopen " + model.getProject().getBaseDir(), false, new Runnable() {
+ @Override
+ public void run() {
+ reopen(options);
+ monitor.end();
+ }
+ });
+ }
+
+ /*
+ * SAVE
+ */
+
+ @Override
+ public void saveCase(File file) {
+ if (file == null) {
+ file = fileToSaveOrNull();
+ }
+ if (file != null) {
+ saveInAThread(file);
+ }
+ }
+
+ protected void saveInAThread(final File baseDir) {
+ monitor.info("");
+ monitor.start("Save: " + baseDir.getAbsolutePath(), false, new Runnable() {
+ @Override
+ public void run() {
+ save(baseDir);
+ monitor.end();
+ }
+ });
+ }
+
+ @Override
+ public void save(File baseDir) {
+ if (baseDir == null) {
+ baseDir = model.getProject().getBaseDir();
+ }
+ logger.debug("Save file {}", baseDir.getAbsolutePath());
+ if (listener != null)
+ listener.beforeSaveCase();
+ writer.write(baseDir);
+ writeScripts();
+ if (listener != null) {
+ listener.afterSaveCase();
+ }
+ logger.debug("Save file {} done.", baseDir.getName());
+ }
+
+ private File fileToSaveOrNull() {
+ final File[] file = new File[1];
+ Runnable r = new Runnable() {
+ @Override
+ public void run() {
+ File workDir = PrefUtil.getWorkDir(PrefUtil.WORK_DIR);
+
+ HelyxFileChooser fileChooser = new HelyxFileChooser(workDir.getAbsolutePath());
+ if (model.getProject().getBaseDir().getAbsoluteFile().getParentFile().equals(workDir)) {
+ fileChooser.selectFile(model.getProject().getBaseDir());
+ }
+ fileChooser.setTitle("Save As");
+ fileChooser.setSelectionMode(SelectionMode.DIRS_ONLY);
+
+ ReturnValue returnValue = fileChooser.showSaveAsDialog();
+ if (returnValue.isApprove()) {
+ File baseDir = fileChooser.getSelectedFile();
+ if (baseDir != null) {
+ if (baseDir.exists() && !baseDir.equals(model.getProject().getBaseDir())) {
+ int retVal = JOptionPane.showConfirmDialog(UiUtil.getActiveWindow(), "Folder already exists. Continue anyway?", "Warning", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
+ if (retVal == JOptionPane.NO_OPTION) {
+ file[0] = fileToSaveOrNull();
+ return;
+ }
+ }
+ PrefUtil.putFile(PrefUtil.WORK_DIR, baseDir.getParentFile());
+ }
+ file[0] = baseDir;
+ return;
+ }
+ file[0] = null;
+ return;
+ }
+ };
+ ExecUtil.invokeAndWait(r);
+ return file[0];
+ }
+
+ /*
+ * MESH
+ */
+
+ @Action(key = "mesh.delete")
+ public void deleteMesh() {
+ int retVal = JOptionPane.showConfirmDialog(UiUtil.getActiveWindow(), "This action will delete the existing mesh.\nContinue?", "Delete Mesh", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
+ if (retVal == JOptionPane.YES_OPTION) {
+ saveInAThread(model.getProject().getBaseDir());
+ new DeleteMesh(model, this).executeClient();
+ reopenCase(OpenOptions.CURRENT_SETTINGS);
+ }
+ }
+
+ private void writeScripts() {
+ scriptFactory.getMeshScript(model);
+ scriptFactory.getInitialiseScript(model);
+ scriptFactory.getSolverScript(model);
+ if (model.getSolverModel().isQueue()) {
+ scriptFactory.getQueueDriver(model);
+ scriptFactory.getQueueLauncher(model);
+ }
+ }
+
+ /*
+ * OTHER
+ */
+
+ @Override
+ public void createReport() {
+ }
+
+ protected void clearModel() {
+ logger.info("--- CLEAR MODEL ---");
+ model.init();
+ model.setProject(null);
+ System.gc();
+ }
+
+ @Override
+ public ProjectReader getReader() {
+ return reader;
+ }
+
+ @Override
+ public ProjectWriter getWriter() {
+ return writer;
+ }
+
+ public boolean isSuitable(File file) {
+ return ProjectFolderAnalyzer.isSuitable(file);
+ }
+
+ @Override
+ public boolean allowActionsOnRunning(boolean exit) {
+ if (model != null && model.getSolverModel() != null) {
+ SolverState solverState = model.getSolverModel().getServerState().getSolverState();
+ if (solverState.isMeshing()) {
+ return handleExitOnMeshRunning();
+ } else if (solverState.isInitialising()) {
+ return handleExitOnFieldsInitialising();
+ } else if (solverState.isRunning()) {
+ return handleExitOnSolverRunning();
+ } else if (exit) {
+ int option = JOptionPane.showConfirmDialog(UiUtil.getActiveWindow(), EXIT_LABEL + " " + ApplicationInfo.getName() + "?", EXIT_LABEL, JOptionPane.OK_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE, EXIT_BIG_ICON);
+ if (option == JOptionPane.CANCEL_OPTION) {
+ return false;
+ } else {
+ if (getClient() != null && getClient().getServer() != null) {
+ shutdownServer();
+ }
+ return true;
+ }
+ } else if (getClient() != null && getClient().getServer() != null) {
+ shutdownServer();
+ return true;
+ }
+ } else if (exit) {// If no case has been loaded yet
+ int option = JOptionPane.showConfirmDialog(UiUtil.getActiveWindow(), EXIT_LABEL + " " + ApplicationInfo.getName() + "?", EXIT_LABEL, JOptionPane.OK_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE, EXIT_BIG_ICON);
+ if (option == JOptionPane.CANCEL_OPTION) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private void shutdownServer() {
+ try {
+ getClient().getServer().shutdown();
+ } catch (RemoteException e) {
+ logger.error("Error shutting down server: {}" + e.getMessage());
+ } catch (Exception e) {
+ logger.error("Error shutting down server: {}" + e.getMessage());
+ }
+ }
+
+ protected boolean handleExitOnMeshRunning() {
+ Object[] options = new Object[] { STOP_MESH_GENERATOR, CONTINUE_IN_BATCH, CANCEL };
+ int option = JOptionPane.showOptionDialog(UiUtil.getActiveWindow(), "Mesh Generator is Running. Select an action to perform.", "Mesh Generator Running", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]);
+
+ if (getClient() != null && option == JOptionPane.YES_OPTION) {
+ kill();
+ return true;
+ } else if (getClient() != null && option == JOptionPane.NO_OPTION) {
+ getClient().goToBatch();
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ protected boolean handleExitOnFieldsInitialising() {
+ Object[] options = new Object[] { STOP_FIELDS_INITIALISATION, CONTINUE_IN_BATCH, CANCEL };
+ int option = JOptionPane.showOptionDialog(UiUtil.getActiveWindow(), "Fields Initialisation is Running. Select an action to perform.", "Fields Initialisation Running", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]);
+
+ if (getClient() != null && option == JOptionPane.YES_OPTION) {
+ kill();
+ return true;
+ } else if (getClient() != null && option == JOptionPane.NO_OPTION) {
+ getClient().goToBatch();
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ protected boolean handleExitOnSolverRunning() {
+ Object[] options = new Object[] { STOP_SOLVER, CONTINUE_IN_BATCH, CANCEL };
+ int option = JOptionPane.showOptionDialog(UiUtil.getActiveWindow(), "Solver is Running. Select an action to perform.", "Solver Running", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]);
+
+ if (getClient() != null && option == JOptionPane.YES_OPTION) {
+ getClient().stopCommand(Command.ANY);
+ return true;
+ } else if (getClient() != null && option == JOptionPane.NO_OPTION) {
+ getClient().goToBatch();
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public void addListener(ControllerListener listener) {
+ this.listener = listener;
+ }
+
+ @Override
+ public ControllerListener getListener() {
+ return listener;
+ }
+
+ @Override
+ public void executeCommand(Command command) throws CommandException {
+ }
+
+ @Override
+ public void executeCommands(Command... commands) throws CommandException {
+ }
+
+ @Override
+ public boolean isRunningCommand() {
+ return false;
+ }
+
+ @Override
+ public String submitCommand(Command command) throws CommandException {
+ return null;
+ }
+
+ @Override
+ public ParserView getResidualView() {
+ return null;
+ }
+
+}
diff --git a/src/eu/engys/core/controller/AbstractScriptFactory.java b/src/eu/engys/core/controller/AbstractScriptFactory.java
new file mode 100644
index 0000000..f38e7c3
--- /dev/null
+++ b/src/eu/engys/core/controller/AbstractScriptFactory.java
@@ -0,0 +1,337 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.controller;
+
+import java.io.File;
+import java.util.List;
+
+import eu.engys.core.project.Model;
+import eu.engys.util.IOUtils;
+import eu.engys.util.Util;
+
+public abstract class AbstractScriptFactory implements ScriptFactory {
+
+ protected static final String RUN_MESH = "Run Mesh";
+ public static final String MESH_SERIAL_RUN = "mesh_serial.run";
+ public static final String MESH_SERIAL_BAT = "mesh_serial.bat";
+ public static final String MESH_PARALLEL_RUN = "mesh_parallel.run";
+ public static final String MESH_PARALLEL_BAT = "mesh_parallel.bat";
+
+ protected static final String CHECK_MESH = "Check Mesh";
+ public static final String CHECK_MESH_SERIAL_RUN = "check_mesh_serial.run";
+ public static final String CHECK_MESH_SERIAL_BAT = "check_mesh_serial.bat";
+ public static final String CHECK_MESH_PARALLEL_RUN = "check_mesh_parallel.run";
+ public static final String CHECK_MESH_PARALLEL_BAT = "check_mesh_parallel.bat";
+
+ protected static final String RUN_CASE = "Run Case";
+ public static final String SOLVER_SERIAL_RUN = "solver_serial.run";
+ public static final String SOLVER_SERIAL_BAT = "solver_serial.bat";
+ public static final String SOLVER_PARALLEL_RUN = "solver_parallel.run";
+ public static final String SOLVER_PARALLEL_BAT = "solver_parallel.bat";
+
+ protected static final String INITIALISE_FIELDS = "Initialise Fields";
+ public static final String INITIALISE_FIELDS_SERIAL_RUN = "initialiseFields_serial.run";
+ public static final String INITIALISE_FIELDS_SERIAL_BAT = "initialiseFields_serial.bat";
+ public static final String INITIALISE_FIELDS_PARALLEL_RUN = "initialiseFields_parallel.run";
+ public static final String INITIALISE_FIELDS_PARALLEL_BAT = "initialiseFields_parallel.bat";
+
+ protected static final String EXTRUDEMESH = "Extrude To Region";
+ private static final String EXTRUDEMESH_SERIAL_RUN = "extrudeMesh_serial.run";
+ private static final String EXTRUDEMESH_SERIAL_BAT = "extrudeMesh_serial.bat";
+ private static final String EXTRUDEMESH_PARALLEL_RUN = "extrudeMesh_parallel.run";
+ private static final String EXTRUDEMESH_PARALLEL_BAT = "extrudeMesh_parallel.bat";
+
+ /*
+ * MESH
+ */
+ @Override
+ public File getMeshScript(Model model) {
+ File parallelScript = getMeshParallelScript(model);
+ File serialScript = getMeshSerialScript(model);
+
+ if (model.getProject().isParallel()) {
+ return parallelScript;
+ } else {
+ return serialScript;
+ }
+ }
+
+ @Override
+ public void deleteMeshScripts(Model model) {
+ File serialFile = new File(model.getProject().getBaseDir(), Util.isWindowsScriptStyle() ? MESH_SERIAL_BAT : MESH_SERIAL_RUN);
+ if (serialFile.exists()) {
+ serialFile.delete();
+ }
+ File parallelFile = new File(model.getProject().getBaseDir(), Util.isWindowsScriptStyle() ? MESH_PARALLEL_BAT : MESH_PARALLEL_RUN);
+ if (parallelFile.exists()) {
+ parallelFile.delete();
+ }
+ }
+
+ @Override
+ public List getDefaultMeshScript(Model model) {
+ List script = null;
+ if (model.getProject().isParallel()) {
+ script = getParallelMeshScript();
+ } else {
+ script = getSerialMeshScript();
+ }
+ return script;
+ }
+
+ private File getMeshParallelScript(Model model) {
+ File file = new File(model.getProject().getBaseDir(), Util.isWindowsScriptStyle() ? MESH_PARALLEL_BAT : MESH_PARALLEL_RUN);
+ writeFileIfNeeded(file, getParallelMeshScript());
+ file.setExecutable(true);
+ return file;
+ }
+
+ private File getMeshSerialScript(Model model) {
+ File file = new File(model.getProject().getBaseDir(), Util.isWindowsScriptStyle() ? MESH_SERIAL_BAT : MESH_SERIAL_RUN);
+ writeFileIfNeeded(file, getSerialMeshScript());
+ file.setExecutable(true);
+ return file;
+ }
+
+ protected abstract List getParallelMeshScript();
+
+ protected abstract List getSerialMeshScript();
+
+ @Override
+ public File getCheckMeshScript(Model model) {
+ File parallelScript = getCheckMeshParallelScript(model);
+ File serialScript = getCheckMeshSerialScript(model);
+
+ if (model.getProject().isParallel()) {
+ return parallelScript;
+ } else {
+ return serialScript;
+ }
+ }
+
+ @Override
+ public List getDefaultCheckMeshScript(Model model) {
+ List script = null;
+ if (model.getProject().isParallel()) {
+ script = getParallelMeshScript();
+ } else {
+ script = getSerialMeshScript();
+ }
+ return script;
+ }
+
+ private File getCheckMeshParallelScript(Model model) {
+ File file = new File(model.getProject().getBaseDir(), Util.isWindowsScriptStyle() ? CHECK_MESH_PARALLEL_BAT : CHECK_MESH_PARALLEL_RUN);
+ writeFileIfNeeded(file, getParallelCheckMeshScript());
+ file.setExecutable(true);
+ return file;
+ }
+
+ private File getCheckMeshSerialScript(Model model) {
+ File file = new File(model.getProject().getBaseDir(), Util.isWindowsScriptStyle() ? CHECK_MESH_SERIAL_BAT : CHECK_MESH_SERIAL_RUN);
+ writeFileIfNeeded(file, getSerialCheckMeshScript());
+ file.setExecutable(true);
+ return file;
+ }
+
+ protected abstract List getParallelCheckMeshScript();
+
+ protected abstract List getSerialCheckMeshScript();
+
+ /*
+ * SOLVER
+ */
+
+ @Override
+ public File getSolverScript(Model model) {
+ File parallelScript = getSolverParallelScript(model);
+ File serialScript = getSolverSerialScript(model);
+
+ if (model.getProject().isParallel()) {
+ return parallelScript;
+ } else {
+ return serialScript;
+ }
+ }
+
+ @Override
+ public List getDefaultSolverScript(Model model) {
+ List script = null;
+ if (model.getProject().isParallel()) {
+ script = getParallelSolverScript();
+ } else {
+ script = getSerialSolverScript();
+ }
+ return script;
+ }
+
+ protected File getSolverParallelScript(Model model) {
+ File file = new File(model.getProject().getBaseDir(), Util.isWindowsScriptStyle() ? SOLVER_PARALLEL_BAT : SOLVER_PARALLEL_RUN);
+ writeFileIfNeeded(file, getParallelSolverScript());
+ file.setExecutable(true);
+ return file;
+ }
+
+ protected File getSolverSerialScript(Model model) {
+ File file = new File(model.getProject().getBaseDir(), Util.isWindowsScriptStyle() ? SOLVER_SERIAL_BAT : SOLVER_SERIAL_RUN);
+ writeFileIfNeeded(file, getSerialSolverScript());
+ file.setExecutable(true);
+ return file;
+ }
+
+ protected abstract List getParallelSolverScript();
+
+ protected abstract List getSerialSolverScript();
+
+ @Override
+ public File getInitialiseScript(Model model) {
+ File parallelScript = getInitialiseParallelScript(model);
+ File serialScript = getInitialiseSerialScript(model);
+
+ if (model.getProject().isParallel()) {
+ return parallelScript;
+ } else {
+ return serialScript;
+ }
+ }
+
+ protected File getInitialiseParallelScript(Model model) {
+ File file = new File(model.getProject().getBaseDir(), Util.isWindowsScriptStyle() ? INITIALISE_FIELDS_PARALLEL_BAT : INITIALISE_FIELDS_PARALLEL_RUN);
+ writeFileIfNeeded(file, getParallelInitialiseScript());
+ file.setExecutable(true);
+ return file;
+ }
+
+ protected File getInitialiseSerialScript(Model model) {
+ File file = new File(model.getProject().getBaseDir(), Util.isWindowsScriptStyle() ? INITIALISE_FIELDS_SERIAL_BAT : INITIALISE_FIELDS_SERIAL_RUN);
+ writeFileIfNeeded(file, getSerialInitialiseScript());
+ file.setExecutable(true);
+ return file;
+ }
+
+ protected abstract List getParallelInitialiseScript();
+
+ protected abstract List getSerialInitialiseScript();
+
+ @Override
+ public List getDefaultInitialiseScript(Model model) {
+ List script = null;
+ if (model.getProject().isParallel()) {
+ script = getParallelInitialiseScript();
+ } else {
+ script = getSerialInitialiseScript();
+ }
+ return script;
+ }
+
+ @Override
+ public File getExtrudeScript(Model model) {
+ File parallelScript = getExtrudeParallelScript(model);
+ File serialScript = getExtrudeSerialScript(model);
+
+ if (model.getProject().isParallel()) {
+ return parallelScript;
+ } else {
+ return serialScript;
+ }
+ }
+
+ protected File getExtrudeParallelScript(Model model) {
+ File file = new File(model.getProject().getBaseDir(), Util.isWindowsScriptStyle() ? EXTRUDEMESH_PARALLEL_BAT : EXTRUDEMESH_PARALLEL_RUN);
+ writeFileIfNeeded(file, getParallelExtrudeScript());
+ file.setExecutable(true);
+ return file;
+ }
+
+ protected File getExtrudeSerialScript(Model model) {
+ File file = new File(model.getProject().getBaseDir(), Util.isWindowsScriptStyle() ? EXTRUDEMESH_SERIAL_BAT : EXTRUDEMESH_SERIAL_RUN);
+ writeFileIfNeeded(file, getSerialExtrudeScript());
+ file.setExecutable(true);
+ return file;
+ }
+
+ protected abstract List getParallelExtrudeScript();
+
+ protected abstract List getSerialExtrudeScript();
+
+ @Override
+ public List getDefaultExtrudeScript(Model model) {
+ List script = null;
+ if (model.getProject().isParallel()) {
+ script = getParallelExtrudeScript();
+ } else {
+ script = getSerialExtrudeScript();
+ }
+ return script;
+ }
+
+ @Override
+ public File getQueueLauncher(Model model) {
+ // if (Util.isWindowsScriptStyle()) {
+ // File file = new File(model.getProject().getBaseDir(), "driver.pbs");
+ // writeFileIfNeeded(file, getWindowsQueueLauncher());
+ // return file;
+ // } else {
+ File file = new File(model.getProject().getBaseDir(), "pbs.run");
+ writeFileIfNeeded(file, getLinuxQueueLauncher());
+ return file;
+ // }
+ }
+
+ protected abstract List getWindowsQueueLauncher();
+
+ protected abstract List getLinuxQueueLauncher();
+
+ @Override
+ public List getDefaultQueueLauncher(Model model) {
+ return getLinuxQueueLauncher();
+ }
+
+ protected abstract List getWindowsSetupCaseScript();
+
+ protected abstract List getLinuxSetupCaseScript();
+
+ @Override
+ public File getExportScript(Model model) {
+ File file = new File(model.getProject().getBaseDir(), "export.py");
+ writeFileIfNeeded(file, getExportScript());
+ return file;
+ }
+
+ @Override
+ public List getDefaultExportScript(Model model) {
+ return getExportScript();
+ }
+
+ protected abstract List getExportScript();
+
+ protected void writeFileIfNeeded(File file, List script) {
+ if (!file.exists()) {
+ IOUtils.writeLinesToFile(file, script);
+ file.setExecutable(true);
+ }
+ }
+}
diff --git a/src/eu/engys/core/controller/ApplicationActions.java b/src/eu/engys/core/controller/ApplicationActions.java
new file mode 100644
index 0000000..6c5f5ef
--- /dev/null
+++ b/src/eu/engys/core/controller/ApplicationActions.java
@@ -0,0 +1,44 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.core.controller;
+
+import java.io.File;
+
+import eu.engys.core.controller.Controller.OpenOptions;
+import eu.engys.core.project.CaseParameters;
+
+public interface ApplicationActions {
+
+ void createCase(CaseParameters params);
+
+ void openCase(File file);
+
+ void reopenCase(OpenOptions options);
+
+ void saveCase(File file);
+
+}
diff --git a/src/eu/engys/core/controller/BatchActions.java b/src/eu/engys/core/controller/BatchActions.java
new file mode 100644
index 0000000..1dccc86
--- /dev/null
+++ b/src/eu/engys/core/controller/BatchActions.java
@@ -0,0 +1,46 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.core.controller;
+
+import java.io.File;
+
+import eu.engys.core.controller.Controller.OpenOptions;
+import eu.engys.core.controller.actions.TimeoutException;
+import eu.engys.core.project.CaseParameters;
+
+public interface BatchActions {
+
+ void create(CaseParameters params);
+ void open(File file);
+ void reopen(OpenOptions options);
+ void save(File file);
+
+ void setupCase();
+ void stopCase() throws TimeoutException;
+ void kill();
+
+}
diff --git a/src/eu/engys/core/controller/Client.java b/src/eu/engys/core/controller/Client.java
new file mode 100644
index 0000000..a5aa530
--- /dev/null
+++ b/src/eu/engys/core/controller/Client.java
@@ -0,0 +1,62 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.controller;
+
+import javax.swing.JComponent;
+
+import eu.engys.core.project.system.monitoringfunctionobjects.ParserView;
+
+public interface Client {
+
+ void executeCommand(Command command);
+
+ void executeCommands(Command... command);
+
+ ParserView getResidualView();
+
+ void refreshOnce();
+
+ void loadState();
+
+ void stopCommand(Command command);
+
+ void killCommand(Command command);
+
+ void goToBatch();
+
+ void reset();
+
+ Server getServer();
+
+ void createReport();
+
+ JComponent getServerPanel();
+
+ JComponent getQueuePanel();
+
+ void waitForFinished();
+
+}
diff --git a/src/eu/engys/core/controller/ClientInfo.java b/src/eu/engys/core/controller/ClientInfo.java
new file mode 100644
index 0000000..719c8b3
--- /dev/null
+++ b/src/eu/engys/core/controller/ClientInfo.java
@@ -0,0 +1,50 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.controller;
+
+import java.io.Serializable;
+
+public class ClientInfo implements Serializable {
+
+ private boolean connected;
+
+ private ClientInfo(boolean connected) {
+ this.connected = connected;
+ }
+
+ public boolean isConnected() {
+ return connected;
+ }
+
+ public static ClientInfo clientConnected() {
+ return new ClientInfo(true);
+ }
+
+ public static ClientInfo clientDisconnected() {
+ return new ClientInfo(false);
+ }
+
+}
diff --git a/src/eu/engys/core/controller/ClientServerCommand.java b/src/eu/engys/core/controller/ClientServerCommand.java
new file mode 100644
index 0000000..4ecee38
--- /dev/null
+++ b/src/eu/engys/core/controller/ClientServerCommand.java
@@ -0,0 +1,99 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.controller;
+
+import java.io.Serializable;
+
+public class ClientServerCommand implements Serializable {
+
+ private Command[] commands;
+ private String open;
+ private boolean parallel;
+ private boolean startParsers;
+ private boolean queue;
+
+ public ClientServerCommand(Command... commands) {
+ this.commands = commands;
+ this.open = null;
+ this.parallel = false;
+ this.startParsers = false;
+ }
+
+ public ClientServerCommand(Command command, String open, boolean parallel, boolean startParsers) {
+ this.commands = new Command[]{command};
+ this.open = open;
+ this.parallel = parallel;
+ this.startParsers = startParsers;
+ }
+
+ public Command getCommand() {
+ return commands[0];
+ }
+
+ public Command[] getCommands() {
+ return commands;
+ }
+
+ public void setCommands(Command[] commands) {
+ this.commands = commands;
+ }
+
+ public String getOpen() {
+ return open;
+ }
+
+ public void setOpen(String open) {
+ this.open = open;
+ }
+
+ public boolean isParallel() {
+ return parallel;
+ }
+
+ public void setParallel(boolean parallel) {
+ this.parallel = parallel;
+ }
+
+ public boolean isStartParsers() {
+ return startParsers;
+ }
+
+ public void setStartParsers(boolean startParsers) {
+ this.startParsers = startParsers;
+ }
+
+ public boolean isCommandSequence() {
+ return commands.length > 1;
+ }
+
+ public void setQueue(boolean queue) {
+ this.queue = queue;
+ }
+
+ public boolean isQueue() {
+ return queue;
+ }
+}
diff --git a/src/eu/engys/core/controller/Command.java b/src/eu/engys/core/controller/Command.java
new file mode 100644
index 0000000..fbbc050
--- /dev/null
+++ b/src/eu/engys/core/controller/Command.java
@@ -0,0 +1,59 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.controller;
+
+public enum Command {
+
+ CREATE_MESH("", ""),
+ RUN_CASE("", ""),
+ INITIALISE_FIELDS("", ""),
+ RUN_ALL("", ""),
+ EXTRUDE_TO_REGION("", ""),
+ ANY("any", "Any"),
+ NONE("none", "None");
+
+ private String key;
+ private String label;
+
+ private Command(String key, String label) {
+ this.key = key;
+ this.label = label;
+ }
+
+ public String label() {
+ return label;
+ }
+
+ public String key() {
+ return key;
+ }
+
+ public boolean isRunCase(){
+ return this == RUN_CASE || this == RUN_ALL;
+ }
+
+
+}
diff --git a/src/eu/engys/core/controller/CommandInfo.java b/src/eu/engys/core/controller/CommandInfo.java
new file mode 100644
index 0000000..81afbf7
--- /dev/null
+++ b/src/eu/engys/core/controller/CommandInfo.java
@@ -0,0 +1,91 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.controller;
+
+import java.io.Serializable;
+import java.rmi.RemoteException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CommandInfo implements Serializable {
+
+ private static final Logger logger = LoggerFactory.getLogger(CommandInfo.class);
+
+ public boolean success;
+ public String message;
+ public Exception exception;
+ public String jobID;
+
+ public static CommandInfo remoteException(RemoteException e) {
+ logger.warn(">>> SERVER REMOTE ERROR", e);
+ CommandInfo ci = new CommandInfo();
+ ci.message = "Error";
+ ci.exception = e;
+ ci.success = false;
+ return ci;
+ }
+
+ public static CommandInfo genericException(Exception e) {
+ logger.error(">>> SERVER GENERIC ERROR", e);
+ CommandInfo ci = new CommandInfo();
+ ci.message = "Error";
+ ci.exception = e;
+ ci.success = false;
+ return ci;
+ }
+
+ public static CommandInfo error(String message) {
+ logger.warn(">>> SERVER WARNING: {}", message);
+ CommandInfo ci = new CommandInfo();
+ ci.message = message;
+ ci.exception = null;
+ ci.success = false;
+ return ci;
+ }
+
+ public static CommandInfo notConnected() {
+ CommandInfo ci = new CommandInfo();
+ ci.message = "Not Connected";
+ ci.exception = null;
+ ci.success = false;
+ return ci;
+ }
+
+ public static CommandInfo success() {
+ return success("Success");
+ }
+
+ public static CommandInfo success(String message) {
+ logger.info(">>> SERVER: {}", message);
+ CommandInfo ci = new CommandInfo();
+ ci.message = message;
+ ci.exception = null;
+ ci.success = true;
+ return ci;
+ }
+
+}
diff --git a/src/eu/engys/core/controller/Controller.java b/src/eu/engys/core/controller/Controller.java
new file mode 100644
index 0000000..a8aedc9
--- /dev/null
+++ b/src/eu/engys/core/controller/Controller.java
@@ -0,0 +1,68 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.core.controller;
+
+import eu.engys.core.controller.actions.CommandException;
+import eu.engys.core.project.ProjectReader;
+import eu.engys.core.project.ProjectWriter;
+import eu.engys.core.project.system.monitoringfunctionobjects.ParserView;
+
+public interface Controller extends ApplicationActions, BatchActions {
+
+ public enum CloseOptions {
+ EXIT, CONTINUE, NONE
+ }
+
+ public enum OpenOptions {
+ SERIAL, PARALLEL, CURRENT_SETTINGS, CHECK_FOLDER, MESH_ONLY
+ }
+
+ boolean isDemo();
+
+ ProjectWriter getWriter();
+ ProjectReader getReader();
+
+ void addListener(ControllerListener l);
+ ControllerListener getListener();
+
+ public Client getClient();
+ public Server getServer();
+ public ParserView getResidualView();
+
+ boolean allowActionsOnRunning(boolean exit);
+
+ void createReport();
+
+ void executeCommand(Command command) throws CommandException;
+
+ void executeCommands(Command... commands) throws CommandException;
+
+ String submitCommand(Command command) throws CommandException;
+
+ boolean isRunningCommand();
+
+}
diff --git a/src/eu/engys/core/controller/ControllerListener.java b/src/eu/engys/core/controller/ControllerListener.java
new file mode 100644
index 0000000..6225c74
--- /dev/null
+++ b/src/eu/engys/core/controller/ControllerListener.java
@@ -0,0 +1,60 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.core.controller;
+
+
+public interface ControllerListener {
+
+ void beforeNewCase();
+ void afterNewCase();
+
+ void beforeLoadCase();
+ void afterLoadCase();
+
+ void beforeReopenCase();
+ void afterReopenCase();
+
+ void beforeSaveCase();
+ void afterSaveCase();
+
+ void beforeRunCase();
+ void afterRunCase();
+
+ void beforeVirtualise();
+ void afterVirtualise(GeometryToMesh g2m);
+
+ void beforeCheckMesh();
+ void afterCheckMesh();
+
+ void selectDestinationAndGo();
+
+ void saveLocation();
+ void goToLocation();
+
+ void afterBlockMesh();
+
+}
diff --git a/src/eu/engys/core/controller/DefaultNamingConvention.java b/src/eu/engys/core/controller/DefaultNamingConvention.java
new file mode 100644
index 0000000..b8a8bdd
--- /dev/null
+++ b/src/eu/engys/core/controller/DefaultNamingConvention.java
@@ -0,0 +1,41 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.controller;
+
+import eu.engys.core.controller.actions.NamingConvention;
+import eu.engys.core.project.geometry.Surface;
+
+public class DefaultNamingConvention implements NamingConvention {
+ @Override
+ public String getCellZoneName(Surface surface) {
+ return surface.getZoneName();
+ }
+
+ @Override
+ public String getPatchName(Surface surface) {
+ return surface.getPatchName();
+ }
+}
diff --git a/src/eu/engys/core/controller/DefaultScriptFactory.java b/src/eu/engys/core/controller/DefaultScriptFactory.java
new file mode 100644
index 0000000..03fb1d2
--- /dev/null
+++ b/src/eu/engys/core/controller/DefaultScriptFactory.java
@@ -0,0 +1,398 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.core.controller;
+
+import static eu.engys.core.OpenFOAMEnvironment.loadEnvironment;
+import static eu.engys.core.OpenFOAMEnvironment.printHeader;
+import static eu.engys.core.OpenFOAMEnvironment.printVariables;
+import static eu.engys.util.OpenFOAMCommands.BLOCK_MESH;
+import static eu.engys.util.OpenFOAMCommands.DECOMPOSE_PAR;
+import static eu.engys.util.OpenFOAMCommands.DECOMPOSE_PAR_ALLREGIONS;
+import static eu.engys.util.OpenFOAMCommands.DECOMPOSE_PAR_CONSTANT_ALLREGIONS;
+import static eu.engys.util.OpenFOAMCommands.EXTRUDE_REGION_TO_MESH;
+import static eu.engys.util.OpenFOAMCommands.INITIALISE_FIELDS_PARALLEL;
+import static eu.engys.util.OpenFOAMCommands.INITIALISE_FIELDS_SERIAL;
+import static eu.engys.util.OpenFOAMCommands.RECONSTRUCT_PAR_MESH;
+import static eu.engys.util.OpenFOAMCommands.RECONSTRUCT_PAR_MESH_CONSTANT;
+import static eu.engys.util.OpenFOAMCommands.RUN_CASE_PARALLEL;
+import static eu.engys.util.OpenFOAMCommands.RUN_CASE_SERIAL;
+import static eu.engys.util.OpenFOAMCommands.RUN_MESH_PARALLEL;
+import static eu.engys.util.OpenFOAMCommands.RUN_MESH_SERIAL;
+//import static eu.engys.util.OpenFOAMCommands.CHECK_MESH_PARALLEL;
+//import static eu.engys.util.OpenFOAMCommands.CHECK_MESH_SERIAL;
+import static eu.engys.util.OpenFOAMCommands.SNAPPY_CHECK_MESH_PARALLEL;
+import static eu.engys.util.OpenFOAMCommands.SNAPPY_CHECK_MESH_SERIAL;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.commons.io.FileUtils;
+
+import eu.engys.core.project.Model;
+import eu.engys.util.IOUtils;
+import eu.engys.util.Util;
+import eu.engys.util.connection.QueueParameters;
+
+public class DefaultScriptFactory extends AbstractScriptFactory {
+
+ private static final String DO_NOT_EDIT_BELOW_THIS_LINE = "# DO NOT EDIT BELOW THIS LINE";
+ private static final String DO_NOT_EDIT_ABOVE_THIS_LINE = "# DO NOT EDIT ABOVE THIS LINE";
+ protected Model model;
+
+ @Inject
+ public DefaultScriptFactory(Model model) {
+ this.model = model;
+ }
+
+ /*
+ * MESH
+ */
+
+ @Override
+ protected List getSerialMeshScript() {
+ ScriptBuilder sb = new ScriptBuilder();
+ printHeader(sb, RUN_MESH);
+ printVariables(sb);
+ loadEnvironment(sb);
+ sb.newLine();
+ sb.appendIf(performBlockMesh(), BLOCK_MESH());
+ sb.newLine();
+ sb.append(RUN_MESH_SERIAL());
+ sb.newLine();
+ return sb.getLines();
+ }
+
+ @Override
+ protected List getParallelMeshScript() {
+ ScriptBuilder sb = new ScriptBuilder();
+ printHeader(sb, RUN_MESH);
+ printVariables(sb);
+ loadEnvironment(sb);
+ sb.newLine();
+ sb.appendIf(performBlockMesh(), BLOCK_MESH());
+ sb.newLine();
+ sb.appendIf(performBlockMesh(), DECOMPOSE_PAR());
+ sb.newLine();
+ sb.append(RUN_MESH_PARALLEL());
+ sb.newLine();
+ sb.appendIf(performBlockMesh() && Util.isUnixScriptStyle(), "rm -rf constant/polyMesh");
+ sb.newLine();
+ return sb.getLines();
+ }
+
+ @Override
+ protected List getSerialCheckMeshScript() {
+ ScriptBuilder sb = new ScriptBuilder();
+ printHeader(sb, CHECK_MESH);
+ printVariables(sb);
+ loadEnvironment(sb);
+ sb.newLine();
+ sb.append(SNAPPY_CHECK_MESH_SERIAL());
+ sb.newLine();
+ return sb.getLines();
+ }
+
+ @Override
+ protected List getParallelCheckMeshScript() {
+ ScriptBuilder sb = new ScriptBuilder();
+ printHeader(sb, CHECK_MESH);
+ printVariables(sb);
+ loadEnvironment(sb);
+ sb.newLine();
+ sb.append(SNAPPY_CHECK_MESH_PARALLEL());
+ sb.newLine();
+ return sb.getLines();
+ }
+
+ /*
+ * SOLVER
+ */
+
+ @Override
+ protected List getSerialSolverScript() {
+ ScriptBuilder sb = new ScriptBuilder();
+ printHeader(sb, RUN_CASE);
+ printVariables(sb);
+ loadEnvironment(sb);
+ sb.newLine();
+ sb.append(RUN_CASE_SERIAL());
+ sb.newLine();
+ return sb.getLines();
+ }
+
+ @Override
+ protected List getParallelSolverScript() {
+ ScriptBuilder sb = new ScriptBuilder();
+ printHeader(sb, RUN_CASE);
+ printVariables(sb);
+ loadEnvironment(sb);
+ sb.newLine();
+ sb.append(RUN_CASE_PARALLEL());
+ sb.newLine();
+ return sb.getLines();
+ }
+
+ /*
+ * INITIALISE
+ */
+
+ @Override
+ protected List getSerialInitialiseScript() {
+ ScriptBuilder sb = new ScriptBuilder();
+ printHeader(sb, INITIALISE_FIELDS.toUpperCase());
+ printVariables(sb);
+ loadEnvironment(sb);
+ sb.newLine();
+ sb.append(INITIALISE_FIELDS_SERIAL());
+ sb.newLine();
+ return sb.getLines();
+ }
+
+ @Override
+ protected List getParallelInitialiseScript() {
+ ScriptBuilder sb = new ScriptBuilder();
+ printHeader(sb, INITIALISE_FIELDS.toUpperCase());
+ printVariables(sb);
+ loadEnvironment(sb);
+ sb.newLine();
+ sb.append(INITIALISE_FIELDS_PARALLEL());
+ sb.newLine();
+ return sb.getLines();
+ }
+
+ /*
+ * EXTRUDE REGION
+ */
+
+ @Override
+ protected List getSerialExtrudeScript() {
+ ScriptBuilder sb = new ScriptBuilder();
+ printHeader(sb, EXTRUDEMESH.toUpperCase());
+ printVariables(sb);
+ loadEnvironment(sb);
+ sb.newLine();
+ sb.append(EXTRUDE_REGION_TO_MESH());
+ sb.newLine();
+ return sb.getLines();
+ }
+
+ @Override
+ protected List getParallelExtrudeScript() {
+ ScriptBuilder sb = new ScriptBuilder();
+ printHeader(sb, EXTRUDEMESH.toUpperCase());
+ printVariables(sb);
+ loadEnvironment(sb);
+ sb.newLine();
+ sb.appendIf(meshOnZero(), RECONSTRUCT_PAR_MESH(), RECONSTRUCT_PAR_MESH_CONSTANT());
+ sb.append(EXTRUDE_REGION_TO_MESH());
+ sb.appendIf(meshOnZero(), DECOMPOSE_PAR_ALLREGIONS(), DECOMPOSE_PAR_CONSTANT_ALLREGIONS());
+ sb.newLine();
+ return sb.getLines();
+ }
+
+ private boolean meshOnZero() {
+ return model.getProject().isMeshOnZero();
+ }
+
+ /*
+ * QUEUE
+ */
+
+ @Override
+ public List getDefaultQueueDriver(Model model) {
+ return getLinuxQueueDriver(defaultBody());
+ }
+
+ @Override
+ public File getQueueDriver(Model model) {
+ File file = new File(model.getProject().getBaseDir(), "driver.pbs");
+ List lines = null;
+ if (file.exists()) {
+ lines = getLinuxQueueDriver(extractBody(file));
+ } else {
+ lines = getLinuxQueueDriver(defaultBody());
+ }
+
+ IOUtils.writeLinesToFile(file, lines);
+ return file;
+ }
+
+ private List extractBody(File file) {
+ try {
+ return extractLine(file, DO_NOT_EDIT_ABOVE_THIS_LINE, DO_NOT_EDIT_BELOW_THIS_LINE);
+ } catch (IOException e) {
+ e.printStackTrace();
+ return Collections.emptyList();
+ }
+ }
+
+ public static List extractLine(File file, String start, String end) throws IOException {
+ List lines = FileUtils.readLines(file);
+ List support = new LinkedList();
+
+ boolean copy = false;
+ for (String l : lines) {
+ if(l.startsWith(end)){
+ break;
+ }
+ if(copy){
+ support.add(l);
+ }
+ if(l.startsWith(start)){
+ copy = true;
+ }
+ }
+ return support;
+ }
+
+ private List defaultBody() {
+ InputStream inputStream = DefaultScriptFactory.class.getClassLoader().getResourceAsStream("eu/engys/resources/driver.pbs");
+ try {
+ String body = IOUtils.readStringFromStream(inputStream);
+ return Arrays.asList(body.split(IOUtils.EOL));
+ } catch (IOException e) {
+ e.printStackTrace();
+ return Collections.emptyList();
+ }
+ }
+
+ private List getWindowsQueueDriver() {
+ throw new RuntimeException("NOT IMPLEMENTED");
+ }
+
+ private List getLinuxQueueDriver(List body) {
+
+ String name = model.getProject().getBaseDir().getName();
+ QueueParameters queueParameters = model.getSolverModel().getQueueParameters();
+ int nodes = queueParameters.getNumberOfNodes();
+ int cpus = queueParameters.getCpuPerNode();
+ int timeout = queueParameters.getTimeout();
+ String feature = queueParameters.getFeature();
+ String names = queueParameters.getNodeNames();
+
+ ScriptBuilder sb = new ScriptBuilder();
+ sb.append("#PBS -o " + name + ".out");
+ // sb.append("#PBS -e " + name + ".err");
+ sb.append("#PBS -j oe");
+ // sb.append("#PBS -k oe");
+ sb.append("#PBS -N " + name);
+ if (names == null || names.isEmpty()) {
+ sb.append("#PBS -l nodes=" + nodes + ":ppn=" + cpus + (feature.isEmpty() ? "" : (":" + feature)));
+ } else {
+ sb.append("#PBS -l nodes=" + names + ":ppn=" + cpus + (feature.isEmpty() ? "" : (":" + feature)));
+ }
+ sb.append("#PBS -l walltime=" + timeout + ":00:00");
+ sb.append("#PBS -V");
+ sb.newLine();
+ sb.append(DO_NOT_EDIT_ABOVE_THIS_LINE);
+ sb.newLine();
+ for (String line : body) {
+ sb.append(line);
+ }
+ sb.newLine();
+ sb.append(DO_NOT_EDIT_BELOW_THIS_LINE);
+ sb.newLine();
+ sb.append("echo \" Environment\"");
+ sb.append("echo \"---------------------------------\"");
+ sb.append("echo \" APPLICATION = $APPLICATION\"");
+ sb.append("echo \" ENV_LOADER = $ENV_LOADER\"");
+ sb.append("echo \" HOSTFILE = $HOSTFILE\"");
+ sb.append("echo \" CASE = $CASE\"");
+ sb.append("echo \" LOG = $LOG\"");
+ sb.append("echo \" NP = $NP\"");
+ sb.append("echo \"---------------------------------\"");
+ sb.append("echo \" PBS_O_WORKDIR = $PBS_O_WORKDIR\"");
+ sb.append("echo \" PBS_NODEFILE = $PBS_NODEFILE\"");
+ sb.append("echo \"---------------------------------\"");
+ sb.append("echo \" HOSTNAME = `hostname`\"");
+ sb.append("echo \" TIME = `date`\"");
+ sb.append("echo \" PWD = `pwd`\"");
+ sb.append("echo \"---------------------------------\"");
+ sb.newLine();
+ sb.append("unset DISPLAY");
+ sb.append("export HOSTFILE=$PBS_NODEFILE");
+ sb.append("NPROCS=`wc -l < $HOSTFILE`");
+ sb.append("NNODES=`uniq $HOSTFILE | wc -l`");
+ sb.append("echo \" Using $NPROCS processors across $NNODES nodes\"");
+ sb.newLine();
+ sb.append("cd $PBS_O_WORKDIR");
+ sb.newLine();
+ sb.append("$APPLICATION -case $CASE &> $LOG");
+ sb.newLine();
+ sb.append("exit $?");
+
+ return sb.getLines();
+ }
+
+ @Override
+ protected List getLinuxSetupCaseScript() {
+ throw new RuntimeException("NOT IMPLEMENTED");
+ }
+
+ @Override
+ protected List getWindowsSetupCaseScript() {
+ throw new RuntimeException("NOT IMPLEMENTED");
+ }
+
+ @Override
+ protected List getExportScript() {
+ throw new RuntimeException("NOT IMPLEMENTED");
+ }
+
+ @Override
+ protected List getLinuxQueueLauncher() {
+ InputStream inputStream = DefaultScriptFactory.class.getClassLoader().getResourceAsStream("eu/engys/resources/pbs.run");
+ String driverString = "";
+ try {
+ driverString = IOUtils.readStringFromStream(inputStream);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ return Arrays.asList(driverString.split(IOUtils.EOL));
+ }
+
+ @Override
+ protected List getWindowsQueueLauncher() {
+ throw new RuntimeException("NOT IMPLEMENTED");
+ }
+
+ /*
+ * UTILS
+ */
+
+ protected boolean performBlockMesh() {
+ return !model.getGeometry().isAutoBoundingBox();
+ }
+}
diff --git a/src/eu/engys/core/controller/GeometryToMesh.java b/src/eu/engys/core/controller/GeometryToMesh.java
new file mode 100644
index 0000000..be0d799
--- /dev/null
+++ b/src/eu/engys/core/controller/GeometryToMesh.java
@@ -0,0 +1,251 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.controller;
+
+import static eu.engys.core.project.system.SnappyHexMeshDict.BAFFLE_KEY;
+import static eu.engys.core.project.system.SnappyHexMeshDict.BOUNDARY_KEY;
+import static eu.engys.core.project.system.SnappyHexMeshDict.FACE_TYPE_KEY;
+import static eu.engys.core.project.system.SnappyHexMeshDict.FACE_ZONE_KEY;
+import static eu.engys.core.project.system.SnappyHexMeshDict.INSIDE;
+import static eu.engys.core.project.system.SnappyHexMeshDict.LEVELS_KEY;
+import static eu.engys.core.project.system.SnappyHexMeshDict.MODE_KEY;
+import static eu.engys.core.project.system.SnappyHexMeshDict.NONE_KEY;
+import static eu.engys.core.project.system.SnappyHexMeshDict.OUTSIDE_KEY;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import eu.engys.core.controller.actions.NamingConvention;
+import eu.engys.core.dictionary.Dictionary;
+import eu.engys.core.project.Model;
+import eu.engys.core.project.geometry.Surface;
+import eu.engys.core.project.geometry.surface.Region;
+import eu.engys.core.project.geometry.surface.Solid;
+import eu.engys.core.project.zero.cellzones.CellZone;
+import eu.engys.core.project.zero.patches.BoundaryConditions;
+import eu.engys.core.project.zero.patches.BoundaryType;
+import eu.engys.core.project.zero.patches.Patch;
+
+public class GeometryToMesh {
+
+ private static final Logger logger = LoggerFactory.getLogger(GeometryToMesh.class);
+
+ private Model model;
+ private List patches = new ArrayList<>();
+ private List cellZones = new ArrayList<>();
+
+ private List willBePatches = new ArrayList<>();
+ private List willBeCellZones = new ArrayList<>();
+
+ private NamingConvention naming;
+
+ public GeometryToMesh(Model model) {
+ this.model = model;
+ this.naming = new DefaultNamingConvention();
+ }
+
+ public String[] listPatches() {
+ extractPatchesFromGeometry();
+
+ String[] names = new String[patches.size()];
+ for (int i = 0; i < names.length; i++) {
+ names[i] = patches.get(i).getName();
+ }
+
+ return names;
+ }
+
+ public void execute() {
+ model.getPatches().clear();
+ model.getCellZones().clear();
+
+ extractPatchesFromGeometry();
+
+ model.getPatches().addPatches(patches);
+ model.getCellZones().addZones(cellZones);
+ }
+
+ public List getWillBePatches() {
+ return willBePatches;
+ }
+
+ public List getWillBeCellZones() {
+ return willBeCellZones;
+ }
+
+ private void extractPatchesFromGeometry() {
+ for (Surface surface : model.getGeometry().getSurfaces()) {
+ logger.debug("Surface {}: {} {} {}", surface.getName(), surface.getSurfaceDictionary(), surface.getVolumeDictionary(), surface.getZoneDictionary());
+ surfaceToPatch(surface);
+ surfaceToCellZone(surface);
+ }
+
+ if (model.getGeometry().hasBlock()) {
+ surfaceToPatch(model.getGeometry().getBlock());
+ }
+ }
+
+ private void surfaceToCellZone(Surface surface) {
+ if (willBeACellZone(surface)) {
+ if (willCreatePatches(surface)) {
+ zoneToPatches(surface);
+ } else {
+ logger.debug("'{}' does NOT become a PATCH+SLAVE", surface.getName());
+ }
+ String zoneName = naming.getCellZoneName(surface);
+ CellZone zone = new CellZone(zoneName);
+ zone.setName(zoneName);
+ zone.setVisible(true);
+ zone.setLoaded(true);
+
+ logger.debug("'{}' becomes a ZONE with name {}", surface.getName(), zoneName);
+
+ cellZones.add(zone);
+ willBeCellZones.add(surface);
+ } else {
+ logger.debug("'{}' does NOT become a ZONE", surface.getName());
+ }
+ }
+
+ private void zoneToPatches(Surface surface) {
+ if (surface.hasRegions()) {
+ if (surface.isSingleton()) {
+ addPatchAndSlave(surface.getRegions()[0]);
+ } else if (isBaffle(surface)) {
+ addPatchAndSlave(surface.getRegions()[0]);
+ } else if (isBoundary(surface)) {
+ for (Region region : surface.getRegions()) {
+ addPatchAndSlave(region);
+ }
+ }
+ } else {
+ addPatchAndSlave(surface);
+ }
+ }
+
+ private boolean willBeACellZone(Surface surface) {
+ Dictionary zoneDictionary = surface.getZoneDictionary();
+ return zoneDictionary != null && !zoneDictionary.isEmpty() && zoneDictionary.isField(FACE_ZONE_KEY) && zoneDictionary.found(FACE_TYPE_KEY) && !zoneDictionary.lookup(FACE_TYPE_KEY).equals(NONE_KEY);
+ }
+
+ private boolean willCreatePatches(Surface surface) {
+ Dictionary zoneDictionary = surface.getZoneDictionary();
+ return zoneDictionary.found(FACE_TYPE_KEY) && (zoneDictionary.lookup(FACE_TYPE_KEY).equals(BOUNDARY_KEY) || zoneDictionary.lookup(FACE_TYPE_KEY).equals(BAFFLE_KEY));
+ }
+
+ private boolean isBoundary(Surface surface) {
+ Dictionary zoneDictionary = surface.getZoneDictionary();
+ return zoneDictionary.lookup(FACE_TYPE_KEY).equals(BOUNDARY_KEY);
+ }
+
+ private boolean isBaffle(Surface surface) {
+ Dictionary zoneDictionary = surface.getZoneDictionary();
+ return zoneDictionary.lookup(FACE_TYPE_KEY).equals(BAFFLE_KEY);
+ }
+
+ private void surfaceToPatch(Surface surface) {
+ if (surface.isSingleton()) {
+ addPatch(surface);
+ } else if (surface.hasRegions()) {
+ for (Region region : surface.getRegions()) {
+ addPatch(region);
+ }
+ } else {
+ addPatch(surface);
+ }
+ }
+
+ private void addPatch(Surface surface) {
+ if (willBeAPatch(surface)) {
+ String patchName = naming.getPatchName(surface);
+ logger.debug("'{}' becomes a PATCH with name {}, {}", surface.getName(), patchName, surface.getSurfaceDictionary());
+ patches.add(newPatch(patchName));
+ willBePatches.add(surface);
+ } else {
+ logger.debug("'{}' does NOT become a PATCH", surface.getName());
+ }
+ }
+
+ private void addPatchAndSlave(Surface surface) {
+ String patchName = naming.getPatchName(surface);
+ String slaveName = patchName + "_slave";
+ logger.debug("'{}' becomes 2 PATCHES with name {} and {}", surface.getName(), patchName, slaveName);
+ patches.add(newPatch(patchName));
+ willBePatches.add(surface);
+ patches.add(newPatch(slaveName));
+ willBePatches.add(surface);
+ }
+
+ private Patch newPatch(String name) {
+ Patch patch = new Patch(name);
+ patch.setName(name);
+ patch.setDictionary(new Dictionary(name));
+ patch.setVisible(true);
+ patch.setLoaded(true);
+ patch.setEmpty(false);
+ patch.setPhisicalType(BoundaryType.getDefaultType());
+ patch.setBoundaryConditions(new BoundaryConditions());
+ return patch;
+ }
+
+ private boolean willBeAPatch(Surface surface) {
+ return surface.getType().isPlane()
+ || (surface.getType().isStl() && surface.isSingleton() && isSurfaceRefinementOnly(surface))
+ || (surface.getType().isSolid() && willBeAPatch(((Solid)surface).getParent()) )
+ || (!surface.getType().isSolid() && isSurfaceRefinementOnly(surface));
+ }
+
+ private boolean isSurfaceRefinementOnly(Surface surface) {
+ boolean surfaceRefinement = isSurfaceRefinement(surface);
+ boolean volumeRefinement = isVolumeRefinement(surface);
+ boolean willBeACellZone = willBeACellZone(surface);
+
+ // System.err.println("GeometryToMesh.isSurfaceRefinementOnly() surfaceRefinement: "+surfaceRefinement+", volumeRefinement: "+volumeRefinement+", willBeACellZone: "+willBeACellZone);
+ return surfaceRefinement && !volumeRefinement && !willBeACellZone;
+ }
+
+ private boolean isVolumeRefinement(Surface surface) {
+ Dictionary volumeDictionary = surface.getVolumeDictionary();
+ return volumeDictionary != null && !volumeDictionary.isEmpty() && volumeDictionary.isField(LEVELS_KEY) && volumeDictionary.isField(MODE_KEY) && (volumeDictionary.lookup(MODE_KEY).equals(INSIDE) || volumeDictionary.lookup(MODE_KEY).equals(OUTSIDE_KEY));
+ }
+
+ private boolean isSurfaceRefinement(Surface surface) {
+ Dictionary surfaceDictionary = surface.getSurfaceDictionary();
+ return surfaceDictionary != null && !surfaceDictionary.isEmpty() && surfaceDictionary.isField("level");
+ }
+
+ public String getPatchName(Surface surface) {
+ return naming.getPatchName(surface);
+ }
+
+ public String getCellZoneName(Surface surface) {
+ return naming.getCellZoneName(surface);
+ }
+
+}
diff --git a/src/eu/engys/core/controller/HelyxOSController.java b/src/eu/engys/core/controller/HelyxOSController.java
new file mode 100644
index 0000000..26c3443
--- /dev/null
+++ b/src/eu/engys/core/controller/HelyxOSController.java
@@ -0,0 +1,428 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.controller;
+
+import static eu.engys.core.project.system.SetFieldsDict.CELL_SET_KEY;
+
+import java.io.File;
+import java.util.List;
+import java.util.Set;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.ThreadPoolExecutor;
+
+import javax.swing.JOptionPane;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.inject.Inject;
+
+import eu.engys.core.controller.actions.CheckMesh;
+import eu.engys.core.controller.actions.InitialiseFields;
+import eu.engys.core.controller.actions.RunCommand;
+import eu.engys.core.controller.actions.StandardInitialiseFields;
+import eu.engys.core.controller.actions.StandardRunCase;
+import eu.engys.core.controller.actions.StandardRunMesh;
+import eu.engys.core.controller.actions.TimeoutException;
+import eu.engys.core.executor.Executor;
+import eu.engys.core.modules.ApplicationModule;
+import eu.engys.core.presentation.Action;
+import eu.engys.core.presentation.ActionManager;
+import eu.engys.core.project.Model;
+import eu.engys.core.project.ProjectReader;
+import eu.engys.core.project.ProjectWriter;
+import eu.engys.core.project.state.ServerState;
+import eu.engys.core.project.system.monitoringfunctionobjects.ParserView;
+import eu.engys.core.project.system.monitoringfunctionobjects.TimeBlocks;
+import eu.engys.core.project.zero.cellzones.CellZonesBuilder;
+import eu.engys.core.project.zero.fields.Field;
+import eu.engys.gui.casesetup.fields.StandardInitialisations;
+import eu.engys.gui.events.EventManager;
+import eu.engys.gui.events.EventManager.Event;
+import eu.engys.gui.events.EventManager.GenericEventListener;
+import eu.engys.gui.events.application.ApplicationEvent;
+import eu.engys.gui.events.application.BaseMeshTypeChangedEvent;
+import eu.engys.gui.events.application.OpenMonitorEvent;
+import eu.engys.gui.solver.postprocessing.ParsersHandler;
+import eu.engys.gui.solver.postprocessing.ParsersViewHandler;
+import eu.engys.gui.solver.postprocessing.panels.residuals.ResidualsView;
+import eu.engys.util.progress.ProgressMonitor;
+import eu.engys.util.ui.ScriptEditor;
+import eu.engys.util.ui.UiUtil;
+
+public class HelyxOSController extends AbstractController implements GenericEventListener, ParsersManager {
+
+ private static final long TIMER_INITIAL_DELAY = 500L;
+ private static final long TIMER_REFRESH_RATE = 1000L;
+
+ private static final Logger logger = LoggerFactory.getLogger(HelyxOSController.class);
+ private ResidualsView residualsView;
+ private RunCommand command;
+
+ private Timer timer;
+ private ParsersHandler parsersHandler;
+ private ParsersViewHandler viewHandler;
+ private ThreadPoolExecutor executor;
+
+ @Inject
+ public HelyxOSController(Model model, CellZonesBuilder cellZonesBuilder, Set modules, ProjectReader reader, ProjectWriter writer, CellZonesBuilder zonesBuilder, ProgressMonitor monitor, ScriptFactory scriptFactory) {
+ super(model, modules, reader, writer, zonesBuilder, monitor, scriptFactory);
+ this.residualsView = new ResidualsView(model, monitor);
+ EventManager.registerEventListener(this, ApplicationEvent.class);
+ ActionManager.getInstance().parseActions(this);
+ }
+
+ @Override
+ public void eventTriggered(Object obj, Event e) {
+ logger.info("Event triggered {}", e.getClass().getName());
+ if (e instanceof OpenMonitorEvent) {
+ monitor.start(null);
+ } else if (e instanceof BaseMeshTypeChangedEvent) {
+ scriptFactory.getMeshScript(model).delete();
+ }
+ }
+
+ /*
+ * MESH
+ */
+
+ @Action(key = "mesh.create", checkEnv = true)
+ public void runMesh() {
+ save(model.getProject().getBaseDir());
+
+ command = new StandardRunMesh(model, this, scriptFactory);
+ command.beforeExecute();
+ command.executeClient();
+ }
+
+ @Action(key = "mesh.check", checkEnv = true)
+ public void checkMesh() {
+ model.getProject().getSystemFolder().write(model, null);
+ RunCommand checkMesh = new CheckMesh(model, this, scriptFactory);
+ checkMesh.beforeExecute();
+ checkMesh.executeClient();
+ }
+
+ /*
+ * CASE SETUP
+ */
+ @Override
+ public void setupCase() {
+ /* JUST REOPEN IN THIS CASE */
+ monitor.start("Open " + model.getProject().getBaseDir(), false, new Runnable() {
+ @Override
+ public void run() {
+ reopen(OpenOptions.CURRENT_SETTINGS);
+ monitor.end();
+ }
+ });
+ }
+
+ @Action(key = "initialise.fields", checkEnv = true)
+ public void initialiseFields() {
+ if (model.getProject().getZeroFolder().hasNonZeroTimeFolders()) {
+ int retVal = JOptionPane.showConfirmDialog(UiUtil.getActiveWindow(), "This action will DELETE all the time folders. Continue?", "Initialise Fields", JOptionPane.YES_NO_OPTION);
+ if (retVal == JOptionPane.YES_OPTION) {
+ model.getProject().getSystemFolder().getControlDict().startFromZero();
+ model.projectChanged();
+ } else {
+ return;
+ }
+ }
+ monitor.start(InitialiseFields.ACTION_NAME, false, new Runnable() {
+ @Override
+ public void run() {
+ save(null);
+ monitor.end();
+ }
+ });
+
+ new StandardInitialisations(model, cellZonesBuilder, modules).initializeFields();
+ if (cellSetFieldPresent()) {
+ save(model.getProject().getBaseDir());
+
+ command = new StandardInitialiseFields(model, this, scriptFactory);
+ command.beforeExecute();
+ command.executeClient();
+ }
+ }
+
+ public boolean cellSetFieldPresent() {
+ for (Field f : model.getFields().values()) {
+ if (f.getInitialisationType().equals(CELL_SET_KEY)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /*
+ * SOLVER
+ */
+
+ private void startTimer() {
+ startParsers();
+ viewHandler = new ParsersViewHandler(model, this, residualsView);
+
+ executor = Executor.newExecutor("ServerStateMonitor");
+ if (timer == null) {
+ timer = new Timer("- Client Monitor -", true);
+ }
+ timer.schedule(new TimerTask() {
+ @Override
+ public void run() {
+ if (executor.getQueue().isEmpty()) {
+ executor.submit(new Runnable() {
+ @Override
+ public void run() {
+ runTimer();
+ }
+
+ });
+ } else {
+ logger.debug("Timer running...");
+ }
+ }
+ }, TIMER_INITIAL_DELAY, TIMER_REFRESH_RATE);
+ }
+
+ private void runTimer() {
+ ServerState state = model.getSolverModel().getServerState();
+ Command c = state.getCommand();
+ logger.debug("RUN TIMER, STATE IS {}", state.getSolverState());
+ if (c.isRunCase()) {
+ viewHandler.serverChanged(state);
+ if (state.getSolverState().isFinished() || state.getSolverState().isError()) {
+ stopTimer();
+ }
+ }
+ }
+
+ private void stopTimer() {
+ logger.debug("STOP TIMER");
+ if (viewHandler != null) {
+ viewHandler = null;
+ }
+ if (executor != null) {
+ executor.shutdown();
+ executor = null;
+ }
+ if (timer != null) {
+ timer.cancel();
+ timer.purge();
+ timer = null;
+ }
+ }
+
+ @Action(key = "solver.run", checkEnv = true)
+ public void runCase() {
+ save(model.getProject().getBaseDir());
+
+ listener.beforeRunCase();
+ command = new StandardRunCase(model, this, scriptFactory);
+ command.beforeExecute();
+ command.executeClient();
+
+ startTimer();
+ }
+
+ @Action(key = "solver.refresh.once")
+ public void refreshOnce() {
+ ParsersViewHandler viewHandler = new ParsersViewHandler(model, this, residualsView);
+ viewHandler.refreshOnce();
+ }
+
+ @Override
+ @Action(key = "solver.stop")
+ public void stopCase() {
+ monitor.setIndeterminate(true);
+ monitor.start("Stop Solver", false, new Runnable() {
+ @Override
+ public void run() {
+ _stopCase();
+ monitor.info("DONE");
+ monitor.end();
+ }
+
+ });
+ }
+
+ private void _stopCase() {
+ try {
+ command.stop();
+ } catch (TimeoutException e) {
+ Object[] options = new Object[] { "Wait", "Kill Process" };
+ int option = JOptionPane.showOptionDialog(monitor.getDialog(), "Solver has not finished yet.\nSelect an action to perform.", "Stop Execution", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]);
+ if (timer != null) {
+ if (option == JOptionPane.YES_OPTION) {
+ _stopCase();
+ } else {
+ _kill();
+ }
+
+ }
+ }
+ }
+
+ @Override
+ public void kill() {
+ monitor.setIndeterminate(true);
+ monitor.start("Killing Command", false, new Runnable() {
+ @Override
+ public void run() {
+ _kill();
+ monitor.info("DONE");
+ monitor.end();
+ }
+
+ });
+ }
+
+ private void _kill() {
+ command.kill();
+ }
+
+ /*
+ * EDIT SCRIPTS
+ */
+
+ @Action(key = "solver.run.edit")
+ public void editRunCaseScript() {
+ ScriptEditor.getInstance().show(scriptFactory.getSolverScript(model).toPath(), scriptFactory.getDefaultSolverScript(model));
+ }
+
+ @Action(key = "mesh.create.edit")
+ public void editRunMeshScript() {
+ ScriptEditor.getInstance().show(scriptFactory.getMeshScript(model).toPath(), scriptFactory.getDefaultMeshScript(model));
+ }
+
+ @Action(key = "mesh.check.edit")
+ public void editCheckMeshScript() {
+ ScriptEditor.getInstance().show(scriptFactory.getCheckMeshScript(model).toPath(), scriptFactory.getDefaultCheckMeshScript(model));
+ }
+
+ @Action(key = "initialise.fields.edit")
+ public void editInitialiseScript() {
+ ScriptEditor.getInstance().show(scriptFactory.getInitialiseScript(model).toPath(), scriptFactory.getDefaultInitialiseScript(model));
+ }
+
+ /*
+ * Parsers
+ */
+ @Override
+ public void startParsers() {
+ logger.info("[SERVER] START PARSERS");
+ parsersHandler = new ParsersHandler(model);
+ parsersHandler.deleteUselessLogFiles();
+ }
+
+ @Override
+ public void endParsers() {
+ logger.info("[SERVER] END PARSERS");
+ if (parsersHandler != null) {
+ parsersHandler.endParsers();
+ parsersHandler = null;
+ }
+ }
+
+ @Override
+ public List updateParser(String foName) {
+ logger.info("[SERVER] UPDATE PARSERS");
+ return parsersHandler.refreshParsersForFunctionObject(foName);
+ }
+
+ @Override
+ public List updateParserOnce(String foName) {
+ logger.info("[SERVER] UPDATE PARSERS ONCE");
+ ParsersHandler ph = new ParsersHandler(model);
+ return ph.refreshOnceForFunctionObject(foName);
+ }
+
+ /*
+ * OTHER
+ */
+
+ @Override
+ public ParserView getResidualView() {
+ return residualsView;
+ }
+
+ @Override
+ public void open(File baseDir) {
+ super.open(baseDir);
+ if (listener != null) {
+ // client.loadState();
+ listener.selectDestinationAndGo();
+ }
+ }
+
+ @Override
+ public void reopen(OpenOptions options) {
+ if (listener != null) {
+ listener.saveLocation();
+ }
+
+ super.reopen(options);
+
+ if (listener != null) {
+ // client.loadState();
+ listener.goToLocation();
+ }
+
+ }
+
+ @Override
+ public Client getClient() {
+ return null;
+ }
+
+ @Override
+ public Server getServer() {
+ return null;
+ }
+
+ @Override
+ public boolean isDemo() {
+ return false;
+ }
+
+ @Override
+ protected boolean handleExitOnSolverRunning() {
+ Object[] options = new Object[] { STOP_SOLVER, KILL_SOLVER, CANCEL };
+ int option = JOptionPane.showOptionDialog(UiUtil.getActiveWindow(), "Solver is Running. Select an action to perform.", STOP_SOLVER, JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]);
+
+ if (option == JOptionPane.YES_OPTION) {
+ stopCase();
+ return true;
+ } else if (option == JOptionPane.NO_OPTION) {
+ kill();
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
diff --git a/src/eu/engys/core/controller/ILogServer.java b/src/eu/engys/core/controller/ILogServer.java
new file mode 100644
index 0000000..0f5708d
--- /dev/null
+++ b/src/eu/engys/core/controller/ILogServer.java
@@ -0,0 +1,40 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.controller;
+
+import java.io.Serializable;
+
+public interface ILogServer extends Serializable {
+
+ void start(String key);
+
+ void pump(String key, String lines);
+
+ void close();
+
+ void stop(String key);
+
+}
diff --git a/src/eu/engys/core/controller/LogClient.java b/src/eu/engys/core/controller/LogClient.java
new file mode 100644
index 0000000..97ea61f
--- /dev/null
+++ b/src/eu/engys/core/controller/LogClient.java
@@ -0,0 +1,41 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.controller;
+
+import java.io.OutputStream;
+import java.io.Serializable;
+
+public interface LogClient extends Serializable {
+
+ void start(String key, OutputStream out, OutputStream err);
+
+ void pump(String key, String lines);
+
+ void close();
+
+ void stop(String key);
+
+}
diff --git a/src/eu/engys/core/controller/ParsersManager.java b/src/eu/engys/core/controller/ParsersManager.java
new file mode 100644
index 0000000..eaefad8
--- /dev/null
+++ b/src/eu/engys/core/controller/ParsersManager.java
@@ -0,0 +1,43 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.controller;
+
+import java.rmi.RemoteException;
+import java.util.List;
+
+import eu.engys.core.project.system.monitoringfunctionobjects.TimeBlocks;
+
+public interface ParsersManager {
+
+ void startParsers() throws RemoteException;
+
+ List updateParser(String functionObjectName) throws RemoteException;
+
+ List updateParserOnce(String functionObjectName) throws RemoteException;
+
+ void endParsers() throws RemoteException;
+
+}
diff --git a/src/eu/engys/core/controller/QueueConnector.java b/src/eu/engys/core/controller/QueueConnector.java
new file mode 100644
index 0000000..0ecf225
--- /dev/null
+++ b/src/eu/engys/core/controller/QueueConnector.java
@@ -0,0 +1,36 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.controller;
+
+import java.util.Map;
+
+public interface QueueConnector {
+
+ String submit(Map env);
+
+ void kill();
+
+}
diff --git a/src/eu/engys/core/controller/QueueInfo.java b/src/eu/engys/core/controller/QueueInfo.java
new file mode 100644
index 0000000..c18d168
--- /dev/null
+++ b/src/eu/engys/core/controller/QueueInfo.java
@@ -0,0 +1,41 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.controller;
+
+import java.io.Serializable;
+import java.util.List;
+
+import com.tupilabs.pbs.model.Job;
+import com.tupilabs.pbs.model.Node;
+import com.tupilabs.pbs.model.Queue;
+
+public class QueueInfo implements Serializable {
+
+ public List nodes;
+ public List queues;
+ public List jobs;
+
+}
diff --git a/src/eu/engys/core/controller/ScriptBuilder.java b/src/eu/engys/core/controller/ScriptBuilder.java
new file mode 100644
index 0000000..4195303
--- /dev/null
+++ b/src/eu/engys/core/controller/ScriptBuilder.java
@@ -0,0 +1,65 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.controller;
+
+import java.util.LinkedList;
+import java.util.List;
+
+public class ScriptBuilder {
+
+ private List lines;
+
+ public ScriptBuilder() {
+ lines = new LinkedList();
+ }
+
+ public void append(String s) {
+ lines.add(s);
+ }
+
+ public void appendIf(boolean b, String s) {
+ if (b) {
+ lines.add(s);
+ }
+ }
+
+ public void appendIf(boolean b, String s1, String s2) {
+ if (b) {
+ lines.add(s1);
+ } else {
+ lines.add(s2);
+ }
+ }
+
+ public void newLine() {
+ lines.add("");
+ }
+
+ public List getLines() {
+ return lines;
+ }
+
+}
diff --git a/src/eu/engys/core/controller/ScriptFactory.java b/src/eu/engys/core/controller/ScriptFactory.java
new file mode 100644
index 0000000..511cf80
--- /dev/null
+++ b/src/eu/engys/core/controller/ScriptFactory.java
@@ -0,0 +1,62 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.core.controller;
+
+import java.io.File;
+import java.util.List;
+
+import eu.engys.core.project.Model;
+
+public interface ScriptFactory {
+
+ File getMeshScript(Model model);
+ List getDefaultMeshScript(Model model);
+
+ File getCheckMeshScript(Model model);
+ List getDefaultCheckMeshScript(Model model);
+
+ File getSolverScript(Model model);
+ List getDefaultSolverScript(Model model);
+
+ File getInitialiseScript(Model model);
+ List getDefaultInitialiseScript(Model model);
+
+ File getExtrudeScript(Model model);
+ List getDefaultExtrudeScript(Model model);
+
+ void deleteMeshScripts(Model model);
+
+ File getQueueDriver(Model model);
+ List getDefaultQueueDriver(Model model);
+
+ File getQueueLauncher(Model model);
+ List getDefaultQueueLauncher(Model model);
+
+ File getExportScript(Model model);
+ List getDefaultExportScript(Model model);
+
+}
diff --git a/src/eu/engys/core/controller/Server.java b/src/eu/engys/core/controller/Server.java
new file mode 100644
index 0000000..8dfbff2
--- /dev/null
+++ b/src/eu/engys/core/controller/Server.java
@@ -0,0 +1,69 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.controller;
+
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.util.List;
+
+import eu.engys.core.controller.actions.StopCommandInfo;
+import eu.engys.core.project.state.ServerState;
+
+public interface Server extends Remote, ParsersManager {
+
+ void heartBeat() throws RemoteException;
+
+ CommandInfo executeCommand(ClientServerCommand command) throws RemoteException;
+
+ StopCommandInfo stopCommand(Command command) throws RemoteException;
+
+ CommandInfo killCommand(Command command) throws RemoteException;
+
+ StateConnector getStateConnector() throws RemoteException;
+
+ ILogServer getLogConnector() throws RemoteException;
+
+ QueueConnector getQueueConnector() throws RemoteException;
+
+ List getStates() throws RemoteException;
+
+ ServerInfo start() throws Exception;
+
+ void stop() throws RemoteException;
+
+ void shutdown() throws RemoteException;
+
+ String test() throws RemoteException;
+
+ void disconnect() throws RemoteException;
+
+ QueueInfo getQueueInfo() throws RemoteException;
+
+ void goToBatch() throws RemoteException;
+
+ void connect(ClientInfo clientInfo) throws RemoteException;
+
+}
diff --git a/src/eu/engys/core/controller/ServerInfo.java b/src/eu/engys/core/controller/ServerInfo.java
new file mode 100644
index 0000000..f5ffb23
--- /dev/null
+++ b/src/eu/engys/core/controller/ServerInfo.java
@@ -0,0 +1,53 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.controller;
+
+import java.util.Scanner;
+
+public class ServerInfo {
+
+ public boolean success;
+ public String message;
+ public int port1;
+ public int port2;
+ public String date;
+ public String id;
+
+ public void decodePorts(String payload) {
+ if (payload != null && !payload.isEmpty()) {
+ Scanner scanner = new Scanner(payload);
+ String date = scanner.hasNextLine() ? scanner.nextLine() : "";
+ this.port1 = scanner.hasNextInt() ? scanner.nextInt() : 0;
+ this.port2 = scanner.hasNextInt() ? scanner.nextInt() : 0;
+ scanner.close();
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "ServerInfo - ID: " + id + ", msg: " + message + ", port1: " + port1 + ", port2: " + port2 + ", succes: " + success + "date: " + date;
+ }
+}
diff --git a/src/eu/engys/core/controller/StateConnector.java b/src/eu/engys/core/controller/StateConnector.java
new file mode 100644
index 0000000..59d1d29
--- /dev/null
+++ b/src/eu/engys/core/controller/StateConnector.java
@@ -0,0 +1,38 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.controller;
+
+import java.io.Serializable;
+
+import eu.engys.core.project.state.ServerState;
+
+public interface StateConnector extends Serializable {
+
+ void offer(ServerState serverState);
+ ServerState take();
+ ServerState peek();
+
+}
diff --git a/src/eu/engys/core/controller/StopOrKillCommandOS.java b/src/eu/engys/core/controller/StopOrKillCommandOS.java
new file mode 100644
index 0000000..7110cdb
--- /dev/null
+++ b/src/eu/engys/core/controller/StopOrKillCommandOS.java
@@ -0,0 +1,59 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.controller;
+
+import static eu.engys.core.controller.AbstractController.CANCEL;
+import static eu.engys.core.controller.AbstractController.KILL_SOLVER;
+import static eu.engys.core.controller.AbstractController.STOP_SOLVER;
+
+import javax.swing.JOptionPane;
+
+import eu.engys.core.controller.actions.TimeoutException;
+import eu.engys.util.ui.UiUtil;
+
+public class StopOrKillCommandOS implements Runnable {
+
+ private Controller controller;
+
+ public StopOrKillCommandOS(Controller controller) {
+ this.controller = controller;
+ }
+
+ @Override
+ public void run() {
+ Object[] options = new Object[] { STOP_SOLVER, KILL_SOLVER, CANCEL };
+ int option = JOptionPane.showOptionDialog(UiUtil.getActiveWindow(), "Select an action to perform.", STOP_SOLVER, JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]);
+ if (option == JOptionPane.YES_OPTION) {
+ try {
+ controller.stopCase();
+ } catch (TimeoutException e) {
+ // should never pass here
+ }
+ } else if (option == JOptionPane.NO_OPTION) {
+ controller.kill();
+ }
+ }
+}
diff --git a/src/eu/engys/core/controller/View3DOptions.java b/src/eu/engys/core/controller/View3DOptions.java
new file mode 100644
index 0000000..f1e380a
--- /dev/null
+++ b/src/eu/engys/core/controller/View3DOptions.java
@@ -0,0 +1,55 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.controller;
+
+import javax.swing.BorderFactory;
+import javax.swing.JCheckBox;
+import javax.swing.JPanel;
+
+import eu.engys.util.filechooser.gui.Options;
+import eu.engys.util.ui.builder.PanelBuilder;
+
+public class View3DOptions implements Options {
+
+ private JCheckBox loadMesh = new JCheckBox("Display Mesh After Reading", true);
+
+ @Override
+ public void onSelectionChanged() {
+ }
+
+ @Override
+ public JPanel getPanel() {
+ PanelBuilder builder = new PanelBuilder();
+ builder.addLeft(loadMesh);
+ builder.getPanel().setBorder(BorderFactory.createTitledBorder("Display Options"));
+ return builder.getPanel();
+ }
+
+ public boolean loadMesh() {
+ return loadMesh.isSelected();
+ }
+
+}
diff --git a/src/eu/engys/core/controller/actions/AbstractRunCommand.java b/src/eu/engys/core/controller/actions/AbstractRunCommand.java
new file mode 100644
index 0000000..7f7e23f
--- /dev/null
+++ b/src/eu/engys/core/controller/actions/AbstractRunCommand.java
@@ -0,0 +1,94 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.controller.actions;
+
+import java.util.concurrent.ExecutorService;
+
+import eu.engys.core.controller.Controller;
+import eu.engys.core.controller.Server;
+import eu.engys.core.executor.Executor;
+import eu.engys.core.executor.ExecutorTerminal;
+import eu.engys.core.project.Model;
+
+public abstract class AbstractRunCommand implements RunCommand {
+
+ protected Model model;
+ protected Executor executor;
+ protected Controller controller;
+ protected ExecutorService service;
+ protected ExecutorTerminal terminal;
+
+ public AbstractRunCommand(Model model, Controller controller) {
+ this.model = model;
+ this.controller = controller;
+ }
+
+ @Override
+ public void inService(ExecutorService service) {
+ this.service = service;
+ }
+
+ @Override
+ public void inTerminal(ExecutorTerminal terminal) {
+ this.terminal = terminal;
+ }
+
+ @Override
+ public boolean isRunning() {
+ return executor != null && executor.getState().isDoingSomething();
+ }
+
+ @Override
+ public void kill() {
+ executor.getService().shutdownNow();
+ }
+
+ @Override
+ public void beforeExecute() {
+ }
+
+ @Override
+ public void stop() throws TimeoutException {
+ }
+
+ @Override
+ public void executeClient() {
+ }
+
+ @Override
+ public void executeServer(Server server) throws CommandException {
+ }
+
+ @Override
+ public String executeQueue(Server server) throws CommandException {
+ return null;
+ }
+
+ @Override
+ public void executeBatch() {
+ }
+
+}
diff --git a/src/eu/engys/core/controller/actions/CheckMesh.java b/src/eu/engys/core/controller/actions/CheckMesh.java
new file mode 100644
index 0000000..c844f55
--- /dev/null
+++ b/src/eu/engys/core/controller/actions/CheckMesh.java
@@ -0,0 +1,88 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.controller.actions;
+
+import static eu.engys.core.OpenFOAMEnvironment.getEnvironment;
+import static eu.engys.core.project.openFOAMProject.LOG;
+
+import java.io.File;
+import java.nio.file.Paths;
+
+import eu.engys.core.controller.Controller;
+import eu.engys.core.controller.Controller.OpenOptions;
+import eu.engys.core.controller.ScriptFactory;
+import eu.engys.core.executor.Executor;
+import eu.engys.core.executor.ExecutorHook;
+import eu.engys.core.executor.ExecutorListener.ExecutorState;
+import eu.engys.core.executor.ExecutorMonitor;
+import eu.engys.core.executor.ExecutorTerminal;
+import eu.engys.core.executor.TerminalExecutorMonitor;
+import eu.engys.core.project.Model;
+import eu.engys.util.IOUtils;
+
+public class CheckMesh extends AbstractRunCommand {
+
+ public static final String ACTION_NAME = "Check Mesh";
+ public static final String LOG_NAME = "checkMesh.log";
+
+ private File logFile;
+ private ScriptFactory scriptFactory;
+
+ public CheckMesh(Model model, Controller controller, ScriptFactory scriptFactory) {
+ super(model, controller);
+ this.scriptFactory = scriptFactory;
+ this.logFile = Paths.get(model.getProject().getBaseDir().getAbsolutePath(), LOG, LOG_NAME).toFile();
+ }
+
+ @Override
+ public void beforeExecute() {
+ IOUtils.clearFile(logFile);
+ if (controller.getListener() != null) {
+ controller.getListener().beforeCheckMesh();
+ }
+ }
+
+ @Override
+ public void executeClient() {
+ ExecutorTerminal terminal = new TerminalExecutorMonitor(logFile);
+ ExecutorMonitor monitor = new ExecutorMonitor();
+ monitor.addHook(ExecutorState.FINISH, new FinishHook());
+
+ this.executor = Executor.script(scriptFactory.getCheckMeshScript(model)).description(ACTION_NAME).inFolder(model.getProject().getBaseDir()).inTerminal(terminal).withMonitors(monitor).env(getEnvironment(model, LOG_NAME)).keepFileOnEnd();
+ executor.exec();
+ }
+
+ private class FinishHook implements ExecutorHook {
+
+ @Override
+ public void run(ExecutorMonitor monitor) {
+ if (controller.getListener() != null) {
+ controller.reopenCase(OpenOptions.MESH_ONLY);
+ controller.getListener().afterCheckMesh();
+ }
+ }
+ }
+}
diff --git a/src/eu/engys/core/controller/actions/CommandException.java b/src/eu/engys/core/controller/actions/CommandException.java
new file mode 100644
index 0000000..707ea9b
--- /dev/null
+++ b/src/eu/engys/core/controller/actions/CommandException.java
@@ -0,0 +1,34 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.controller.actions;
+
+public class CommandException extends Exception {
+
+ public CommandException(String message) {
+ super(message);
+ }
+
+}
diff --git a/src/eu/engys/core/controller/actions/DeleteMesh.java b/src/eu/engys/core/controller/actions/DeleteMesh.java
new file mode 100644
index 0000000..e2b0c31
--- /dev/null
+++ b/src/eu/engys/core/controller/actions/DeleteMesh.java
@@ -0,0 +1,42 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.controller.actions;
+
+import eu.engys.core.controller.Controller;
+import eu.engys.core.project.Model;
+
+public class DeleteMesh extends AbstractRunCommand {
+
+ public DeleteMesh(Model model, Controller controller) {
+ super(model, controller);
+ }
+
+ @Override
+ public void executeClient() {
+ model.getProject().getZeroFolder().deleteMesh();
+ }
+
+}
diff --git a/src/eu/engys/core/controller/actions/InitialiseFields.java b/src/eu/engys/core/controller/actions/InitialiseFields.java
new file mode 100644
index 0000000..94f32cf
--- /dev/null
+++ b/src/eu/engys/core/controller/actions/InitialiseFields.java
@@ -0,0 +1,69 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.controller.actions;
+
+import static eu.engys.core.project.openFOAMProject.LOG;
+
+import java.io.File;
+import java.nio.file.Paths;
+
+import eu.engys.core.controller.Controller;
+import eu.engys.core.controller.ScriptFactory;
+import eu.engys.core.project.Model;
+import eu.engys.core.project.openFOAMProject;
+import eu.engys.core.project.zero.ZeroFileManager;
+import eu.engys.util.IOUtils;
+
+public class InitialiseFields extends AbstractRunCommand {
+
+ public static final String ACTION_NAME = "Initialise Fields";
+ public static final String LOG_NAME = "initialise.log";
+
+ protected ScriptFactory scriptFactory;
+
+ public InitialiseFields(Model model, Controller controller, ScriptFactory scriptFactory) {
+ super(model, controller);
+ this.scriptFactory = scriptFactory;
+ }
+
+ @Override
+ public void beforeExecute() {
+ IOUtils.clearFile(Paths.get(model.getProject().getBaseDir().getAbsolutePath(), LOG, LOG_NAME).toFile());
+ clearLogFolder();
+ clearPolyMesh();
+ }
+
+ private void clearLogFolder() {
+ File log = new File(model.getProject().getBaseDir(), openFOAMProject.LOG);
+ if (!log.exists())
+ log.mkdir();
+ }
+
+ private void clearPolyMesh() {
+ ((ZeroFileManager) model.getProject().getZeroFolder().getFileManager()).removeNonZeroDirs("0");
+ }
+
+}
diff --git a/src/eu/engys/core/controller/actions/NamingConvention.java b/src/eu/engys/core/controller/actions/NamingConvention.java
new file mode 100644
index 0000000..baf8d0d
--- /dev/null
+++ b/src/eu/engys/core/controller/actions/NamingConvention.java
@@ -0,0 +1,35 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.controller.actions;
+
+import eu.engys.core.project.geometry.Surface;
+
+public interface NamingConvention {
+
+ String getPatchName(Surface surface);
+
+ String getCellZoneName(Surface surface);
+}
diff --git a/src/eu/engys/core/controller/actions/RunCase.java b/src/eu/engys/core/controller/actions/RunCase.java
new file mode 100644
index 0000000..05bbd68
--- /dev/null
+++ b/src/eu/engys/core/controller/actions/RunCase.java
@@ -0,0 +1,134 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.controller.actions;
+
+import static eu.engys.core.project.system.ControlDict.CONTROL_DICT;
+import static eu.engys.core.project.system.ControlDict.END_TIME_KEY;
+import static eu.engys.core.project.system.ControlDict.STOP_AT_KEY;
+import static eu.engys.core.project.system.ControlDict.WRITE_NOW_KEY;
+
+import java.io.File;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import eu.engys.core.controller.Command;
+import eu.engys.core.controller.Controller;
+import eu.engys.core.controller.ScriptFactory;
+import eu.engys.core.dictionary.DictionaryUtils;
+import eu.engys.core.executor.ExecutorHook;
+import eu.engys.core.executor.ExecutorMonitor;
+import eu.engys.core.project.Model;
+import eu.engys.core.project.SolverState;
+import eu.engys.core.project.openFOAMProject;
+import eu.engys.core.project.state.ServerState;
+import eu.engys.core.project.system.ControlDict;
+import eu.engys.util.PrefUtil;
+
+public class RunCase extends AbstractRunCommand {
+
+ private static final Logger logger = LoggerFactory.getLogger(RunCase.class);
+
+ public static final String ACTION_NAME = "Run Case";
+ public static final String RUNNING_LABEL = "Running: ";
+
+ protected final ScriptFactory scriptFactory;
+
+ public RunCase(Model model, Controller controller, ScriptFactory scriptFactory) {
+ super(model, controller);
+ this.scriptFactory = scriptFactory;
+ }
+
+ @Override
+ public void beforeExecute() {
+ setupLogFolder();
+ setupPostProcFolder();
+ clearPolyMesh();
+ setStopAtVariableToEndTime();
+ }
+
+ private void setupLogFolder() {
+ File log = new File(model.getProject().getBaseDir(), openFOAMProject.LOG);
+ if (!log.exists())
+ log.mkdir();
+ }
+
+ private void setupPostProcFolder() {
+ File log = new File(model.getProject().getBaseDir(), openFOAMProject.POST_PROC);
+ if (!log.exists())
+ log.mkdir();
+ }
+
+ private void clearPolyMesh() {
+ model.getProject().getZeroFolder().removeNonZeroTimeFolders_GreaterThanActualTimeStep();
+ }
+
+ @Override
+ public void stop() throws TimeoutException {
+ int stop_refresh_time = PrefUtil.getInt(PrefUtil.SERVER_CONNECTION_REFRESH_TIME, 1000);
+ int stop_max_tries = PrefUtil.getInt(PrefUtil.SERVER_CONNECTION_MAX_TRIES, 60);
+
+ int tryIndex = 0;
+ while (this.executor.getState().isDoingSomething() && (tryIndex < stop_max_tries)) {
+ try {
+ Thread.sleep(stop_refresh_time);
+ } catch (Exception e) {
+ }
+ setStopAtVariableToWriteNow();
+ tryIndex++;
+ }
+ if (tryIndex >= stop_max_tries) {
+ throw new TimeoutException("Timeout stopping solver");
+ }
+ setStopAtVariableToEndTime();
+ }
+
+ private void setStopAtVariableToWriteNow() {
+ File systemFolder = model.getProject().getSystemFolder().getFileManager().getFile();
+ ControlDict controlDict = new ControlDict(new File(systemFolder, CONTROL_DICT));
+ controlDict.add(STOP_AT_KEY, WRITE_NOW_KEY);
+ controlDict.functionObjectsToList();
+ DictionaryUtils.writeDictionary(systemFolder, controlDict, null);
+ }
+
+ private void setStopAtVariableToEndTime() {
+ File systemFolder = model.getProject().getSystemFolder().getFileManager().getFile();
+ ControlDict controlDict = new ControlDict(new File(systemFolder, CONTROL_DICT));
+ if (controlDict.found(STOP_AT_KEY) && controlDict.lookup(STOP_AT_KEY).equals(WRITE_NOW_KEY)) {
+ controlDict.add(STOP_AT_KEY, END_TIME_KEY);
+ controlDict.functionObjectsToList();
+ DictionaryUtils.writeDictionary(systemFolder, controlDict, null);
+ }
+ }
+
+ protected class StartHook implements ExecutorHook {
+ @Override
+ public void run(ExecutorMonitor m) {
+ model.getSolverModel().writeState(new ServerState(Command.RUN_CASE, SolverState.RUNNING), model);
+ }
+ }
+
+}
diff --git a/src/eu/engys/core/controller/actions/RunCommand.java b/src/eu/engys/core/controller/actions/RunCommand.java
new file mode 100644
index 0000000..7e45ed2
--- /dev/null
+++ b/src/eu/engys/core/controller/actions/RunCommand.java
@@ -0,0 +1,55 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.controller.actions;
+
+import java.util.concurrent.ExecutorService;
+
+import eu.engys.core.controller.Server;
+import eu.engys.core.executor.ExecutorTerminal;
+
+public interface RunCommand {
+
+ public void beforeExecute();
+
+ public void executeClient();
+
+ public void executeBatch();
+
+ public void executeServer(Server server) throws CommandException;
+
+ public String executeQueue(Server server) throws CommandException;
+
+ public void stop() throws TimeoutException;
+
+ public void kill();
+
+ public void inService(ExecutorService service);
+
+ public void inTerminal(ExecutorTerminal terminal);
+
+ public boolean isRunning();
+
+}
diff --git a/src/eu/engys/core/controller/actions/RunMesh.java b/src/eu/engys/core/controller/actions/RunMesh.java
new file mode 100644
index 0000000..cbfebd9
--- /dev/null
+++ b/src/eu/engys/core/controller/actions/RunMesh.java
@@ -0,0 +1,74 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.controller.actions;
+
+import static eu.engys.core.project.openFOAMProject.LOG;
+
+import java.io.File;
+import java.nio.file.Paths;
+
+import eu.engys.core.controller.Controller;
+import eu.engys.core.controller.ScriptFactory;
+import eu.engys.core.project.Model;
+import eu.engys.core.project.openFOAMProject;
+import eu.engys.util.IOUtils;
+
+public class RunMesh extends AbstractRunCommand {
+
+ public static final String ACTION_NAME = "Create Mesh";
+ public static final String LOG_NAME = "snappyHexMesh.log";
+
+ protected final ScriptFactory scriptFactory;
+
+ public RunMesh(Model model, Controller controller, ScriptFactory scriptFactory) {
+ super(model, controller);
+ this.scriptFactory = scriptFactory;
+ }
+
+ @Override
+ public void beforeExecute() {
+ IOUtils.clearFile(Paths.get(model.getProject().getBaseDir().getAbsolutePath(), LOG, LOG_NAME).toFile());
+ clearPolyMesh();
+ setupLogFolder();
+ fixDecomposeParDict(model);
+ }
+
+ private void fixDecomposeParDict(Model model) {
+ model.getProject().getSystemFolder().getDecomposeParDict().toHierarchical(model);
+ }
+
+ private void clearPolyMesh() {
+ model.getProject().getZeroFolder().deleteMesh();
+ }
+
+ private void setupLogFolder() {
+ File log = new File(model.getProject().getBaseDir(), openFOAMProject.LOG);
+ if (!log.exists()) {
+ log.mkdir();
+ }
+ }
+
+}
diff --git a/src/eu/engys/core/controller/actions/StandardInitialiseFields.java b/src/eu/engys/core/controller/actions/StandardInitialiseFields.java
new file mode 100644
index 0000000..0cb18c8
--- /dev/null
+++ b/src/eu/engys/core/controller/actions/StandardInitialiseFields.java
@@ -0,0 +1,80 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.controller.actions;
+
+import static eu.engys.core.OpenFOAMEnvironment.getEnvironment;
+
+import java.io.File;
+import java.nio.file.Paths;
+import java.util.concurrent.ExecutorService;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import eu.engys.core.controller.Controller;
+import eu.engys.core.controller.Controller.OpenOptions;
+import eu.engys.core.controller.ScriptFactory;
+import eu.engys.core.executor.Executor;
+import eu.engys.core.executor.ExecutorHook;
+import eu.engys.core.executor.ExecutorListener.ExecutorState;
+import eu.engys.core.executor.ExecutorMonitor;
+import eu.engys.core.executor.ExecutorTerminal;
+import eu.engys.core.executor.TerminalExecutorMonitor;
+import eu.engys.core.project.Model;
+import eu.engys.core.project.openFOAMProject;
+
+public class StandardInitialiseFields extends InitialiseFields {
+
+ private static final Logger logger = LoggerFactory.getLogger(StandardInitialiseFields.class);
+
+ public StandardInitialiseFields(Model model, Controller controller, ScriptFactory scriptFactory) {
+ super(model, controller, scriptFactory);
+ }
+
+ @Override
+ public void executeClient() {
+ logger.debug("EXECUTE IN CLIENT");
+ File script = scriptFactory.getInitialiseScript(model);
+ File baseDir = model.getProject().getBaseDir();
+ File logFile = Paths.get(baseDir.getAbsolutePath(), openFOAMProject.LOG, LOG_NAME).toFile();
+
+ ExecutorTerminal terminal = new TerminalExecutorMonitor(logFile);
+ ExecutorMonitor monitor = new ExecutorMonitor();
+ ExecutorService service = Executor.newExecutor(ACTION_NAME);
+ monitor.addHook(ExecutorState.FINISH, new FinishHook());
+
+ this.executor = Executor.script(script).description(ACTION_NAME).inFolder(baseDir).inTerminal(terminal).withMonitors(monitor).inService(service).env(getEnvironment(model, LOG_NAME)).keepFileOnEnd();
+ executor.exec();
+ }
+
+ private class FinishHook implements ExecutorHook {
+ @Override
+ public void run(ExecutorMonitor m) {
+ controller.reopenCase(OpenOptions.CURRENT_SETTINGS);
+ }
+ }
+
+}
diff --git a/src/eu/engys/core/controller/actions/StandardRunCase.java b/src/eu/engys/core/controller/actions/StandardRunCase.java
new file mode 100644
index 0000000..fb18cca
--- /dev/null
+++ b/src/eu/engys/core/controller/actions/StandardRunCase.java
@@ -0,0 +1,108 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.controller.actions;
+
+import static eu.engys.core.OpenFOAMEnvironment.getEnvironment;
+
+import java.io.File;
+import java.nio.file.Paths;
+import java.util.concurrent.ExecutorService;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import eu.engys.core.controller.Command;
+import eu.engys.core.controller.Controller;
+import eu.engys.core.controller.ScriptFactory;
+import eu.engys.core.controller.StopOrKillCommandOS;
+import eu.engys.core.executor.Executor;
+import eu.engys.core.executor.ExecutorHook;
+import eu.engys.core.executor.ExecutorListener.ExecutorState;
+import eu.engys.core.executor.ExecutorMonitor;
+import eu.engys.core.executor.TerminalExecutorMonitor;
+import eu.engys.core.project.Model;
+import eu.engys.core.project.SolverState;
+import eu.engys.core.project.openFOAMProject;
+import eu.engys.core.project.state.ServerState;
+
+public class StandardRunCase extends RunCase {
+
+ private static final Logger logger = LoggerFactory.getLogger(StandardRunCase.class);
+
+ public StandardRunCase(Model model, Controller controller, ScriptFactory scriptFactory) {
+ super(model, controller, scriptFactory);
+ }
+
+ @Override
+ public void executeClient() {
+ logger.debug("EXECUTE IN CLIENT");
+ File logFile = Paths.get(model.getProject().getBaseDir().getAbsolutePath(), openFOAMProject.LOG, model.getSolverModel().getLogFile()).toFile();
+ TerminalExecutorMonitor terminal = new TerminalExecutorMonitor(logFile);
+ terminal.setStopCommand(new StopOrKillCommandOS(controller));
+
+ ExecutorMonitor monitor = new ExecutorMonitor();
+ monitor.addHook(ExecutorState.START, new StartHook());
+ monitor.addHook(ExecutorState.RUNNING, new RunningHook());
+ monitor.addHook(ExecutorState.FINISH, new FinishHook());
+ monitor.addHook(ExecutorState.ERROR, new ErrorHook());
+
+ ExecutorService service = Executor.newExecutor(ACTION_NAME);
+
+ File baseDir = model.getProject().getBaseDir();
+
+ this.executor = Executor.script(scriptFactory.getSolverScript(model)).description(ACTION_NAME).inFolder(baseDir).inTerminal(terminal).withMonitors(monitor).inService(service).env(getEnvironment(model, model.getSolverModel().getLogFile())).keepFileOnEnd();
+ executor.exec();
+ }
+
+ private class StartHook implements ExecutorHook {
+ @Override
+ public void run(ExecutorMonitor m) {
+ model.getSolverModel().setServerState(new ServerState(Command.RUN_CASE, SolverState.STARTED));
+ }
+ }
+
+ private class RunningHook implements ExecutorHook {
+ @Override
+ public void run(ExecutorMonitor m) {
+ model.getSolverModel().setServerState(new ServerState(Command.RUN_CASE, SolverState.RUNNING));
+ }
+ }
+
+ protected class FinishHook implements ExecutorHook {
+ @Override
+ public void run(ExecutorMonitor m) {
+ model.getSolverModel().setServerState(new ServerState(Command.RUN_CASE, SolverState.FINISHED));
+ }
+ }
+
+ protected class ErrorHook implements ExecutorHook {
+ @Override
+ public void run(ExecutorMonitor m) {
+ model.getSolverModel().setServerState(new ServerState(Command.RUN_CASE, SolverState.ERROR));
+ }
+ }
+
+}
diff --git a/src/eu/engys/core/controller/actions/StandardRunMesh.java b/src/eu/engys/core/controller/actions/StandardRunMesh.java
new file mode 100644
index 0000000..498ce38
--- /dev/null
+++ b/src/eu/engys/core/controller/actions/StandardRunMesh.java
@@ -0,0 +1,77 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.controller.actions;
+
+import static eu.engys.core.OpenFOAMEnvironment.getEnvironment;
+
+import java.io.File;
+import java.nio.file.Paths;
+import java.util.concurrent.ExecutorService;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import eu.engys.core.controller.Controller;
+import eu.engys.core.controller.ScriptFactory;
+import eu.engys.core.executor.Executor;
+import eu.engys.core.executor.ExecutorHook;
+import eu.engys.core.executor.ExecutorListener.ExecutorState;
+import eu.engys.core.executor.ExecutorMonitor;
+import eu.engys.core.executor.TerminalExecutorMonitor;
+import eu.engys.core.project.Model;
+import eu.engys.core.project.openFOAMProject;
+
+public class StandardRunMesh extends RunMesh {
+
+ private static final Logger logger = LoggerFactory.getLogger(StandardRunMesh.class);
+
+ public StandardRunMesh(Model model, Controller controller, ScriptFactory scriptFactory) {
+ super(model, controller, scriptFactory);
+ }
+
+ @Override
+ public void executeClient() {
+ logger.debug("EXECUTE IN CLIENT");
+ File baseDir = model.getProject().getBaseDir();
+ File logFile = Paths.get(baseDir.getAbsolutePath(), openFOAMProject.LOG, LOG_NAME).toFile();
+
+ ExecutorMonitor monitor = new ExecutorMonitor();
+ monitor.addHook(ExecutorState.FINISH, new FinishHook());
+
+ ExecutorService service = Executor.newExecutor(ACTION_NAME);
+
+ this.executor = Executor.script(scriptFactory.getMeshScript(model)).description(ACTION_NAME).inFolder(baseDir).inService(service).inTerminal(new TerminalExecutorMonitor(logFile)).withMonitors(monitor).env(getEnvironment(model, LOG_NAME)).keepFileOnEnd();
+ executor.exec();
+ }
+
+ private class FinishHook implements ExecutorHook {
+ @Override
+ public void run(ExecutorMonitor m) {
+ controller.setupCase();
+ }
+ }
+
+}
diff --git a/src/eu/engys/core/controller/actions/StopCommandInfo.java b/src/eu/engys/core/controller/actions/StopCommandInfo.java
new file mode 100644
index 0000000..76a1664
--- /dev/null
+++ b/src/eu/engys/core/controller/actions/StopCommandInfo.java
@@ -0,0 +1,63 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.controller.actions;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import eu.engys.core.controller.CommandInfo;
+
+public class StopCommandInfo extends CommandInfo {
+
+ private static final Logger logger = LoggerFactory.getLogger(StopCommandInfo.class);
+
+ public boolean timeout;
+
+ public static StopCommandInfo wrap(CommandInfo info) {
+ StopCommandInfo ci = new StopCommandInfo();
+ ci.message = info.message;
+ ci.exception = info.exception;
+ ci.success = info.success;
+ ci.timeout = false;
+ return ci;
+ }
+
+ public static StopCommandInfo timeoutException(Exception e) {
+ logger.error(">>> SERVER STOP ERROR", e);
+ StopCommandInfo ci = new StopCommandInfo();
+ ci.message = "Timeout";
+ ci.exception = e;
+ ci.success = false;
+ ci.timeout = true;
+ return ci;
+ }
+
+ @Override
+ public String toString() {
+ return "Stop Command [success: " + success + "] - [timeout: " + timeout + "] - [message: " + message + "] - [exception: " + exception.getMessage() + "]";
+ }
+
+}
diff --git a/src/eu/engys/core/controller/actions/TimeoutException.java b/src/eu/engys/core/controller/actions/TimeoutException.java
new file mode 100644
index 0000000..66a8ae3
--- /dev/null
+++ b/src/eu/engys/core/controller/actions/TimeoutException.java
@@ -0,0 +1,34 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.controller.actions;
+
+public class TimeoutException extends Exception {
+
+ public TimeoutException(String message) {
+ super(message);
+ }
+
+}
diff --git a/src/eu/engys/core/dictionary/BeanToDict.java b/src/eu/engys/core/dictionary/BeanToDict.java
new file mode 100644
index 0000000..c27988a
--- /dev/null
+++ b/src/eu/engys/core/dictionary/BeanToDict.java
@@ -0,0 +1,274 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.dictionary;
+
+import java.io.File;
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class BeanToDict {
+
+ private static final Logger logger = LoggerFactory.getLogger(BeanToDict.class);
+
+ public static B dictToBean(Dictionary dictionary, Class klass) {
+ try {
+ B bean = klass.newInstance();
+
+ dictToBean(dictionary, bean);
+
+ return bean;
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ return null;
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public static void dictToBean(Dictionary dictionary, B bean) {
+ Method[] methods = bean.getClass().getMethods();
+ for (Method m : methods) {
+ if (m.getName().startsWith("set")) {
+ String fieldName = getFieldNameFromSetter(m);
+ if (dictionary.found(fieldName)) {
+ if (dictionary.isField(fieldName)) {
+ String value = dictionary.lookup(fieldName);
+ Class> param = m.getParameterTypes()[0];
+ if (param.equals(double.class)) {
+ setValue(bean, m, Double.valueOf(value));
+ } else if (param.equals(long.class)) {
+ setValue(bean, m, Long.valueOf(value));
+ } else if (param.equals(int.class)) {
+ setValue(bean, m, Integer.valueOf(value));
+ } else if (param.equals(boolean.class)) {
+ setValue(bean, m, Boolean.valueOf(value));
+ } else if (param.equals(String.class)) {
+ setValue(bean, m, value);
+ } else if (param.isEnum()) {
+ try {
+ setValue(bean, m, Enum.valueOf((Class extends Enum>) param, value));
+ } catch (Exception e) {
+ setValue(bean, m, ((Class extends Enum>) param).getEnumConstants()[0]);
+ }
+ } else {
+ System.err.println("ERROR: " + param);
+ logger.error("");
+ }
+ } else if (dictionary.isDictionary(fieldName)) {
+ Class> class1 = m.getParameterTypes()[0];
+ Object bean1 = dictToBean(dictionary.subDict(fieldName), class1);
+ setValue(bean, m, bean1);
+ }
+
+ }
+ }
+ }
+ }
+
+ private static void setValue(B bean, Method m, Object value) {
+ try {
+ m.invoke(bean, value);
+ } catch (Exception e) {
+ logger.error("ERROR: double parameter", e);
+ }
+ }
+
+ // public static void dictToBean(Dictionary dictionary, Object bean) {
+ // Method[] methods = bean.getClass().getMethods();
+ // try {
+ // for (Method m : methods) {
+ // if (m.getName().startsWith("set")) {
+ // String fieldName = getFieldNameFromSetter(m);
+ // if (dictionary.isField(fieldName)) {
+ // String value = dictionary.lookup(fieldName);
+ // m.invoke(bean, Double.valueOf(value));
+ // }
+ // }
+ // }
+ // } catch(Exception ex) {
+ // ex.printStackTrace();
+ // }
+ // }
+
+ public static Dictionary beanToDict(Object obj) {
+ return beanToDict(null, obj);
+ }
+
+ public static Dictionary beanToDict(String name, Object obj) {
+ Class> klass = obj.getClass();
+ Method[] methods = klass.getMethods();
+ Dictionary dictionary = new Dictionary(name != null ? name : getFieldNameFromClass(klass));
+ // dictionary.add("class", obj.getClass().getName());
+
+ for (Method m : methods) {
+ String fieldName = "";
+ if (m.getName().startsWith("get") && !m.getName().startsWith("getClass")) {
+ fieldName = getFieldNameFromGetter(m);
+ } else if (m.getName().startsWith("is")) {
+ fieldName = getFieldNameFromBooleanGetter(m);
+ } else {
+ continue;
+ }
+ try {
+ Object value = m.invoke(obj);
+ if (value != null) {
+ addToDictionary(dictionary, fieldName, value);
+ }
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+ return dictionary;
+ }
+
+ private static void addToDictionary(Dictionary dictionary, String fieldName, Object value) throws Exception {
+ if (isSimple(value.getClass())) {
+ dictionary.add(fieldName, value.toString());
+ } else if (isList(value)) {
+ dictionary.add(toList(fieldName, value));
+ } else if (isArray(value)) {
+ dictionary.add(fieldName, toArray(value));
+ } else if (isMap(value)) {
+ dictionary.add(mapToDict(fieldName, value));
+ } else if (isFile(value)) {
+ dictionary.add(fieldName, ((File) value).getAbsolutePath());
+ } else if (isDictionary(value)) {
+ Dictionary d = new Dictionary((Dictionary) value);
+ d.setName(fieldName);
+ dictionary.add(d);
+ } else {
+ dictionary.add(beanToDict(fieldName, value));
+ }
+ }
+
+ private static boolean isSimple(Class> klass) {
+ boolean isString = String.class.isAssignableFrom(klass);
+ boolean isNumber = Number.class.isAssignableFrom(klass);
+ boolean isBoolean = Boolean.class.isAssignableFrom(klass);
+ boolean isEnum = Enum.class.isAssignableFrom(klass);
+ boolean isPrimitive = klass.isPrimitive();
+ return isString || isNumber || isBoolean || isEnum || isPrimitive;
+ }
+
+ private static boolean isList(Object value) {
+ return List.class.isAssignableFrom(value.getClass()) || (value.getClass().isArray() && !isSimple(value.getClass().getComponentType()));
+ }
+
+ private static boolean isMap(Object value) {
+ return Map.class.isAssignableFrom(value.getClass());
+ }
+
+ private static boolean isFile(Object value) {
+ return File.class.isAssignableFrom(value.getClass());
+ }
+
+ private static boolean isDictionary(Object value) {
+ return Dictionary.class.isAssignableFrom(value.getClass());
+ }
+
+ private static boolean isArray(Object value) {
+ return value.getClass().isArray();
+ }
+
+ private static ListField toList(String name, Object value) throws Exception {
+ ListField listField = new ListField(name);
+ List> list = null;
+ if (value.getClass().isArray()) {
+ list = Arrays.asList((Object[]) value);
+ } else {
+ list = (List>) value;
+ }
+ for (Object obj : list) {
+ listField.add(beanToDict(obj));
+ }
+ return listField;
+ }
+
+ public static Dictionary mapToDict(String name, Object value) {
+ Map, ?> map = (Map, ?>) value;
+ Dictionary dict = new Dictionary(name);
+ try {
+ for (Object key : map.keySet()) {
+ addToDictionary(dict, key.toString(), map.get(key));
+ }
+ } catch (Exception ex) {
+
+ }
+ return dict;
+ }
+
+ private static String toArray(Object array) throws Exception {
+ return toBracketedArrayOfStrings(array);
+ }
+
+ private static String toBracketedArrayOfStrings(Object array) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("(");
+ for (int i = 0; i < Array.getLength(array); i++) {
+ sb.append(" ");
+ sb.append(Array.get(array, i).toString());
+ }
+ sb.append(")");
+
+ return sb.toString();
+ }
+
+ private static String getFieldNameFromGetter(Method m) {
+ String name = m.getName().substring(3);
+ return name.substring(0, 1).toLowerCase() + name.substring(1);
+ }
+
+ private static String getFieldNameFromBooleanGetter(Method m) {
+ String name = m.getName().substring(2);
+ return name.substring(0, 1).toLowerCase() + name.substring(1);
+ }
+
+ private static String getFieldNameFromSetter(Method m) {
+ String name = m.getName().substring(3);
+ return name.substring(0, 1).toLowerCase() + name.substring(1);
+ }
+
+ static private String getFieldNameFromClass(Class> klass) {
+ String name = klass.getSimpleName();
+ return name.substring(0, 1).toLowerCase() + name.substring(1);
+ }
+
+ // private Method getSetterFromFieldName(String name, Class> klass) throws Exception {
+ // String methodName = name.substring(0,1).toUpperCase()+name.substring(1);
+ // methodName = "set"+methodName;
+ // return klass.getMethod(methodName);
+ // }
+ //
+ // private static Class> getClassFromFieldName(String name) throws ClassNotFoundException{
+ // String className = name.substring(0,1).toUpperCase()+name.substring(1);
+ // return Class.forName(className);
+ // }
+}
diff --git a/src/eu/engys/core/dictionary/BlockMeshWriter.java b/src/eu/engys/core/dictionary/BlockMeshWriter.java
new file mode 100644
index 0000000..6670671
--- /dev/null
+++ b/src/eu/engys/core/dictionary/BlockMeshWriter.java
@@ -0,0 +1,120 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.core.dictionary;
+
+import static eu.engys.core.dictionary.Dictionary.SPACER;
+import static eu.engys.core.dictionary.Dictionary.TAB;
+import static eu.engys.core.dictionary.Dictionary.VERBOSE;
+import eu.engys.core.dictionary.parser.ListField2;
+
+public class BlockMeshWriter extends DictionaryWriter {
+
+
+ public BlockMeshWriter(Dictionary dictionary) {
+ super(dictionary);
+ }
+
+ public String write() {
+ StringBuffer sb = new StringBuffer();
+ writeDictionary(sb, "");
+ return sb.toString();
+ }
+
+ public void writeDictionary(StringBuffer sb, String rowHeader) {
+ if (dictionary.getFoamFile() != null) {
+ sb.append(FoamFile.HEADER);
+ BlockMeshWriter writer = new BlockMeshWriter(dictionary.getFoamFile());
+ writer.writeDictionary(sb, "");
+
+// if (dictionary.isList("")) {
+// ListField.class.cast(dictionary.getList()).writeListDict(sb, rowHeader);
+// return;
+// }
+ } else {
+ sb.append("\n");
+ sb.append(rowHeader);
+ sb.append(dictionary.getName());
+ sb.append("\n");
+ sb.append(rowHeader);
+ sb.append(START);
+ }
+ for (String key : dictionary.getKeys()) {
+ DefaultElement ele = dictionary.getElement(key);
+ write(sb, rowHeader, ele);
+ }
+
+ for (String includeFile : dictionary.getIncludeFiles()) {
+ writeInclude(sb, includeFile, rowHeader);
+ }
+
+ if (dictionary.getFoamFile() == null)
+ sb.append("\n" + rowHeader + END);
+ }
+
+ private void write(StringBuffer sb, String rowHeader, DefaultElement ele) {
+ if (ele instanceof Dictionary) {
+ BlockMeshWriter writer = new BlockMeshWriter((Dictionary) ele);
+ writer.writeDictionary(sb, rowHeader + TAB);
+ } else if (ele instanceof DimensionedScalar) {
+ writeDimensionedScalar(sb, (DimensionedScalar) ele, rowHeader);
+ } else if (ele instanceof ListField2) {
+ ListField2.class.cast(ele).writeListField(sb, rowHeader);
+ } else if (ele instanceof ListField) {
+ ListField.class.cast(ele).writeListField(sb, rowHeader);
+ } else {
+ super.writeField(sb, (FieldElement) ele, rowHeader);
+ }
+ }
+
+ @Override
+ protected void writeInclude(StringBuffer sb, String includeFile, String rowHeader) {
+ if (VERBOSE)
+ System.out.println("Dictionary.writeInclude() " + includeFile);
+ sb.append("\n");
+ sb.append(rowHeader);
+ sb.append(TAB);
+ sb.append("#include");
+ sb.append(SPACER);
+ sb.append(includeFile);
+ }
+
+ private static void writeDimensionedScalar(StringBuffer sb, DimensionedScalar ds, String rowHeader) {
+ if (VERBOSE)
+ System.out.println("Dictionary.writeDimensionedScalar() " + (ds != null ? ds.getName() : "NULL!!!"));
+ sb.append("\n");
+ sb.append(rowHeader);
+ sb.append(TAB);
+ sb.append(ds.getName());
+ sb.append(SPACER);
+ sb.append(ds.getName());
+ sb.append(SPACER);
+ sb.append(ds.getDimensions());
+ sb.append(SPACER);
+ sb.append(ds.getValue());
+ sb.append(";");
+ }
+}
diff --git a/src/eu/engys/core/dictionary/DefaultElement.java b/src/eu/engys/core/dictionary/DefaultElement.java
new file mode 100644
index 0000000..0fb3d97
--- /dev/null
+++ b/src/eu/engys/core/dictionary/DefaultElement.java
@@ -0,0 +1,52 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.core.dictionary;
+
+public class DefaultElement {
+
+ private String name;
+
+ public DefaultElement(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof DefaultElement) {
+ return ((DefaultElement) obj).name.equals(name);
+ }
+ return super.equals(obj);
+ }
+}
diff --git a/src/eu/engys/core/dictionary/Dictionary.java b/src/eu/engys/core/dictionary/Dictionary.java
new file mode 100644
index 0000000..3511d55
--- /dev/null
+++ b/src/eu/engys/core/dictionary/Dictionary.java
@@ -0,0 +1,807 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.core.dictionary;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang.ArrayUtils;
+
+import eu.engys.core.dictionary.parser.ListField2;
+import eu.engys.core.dictionary.parser.ThetaListField2;
+
+public class Dictionary extends DefaultElement {
+
+ public static boolean VERBOSE = false;
+
+ public static final String SPACER = " ";
+ public static final String TAB = " ";
+
+ public static final String DICTIONARY_LINK = "DICTIONARY_LINK";
+ public static final String VALUE_LINK = "VALUE_LINK";
+ public static final String VALUE_UNIFORM_LINK = "VALUE_UNIFORM_LINK";
+
+ public static final String TYPE = "type";
+ public static final String VALUE = "value";
+
+ private FoamFile foamFile;
+
+ private Map elements = new LinkedHashMap();
+ private List keys = new ArrayList();
+ private List genericKeys = new ArrayList();
+ private List includeFiles = new ArrayList();
+
+ public Dictionary(String name, File file) {
+ super(name);
+ readDictionary(file);
+ }
+
+ public Dictionary(File file) {
+ this(file.getName(), file);
+ }
+
+
+ public Dictionary(String name, InputStream input, DictionaryLinkResolver resolver) {
+ super(name);
+ readDictionary(input, resolver);
+ }
+
+ public Dictionary(String name, InputStream input) {
+ super(name);
+ readDictionary(input);
+ }
+
+ public Dictionary(String name) {
+ super(name);
+ }
+
+ public Dictionary(Dictionary d) {
+ this(d.getName(), d);
+ }
+
+ public Dictionary(String name, Dictionary d) {
+ super(name);
+ setFoamFile(d.getFoamFile());
+ for (String key : d.keys) {
+ DefaultElement el = d.elements.get(key);
+ if (el instanceof Dictionary) {
+ add(new Dictionary((Dictionary) el));
+ } else if (el instanceof DimensionedScalar) {
+ DimensionedScalar ds = (DimensionedScalar) el;
+ add(new DimensionedScalar(ds));
+ } else if (el instanceof FieldElement) {
+ FieldElement f = (FieldElement) el;
+ add(f.getName(), f.getValue());
+ } else if (el instanceof ListField) {
+ ListField lf = (ListField) el;
+ add(lf.getName(), new ListField(lf));
+ } else if (el instanceof ThetaListField2) {
+ ThetaListField2 tf = (ThetaListField2) el;
+ add(tf.getName(), new ThetaListField2(tf));
+ } else if (el instanceof ListField2) {
+ ListField2 lf = (ListField2) el;
+ add(lf.getName(), new ListField2(lf));
+ }
+ }
+ genericKeys.addAll(d.genericKeys);
+ }
+
+ public void setFoamFile(FoamFile file) {
+ if (found("FoamFile"))
+ remove("FoamFile");
+ this.foamFile = file;
+ }
+
+ public FoamFile getFoamFile() {
+ return foamFile;
+ }
+
+ public void check() throws DictionaryException {
+ }
+
+ public void include(String includeFile) {
+ includeFiles.add(includeFile);
+ }
+
+ private void put(String key, DefaultElement value) {
+ elements.put(key, value);
+ if (!keys.contains(key))
+ keys.add(key);
+ }
+
+ public void add(DefaultElement el) {
+ put(el.getName(), el);
+ }
+
+ public void addGeneric(DefaultElement el) {
+ String name = el.getName();
+ if (!genericKeys.contains(name)) {
+ genericKeys.add(name);
+ }
+ put(name, el);
+ }
+
+ public void add(Dictionary dictionary) {
+ put(dictionary.getName(), dictionary);
+ }
+
+ public void addToList(Dictionary dictionary) {
+ addToList("", dictionary);
+ }
+
+ public void addToList(String listName, Dictionary dictionary) {
+ ListField list = getList(listName);
+ if (list == null) {
+ list = new ListField(listName);
+ add(list);
+ }
+ list.add(dictionary);
+ }
+
+ public void addToList(String listName, FieldElement fe) {
+ ListField list = getList(listName);
+ if (list == null) {
+ list = new ListField(listName);
+ add(list);
+ }
+ list.add(fe);
+ }
+
+ public void add(String name, String value) {
+ put(name, new FieldElement(name, value));
+ }
+
+// public void add(Finder finder, String value) {
+// String key = findKey(finder);
+// put(key, new FieldElement(key, value));
+// }
+
+ public void addGeneric(String name, String value) {
+ if (!genericKeys.contains(name)) {
+ genericKeys.add(name);
+ }
+ put(name, new FieldElement(name, value));
+ }
+
+ public void add(String name, double[] values) {
+ StringBuffer sb = new StringBuffer("(");
+ for (double d : values) {
+ sb.append(String.valueOf(d) + " ");
+ }
+ sb.append(")");
+ this.add(name, sb.toString());
+ }
+
+ public void add(String name, int[] values) {
+ StringBuffer sb = new StringBuffer("(");
+ for (int d : values) {
+ sb.append(String.valueOf(d) + " ");
+ }
+ sb.append(")");
+ this.add(name, sb.toString());
+ }
+
+ public void add(String name, String[] values) {
+ StringBuffer sb = new StringBuffer("(");
+ for (String p : values) {
+ sb.append(p + " ");
+ }
+ sb.append(")");
+ this.add(name, sb.toString());
+ }
+
+ public void add(String name, List values) {
+ this.add(name, values.toArray(new String[0]));
+ }
+
+ public void add(DimensionedScalar ds) {
+ put(ds.getName(), ds);
+ }
+
+ public void add(String name, ListField list) {
+ put(name, list);
+ }
+
+ public void add(String name, ListField2 list) {
+ put(name, list);
+ }
+
+ public void add(ListField list) {
+ put(list.getName(), list);
+ }
+
+ private String findKey(Finder finder) {
+ for (String key : keys) {
+ if (finder.accept(key)) {
+ return key;
+ }
+ }
+ return null;
+ }
+
+ public boolean found(Finder finder) {
+ String key = findKey(finder);
+ return key != null;
+ }
+
+ public boolean found(String name) {
+ if (foundGeneric(name))
+ return true;
+ else
+ return keys.contains(name);
+ }
+
+ private boolean foundGeneric(String name) {
+ if (!genericKeys.isEmpty()) {
+ for (String genericKey : genericKeys) {
+ if (("\"" + name + "\"").matches(genericKey)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ DefaultElement getElement(String name) {
+ if (elements.containsKey(name))
+ return elements.get(name);
+
+ if (!genericKeys.isEmpty()) {
+ for (String genericKey : genericKeys) {
+ if (("\"" + name + "\"").matches(genericKey)) {
+ return elements.get(genericKey);
+ }
+ }
+ }
+ return null;
+ }
+
+ public boolean isDictionary(String name) {
+ DefaultElement el = getElement(name);
+ return (el != null && el instanceof Dictionary);
+ }
+
+ public boolean isField(String name) {
+ DefaultElement el = getElement(name);
+ return (el != null && el instanceof FieldElement);
+ }
+
+ public boolean isList(String name) {
+ DefaultElement el = getElement(name);
+ return (el != null && el instanceof ListField);
+ }
+
+ public boolean isList2(String name) {
+ DefaultElement el = getElement(name);
+ return (el != null && el instanceof ListField2);
+ }
+
+ public boolean isThetaList2(String name) {
+ DefaultElement el = getElement(name);
+ return (el != null && el instanceof ThetaListField2);
+ }
+
+ public Dictionary subDict(String name) {
+ DefaultElement el = getElement(name);
+ if (isDictionary(name)) {
+ return (Dictionary) el;
+ } else if (el != null)
+ throw new DictionaryException(name + " not a dictionary");
+ else
+ return null;
+ }
+
+// public ListField getList() {
+// return getList("");
+// }
+//
+// public ListField2 getList2() {
+// return getList2("");
+// }
+
+ public ListField getList(String name) {
+ DefaultElement el = getElement(name);
+ if (isList(name)) {
+ return (ListField) el;
+ } else if (el != null)
+ throw new DictionaryException(name + " not a list");
+ else
+ return null;
+ }
+
+ public ListField2 getList2(String name) {
+ DefaultElement el = getElement(name);
+ if (isList2(name)) {
+ return (ListField2) el;
+ } else if (el != null)
+ throw new DictionaryException(name + " not a list");
+ else
+ return null;
+ }
+
+ public ThetaListField2 getThetaList2(String name) {
+ DefaultElement el = getElement(name);
+ if (isThetaList2(name)) {
+ return (ThetaListField2) el;
+ } else if (el != null)
+ throw new DictionaryException(name + " not a theta list");
+ else
+ return null;
+ }
+
+ public DefaultElement lookup(Finder finder) {
+ String key = findKey(finder);
+ if (key == null) {
+ throw new DictionaryException("Key " + key + " is NULL");
+ }
+
+ return getElement(key);
+ }
+
+ public String lookup(String key) {
+ return lookupString(key);
+ }
+
+ public String lookupString(String key) {
+ if (key == null) {
+ throw new DictionaryException("Key " + key + " is NULL");
+ }
+ DefaultElement el = getElement(key);
+ if (isField(key)) {
+ return ((FieldElement) el).getValue();
+ } else if (el != null)
+ throw new DictionaryException(key + " not a field");
+ else
+ return null;
+ }
+
+ public int lookupInt(String name) {
+ String value = lookupString(name);
+ try {
+ return Integer.parseInt(value);
+ } catch (NumberFormatException e) {
+ return -1;
+ }
+ }
+
+ public double lookupDouble(String name) {
+ String value = lookupString(name);
+ try {
+ return Double.parseDouble(value);
+ } catch (NumberFormatException e) {
+ return Double.NaN;
+ }
+ }
+
+ public DimensionedScalar lookupScalar(String name) {
+ DefaultElement el = getElement(name);
+ if (el != null && el instanceof DimensionedScalar) {
+ return (DimensionedScalar) el;
+ } else if (el != null)
+ throw new DictionaryException(name + " not a dimensioned scalar");
+ else
+ return null;
+ }
+
+ public String[] lookupArray(String name) {
+ DefaultElement el = getElement(name);
+ if (el != null && el instanceof FieldElement) {
+ String value = ((FieldElement) el).getValue();
+ if (value.startsWith("uniform")) {
+ value = value.replace("uniform", "").trim();
+ }
+ if (value.startsWith("nonuniform")) {
+ return new String[] { "Infinity", "Infinity", "Infinity" };
+ }
+ if (value.startsWith("(") && value.endsWith(")")) {
+ value = value.replace("(", "").replace(")", "").trim();
+ // value = value.substring(1, value.length()-1);
+ if (value.isEmpty()) {
+ return new String[0];
+ }
+ String[] values = value.split(SPACER);
+ // System.out.println("Dictionary.lookupArray() "+Arrays.toString(values));
+ return values;
+ } else
+ throw new DictionaryException(name + " not an array");
+ } else if (el != null)
+ throw new DictionaryException(name + " not a field");
+ else
+ return null;
+ }
+
+ public String[][] lookupMatrix(String name) {
+ DefaultElement el = getElement(name);
+ if (el != null && el instanceof FieldElement) {
+ String value = ((FieldElement) el).getValue();
+ if (value.startsWith("uniform")) {
+ value = value.replace("uniform", "").trim();
+ }
+ if (value.startsWith("(") && value.endsWith(")")) {
+ value = value.replaceAll("\\(\\s*\\(", "");
+ value = value.replaceAll("\\)\\s*\\)", "");
+
+ String[] values = value.split("\\)\\s*\\(");
+ String[][] matrix = new String[values.length][];
+ for (int r = 0; r < values.length; r++) {
+ String[] row = values[r].trim().split("\\s+");
+ matrix[r] = row;
+ }
+ return matrix;
+ } else
+ throw new DictionaryException(name + " not an array");
+ } else if (el != null)
+ throw new DictionaryException(name + " not a field");
+ else
+ return null;
+ }
+
+ public String[] lookupArray2(String name) {
+ DefaultElement el = getElement(name);
+ if (el != null && el instanceof ListField2) {
+ ListField2 list = (ListField2) el;
+ return listToArray(list);
+ } else if (el != null)
+ throw new DictionaryException(name + " not a field");
+ else
+ return null;
+ }
+
+ private String[] listToArray(ListField2 list) {
+ List elements = list.getListElements();
+
+ String[] values = new String[elements.size()];
+
+ for (int i = 0; i < elements.size(); i++) {
+ DefaultElement element = elements.get(i);
+ if (element instanceof FieldElement) {
+ String value = ((FieldElement) element).getValue();
+ values[i] = value;
+ } else if (element instanceof ListField2) {
+ String[] listField = listToArray((ListField2) element);
+ values[i] = "(";
+ for (int j = 0; j < listField.length; j++) {
+ values[i] += listField[j] + " ";
+ }
+ values[i] += ")";
+ }
+ }
+ return values;
+ }
+
+ public String[][] lookupMatrix2(String name) {
+ DefaultElement el = getElement(name);
+ if (el != null && el instanceof ListField2) {
+ ListField2 list = (ListField2) el;
+ return listToMatrix(list);
+ } else if (el != null) {
+ throw new DictionaryException(name + " not a field");
+ } else {
+ return null;
+ }
+ }
+
+ private String[][] listToMatrix(ListField2 list) {
+ List rows = list.getListElements();
+ if (rows.size() > 0 && rows.get(0) instanceof ListField2) {
+ ListField2 firstRow = (ListField2) rows.get(0);
+ String[][] values = new String[rows.size()][firstRow.getListElements().size()];
+
+ for (int i = 0; i < rows.size(); i++) {
+ if (rows.get(i) instanceof ListField2) {
+ ListField2 row = (ListField2) rows.get(i);
+ values[i] = listToArray(row);
+ }
+ }
+ return values;
+ } else {
+ return new String[0][0];
+ }
+ }
+
+ public double[] lookupDoubleArray(String name) {
+ String[] array = lookupArray(name);
+ double[] doubleArray = new double[array.length];
+ for (int i = 0; i < doubleArray.length; i++) {
+ try {
+ doubleArray[i] = Double.valueOf(array[i]);
+ } catch (NumberFormatException e) {
+ }
+ }
+ return doubleArray;
+ }
+
+ public double[] lookupDoubleArray2(String name) {
+ String[] array = lookupArray2(name);
+ double[] doubleArray = new double[array.length];
+ for (int i = 0; i < doubleArray.length; i++) {
+ try {
+ doubleArray[i] = Double.valueOf(array[i]);
+ } catch (NumberFormatException e) {
+ }
+ }
+ return doubleArray;
+ }
+
+ public double[][] lookupDoubleMatrix(String name) {
+ String[][] matrix = lookupMatrix(name);
+ double[][] doubleMatrix = new double[matrix.length][matrix[0].length];
+ for (int i = 0; i < doubleMatrix.length; i++) {
+ for (int j = 0; j < doubleMatrix[i].length; j++) {
+ try {
+ doubleMatrix[i][j] = Double.valueOf(matrix[i][j]);
+ } catch (NumberFormatException e) {
+ }
+ }
+ }
+ return doubleMatrix;
+ }
+
+ public double[][] lookupDoubleMatrix2(String name) {
+ String[][] matrix = lookupMatrix2(name);
+ double[][] doubleMatrix = new double[matrix.length][matrix[0].length];
+ for (int i = 0; i < doubleMatrix.length; i++) {
+ for (int j = 0; j < doubleMatrix[i].length; j++) {
+ try {
+ doubleMatrix[i][j] = Double.valueOf(matrix[i][j]);
+ } catch (NumberFormatException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ return doubleMatrix;
+ }
+
+ public int[] lookupIntArray(String name) {
+ String[] array = lookupArray(name);
+ int[] intArray = new int[array.length];
+ for (int i = 0; i < intArray.length; i++) {
+ try {
+ intArray[i] = Integer.valueOf(array[i]);
+ } catch (NumberFormatException e) {
+ }
+ }
+ return intArray;
+ }
+
+ public Dictionary removeDict(String name) {
+ keys.remove(name);
+ return (Dictionary) elements.remove(name);
+ }
+
+ public DefaultElement remove(String name) {
+ keys.remove(name);
+ return elements.remove(name);
+ }
+
+ public DefaultElement remove(Finder finder) {
+ String key = findKey(finder);
+ return remove(key);
+ }
+
+ List getGenericKeys() {
+ return genericKeys;
+ }
+
+ List getKeys() {
+ return keys;
+ }
+
+ List getIncludeFiles() {
+ return includeFiles;
+ }
+
+ public boolean isEmpty() {
+ return keys.isEmpty();
+ }
+
+ @Override
+ public String toString() {
+ return new DictionaryWriter(this).write();
+ }
+
+ public List getDictionaries() {
+ List list = new ArrayList();
+ for (String key : keys) {
+ DefaultElement el = elements.get(key);
+ if (el instanceof Dictionary) {
+ list.add((Dictionary) el);
+ }
+ }
+ return list;
+ }
+
+ public Map getDictionariesMap() {
+ Map map = new LinkedHashMap();
+ for (String key : keys) {
+ DefaultElement el = elements.get(key);
+ if (el instanceof Dictionary) {
+ map.put(el.getName(), (Dictionary) el);
+ }
+ }
+ return map;
+ }
+
+ public List getFields() {
+ List list = new ArrayList();
+ for (DefaultElement el : elements.values()) {
+ if (el instanceof FieldElement) {
+ list.add((FieldElement) el);
+ }
+ }
+ return list;
+ }
+
+ public List getListFields() {
+ List list = new ArrayList<>();
+ for (DefaultElement el : elements.values()) {
+ if (el instanceof ListField) {
+ list.add((ListField) el);
+ }
+ }
+ return list;
+ }
+
+ public boolean hasOnlyList(){
+ return !getListFields().isEmpty() && getDictionaries().isEmpty() && getFieldsMap().isEmpty();
+ }
+
+ public boolean hasOnlyList2(){
+ return !getListFields2().isEmpty() && getDictionaries().isEmpty() && getFieldsMap().isEmpty();
+ }
+
+ public List getListFields2() {
+ List list = new ArrayList<>();
+ for (DefaultElement el : elements.values()) {
+ if (el instanceof ListField2) {
+ list.add((ListField2) el);
+ }
+ }
+ return list;
+ }
+
+ public Map getFieldsMap() {
+ Map map = new LinkedHashMap();
+ for (DefaultElement el : elements.values()) {
+ if (el instanceof FieldElement) {
+ FieldElement field = (FieldElement) el;
+ map.put(field.getName(), field.getValue());
+ }
+ }
+ return map;
+ }
+
+ public void merge(Dictionary dict) {
+ merge(dict, new String[0]);
+ }
+
+ public void merge(Dictionary dict, String[] keysToExclude) {
+ if (dict == null)
+ return;
+ // System.out.println("Dictionary.merge(): "+dict);
+ for (String key : dict.getKeys()) {
+ if(ArrayUtils.contains(keysToExclude, key)){
+ continue;
+ }
+
+ DefaultElement ele = dict.getElement(key);
+ if (ele instanceof Dictionary) {
+ Dictionary d = (Dictionary) ele;
+ if (found(d.getName()) && isDictionary(d.getName())) {
+ subDict(d.getName()).merge(d);
+ } else {
+ add(new Dictionary(d.getName()));
+ subDict(d.getName()).merge(d);
+ }
+ } else if (ele instanceof ListField) {
+ ListField l = (ListField) ele;
+ if (found(l.getName()) && isList(l.getName())) {
+ getList(l.getName()).merge(l);
+ } else {
+ add(new ListField(l.getName()));
+ getList(l.getName()).merge(l);
+ }
+ } else if (ele instanceof ThetaListField2) {
+ ThetaListField2 t = (ThetaListField2) ele;
+ if (found(t.getName()) && isThetaList2(t.getName())) {
+ getThetaList2(t.getName()).merge(t);
+ } else {
+ add(new ThetaListField2(t));
+ }
+ } else if (ele instanceof ListField2) {
+ ListField2 l = (ListField2) ele;
+ if (found(l.getName()) && isList2(l.getName())) {
+ getList2(l.getName()).merge(l);
+ } else {
+ add(new ListField2(l));
+ }
+ } else if (ele instanceof FieldElement) {
+ FieldElement f = (FieldElement) ele;
+ if (f instanceof DimensionedScalar) {
+ add(new DimensionedScalar((DimensionedScalar) f));
+ } else {
+ add(f.getName(), f.getValue());
+ }
+ }
+ }
+ genericKeys.addAll(dict.genericKeys);
+ }
+
+ public void clear() {
+ elements.clear();
+ keys.clear();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof Dictionary) {
+ Dictionary d = (Dictionary) obj;
+ if (elements.size() != d.elements.size())
+ return false;
+ for (String key : elements.keySet()) {
+ if (!elements.get(key).equals(d.elements.get(key)))
+ return false;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /* * * * * * * * * * * * *
+ * READ/WRITE STUFF * * * * * * * * * * * *
+ */
+
+ public void readDictionary(File file) {
+ DictionaryReader reader = new DictionaryReader(this);
+ reader.read(file);
+ }
+
+ protected void readDictionary(InputStream input, DictionaryLinkResolver resolver) {
+ DictionaryReader reader = new DictionaryReader(this, resolver);
+ reader.read(input);
+ }
+
+ protected void readDictionary(InputStream input) {
+ DictionaryReader reader = new DictionaryReader(this);
+ reader.read(input);
+ }
+
+ protected void readDictionaryFromString(String text) {
+ DictionaryReader reader = new DictionaryReader(this);
+ reader.read(text);
+ }
+
+ protected String write() {
+ DictionaryWriter writer = new DictionaryWriter(this);
+ return writer.write();
+ }
+
+}
diff --git a/src/eu/engys/core/dictionary/DictionaryBuilder.java b/src/eu/engys/core/dictionary/DictionaryBuilder.java
new file mode 100644
index 0000000..1bce27d
--- /dev/null
+++ b/src/eu/engys/core/dictionary/DictionaryBuilder.java
@@ -0,0 +1,96 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.core.dictionary;
+
+import eu.engys.core.dictionary.parser.ListField2;
+
+public class DictionaryBuilder {
+
+
+ private Dictionary dictionary;
+
+ private DictionaryBuilder(String name) {
+ this.dictionary = new Dictionary(name);
+ }
+
+ public static DictionaryBuilder newDictionary(String name) {
+ return new DictionaryBuilder(name);
+ }
+
+ public DictionaryBuilder field(String k, String v) {
+ dictionary.add(k, v);
+ return this;
+ }
+
+ public DictionaryBuilder dimensionedScalar(String k, String v, String d) {
+ dictionary.add(new DimensionedScalar(k, v, d));
+ return this;
+ }
+
+ public DictionaryBuilder array(String k, String... v) {
+ dictionary.add(k, v);
+ return this;
+ }
+
+ public DictionaryBuilder dict(Dictionary d) {
+ dictionary.add(d);
+ return this;
+ }
+
+ public Dictionary done() {
+ return dictionary;
+ }
+
+ public DictionaryBuilder list(String string, Dictionary... dicts) {
+ ListField list = new ListField(string);
+ for (Dictionary dictionary : dicts) {
+ list.add(dictionary);
+ }
+ dictionary.add(list);
+ return this;
+ }
+
+ public DictionaryBuilder list2(String string, DefaultElement... elements) {
+ ListField2 list = new ListField2(string);
+ for (DefaultElement fieldElement : elements) {
+ list.add(fieldElement);
+ }
+ dictionary.add(list);
+ return this;
+ }
+
+ public DictionaryBuilder scalar(String k, String dimensions, String v) {
+ dictionary.add(new DimensionedScalar(k, v, dimensions));
+ return this;
+ }
+
+ public DictionaryBuilder foamFile(String parent, String name) {
+ dictionary.setFoamFile(FoamFile.getDictionaryFoamFile(parent,name));
+ return this;
+ }
+
+}
diff --git a/src/eu/engys/core/dictionary/DictionaryEditor.java b/src/eu/engys/core/dictionary/DictionaryEditor.java
new file mode 100644
index 0000000..756fe39
--- /dev/null
+++ b/src/eu/engys/core/dictionary/DictionaryEditor.java
@@ -0,0 +1,253 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.core.dictionary;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dialog.ModalityType;
+import java.awt.FlowLayout;
+import java.awt.Window;
+import java.awt.event.ActionEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+
+import javax.swing.AbstractAction;
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JPanel;
+import javax.swing.JSeparator;
+import javax.swing.SwingConstants;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+
+import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
+import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
+import org.fife.ui.rtextarea.RTextScrollPane;
+
+import eu.engys.core.dictionary.parser.DictionaryReader2;
+import eu.engys.core.project.system.BlockMeshDict;
+import eu.engys.util.ui.ExecUtil;
+import eu.engys.util.ui.UiUtil;
+
+public class DictionaryEditor {
+
+ public static final String CODE_EDITOR = "codeEditor";
+ public static final String DICTIONARY_EDITOR_DIALOG_NAME = "dictionary.editor.dialog";
+
+ private static DictionaryEditor instance;
+
+ private JDialog dialog;
+ private RSyntaxTextArea editor;
+ private DocumentListener documentListener;
+
+ private Dictionary dictionary;
+ private boolean modified;
+
+ private Runnable onDisposeRunnable;
+
+ private Runnable onOKRunnable;
+
+ private JButton okButton;
+
+ public static DictionaryEditor getInstance() {
+ if (instance == null)
+ instance = new DictionaryEditor();
+ return instance;
+ }
+
+ private DictionaryEditor() {
+ initEditor();
+ initListeners();
+ }
+
+ private void initEditor() {
+ this.editor = new RSyntaxTextArea();
+ editor.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JSON);
+ editor.setCodeFoldingEnabled(true);
+ editor.setAntiAliasingEnabled(true);
+ editor.setBackground(new Color(240, 240, 240));
+ editor.setName(CODE_EDITOR);
+ }
+
+ private void initListeners() {
+ documentListener = new DocumentListener() {
+
+ @Override
+ public void removeUpdate(DocumentEvent e) {
+ documentModified();
+ }
+
+ @Override
+ public void insertUpdate(DocumentEvent e) {
+ documentModified();
+ }
+
+ @Override
+ public void changedUpdate(DocumentEvent e) {
+ documentModified();
+ }
+ };
+ }
+
+ private void documentModified() {
+ if (!modified) {
+ dialog.setTitle("*" + dialog.getTitle());
+ this.modified = true;
+ }
+ }
+
+ public void show(Window parent, Dictionary dictionary) {
+ show(parent, dictionary, null, null, null);
+ }
+
+ public void show(final Window parent, Dictionary dictionary, final Runnable onShowRunnable, Runnable onDisposeRunnable, Runnable onOKRunnable) {
+ this.dictionary = dictionary;
+ this.onDisposeRunnable = onDisposeRunnable;
+ this.onOKRunnable = onOKRunnable;
+ ExecUtil.invokeAndWait(new Runnable() {
+
+ @Override
+ public void run() {
+ initDialog(parent);
+ load();
+ if (onShowRunnable != null) {
+ onShowRunnable.run();
+ }
+ dialog.setVisible(true);
+ }
+ });
+ }
+
+ private void initDialog(Window parent) {
+ dialog = new JDialog(parent != null ? parent : UiUtil.getActiveWindow(), ModalityType.MODELESS);
+ dialog.setName(DICTIONARY_EDITOR_DIALOG_NAME);
+ dialog.getContentPane().setLayout(new BorderLayout());
+ dialog.getContentPane().add(createMainPanel(), BorderLayout.CENTER);
+ dialog.getContentPane().add(createButtonsPanel(), BorderLayout.SOUTH);
+ dialog.getContentPane().doLayout();
+ dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
+ dialog.addWindowListener(new WindowAdapter() {
+ @Override
+ public void windowClosing(WindowEvent e) {
+ closeDialog();
+ }
+ });
+
+ dialog.setSize(800, 600);
+ dialog.setLocationRelativeTo(null);
+ dialog.getRootPane().setDefaultButton(okButton);
+ }
+
+ private JPanel createMainPanel() {
+ RTextScrollPane scrollPane = new RTextScrollPane(editor);
+ scrollPane.setFoldIndicatorEnabled(true);
+ scrollPane.setBorder(BorderFactory.createEmptyBorder());
+ JPanel mainPanel = new JPanel(new BorderLayout());
+ mainPanel.add(scrollPane);
+ return mainPanel;
+ }
+
+ private JPanel createButtonsPanel() {
+ JPanel panel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
+
+ okButton = new JButton(new OKAction());
+ okButton.setName("OK");
+
+ JButton cancelButton = new JButton(new CancelAction());
+ cancelButton.setName("Cancel");
+
+ panel.add(okButton);
+ panel.add(cancelButton);
+
+ JPanel buttonsPanel = new JPanel(new BorderLayout());
+ buttonsPanel.add(new JSeparator(SwingConstants.HORIZONTAL), BorderLayout.NORTH);
+ buttonsPanel.add(panel, BorderLayout.CENTER);
+
+ return buttonsPanel;
+ }
+
+ private void closeDialog() {
+ dialog.setVisible(false);
+ dialog.dispose();
+ dialog = null;
+ if (onDisposeRunnable != null) {
+ onDisposeRunnable.run();
+ }
+ }
+
+ private void load() {
+ editor.getDocument().removeDocumentListener(documentListener);
+ try {
+ editor.setText(dictionary.toString());
+ editor.setCaretPosition(0);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ dialog.setTitle(dictionary.getName());
+ editor.getDocument().addDocumentListener(documentListener);
+ this.modified = false;
+ }
+
+ private void save() {
+ dictionary.clear();
+ // use name not instanceof!
+ if (dictionary.getName().equals(BlockMeshDict.BLOCK_DICT)) {
+ new DictionaryReader2(dictionary).read(editor.getText(), true);
+ } else {
+ new DictionaryReader(dictionary).read(editor.getText(), true);
+ }
+ dialog.setTitle(dictionary.getName());
+ }
+
+ private class OKAction extends AbstractAction {
+ public OKAction() {
+ super("OK");
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ save();
+ if(onOKRunnable != null){
+ onOKRunnable.run();
+ }
+ closeDialog();
+ }
+ }
+
+ private class CancelAction extends AbstractAction {
+ public CancelAction() {
+ super("Cancel");
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ closeDialog();
+ }
+ }
+
+}
diff --git a/src/eu/engys/core/dictionary/DictionaryException.java b/src/eu/engys/core/dictionary/DictionaryException.java
new file mode 100644
index 0000000..51119be
--- /dev/null
+++ b/src/eu/engys/core/dictionary/DictionaryException.java
@@ -0,0 +1,34 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.core.dictionary;
+
+public class DictionaryException extends RuntimeException {
+
+ public DictionaryException(String message) {
+ super(message);
+ }
+}
diff --git a/src/eu/engys/core/dictionary/DictionaryLinkResolver.java b/src/eu/engys/core/dictionary/DictionaryLinkResolver.java
new file mode 100644
index 0000000..98f3411
--- /dev/null
+++ b/src/eu/engys/core/dictionary/DictionaryLinkResolver.java
@@ -0,0 +1,116 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.core.dictionary;
+
+public class DictionaryLinkResolver {
+
+// private Dictionary dictionary;
+ private Dictionary linksDestination;
+
+ public DictionaryLinkResolver(Dictionary linksDestination) {
+ this.linksDestination = linksDestination;
+ }
+
+ public void resolve(Dictionary dictionary) {
+ resolveLinks(dictionary, linksDestination);
+ }
+
+ private void resolveLinks(Dictionary dict, Dictionary linksDestination) {
+ for (Dictionary d : dict.getDictionaries()) {
+ resolveLinks(d, linksDestination);
+ }
+ if (dict.found(Dictionary.DICTIONARY_LINK)) {
+ String link = dict.lookupString(Dictionary.DICTIONARY_LINK);
+ //System.out.println("------------> link: "+link);
+ String name = link.replace("$", "");
+ //System.out.println("------------> name: "+name);
+ dict.remove(Dictionary.DICTIONARY_LINK);
+
+ Dictionary dest = findDestination(name, linksDestination);
+ if (dest != null) {
+ dict.merge(dest);
+ //System.out.println("------------> dest: "+dest);
+ }
+ }
+
+ for(ListField lf : dict.getListFields()) {
+ for(DefaultElement el : lf.getListElements()) {
+ if (el instanceof Dictionary) {
+ resolveLinks((Dictionary) el, linksDestination);
+ }
+ }
+ }
+
+ for(FieldElement f : dict.getFields()) {
+ if (f.getName().startsWith(Dictionary.VALUE_LINK)) {
+ String key = f.getName().replace(Dictionary.VALUE_LINK, "");
+ //System.out.println("------------> key: "+key);
+ String link = dict.lookupString(f.getName());
+ //System.out.println("------------> link: "+link);
+ String name = link.replace("$", "");
+ //System.out.println("------------> name: "+name);
+ dict.remove(f.getName());
+ if (linksDestination.found(name)) {
+ String dest = linksDestination.lookupString(name);
+ //System.out.println("------------> dest: "+dest);
+ dict.add(key, dest);
+ } else {
+ //System.err.println("Warning: "+name+" not found in dictionary "+linksDestination.getName());
+ }
+ } else if (f.getName().startsWith(Dictionary.VALUE_UNIFORM_LINK)) {
+ String key = f.getName().replace(Dictionary.VALUE_UNIFORM_LINK, "");
+ //System.out.println("------------> key: "+key);
+ String link = dict.lookupString(f.getName());
+ //System.out.println("------------> link: "+link);
+ String name = link.replace("$", "");
+ //System.out.println("------------> name: "+name);
+ dict.remove(f.getName());
+ if (linksDestination.found(name)) {
+ String dest = linksDestination.lookupString(name);
+ //System.out.println("------------> dest: "+dest);
+ dict.add(key, "uniform "+dest);
+ } else {
+ //System.err.println("Warning: "+name+" not found in dictionary "+linksDestination.getName());
+ }
+ }
+ }
+ }
+
+ private Dictionary findDestination(String name, Dictionary linksDestination) {
+ if (linksDestination.isDictionary(name)) {
+ return linksDestination.subDict(name);
+ } else {
+ for (Dictionary d : linksDestination.getDictionaries()) {
+ Dictionary dest = findDestination(name, d);
+ if (dest != null) {
+ return dest;
+ }
+ }
+ }
+ return null;
+ }
+}
diff --git a/src/eu/engys/core/dictionary/DictionaryReader.java b/src/eu/engys/core/dictionary/DictionaryReader.java
new file mode 100644
index 0000000..34fdc18
--- /dev/null
+++ b/src/eu/engys/core/dictionary/DictionaryReader.java
@@ -0,0 +1,363 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.core.dictionary;
+
+import static eu.engys.core.dictionary.Dictionary.DICTIONARY_LINK;
+import static eu.engys.core.dictionary.Dictionary.SPACER;
+import static eu.engys.core.dictionary.Dictionary.VALUE_LINK;
+import static eu.engys.core.dictionary.Dictionary.VALUE_UNIFORM_LINK;
+import static eu.engys.core.dictionary.Dictionary.VERBOSE;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Stack;
+import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import eu.engys.util.IOUtils;
+import eu.engys.util.RegexpUtils;
+
+public class DictionaryReader {
+
+ private static final Logger logger = LoggerFactory.getLogger(DictionaryReader.class);
+
+ private static final String LIST_START = "!";
+ private static final String MATRIX_START = "&";
+ private static final String MATRIX_DELIMITER = "|";
+ private static final String FIELD_END = ";";
+ private static final String DICTIONARY_END = "}";
+ private static final String DICTIONARY_START = "{";
+ private static final String COMMENT_REGEX = "/\\*(?:.|[\\n\\r])*?\\*/";
+ private Dictionary dictionary;
+ private DictionaryLinkResolver linkResolver;
+
+ public DictionaryReader(Dictionary dictionary) {
+ this(dictionary, new DictionaryLinkResolver(dictionary));
+ }
+
+ public DictionaryReader(Dictionary dictionary, DictionaryLinkResolver linkResolver) {
+ this.dictionary = dictionary;
+ this.linkResolver = linkResolver;
+ }
+
+ public void read(File file) {
+ String text = readFile(file);
+ text = prepareText(text, file);
+ textToDictionary(text);
+ if (dictionary.found("FoamFile"))
+ dictionary.remove("FoamFile");
+ }
+
+ public void read(InputStream is) {
+ String text = readStream(is);
+ text = prepareText(text, null);
+ textToDictionary(text);
+ if (dictionary.found("FoamFile"))
+ dictionary.remove("FoamFile");
+ }
+
+ public void read(String text) {
+ read(text, false);
+ }
+
+ public void read(String text, boolean removeHeader) {
+ text = prepareText(text, null);
+ textToDictionary(text);
+ if (dictionary.found("FoamFile") && removeHeader) {
+ dictionary.remove("FoamFile");
+ }
+ }
+
+ private String readFile(File file) {
+ return IOUtils.readStringFromFile(file);
+ }
+
+ private String readStream(InputStream is) {
+ String text = "";
+ try {
+ text = IOUtils.readStringFromStream(is);
+ } catch (IOException e) {
+ logger.warn("Error reading stream: {} ", e.getMessage());
+ }
+ return text;
+ }
+
+ private String prepareText(String text, File file) {
+// text = text.replaceAll(COMMENT_REGEX, "");
+ text = new jregex.Pattern(COMMENT_REGEX).replacer("").replace(text);
+ text = text.replaceAll("\t", SPACER);
+
+ StringTokenizer rowTokenizer = new StringTokenizer(text, "\n");
+ StringBuffer sb = new StringBuffer();
+ while (rowTokenizer.hasMoreTokens()) {
+ String token = rowTokenizer.nextToken();
+ token = token.trim();
+ if (token.startsWith("//"))
+ continue;
+ if (token.contains("//")) {
+ token = token.substring(0, token.indexOf("//")).trim();
+ }
+ if (token.startsWith("#include")) {
+ sb.append(importFile(token, file));
+ continue;
+ }
+ sb.append(token);
+ sb.append("\n");
+ }
+ text = sb.toString();
+ return text;
+ }
+
+ private String importFile(String token, File file) {
+ String text = "";
+ if (file != null) {
+ try {
+ Pattern regex = Pattern.compile("#include\\s+\"(.+)\"");
+ Matcher regexMatcher = regex.matcher(token);
+ if (regexMatcher.find() && regexMatcher.groupCount() == 1) {
+ String fileName = regexMatcher.group(1).trim();
+ String parentDir = file.getParent();
+
+ File fileToImport = new File(parentDir, fileName);
+ text = readFile(fileToImport);
+ text = prepareText(text, fileToImport);
+ }
+ } catch (PatternSyntaxException ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ return text;
+ }
+
+ protected void textToDictionary(String text) {
+ text = text.replace("\n", SPACER);
+
+ // exploit table data structure
+ text = text.replaceAll("\\(\\s*(" + RegexpUtils.DOUBLE + ")\\s*\\(([^\\)]*)\\)\\s*\\)", "< $1 <$2> >");
+
+ // exploit matrix structure
+ text = text.replaceAll("([\\d | \\s])\\(\\s*\\(", "$1" + SPACER + MATRIX_START);
+ text = text.replaceAll("\\)\\s*\\(", MATRIX_DELIMITER);
+
+ // exploit list structure
+ /* a parenthesis preceded by whatever AND at least a space */
+ text = text.replaceAll("(?<=[^\\]])\\s+\\(", SPACER + LIST_START);
+ /* a parenthesis preceded by a space+digit OR digit+digit */
+ text = text.replaceAll("(?<=\\W\\d)\\(", SPACER + LIST_START);
+
+ if (VERBOSE)
+ System.out.println(text);
+
+ parseDictionary(text);
+ }
+
+ protected void parseDictionary(String text) {
+ StringTokenizer tokenizer = new StringTokenizer(text, "};{!&", true);
+ Stack stack = new Stack();
+ readDictionary(tokenizer, stack);
+ if (VERBOSE)
+ System.out.println("##################################\n" + toString());
+ linkResolver.resolve(dictionary);
+ }
+
+ void readDictionary(StringTokenizer st, Stack stack) {
+ while (st.hasMoreTokens()) {
+ String token = st.nextToken();
+ token = token.trim(); // tolgo gli spazi
+ stack.push(token);// metto nella pila
+
+ if (stack.peek().equals(DICTIONARY_START)) {
+ stack.pop();
+ String name = stack.peek();
+ Dictionary d = new Dictionary(name);
+ if (VERBOSE)
+ System.out.println("START DICTIONARY: " + name);
+
+ new DictionaryReader(d).readDictionary(st, stack);
+
+ if (isMultiple(name)) {
+ String[] names = extractMultipleKeys(name);
+ for (String n : names) {
+ if (isGeneric(withDoubleQuotes(n))) {
+ Dictionary copy = new Dictionary(d);
+ copy.setName(withDoubleQuotes(n));
+ dictionary.addGeneric(copy);
+ } else {
+ Dictionary copy = new Dictionary(d);
+ copy.setName(n);
+ dictionary.add(copy);
+ }
+ }
+ } else if (isGeneric(name)) {
+ dictionary.addGeneric(d);
+ } else {
+ dictionary.add(d);
+ }
+ } else if (stack.peek().equals(DICTIONARY_END)) {
+ stack.pop();
+ String name = stack.pop();
+ if (VERBOSE)
+ System.out.println("FINE DICTIONARY: " + name);
+ return;
+ } else if (stack.peek().equals(FIELD_END)) {
+ stack.pop();
+ String field = stack.pop();
+ if (VERBOSE)
+ System.out.println(field);
+
+ if (field.startsWith("$")) {
+ dictionary.add(DICTIONARY_LINK, field);
+ } else if (field.equals(")")) {
+ if (VERBOSE)
+ System.out.println("END LIST");
+ return;
+ } else {
+ readField(field);
+ }
+ } else if (stack.peek().equals(LIST_START)) {
+ stack.pop();
+ String name = stack.pop();
+ if (VERBOSE)
+ System.out.println("START LIST: " + name);
+ ListField list = new ListField(name);
+ ListReader reader = new ListReader(list, dictionary);
+ reader.readList(st, stack);
+ if (!reader.isSimpleList()) {
+ dictionary.add(list);
+ }
+ } else if (stack.peek().equals(MATRIX_START)) {
+ stack.pop();
+ String name = stack.pop();
+ if (VERBOSE)
+ System.out.println("START MATRIX: " + name);
+ FieldElement matrix = new FieldElement(name, "");
+ MatrixReader reader = new MatrixReader(matrix, dictionary);
+ reader.readMatrix(st, stack);
+ }
+ }
+ }
+
+ protected void readField(String field) {
+ try {
+ dictionary.add(new DimensionedScalar(field));
+ } catch (DictionaryException e) {
+ int splitIndex = field.indexOf(SPACER);
+ if (splitIndex < 0) {
+ String key = field.trim();
+ String value = "";
+ dictionary.add(key, value);
+ } else {
+ String key = field.substring(0, splitIndex).trim();
+ String value = field.substring(splitIndex).trim();
+
+ // System.out.println("DictionaryReader.readField() FIELD: "+field+" -> K: "+key+", V: "+value);
+
+ if (isMultiple(key)) {
+ String[] keys = extractMultipleKeys(key);
+ for (String k : keys) {
+ if (isGeneric(withDoubleQuotes(k))) {
+ dictionary.addGeneric(withDoubleQuotes(k), value);
+ } else {
+ dictionary.add(k, value);
+ }
+ }
+ } else if (isGeneric(key)) {
+ dictionary.addGeneric(key, value);
+ } else if (isLink(value)) {
+ extractLink(key, value);
+ } else {
+ dictionary.add(key, value);
+ }
+ }
+ }
+ }
+
+ private String withDoubleQuotes(String k) {
+ return "\"" + k + "\"";
+ }
+
+ public static String[] extractMultipleKeys(String key) {
+ key = key.replace("\"", "");
+
+ if (key.contains("(") && key.contains(")")) {
+ int start = key.indexOf("(");
+ int end = key.indexOf(")");
+ String header = key.substring(0, start);
+ String footer = key.substring(end + 1, key.length());
+ String core = key.substring(start + 1, end);
+
+ String[] tokens = core.split("\\|");
+
+ String[] keys = new String[tokens.length];
+ for (int i = 0; i < keys.length; i++) {
+ keys[i] = header + tokens[i] + footer;
+ }
+ return keys;
+ } else {
+ String[] tokens = key.split("\\|");
+ return tokens;
+ }
+
+ }
+
+ public String cleanGenericKey(String key) {
+ key = key.substring(1, key.length() - 1);
+ key = key.substring(0, key.indexOf(".*"));
+ return key;
+ }
+
+ public boolean isGeneric(String key) {
+ return key.startsWith("\"") && key.endsWith("\"") && key.contains(".*");
+ }
+
+ public boolean isMultiple(String key) {
+ return key.startsWith("\"") && key.endsWith("\"") && key.contains(MATRIX_DELIMITER);
+ }
+
+ public boolean isLink(String value) {
+ return !value.startsWith("\"") && value.contains("$");
+ }
+
+ private void extractLink(String key, String value) {
+ if (value.startsWith("uniform")) {
+ String link = value.replace("uniform", "").trim();
+ if (link.startsWith("$")) {
+ dictionary.add(VALUE_UNIFORM_LINK + key, link);
+ }
+ } else if (value.startsWith("$")) {
+ dictionary.add(VALUE_LINK + key, value);
+ }
+ }
+
+}
diff --git a/src/eu/engys/core/dictionary/DictionaryUtils.java b/src/eu/engys/core/dictionary/DictionaryUtils.java
new file mode 100644
index 0000000..1493183
--- /dev/null
+++ b/src/eu/engys/core/dictionary/DictionaryUtils.java
@@ -0,0 +1,160 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.core.dictionary;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.commons.io.FileUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import eu.engys.core.dictionary.parser.DictionaryReader2;
+import eu.engys.util.progress.ProgressMonitor;
+
+public final class DictionaryUtils {
+
+ private static final Logger logger = LoggerFactory.getLogger(DictionaryUtils.class);
+
+ public static Dictionary readDictionary(String text) {
+ Dictionary dictionary = new Dictionary("");
+ dictionary.readDictionaryFromString(text);
+ return dictionary;
+ }
+
+ public static Dictionary readDictionary(File file, ProgressMonitor monitor) {
+ String name = file.getName();
+ if (file.exists()) {
+ if (monitor != null) {
+ monitor.info(file.getName(), 1);
+ }
+ return new Dictionary(file);
+ }
+ if (monitor != null)
+ monitor.warning(file.getName() + " NOT FOUND", 1);
+
+ return new Dictionary(name);
+ }
+
+ public static Dictionary readDictionary2(File file) {
+ String name = file.getName();
+ String parent = file.getParent();
+ if (file.exists()) {
+ Dictionary d = new Dictionary(name);
+ d.setFoamFile(FoamFile.getDictionaryFoamFile(parent, name));
+ DictionaryReader2 reader = new DictionaryReader2(d);
+ reader.read(file);
+
+ return d;
+ }
+
+ return new Dictionary(name);
+ }
+
+ public static Dictionary readDictionary(File file, Dictionary linkDestination) {
+ String name = file.getName();
+ if (file.exists()) {
+ Dictionary d = new Dictionary(name);
+ DictionaryReader reader = new DictionaryReader(d, new DictionaryLinkResolver(linkDestination));
+ reader.read(file);
+
+ return d;
+ }
+ return new Dictionary(name);
+ }
+
+ public static void removeDictionary(File parent, Dictionary dict, ProgressMonitor monitor) {
+ if (dict != null) {
+ File dictFile = new File(parent, dict.getName());
+ if (dictFile.exists()) {
+ logger.info("REMOVE: " + dict.getName() + " -> " + dictFile.getAbsolutePath());
+ if (!dictFile.delete())
+ logger.warn("REMOVE: Cannot remove {}", dictFile);
+ } else {
+ logger.warn("REMOVE: File {} does not exist", dictFile);
+ }
+ }
+ }
+
+ public static void writeDictionary(File parent, Dictionary dict, ProgressMonitor monitor) {
+ if (dict != null) {
+ File dictFile = new File(parent, dict.getName());
+ writeDictionaryFile(dictFile, dict);
+ String msg = "WRITE: " + dict.getName() + " -> " + dictFile.getAbsolutePath();
+ if (monitor != null) {
+ monitor.info(dict.getName(), 1);
+ }
+ logger.info(msg);
+ } else {
+ logger.warn("Dictionary NOT FOUND in parent " + parent, 1);
+ }
+ }
+
+ public static void writeDictionaryFile(File file, Dictionary dictionary) {
+ String text = dictionary.write();
+ try {
+ FileUtils.writeStringToFile(file, text);
+ } catch (IOException e) {
+ logger.error(e.getMessage());
+ }
+ }
+
+ public static Dictionary header(String parent, Dictionary dict) {
+ if (dict == null)
+ return null;
+ dict.setFoamFile(FoamFile.getDictionaryFoamFile(parent, dict.getName()));
+ return dict;
+ }
+
+ public static String[] string2StringArray(String list) {
+ String trimmedString = list.trim();
+ String stringWithoutParentheses = trimmedString.substring(1, trimmedString.length() - 1).trim();
+ if(stringWithoutParentheses.isEmpty()){
+ return new String[0];
+ } else {
+ return stringWithoutParentheses.split("\\s+");
+ }
+ }
+
+ public static String stringArray2String(String[] values) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("(");
+ for (String value : values) {
+ sb.append(value);
+ sb.append(" ");
+ }
+ sb.append(")");
+ return sb.toString();
+ }
+
+ public static void copyIfFound(Dictionary dest, Dictionary source, String key) {
+ if (source.found(key)) {
+ dest.add(key, source.lookup(key));
+ }
+ }
+
+}
diff --git a/src/eu/engys/core/dictionary/DictionaryWriter.java b/src/eu/engys/core/dictionary/DictionaryWriter.java
new file mode 100644
index 0000000..6eefff9
--- /dev/null
+++ b/src/eu/engys/core/dictionary/DictionaryWriter.java
@@ -0,0 +1,182 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.dictionary;
+
+import static eu.engys.core.dictionary.Dictionary.SPACER;
+import static eu.engys.core.dictionary.Dictionary.TAB;
+import static eu.engys.core.dictionary.Dictionary.VERBOSE;
+import eu.engys.core.dictionary.parser.ListField2;
+
+public class DictionaryWriter {
+
+ protected Dictionary dictionary;
+
+ protected final String START = "{";
+ protected final String END = "}\n";
+
+ public DictionaryWriter(Dictionary dictionary) {
+ this.dictionary = dictionary;
+ }
+
+ public String write() {
+ StringBuffer sb = new StringBuffer();
+ writeDictionary(sb, "");
+ return sb.toString();
+ }
+
+ public void writeDictionary(StringBuffer sb, String rowHeader) {
+ if (dictionary.getFoamFile() != null) {
+ sb.append(FoamFile.HEADER);
+ DictionaryWriter writer = new DictionaryWriter(dictionary.getFoamFile());
+ writer.writeDictionary(sb, "");
+
+ if (dictionary.hasOnlyList()) {
+ for (ListField list : dictionary.getListFields()) {
+ if (list.getName().isEmpty()) {
+ list.writeListDict(sb, rowHeader);
+ } else {
+ list.writeListField(sb, rowHeader);
+ }
+ }
+ return;
+ }
+
+ if (dictionary.hasOnlyList2()) {
+ for (ListField2 list : dictionary.getListFields2()) {
+ if (list.nameIsANumber()) {
+ list.writeListDict(sb, rowHeader);
+ } else {
+ list.writeListField(sb, rowHeader);
+ }
+ }
+ return;
+ }
+ } else {
+ sb.append("\n");
+ sb.append(rowHeader);
+ sb.append(dictionary.getName());
+ sb.append("\n");
+ sb.append(rowHeader);
+ sb.append(START);
+ }
+ for (String key : dictionary.getKeys()) {
+ DefaultElement ele = dictionary.getElement(key);
+ if (ele != null) {
+ writeElement(sb, rowHeader, ele);
+ } else {
+ System.out.println("DictionaryWriter.writeDictionary() ------------------------------>> " + key + " is NUUULLLLL in " + dictionary.getKeys() + " and " + dictionary.getDictionaries());
+ }
+ }
+ for (String includeFile : dictionary.getIncludeFiles()) {
+ writeInclude(sb, includeFile, rowHeader);
+ }
+
+ if (dictionary.getFoamFile() == null)
+ sb.append("\n" + rowHeader + END);
+ }
+
+ public static void writeElement(StringBuffer sb, String rowHeader, DefaultElement ele) {
+ if (ele instanceof Dictionary) {
+ DictionaryWriter writer = new DictionaryWriter((Dictionary) ele);
+ writer.writeDictionary(sb, rowHeader + TAB);
+ } else if (ele instanceof DimensionedScalar) {
+ writeDimensionedScalar(sb, (DimensionedScalar) ele, rowHeader);
+ } else if (ele instanceof ListField) {
+ ListField.class.cast(ele).writeListField(sb, rowHeader);
+ } else if (ele instanceof ListField2) {
+ ListField2.class.cast(ele).writeListField(sb, rowHeader);
+ } else if (ele instanceof TableRowElement) {
+ TableRowElement.class.cast(ele).writeTableRow(sb, rowHeader);
+ } else if (hasParenthesis(ele)) {
+ writeMatrix(sb, (FieldElement) ele, rowHeader);
+ } else {
+ writeField(sb, (FieldElement) ele, rowHeader);
+ }
+ }
+
+ private static boolean hasParenthesis(DefaultElement ele) {
+ FieldElement fieldElement = (FieldElement) ele;
+ String value = fieldElement.getValue();
+ return value != null && value.contains("(") && value.contains("List");
+ }
+
+ protected static void writeField(StringBuffer sb, FieldElement field, String rowHeader) {
+ if (field.getName().isEmpty()) {
+ sb.append(SPACER);
+ sb.append(field.getValue());
+ } else {
+ sb.append("\n");
+ sb.append(rowHeader);
+ sb.append(TAB);
+ sb.append(field.getName());
+ sb.append(SPACER);
+ sb.append(field.getValue());
+ sb.append(";");
+ }
+ }
+
+ protected static void writeMatrix(StringBuffer sb, FieldElement field, String rowHeader) {
+ sb.append("\n");
+ sb.append(rowHeader);
+ sb.append(TAB);
+ sb.append(field.getName());
+ sb.append(SPACER);
+ String value = field.getValue();
+ if (value.contains("vector")) {
+ sb.append(value.replace("(", "\n(").replace("))", ")\n)").replace("", "\n"));
+ } else {
+ sb.append(value.replace("(", "\n(").replace("", "\n").replaceAll("\\s+", "\n"));
+ }
+ sb.append(";");
+ }
+
+ protected void writeInclude(StringBuffer sb, String includeFile, String rowHeader) {
+ if (VERBOSE)
+ System.out.println("Dictionary.writeInclude() " + includeFile);
+ sb.append("\n");
+ sb.append(rowHeader);
+ sb.append(TAB);
+ sb.append("#include");
+ sb.append(SPACER);
+ sb.append(includeFile);
+ }
+
+ private static void writeDimensionedScalar(StringBuffer sb, DimensionedScalar ds, String rowHeader) {
+ if (VERBOSE)
+ System.out.println("Dictionary.writeDimensionedScalar() " + (ds != null ? ds.getName() : "NULL!!!"));
+ sb.append("\n");
+ sb.append(rowHeader);
+ sb.append(TAB);
+ sb.append(ds.getName());
+ sb.append(SPACER);
+ sb.append(ds.getName());
+ sb.append(SPACER);
+ sb.append(ds.getDimensions());
+ sb.append(SPACER);
+ sb.append(ds.getValue());
+ sb.append(";");
+ }
+}
diff --git a/src/eu/engys/core/dictionary/DimensionedScalar.java b/src/eu/engys/core/dictionary/DimensionedScalar.java
new file mode 100644
index 0000000..9d43777
--- /dev/null
+++ b/src/eu/engys/core/dictionary/DimensionedScalar.java
@@ -0,0 +1,145 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.core.dictionary;
+
+import java.util.ArrayList;
+import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class DimensionedScalar extends FieldElement {
+ private static final Pattern PATTERN = Pattern.compile("(\\w+)\\s+(\\[.+\\])\\s+(.*\\z)");
+ // private static final Pattern PATTERN =
+ // Pattern.compile("(\\w+)\\s+(\\[.+\\])\\s+(\\d+\\.?\\d?)");
+
+ private Dimensions dimensions;
+
+ public DimensionedScalar(String name, String value, String dimensions) {
+ super(name, value);
+ this.dimensions = new Dimensions(dimensions);
+ }
+
+ public DimensionedScalar(String name, String value, Dimensions dimensions) {
+ super(name, value);
+ this.dimensions = dimensions;
+ }
+
+ public DimensionedScalar(DimensionedScalar ds) {
+ super(ds.getName(), ds.getValue());
+ this.dimensions = new Dimensions(ds.getDimensions().toString());
+ }
+
+ /**
+ * La stringa contiene il value del field di cui bisogna fare il parsing per
+ * estrarre valore e unita' di misura
+ *
+ * @param field
+ * value
+ */
+ public DimensionedScalar(String fieldValue) throws IllegalArgumentException {
+ super("", "");
+
+ Matcher matcher = PATTERN.matcher(fieldValue);
+ if (matcher.find()) {
+ String name = matcher.group(1);
+ String dimensions = matcher.group(2);
+ String value = matcher.group(3);
+ setName(name);
+ setValue(value);
+ this.dimensions = new Dimensions(dimensions);
+ } else {
+ throw new DictionaryException("CANNOT PARSE: >" + fieldValue + "<");
+ }
+ }
+
+ public double doubleValue() {
+ return Double.parseDouble(getValue());
+ }
+
+ public Dimensions getDimensions() {
+ return dimensions;
+ }
+
+ public class Dimensions extends ArrayList {
+ public Dimensions(String dimString) {
+ dimString = dimString.trim();
+ dimString = dimString.substring(1, dimString.length() - 1); // tolgo
+ // le
+ // parentesi
+ // quadre
+ StringTokenizer st = new StringTokenizer(dimString);
+ if (st.countTokens() == 7 || st.countTokens() == 5) {
+ while (st.hasMoreTokens()) {
+ add(Integer.decode(st.nextToken()));
+ }
+ if (size() == 5) {
+ add(Integer.valueOf(0));
+ add(Integer.valueOf(0));
+ }
+ } else {
+ throw new IllegalStateException("Bad number of dimensions: " + dimString);
+ }
+ }
+
+ public Dimensions() {
+ }
+
+ /**
+ * Perform a division among dimensions: we need to subtract each
+ * component
+ *
+ * @param d
+ * @return
+ */
+ public Dimensions divide(Dimensions d) {
+ Dimensions result = new Dimensions();
+ for (int i = 0; i < d.size(); i++) {
+ result.add(new Integer(get(i).intValue() - d.get(i).intValue()));
+ }
+ return result;
+ }
+
+ public String toString() {
+ if (size() == 0)
+ return "[]";
+ StringBuilder sb = new StringBuilder();
+ sb.append('[');
+
+ for (Integer i : this) {
+ sb.append(i);
+ sb.append(" ");
+ }
+ return sb.append(']').toString();
+ }
+ }
+
+ @Override
+ public String toString() {
+ return getName() + " " + getDimensions() + " " + getValue();
+ }
+
+}
diff --git a/src/eu/engys/core/dictionary/FieldChangeListener.java b/src/eu/engys/core/dictionary/FieldChangeListener.java
new file mode 100644
index 0000000..f95afad
--- /dev/null
+++ b/src/eu/engys/core/dictionary/FieldChangeListener.java
@@ -0,0 +1,36 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.core.dictionary;
+
+import java.awt.event.ActionListener;
+
+public interface FieldChangeListener extends ActionListener {
+
+ public void fieldChanged();
+ public boolean isAdjusting();
+ public void setAdjusting(boolean b);
+}
diff --git a/src/eu/engys/core/dictionary/FieldElement.java b/src/eu/engys/core/dictionary/FieldElement.java
new file mode 100644
index 0000000..dcc3763
--- /dev/null
+++ b/src/eu/engys/core/dictionary/FieldElement.java
@@ -0,0 +1,62 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.core.dictionary;
+
+public class FieldElement extends DefaultElement {
+
+ private String value;
+
+ public FieldElement(String name, String value) {
+ super(name);
+ this.value = value;
+ }
+
+ public FieldElement(FieldElement el) {
+ this(el.getName(), el.getValue());
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return getName() + "[" + value + "]";
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof FieldElement) {
+ return ((FieldElement) obj).getName().equals(getName()) && ((FieldElement) obj).value.equals(value) ;
+ }
+ return false;
+ }
+}
diff --git a/src/eu/engys/core/dictionary/FieldListener.java b/src/eu/engys/core/dictionary/FieldListener.java
new file mode 100644
index 0000000..072aa20
--- /dev/null
+++ b/src/eu/engys/core/dictionary/FieldListener.java
@@ -0,0 +1,31 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.core.dictionary;
+
+public interface FieldListener {
+
+}
diff --git a/src/eu/engys/core/dictionary/FileEditor.java b/src/eu/engys/core/dictionary/FileEditor.java
new file mode 100644
index 0000000..4cc76a1
--- /dev/null
+++ b/src/eu/engys/core/dictionary/FileEditor.java
@@ -0,0 +1,254 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.core.dictionary;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dialog.ModalityType;
+import java.awt.FlowLayout;
+import java.awt.Window;
+import java.awt.event.ActionEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.util.List;
+
+import javax.swing.AbstractAction;
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JPanel;
+import javax.swing.JSeparator;
+import javax.swing.SwingConstants;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+
+import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
+import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
+import org.fife.ui.rtextarea.RTextScrollPane;
+
+import eu.engys.util.ui.ExecUtil;
+import eu.engys.util.ui.UiUtil;
+
+public class FileEditor {
+
+ public static final String FILE_EDITOR_DIALOG = "file.editor.dialog";
+ public static final String FILE_EDITOR = "fileEditor";
+
+ private static FileEditor instance;
+
+ private JDialog dialog;
+ private RSyntaxTextArea editor;
+ private DocumentListener documentListener;
+
+ private String fileName;
+ private List fileContent;
+ private boolean modified;
+
+ private Runnable onDisposeRunnable;
+
+ private Runnable onOKRunnable;
+
+ private JButton okButton;
+
+ public static FileEditor getInstance() {
+ if (instance == null)
+ instance = new FileEditor();
+ return instance;
+ }
+
+ private FileEditor() {
+ initEditor();
+ initListeners();
+ }
+
+ private void initEditor() {
+ this.editor = new RSyntaxTextArea();
+ editor.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_NONE);
+ editor.setCodeFoldingEnabled(true);
+ editor.setAntiAliasingEnabled(true);
+ editor.setBackground(new Color(240, 240, 240));
+ editor.setName(FILE_EDITOR);
+ }
+
+ private void initListeners() {
+ documentListener = new DocumentListener() {
+
+ @Override
+ public void removeUpdate(DocumentEvent e) {
+ documentModified();
+ }
+
+ @Override
+ public void insertUpdate(DocumentEvent e) {
+ documentModified();
+ }
+
+ @Override
+ public void changedUpdate(DocumentEvent e) {
+ documentModified();
+ }
+ };
+ }
+
+ private void documentModified() {
+ if (!modified) {
+ dialog.setTitle("*" + dialog.getTitle());
+ this.modified = true;
+ }
+ }
+
+ public void show(final Window parent, List fileContent, String fileName) {
+ show(parent, fileContent, fileName, null, null, null);
+ }
+
+ public void show(final Window parent, List fileContent, String fileName, final Runnable onShowRunnable, Runnable onDisposeRunnable, Runnable onOKRunnable) {
+ this.fileContent = fileContent;
+ this.fileName = fileName;
+ this.onDisposeRunnable = onDisposeRunnable;
+ this.onOKRunnable = onOKRunnable;
+ ExecUtil.invokeAndWait(new Runnable() {
+
+ @Override
+ public void run() {
+ initDialog(parent);
+ load();
+ if (onShowRunnable != null) {
+ onShowRunnable.run();
+ }
+ dialog.setVisible(true);
+ }
+ });
+ }
+
+ private void initDialog(Window parent) {
+ dialog = new JDialog(parent != null ? parent : UiUtil.getActiveWindow(), ModalityType.MODELESS);
+ dialog.setName(FILE_EDITOR_DIALOG);
+ dialog.getContentPane().setLayout(new BorderLayout());
+ dialog.getContentPane().add(createMainPanel(), BorderLayout.CENTER);
+ dialog.getContentPane().add(createButtonsPanel(), BorderLayout.SOUTH);
+ dialog.getContentPane().doLayout();
+ dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
+ dialog.addWindowListener(new WindowAdapter() {
+ @Override
+ public void windowClosing(WindowEvent e) {
+ closeDialog();
+ }
+ });
+
+ dialog.setSize(800, 600);
+ dialog.setLocationRelativeTo(null);
+ dialog.getRootPane().setDefaultButton(okButton);
+ }
+
+ private JPanel createMainPanel() {
+ RTextScrollPane scrollPane = new RTextScrollPane(editor);
+ scrollPane.setFoldIndicatorEnabled(true);
+ scrollPane.setBorder(BorderFactory.createEmptyBorder());
+ JPanel mainPanel = new JPanel(new BorderLayout());
+ mainPanel.add(scrollPane);
+ return mainPanel;
+ }
+
+ private JPanel createButtonsPanel() {
+ JPanel panel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
+
+ okButton = new JButton(new OKAction());
+ okButton.setName("OK");
+
+ JButton cancelButton = new JButton(new CancelAction());
+ cancelButton.setName("Cancel");
+
+ panel.add(okButton);
+ panel.add(cancelButton);
+
+ JPanel buttonsPanel = new JPanel(new BorderLayout());
+ buttonsPanel.add(new JSeparator(SwingConstants.HORIZONTAL), BorderLayout.NORTH);
+ buttonsPanel.add(panel, BorderLayout.CENTER);
+
+ return buttonsPanel;
+ }
+
+ private void closeDialog() {
+ dialog.setVisible(false);
+ dialog.dispose();
+ dialog = null;
+ if (onDisposeRunnable != null) {
+ onDisposeRunnable.run();
+ }
+ }
+
+ private void load() {
+ editor.getDocument().removeDocumentListener(documentListener);
+ editor.setText("");
+ try {
+ for (String line : fileContent) {
+ editor.append(line + "\n");
+ }
+ editor.setCaretPosition(0);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ dialog.setTitle(fileName);
+ editor.getDocument().addDocumentListener(documentListener);
+ this.modified = false;
+ }
+
+ private void save() {
+ fileContent.clear();
+ for (String line : editor.getText().split("\\n")){
+ fileContent.add(line);
+ }
+ dialog.setTitle(fileName);
+ }
+
+ private class OKAction extends AbstractAction {
+ public OKAction() {
+ super("OK");
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ save();
+ if(onOKRunnable != null){
+ onOKRunnable.run();
+ }
+ closeDialog();
+ }
+ }
+
+ private class CancelAction extends AbstractAction {
+ public CancelAction() {
+ super("Cancel");
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ closeDialog();
+ }
+ }
+
+}
diff --git a/src/eu/engys/core/dictionary/Finder.java b/src/eu/engys/core/dictionary/Finder.java
new file mode 100644
index 0000000..6f5547b
--- /dev/null
+++ b/src/eu/engys/core/dictionary/Finder.java
@@ -0,0 +1,32 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.dictionary;
+
+public interface Finder {
+
+ boolean accept(String key);
+
+}
diff --git a/src/eu/engys/core/dictionary/FoamFile.java b/src/eu/engys/core/dictionary/FoamFile.java
new file mode 100644
index 0000000..fcf8f70
--- /dev/null
+++ b/src/eu/engys/core/dictionary/FoamFile.java
@@ -0,0 +1,65 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.core.dictionary;
+
+import eu.engys.util.ApplicationInfo;
+
+public class FoamFile extends Dictionary {
+
+ private static final String HELYX = ApplicationInfo.getName();
+ private static final String VERSION = ApplicationInfo.getVersion();
+ public static final String HEADER =
+ "/*--------------------------------*- C++ -*----------------------------------*\\"+"\n"+
+ "| o | |" +"\n"+
+ "| o o | "+HELYX+" |" +"\n"+
+ "| o O o | Version: "+VERSION+" |" +"\n"+
+ "| o o | Web: http://www.engys.com |" +"\n"+
+ "| o | |" +"\n"+
+ "\\*---------------------------------------------------------------------------*/";
+
+ private FoamFile(String version, String format, String classe, String location, String object) {
+ super("FoamFile");
+ add("version", version);
+ add("format", format);
+ add("class", classe);
+ add("location", location);
+ add("object", object);
+ }
+
+ public static FoamFile getFieldFoamFile(String name) {
+ return new FoamFile("2.0", "ascii", name.startsWith("U") ? "volVectorField" : (name.startsWith("point") ? "pointVectorField" : "volScalarField"), "\"0\"", name);
+ }
+
+ public static FoamFile getDictionaryFoamFile(String parent, String name) {
+ return new FoamFile("2.0", "ascii", "dictionary", parent, name);
+ }
+
+ public static FoamFile getDictionaryFoamFile(String classe, String parent, String name) {
+ return new FoamFile("2.0", "ascii", classe, parent, name);
+ }
+
+}
diff --git a/src/eu/engys/core/dictionary/ListField.java b/src/eu/engys/core/dictionary/ListField.java
new file mode 100644
index 0000000..7ce63b9
--- /dev/null
+++ b/src/eu/engys/core/dictionary/ListField.java
@@ -0,0 +1,188 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.core.dictionary;
+
+import static eu.engys.core.dictionary.Dictionary.TAB;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.StringTokenizer;
+
+public class ListField extends DefaultElement {
+
+ private static final String SPACER = " ";
+ private List list = new ArrayList();
+
+ public ListField(String name) {
+ super(decodeName(name));
+ }
+
+ public boolean isEmpty() {
+ return list.isEmpty();
+ }
+
+ public ListField(ListField lf) {
+ super(lf.getName());
+ for (DefaultElement el : lf.getListElements()) {
+ if (el instanceof Dictionary) {
+ add(new Dictionary((Dictionary) el));
+ } else {
+ System.err.println("ListField only dictionaries are allowed as elements: " + el.getName());
+ }
+ }
+ }
+
+ private static String decodeName(String name) {
+ if (name.contains(SPACER)) {
+ StringTokenizer tokenizer = new StringTokenizer(name, SPACER);
+ if (tokenizer.countTokens() == 1) {
+ // System.out.println("ListField.decodeName() 1 TOKEN");
+ String token = tokenizer.nextToken();
+ try {
+ int size = Integer.parseInt(token);
+ return "";
+ } catch (NumberFormatException ex) {
+ return token;
+ }
+ } else if (tokenizer.countTokens() == 2) {
+ // System.out.println("ListField.decodeName() 2 TOKEN");
+ String token1 = tokenizer.nextToken();
+ String token2 = tokenizer.nextToken();
+ try {
+ int size = Integer.parseInt(token2);
+ } catch (NumberFormatException ex) {
+ return name;
+ }
+ return token1;
+ } else if (tokenizer.countTokens() == 3) {
+ // System.out.println("ListField.decodeName() 3 TOKEN");
+ String token1 = tokenizer.nextToken();
+ String token2 = tokenizer.nextToken();
+ String token3 = tokenizer.nextToken();
+ try {
+ int size = Integer.parseInt(token3);
+ } catch (NumberFormatException ex) {
+ }
+ return name;
+ }
+ } else {
+ // System.out.println("ListField.decodeName() 4+ TOKEN");
+ try {
+ int size = Integer.parseInt(name);
+ return "";
+ } catch (NumberFormatException ex) {
+ return name;
+ }
+ }
+ return name;
+ }
+
+ public void add(DefaultElement element) {
+ list.add(element);
+ }
+
+ public List getListElements() {
+ return Collections.unmodifiableList(list);
+ }
+
+ public void merge(ListField l) {
+ for (DefaultElement el : l.getListElements()) {
+ if (containsElement(el)) {
+ if (el instanceof Dictionary) {
+ Dictionary dictionary = getDictionary(el.getName());
+ if (dictionary != null) {
+ dictionary.merge((Dictionary) el);
+ } else {
+ System.err.println("Error merging list '" + getName() + "' with " + l.getName() + "");
+ }
+ } else {
+ // do nothing
+ }
+ } else {
+ add(el);
+ }
+ }
+ }
+
+ private boolean containsElement(DefaultElement element) {
+ for (DefaultElement e : list) {
+ if (e instanceof Dictionary && e.getName().equals(element.getName()) && !e.getName().isEmpty()) {
+ return true;
+ } else if (e.getName().equals(element.getName()) && e.equals(element)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void writeListField(StringBuffer sb, String rowHeader) {
+ sb.append("\n");
+ sb.append(rowHeader);
+ sb.append(TAB);
+ sb.append(getName());
+ sb.append("\n");
+ sb.append(rowHeader);
+ sb.append(TAB);
+ sb.append("(");
+ for (DefaultElement el : getListElements()) {
+ DictionaryWriter.writeElement(sb, rowHeader, el);
+ }
+ sb.append("\n");
+ sb.append(rowHeader);
+ sb.append(TAB);
+ sb.append(");");
+ }
+
+ public void writeListDict(StringBuffer sb, String rowHeader) {
+ sb.append("\n");
+ sb.append(rowHeader);
+ sb.append(TAB);
+ sb.append(list.size());
+ sb.append("\n");
+ sb.append(rowHeader);
+ sb.append(TAB);
+ sb.append("(");
+ for (DefaultElement el : getListElements()) {
+ DictionaryWriter.writeElement(sb, rowHeader, el);
+ }
+ sb.append("\n");
+ sb.append(rowHeader);
+ sb.append(TAB);
+ sb.append(")");
+ }
+
+ public Dictionary getDictionary(String name) {
+ for (DefaultElement e : list) {
+ if (e instanceof Dictionary && !e.getName().isEmpty() && e.getName().equals(name)) {
+ return (Dictionary) e;
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/src/eu/engys/core/dictionary/ListReader.java b/src/eu/engys/core/dictionary/ListReader.java
new file mode 100644
index 0000000..f83cdfd
--- /dev/null
+++ b/src/eu/engys/core/dictionary/ListReader.java
@@ -0,0 +1,118 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.core.dictionary;
+
+import static eu.engys.core.dictionary.Dictionary.VERBOSE;
+
+import java.util.Stack;
+import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class ListReader {
+
+ private ListField list;
+ private Dictionary parent;
+ private boolean simpleList;
+
+ public ListReader(ListField list, Dictionary parent) {
+ this.list = list;
+ this.parent = parent;
+ }
+
+ public void readList(StringTokenizer st, Stack stack) {
+ while (st.hasMoreTokens()) {
+ String token = st.nextToken();
+ token = token.trim(); /* tolgo gli spazi */
+ stack.push(token);/* metto nella pila */
+
+ if (stack.peek().equals("{")) {
+ stack.pop();
+ String name = stack.peek();
+ Dictionary d = new Dictionary(name);
+ if (VERBOSE)
+ System.out.println("START LIST DICTIONARY: " + name);
+
+ new DictionaryReader(d).readDictionary(st, stack);
+ list.add(d);
+ } else if (stack.peek().equals("}")) {
+ stack.pop();
+ String name = stack.pop();
+ if (VERBOSE)
+ System.out.println("END LIST DICTIONARY: " + name);
+ return;
+ } else if (stack.peek().equals(";")) {
+ stack.pop();
+ String field = stack.pop();
+ if (VERBOSE)
+ System.out.println(list.getName()+", "+field);
+
+ if (field.endsWith(")")) {
+ if (list.getListElements().isEmpty()) {
+ Pattern pattern = Pattern.compile("(\\w+)\\s+nonuniform\\s*(List)?\\s*(\\d+)?\\s*");
+ Matcher listFieldMatcher = pattern.matcher(list.getName());
+ if (field.equals(")")) {
+ if (listFieldMatcher.matches()) {/* is an empty array nonuniform 'nonuniform 0()' */
+ parent.add(listFieldMatcher.group(1), "nonuniform 0()");
+ simpleList = true;
+ }
+ } else {
+ if (listFieldMatcher.matches()) {
+ field = processField(field);
+
+ parent.add(listFieldMatcher.group(1), "nonuniform List "+(listFieldMatcher.groupCount() == 3 ? listFieldMatcher.group(3)+" " : "" )+"( "+field);
+ } else if (list.getName().contains(" uniform")) {/* is a simple array (val1 val2 val3) not empty '( )' */
+ parent.add(list.getName().replace("uniform", "").trim(), "uniform ( " + field);
+ } else if (field.startsWith("<")) {/* is a dataTable ( +++ (+++ +++ +++) ) */
+ parent.add(list.getName(), "( " + field.replace("<", "(").replace(">", ")"));
+ } else {
+ field = processField(field);
+ parent.add(list.getName(), "( " + field);
+ }
+ simpleList = true;
+ }
+ }
+ if (VERBOSE)
+ System.out.println("END LIST");
+ return;
+ }
+ }
+ }
+ }
+
+ private String processField(String field) {
+ if (field.contains("|")) {
+ field = field.replace("|", ") (");
+ }
+ return field;
+ }
+
+ public boolean isSimpleList() {
+ return simpleList;
+ }
+
+}
diff --git a/src/eu/engys/core/dictionary/MatrixReader.java b/src/eu/engys/core/dictionary/MatrixReader.java
new file mode 100644
index 0000000..1282a35
--- /dev/null
+++ b/src/eu/engys/core/dictionary/MatrixReader.java
@@ -0,0 +1,98 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.core.dictionary;
+
+import static eu.engys.core.dictionary.Dictionary.VERBOSE;
+
+import java.util.Stack;
+import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class MatrixReader {
+
+ private FieldElement matrix;
+ private Dictionary parent;
+
+ public MatrixReader(FieldElement matrix, Dictionary parent) {
+ this.matrix = matrix;
+ this.parent = parent;
+ }
+
+ public void readMatrix(StringTokenizer st, Stack stack) {
+ while(st.hasMoreTokens()) {
+ String token = st.nextToken();
+ token = token.trim(); //tolgo gli spazi
+ stack.push(token);//metto nella pila
+
+ if (stack.peek().equals(";")) {
+ stack.pop();
+ String field = stack.pop();
+ if (VERBOSE) System.out.println(field);
+
+ if (field.endsWith(")")) {
+ Pattern pattern = Pattern.compile("(\\w+)\\s+nonuniform\\s+(List)?\\s+(\\d+)?");
+ Matcher matcher = pattern.matcher(matrix.getName());
+
+ if (matcher.matches()) {
+ field = processField(field);
+ parent.add(matcher.group(1), "nonuniform List "+(matcher.groupCount() == 3 ? matcher.group(3)+" " : "" )+"(( "+field);
+ } else {
+ field = processField(field);
+ parent.add(matrix.getName(), "(( "+field);
+ }
+ return;
+ }
+ }
+ }
+ }
+
+ private String processField(String field) {
+ if (field.contains("|")) {
+ field = field.replace("|", ") (");
+ }
+ return field;
+ }
+
+ public static void matrixToVector(Dictionary dictionary, String key) {
+ if ( dictionary.found(key) ) {
+ String value = dictionary.lookupString(key);
+ value = value.replace("(", "").replace(")", "");
+ value = "( "+value+" )";
+ dictionary.add(key, value);
+ }
+ }
+
+ public static void vectorToMatrix(Dictionary dictionary, String key) {
+ if ( dictionary.found(key) ) {
+ String value = dictionary.lookupString(key);
+ value = value.replace("(", "").replace(")", "");
+ value = "(( "+value+" ))";
+ dictionary.add(key, value);
+ }
+ }
+}
diff --git a/src/eu/engys/core/dictionary/StartWithFinder.java b/src/eu/engys/core/dictionary/StartWithFinder.java
new file mode 100644
index 0000000..861483a
--- /dev/null
+++ b/src/eu/engys/core/dictionary/StartWithFinder.java
@@ -0,0 +1,40 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.dictionary;
+
+public class StartWithFinder implements Finder {
+
+ private String keyToFind;
+
+ public StartWithFinder(String keyToFind) {
+ this.keyToFind = keyToFind;
+ }
+
+ @Override
+ public boolean accept(String key) {
+ return key.startsWith(keyToFind);
+ }
+}
diff --git a/src/eu/engys/core/dictionary/TableRowElement.java b/src/eu/engys/core/dictionary/TableRowElement.java
new file mode 100644
index 0000000..6eee171
--- /dev/null
+++ b/src/eu/engys/core/dictionary/TableRowElement.java
@@ -0,0 +1,100 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.core.dictionary;
+
+import static eu.engys.core.dictionary.Dictionary.SPACER;
+import eu.engys.core.dictionary.parser.ListField2;
+
+public class TableRowElement extends DefaultElement {
+
+ private ListField2 key;
+ private FieldElement[] values;
+
+ public TableRowElement(ListField2 key, FieldElement... values) {
+ super("");
+ this.key = key;
+ this.values = values;
+ }
+
+ public TableRowElement(TableRowElement el) {
+ super("");
+ this.key = new ListField2(el.getKey());
+ this.values = copy(el.getValues());
+ }
+
+ private FieldElement[] copy(FieldElement[] values) {
+ FieldElement[] copy = new FieldElement[values.length];
+ for (int i = 0; i < values.length; i++) {
+ copy[i] = new FieldElement(values[i]);
+ }
+ return copy;
+ }
+
+ public void writeTableRow(StringBuffer sb, String rowHeader) {
+// System.out.println("ListField2.writeListField() name: "+getName()+", size: "+size+", uniformity: "+uniformity+", identifier: "+identifier);
+ sb.append("\n");
+ key.writeListField(sb, rowHeader);
+ sb.append(SPACER);
+ for (FieldElement f : values) {
+ sb.append(SPACER);
+ sb.append(f.getValue());
+ }
+ }
+
+ public ListField2 getKey() {
+ return key;
+ }
+
+ public FieldElement[] getValues() {
+ return values;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof TableRowElement) {
+ TableRowElement t = ((TableRowElement) obj);
+ return key.equals(t.key) /*&& valuesAreEquals(t.values)*/;
+ }
+ return super.equals(obj);
+ }
+
+ private boolean valuesAreEquals(FieldElement[] values) {
+ if (this.values.length != values.length) {
+ return false;
+ }
+ for (int i = 0; i < values.length; i++) {
+ if (!this.values[i].equals(values[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public void merge(TableRowElement el) {
+ this.values = el.values;
+ }
+}
diff --git a/src/eu/engys/core/dictionary/model/AbstractTableAdapter.java b/src/eu/engys/core/dictionary/model/AbstractTableAdapter.java
new file mode 100644
index 0000000..d8ea2e8
--- /dev/null
+++ b/src/eu/engys/core/dictionary/model/AbstractTableAdapter.java
@@ -0,0 +1,233 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.core.dictionary.model;
+
+import java.awt.BorderLayout;
+import java.awt.FlowLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import javax.swing.AbstractAction;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JSeparator;
+
+import eu.engys.util.ui.builder.PanelBuilder;
+
+public abstract class AbstractTableAdapter extends JPanel {
+
+ public static final Integer LEAVE_ONE_LINE = 1;
+
+ private Map rowsMap = new LinkedHashMap<>();
+
+ private final String[] columnLabels;
+ private final String rowLabel;
+ private PanelBuilder builder;
+ private final Integer linesToLeave;
+ protected JPanel buttonsPanel;
+ private boolean showColumnNames;
+
+ public AbstractTableAdapter(String[] columnNames) {
+ this(columnNames, "", 0, true);
+ }
+
+ public AbstractTableAdapter(String[] columnNames, String rowsLabel, Integer linesToLeave, boolean showColumnNames) {
+ super(new BorderLayout());
+ this.rowLabel = rowsLabel;
+ this.columnLabels = columnNames;
+ this.linesToLeave = linesToLeave;
+ this.showColumnNames = showColumnNames;
+ layoutComponents();
+ }
+
+ private void layoutComponents() {
+ setOpaque(false);
+ setName("abstract.table.adapter");
+
+ this.builder = new PanelBuilder();
+ buttonsPanel = getButtonsPanel();
+ add(buttonsPanel, BorderLayout.NORTH);
+ add(builder.getPanel(), BorderLayout.CENTER);
+ clear();
+ }
+
+ private JPanel getButtonsPanel() {
+ JPanel buttonsPanel = new JPanel(new FlowLayout());
+ buttonsPanel.setOpaque(false);
+
+ JButton addButton = new JButton(new AddRowAction());
+ addButton.setName("add.row.button");
+ buttonsPanel.add(addButton);
+
+ JButton remButton = new JButton(new RemRowAction());
+ remButton.setName("rem.row.button");
+ buttonsPanel.add(remButton);
+ return buttonsPanel;
+ }
+
+ public void clear() {
+ rowsMap.clear();
+ builder.clear();
+ if(showColumnNames){
+ builder.addComponent("", labelArrayField());
+ builder.addFill(new JSeparator());
+ }
+ }
+
+ private JLabel[] labelArrayField() {
+ JLabel[] labels = new JLabel[columnLabels.length];
+ for (int i = 0; i < labels.length; i++) {
+ labels[i] = new JLabel(columnLabels[i]);
+ }
+ return labels;
+ }
+
+ public void hideButtonsPanel() {
+ buttonsPanel.setVisible(false);
+ }
+
+ protected abstract void addRow();
+
+ protected JComponent[] addRow(JComponent[] field) {
+ return addRow(field, true);
+ }
+
+ protected JComponent[] addRow(JComponent[] field, boolean save) {
+ addPropertyChangeListeners(field);
+ String label = rowLabel.isEmpty() ? "" : rowLabel + (rowsMap.size() + 1);
+ JComponent[] componentToAdd = createComponent(field);
+ builder.addComponent(label, componentToAdd);
+ setNames(rowsMap.size(), field);
+ updateGUI();
+ rowsMap.put(rowsMap.size(), field);
+ if(save){
+ save();
+ }
+ return componentToAdd;
+ }
+
+ private void setNames(int row, JComponent... c) {
+ for (int i = 0; i < c.length; i++) {
+ c[i].setName((rowLabel.isEmpty() ? getName() : rowLabel) + "." + columnLabels[i] + "." + row);
+ }
+ }
+
+ protected JComponent[] createComponent(JComponent[] field) {
+ return field;
+ }
+
+ protected void removeRow() {
+ if (rowsMap.size() > linesToLeave) {
+ removeLastRowFromMap();
+ clear();
+ load();
+ updateGUI();
+ }
+ }
+
+ private void removeLastRowFromMap() {
+ Integer[] keys = rowsMap.keySet().toArray(new Integer[0]);
+ JComponent[] removedComp = rowsMap.remove(keys[keys.length - 1]);
+ save();
+ triggerEventFor3D(removedComp);
+ }
+
+ private void updateGUI() {
+ JPanel panel = builder.getPanel();
+ panel.revalidate();
+ panel.repaint();
+ }
+
+ public Map getRowsMap() {
+ return rowsMap;
+ }
+
+ protected int elementsCount() {
+ return rowsMap.size();
+ }
+
+ protected abstract void load();
+
+ protected abstract void save();
+
+ protected void addPropertyChangeListeners(JComponent[] field) {
+ for (int i = 0; i < field.length; i++) {
+ JComponent f = field[i];
+ if (f instanceof JCheckBox) {
+ ((JCheckBox) f).addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ save();
+ }
+ });
+ } else {
+ f.addPropertyChangeListener(new PropertyChangeListener() {
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ if (evt.getPropertyName().equals("value")) {
+ save();
+ }
+ }
+ });
+ }
+ }
+ }
+
+ protected void triggerEventFor3D(JComponent[] comp) {
+ }
+
+ private final class AddRowAction extends AbstractAction {
+
+ private AddRowAction() {
+ super("+");
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ addRow();
+ }
+ }
+
+ private final class RemRowAction extends AbstractAction {
+ private RemRowAction() {
+ super("-");
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ removeRow();
+ }
+ }
+
+}
diff --git a/src/eu/engys/core/dictionary/model/AxisInfo.java b/src/eu/engys/core/dictionary/model/AxisInfo.java
new file mode 100644
index 0000000..70da1e8
--- /dev/null
+++ b/src/eu/engys/core/dictionary/model/AxisInfo.java
@@ -0,0 +1,56 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.dictionary.model;
+
+import eu.engys.util.ui.textfields.DoubleField;
+
+public class AxisInfo {
+
+ public static final String PROPERTY_NAME = "point.location";
+ public static final String LABEL = "Point ";
+ private DoubleField[] center;
+ private EventActionType action;
+ private DoubleField[] axis;
+
+ public AxisInfo(DoubleField[] axis, DoubleField[] center, EventActionType action) {
+ this.axis = axis;
+ this.center = center;
+ this.action = action;
+ }
+
+ public DoubleField[] getAxis() {
+ return axis;
+ }
+
+ public DoubleField[] getCenter() {
+ return center;
+ }
+
+ public EventActionType getAction() {
+ return action;
+ }
+
+}
diff --git a/src/eu/engys/core/dictionary/model/DictionaryModel.java b/src/eu/engys/core/dictionary/model/DictionaryModel.java
new file mode 100644
index 0000000..dc35441
--- /dev/null
+++ b/src/eu/engys/core/dictionary/model/DictionaryModel.java
@@ -0,0 +1,1428 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.dictionary.model;
+
+import static eu.engys.util.ui.ComponentsFactory.checkBoxControllerField;
+import static eu.engys.util.ui.ComponentsFactory.checkField;
+import static eu.engys.util.ui.ComponentsFactory.comboBoxControllerField;
+import static eu.engys.util.ui.ComponentsFactory.doubleArrayField;
+import static eu.engys.util.ui.ComponentsFactory.doubleField;
+import static eu.engys.util.ui.ComponentsFactory.doublePointField;
+import static eu.engys.util.ui.ComponentsFactory.intArrayField;
+import static eu.engys.util.ui.ComponentsFactory.intField;
+import static eu.engys.util.ui.ComponentsFactory.listField;
+import static eu.engys.util.ui.ComponentsFactory.radioField;
+import static eu.engys.util.ui.ComponentsFactory.selectField;
+import static eu.engys.util.ui.ComponentsFactory.spinnerField;
+import static eu.engys.util.ui.ComponentsFactory.stringField;
+
+import java.awt.Color;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JPanel;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import eu.engys.core.dictionary.Dictionary;
+import eu.engys.core.dictionary.DictionaryUtils;
+import eu.engys.core.dictionary.DimensionedScalar;
+import eu.engys.core.dictionary.FieldChangeListener;
+import eu.engys.core.project.zero.patches.Patches;
+import eu.engys.util.filechooser.util.SelectionMode;
+import eu.engys.util.ui.ComponentsFactory;
+import eu.engys.util.ui.FileFieldPanel;
+import eu.engys.util.ui.ListBuilder;
+import eu.engys.util.ui.ListFieldPanel;
+import eu.engys.util.ui.RadioFieldPanel;
+import eu.engys.util.ui.SelectionValueConfigurator;
+import eu.engys.util.ui.builder.JCheckBoxController;
+import eu.engys.util.ui.builder.JComboBoxController;
+import eu.engys.util.ui.textfields.DoubleField;
+import eu.engys.util.ui.textfields.IntegerField;
+import eu.engys.util.ui.textfields.SpinnerField;
+import eu.engys.util.ui.textfields.StringField;
+
+public class DictionaryModel {
+
+ private static final Logger logger = LoggerFactory.getLogger(DictionaryModel.class);
+
+ private final String key;
+
+ private Dictionary dictionary;
+ private List companions = new LinkedList<>();
+
+ public interface DictionaryListener {
+ public void dictionaryChanged() throws DictionaryError;
+ }
+
+ private List listeners = new CopyOnWriteArrayList();
+ private Map subModels = new HashMap();
+
+ public static class DictionaryError extends Exception {
+ private String[] messages;
+
+ public DictionaryError(String... msg) {
+ super(msg[0]);
+ this.messages = msg;
+ }
+
+ public String[] getMessages() {
+ return messages;
+ }
+ }
+
+ public DictionaryModel() {
+ this(null, new Dictionary(""));
+ }
+
+ public DictionaryModel(String key) {
+ this(key, new Dictionary(""));
+ }
+
+ public DictionaryModel(Dictionary dictionary) {
+ this(null, dictionary);
+ }
+
+ public DictionaryModel(String key, Dictionary dictionary) {
+ this.key = key;
+ this.dictionary = dictionary;
+ }
+
+ public void addCompanion(DictionaryModel companion) {
+ this.companions.add(companion);
+ }
+
+ public void setCompanion(DictionaryModel companion) {
+ this.companions.clear();
+ this.companions.add(companion);
+ }
+
+ public List getCompanions() {
+ return companions;
+ }
+
+ public Dictionary getDictionary() {
+ return dictionary;
+ }
+
+ public DictionaryModel subModel(String key) {
+ if (subModels.containsKey(key)) {
+ return subModels.get(key);
+ } else {
+ Dictionary subDict = dictionary.subDict(key);
+ DictionaryModel model = new DictionaryModel(subDict != null ? subDict : new Dictionary(key));
+ subModels.put(key, model);
+ return model;
+ }
+ }
+
+ public void refresh() {
+ try {
+ fireDictionaryChange();
+ } catch (DictionaryError e) {
+ }
+ }
+
+ public void setDictionary(Dictionary dictionary) {
+ try {
+ if (dictionary != null) {
+ this.dictionary = dictionary;
+ for (String key : subModels.keySet()) {
+ DictionaryModel subModel = subModels.get(key);
+ subModel.setDictionary(dictionary.subDict(key));
+ }
+ fireDictionaryChange();
+ }
+ } catch (DictionaryError e) {
+ String[] messages = e.getMessages();
+
+ StringBuilder sb = new StringBuilder();
+ for (String message : messages) {
+ sb.append(message);
+ sb.append("\n");
+ }
+ // System.err.println(sb.toString());
+ logger.warn(sb.toString());
+ }
+ }
+
+ private void fireDictionaryChange() throws DictionaryError {
+ List errors = new ArrayList();
+ for (DictionaryListener listener : listeners) {
+ try {
+ // System.out.println("Listener: "+listener.getClass());
+ // System.out.println("pre: "+dictionary);
+ listener.dictionaryChanged();
+ // System.out.println("post: "+dictionary);
+
+ } catch (DictionaryError e) {
+ errors.add(e.getMessage());
+ // e.printStackTrace();
+ }
+ }
+ if (!errors.isEmpty()) {
+ throw new DictionaryError(errors.toArray(new String[errors.size()]));
+ }
+ }
+
+ public void addDictionaryListener(DictionaryListener listener) {
+ listeners.add(listener);
+ }
+
+ /*
+ * BINDING
+ */
+ public StringField bindLabel(String key) {
+ StringField field = stringField();
+ field.addPropertyChangeListener(new LabelFieldHandler(key, field));
+ return field;
+ }
+
+ public StringField bindLabel(String key, boolean allowEmpty) {
+ StringField field = stringField();
+ field.setToVerifier(allowEmpty, true);
+ field.addPropertyChangeListener(new LabelFieldHandler(key, field));
+ return field;
+ }
+
+ public JCheckBox bindBoolean(String key) {
+ JCheckBox field = checkField();
+ field.addActionListener(new BooleanFieldHandler(key, field, false));
+ return field;
+ }
+
+ public JCheckBox bindBoolean(String key, boolean def) {
+ JCheckBox field = checkField(def);
+ field.addActionListener(new BooleanFieldHandler(key, field, def));
+ return field;
+ }
+
+ public JCheckBox bindBoolean(String key, String trueValue, String falseValue) {
+ JCheckBox field = checkField();
+ field.addActionListener(new BooleanValuesFieldHandler(key, field, trueValue, falseValue));
+ return field;
+ }
+
+ public JCheckBox bindBoolean(String key, String trueValue, String falseValue, boolean def) {
+ JCheckBox field = checkField(def);
+ field.addActionListener(new BooleanValuesFieldHandler(key, field, trueValue, falseValue));
+ return field;
+ }
+
+ public SpinnerField bindSpinner(String key) {
+ SpinnerField field = spinnerField();
+ field.addPropertyChangeListener(new SpinnerFieldHandler(key, field));
+ return field;
+ }
+
+ public IntegerField bindIntegerPositive(String key) {
+ IntegerField field = intField(0, Integer.MAX_VALUE);
+ field.addPropertyChangeListener(new IntFieldHandler(key, field));
+ return field;
+ }
+
+ public IntegerField bindIntegerNegative(String key) {
+ IntegerField field = intField(-Integer.MAX_VALUE, 0);
+ field.addPropertyChangeListener(new IntFieldHandler(key, field));
+ return field;
+ }
+
+ public IntegerField bindInteger(String key) {
+ IntegerField field = intField(-Integer.MAX_VALUE, Integer.MAX_VALUE);
+ field.addPropertyChangeListener(new IntFieldHandler(key, field));
+ return field;
+ }
+
+ public IntegerField bindInteger(String key, Integer lb, Integer ub) {
+ IntegerField field = intField(lb, ub);
+ field.addPropertyChangeListener(new IntFieldHandler(key, field));
+ return field;
+ }
+
+ public IntegerField bindIntegerAngle_360(String key) {
+ // Negative value = disabled
+ IntegerField field = intField(-Integer.MAX_VALUE, 359);
+ field.addPropertyChangeListener(new IntFieldHandler(key, field));
+ return field;
+ }
+
+ public IntegerField bindIntegerAngle_180(String key) {
+ // Negative value = disabled
+ IntegerField field = intField(-Integer.MAX_VALUE, 180);
+ field.addPropertyChangeListener(new IntFieldHandler(key, field));
+ return field;
+ }
+
+ // public IntegerField bindInteger(String key, String name) {
+ // IntegerField field = bindInteger(key);
+ // field.setName(name);
+ // return field;
+ // }
+
+ public IntegerField bindIntegerLevels(String key, String mode) {
+ IntegerField field = intField();
+ field.addPropertyChangeListener(new IntLevelsFieldHandler(key, mode, field));
+ return field;
+ }
+
+ public IntegerField[] bindIntegerArray(String key, Integer dimensions) {
+ return bindIntegerArray(key, dimensions, null);
+ }
+
+ public IntegerField[] bindIntegerArray(String key, Integer dimensions, FieldChangeListener listener) {
+ IntegerField[] field = intArrayField(dimensions);
+ for (int i = 0; i < field.length; i++) {
+ IntegerField f = field[i];
+ f.addPropertyChangeListener(new IntPointFieldHandler(key, field, listener));
+ }
+ return field;
+ }
+
+ public DoubleField bindDimensionedDouble(String key, String dimensions, Double lb, Double ub) {
+ DoubleField field = doubleField(lb, ub);
+ field.addPropertyChangeListener(new DoubleDimensionedFieldHandler(key, field, dimensions));
+ return field;
+ }
+
+ public DoubleField bindDimensionedDouble(String key, String dimensions) {
+ DoubleField field = doubleField();
+ field.addPropertyChangeListener(new DoubleDimensionedFieldHandler(key, field, dimensions));
+ return field;
+ }
+
+ public DoubleField bindUniformDouble(String key) {
+ DoubleField field = doubleField();
+ field.addPropertyChangeListener(new DoubleUniformFieldHandler(key, field));
+ return field;
+ }
+
+ // public DoubleField bindUniformDoubleWithName(String key, String name) {
+ // DoubleField field = doubleField();
+ // field.setName(name);
+ // field.addPropertyChangeListener(new DoubleUniformFieldHandler(key,
+ // field));
+ // return field;
+ // }
+
+ public DoubleField bindUniformDouble(String key, double lb, double ub, double def) {
+ DoubleField field = doubleField(def, lb, ub);
+ field.addPropertyChangeListener(new DoubleUniformFieldHandler(key, field));
+ return field;
+ }
+
+ public DoubleField bindUniformDouble(String key, double lb, double ub) {
+ DoubleField field = doubleField(lb, ub);
+ field.addPropertyChangeListener(new DoubleUniformFieldHandler(key, field));
+ return field;
+ }
+
+ public DoubleField bindUniformNegativeDouble(String key) {
+ DoubleField field = doubleField();
+ field.addPropertyChangeListener(new DoubleUniformNegativeFieldHandler(key, field));
+ return field;
+ }
+
+ public DoubleField bindUniformPositiveDouble(String key) {
+ DoubleField field = doubleField();
+ field.addPropertyChangeListener(new DoubleUniformPositiveFieldHandler(key, field));
+ return field;
+ }
+
+ public DoubleField bindConstantDouble(String key) {
+ DoubleField field = doubleField();
+ field.addPropertyChangeListener(new DoubleConstantFieldHandler(key, field));
+ return field;
+ }
+
+ public DoubleField bindUniformDouble(String key1, String key2) {
+ DoubleField field = doubleField();
+ field.addPropertyChangeListener(new DoubleUniformFieldHandler(key1, field));
+ field.addPropertyChangeListener(new DoubleUniformFieldHandler(key2, field));
+ return field;
+ }
+
+ public DoubleField bindDouble(String key) {
+ return bindDouble(key, (FieldChangeListener) null);
+ }
+
+ public DoubleField bindDouble(String key, FieldChangeListener listener) {
+ DoubleField field = doubleField();
+ field.addPropertyChangeListener(new DoubleFieldHandler(key, field, listener));
+ return field;
+ }
+
+ public DoubleField bindDouble(String key, Integer places, FieldChangeListener listener) {
+ DoubleField field = doubleField(places);
+ field.addPropertyChangeListener(new DoubleFieldHandler(key, field, listener));
+ return field;
+ }
+
+ public DoubleField bindDouble(String key, Double def) {
+ DoubleField field = doubleField(def);
+ field.addPropertyChangeListener(new DoubleFieldHandler(key, field, null));
+ return field;
+ }
+
+ public DoubleField bindDouble(String key, double lb, double ub) {
+ DoubleField field = doubleField(lb, ub);
+ field.addPropertyChangeListener(new DoubleFieldHandler(key, field, null));
+ return field;
+ }
+
+ public DoubleField bindDoublePositive(String key) {
+ DoubleField field = doubleField(0.0, Double.MAX_VALUE);
+ field.addPropertyChangeListener(new DoubleFieldHandler(key, field, null));
+ return field;
+ }
+
+ public DoubleField bindDoubleNegative(String key) {
+ DoubleField field = doubleField(-Double.MAX_VALUE, 0.0);
+ field.addPropertyChangeListener(new DoubleFieldHandler(key, field, null));
+ return field;
+ }
+
+ public DoubleField bindDoubleAngle_360(String key) {
+ // Negative value = disabled
+ DoubleField field = doubleField(-Double.MAX_VALUE, 360 - Double.MIN_VALUE);
+ field.addPropertyChangeListener(new DoubleFieldHandler(key, field, null));
+ return field;
+ }
+
+ public DoubleField bindDoubleAngle_180(String key) {
+ // Negative value = disabled
+ DoubleField field = doubleField(-Double.MAX_VALUE, 180.0);
+ field.addPropertyChangeListener(new DoubleFieldHandler(key, field, null));
+ return field;
+ }
+
+ public DoubleField[] bindPoint(String key, FieldChangeListener listener) {
+ DoubleField[] field = doublePointField();
+ for (int i = 0; i < field.length; i++) {
+ DoubleField f = field[i];
+ f.setName(key + "." + i);
+ f.addPropertyChangeListener(new PointFieldHandler(key, field, listener));
+ }
+ return field;
+ }
+
+ public DoubleField[] bindPoint(String key, Integer places, FieldChangeListener listener) {
+ DoubleField[] field = doublePointField(places);
+ for (int i = 0; i < field.length; i++) {
+ DoubleField f = field[i];
+ f.setName(key + "." + i);
+ f.addPropertyChangeListener(new PointFieldHandler(key, field, listener));
+ }
+ return field;
+ }
+
+ public DoubleField[] bindPoint(String key) {
+ return bindPoint(key, null);
+ }
+
+ public ShowLocationAdapter bindLocation(String key, int places) {
+ return bindLocation(key, places, Color.RED);
+ }
+
+ public ShowAxisAdapter bindAxis(String key, Color colorKey) {
+ DoubleField[] axis = bindPoint(key, null);
+ DoubleField[] center = bindPoint(key, null);
+ return new ShowAxisAdapter(axis, center);
+ }
+
+ public ShowLocationAdapter bindLocation(String key, int places, Color colorKey) {
+ DoubleField[] field = bindPoint(key, places, null);
+ return new ShowLocationAdapter(field, colorKey);
+ }
+
+ public DoubleField[] bindUniformPoint(String key) {
+ DoubleField[] field = doublePointField();
+ for (int i = 0; i < field.length; i++) {
+ DoubleField f = field[i];
+ f.addPropertyChangeListener(new PointUniformFieldHandler(key, field));
+ }
+ return field;
+ }
+
+ // public DoubleField[] bindUniformPointWithName(String key, String name) {
+ // DoubleField[] field = doublePointField();
+ // for (int i = 0; i < field.length; i++) {
+ // DoubleField f = field[i];
+ // f.setName(name + "." + i);
+ // f.addPropertyChangeListener(new PointUniformFieldHandler(key, field));
+ // }
+ // return field;
+ // }
+
+ public DoubleField[] bindUniformPoint(String key1, String key2) {
+ DoubleField[] field = doublePointField();
+ for (int i = 0; i < field.length; i++) {
+ DoubleField f = field[i];
+ f.addPropertyChangeListener(new PointUniformFieldHandler(key1, field));
+ f.addPropertyChangeListener(new PointUniformFieldHandler(key2, field));
+ }
+ return field;
+ }
+
+ public DoubleField[] bindDimensionedPoint(String key, String dimensions) {
+ DoubleField[] field = doublePointField();
+ for (int i = 0; i < field.length; i++) {
+ DoubleField f = field[i];
+ f.addPropertyChangeListener(new PointDimensionedFieldHandler(key, field, dimensions));
+ }
+ return field;
+ }
+
+ public DoubleField[] bindArray(String key, int dimensions) {
+ DoubleField[] field = doubleArrayField(dimensions);
+ for (int i = 0; i < field.length; i++) {
+ DoubleField f = field[i];
+ f.setColumns(1);
+ f.setName(key + "." + i);
+ f.addPropertyChangeListener(new PointFieldHandler(key, field, null));
+ }
+ return field;
+ }
+
+ public FileFieldPanel bindFile(String key) {
+ FileFieldPanel field = ComponentsFactory.fileField(SelectionMode.FILES_ONLY, "Select file", true);
+ field.addPropertyChangeListener(new FileFieldHandler(key, field));
+ return field;
+ }
+
+ public FileFieldPanel bindFolder(String key) {
+ FileFieldPanel field = ComponentsFactory.fileField(SelectionMode.DIRS_ONLY, "Select folder", true);
+ field.addPropertyChangeListener(new FileFieldHandler(key, field));
+ return field;
+ }
+
+ public JComboBox bindSelection(String key) {
+ JComboBox combo = selectField();
+ combo.addActionListener(new SelectFieldHandler(key, combo, null));
+ return combo;
+ }
+
+ public JComboBox bindSelection(String key, ListBuilder builder) {
+ JComboBox combo = selectField(builder);
+ combo.addActionListener(new SelectFieldHandler(key, combo, null));
+ return combo;
+ }
+
+ public JComboBox bindSelection(String key, String... keys) {
+ JComboBox combo = selectField(keys, keys);
+ combo.addActionListener(new SelectFieldHandler(key, combo, null));
+ return combo;
+ }
+
+ public JComboBox bindSelection(String key, String[] keys, String[] items) {
+ return bindSelection(key, keys, items, null);
+ }
+
+ public JComboBox bindSelection(String key, String[] keys, String[] items, SelectionValueConfigurator configurator) {
+ JComboBox combo = selectField(keys, items);
+ combo.addActionListener(new SelectFieldHandler(key, combo, configurator));
+ return combo;
+ }
+
+ public JComboBoxController bindComboBoxController(String key) {
+ JComboBoxController combo = comboBoxControllerField();
+ combo.addActionListener(new SelectFieldHandler(key, combo, null));
+ return combo;
+ }
+
+ public JCheckBoxController bindCheckBoxController(String key, String name) {
+ JCheckBoxController combo = checkBoxControllerField(name);
+ combo.addActionListener(new BooleanFieldHandler(key, combo, false));
+ return combo;
+ }
+
+ public RadioFieldPanel bindChoice(String key, String[] keys, String[] items) {
+ RadioFieldPanel panel = radioField(keys, items);
+ panel.addPropertyChangeListener(new ChoiceFieldHandler(key, panel));
+ return panel;
+ }
+
+ public ListFieldPanel bindList(String key, ListBuilder listBuilder) {
+ ListFieldPanel field = listField(listBuilder);
+ field.addPropertyChangeListener(new ListFieldHandler(key, field));
+ return field;
+ }
+
+ public PatchesMapTableAdapter bindPatchMapTable(DictionaryModel dictionaryModel, Patches targetPatches) {
+ return new PatchesMapTableAdapter(dictionaryModel, targetPatches);
+ }
+
+ public JPanel bindTableLevels(String[] columnNames, final Class>[] type) {
+ return new LevelsTableAdapter(this, columnNames, type);
+ }
+
+ public PointTableAdapter bindPointMatrix(String[] columnNames, final String tableKey, int linesToLeave, boolean showPoint) {
+ return new PointTableAdapter(this, columnNames, tableKey, linesToLeave, showPoint);
+ }
+
+ public JPanel bindOneDictionaryPerRowTable(String[] columnNames, final String[] columnKeys, final String tableKey, String[] rowNames, String[] rowKeys, final Class>[] type) {
+ return new OneDictionaryPerRowTableAdapter(this, columnNames, columnKeys, rowNames, rowKeys, tableKey, type);
+ }
+
+ class DoubleDimensionedFieldHandler implements PropertyChangeListener, DictionaryListener {
+ private String key;
+ private String dimensions;
+ private DoubleField field;
+
+ public DoubleDimensionedFieldHandler(String key, DoubleField field, String dimensions) {
+ this.key = key;
+ this.field = field;
+ this.dimensions = dimensions;
+ DictionaryModel.this.addDictionaryListener(this);
+ }
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ if (evt.getPropertyName().equals("value")) {
+ dictionary.add(new DimensionedScalar(key, Double.toString(field.getDoubleValue()), dimensions));
+ logger.trace("DoubleFieldHandler -> value: {}", dictionary.lookup(key));
+ }
+ }
+
+ @Override
+ public void dictionaryChanged() throws DictionaryError {
+ String value = dictionary.lookup(key);
+ if (value != null) {
+ field.setDoubleValue(parseDouble(value));
+ } else {
+ field.setDoubleValue(0);
+ }
+ logger.trace("DoubleFieldHandler -> read value: {}", value);
+ }
+ }
+
+ class PointDimensionedFieldHandler implements PropertyChangeListener, DictionaryListener {
+ private String key;
+ private String dimensions;
+ private DoubleField[] field;
+
+ public PointDimensionedFieldHandler(String key, DoubleField[] field, String dimensions) {
+ this.key = key;
+ this.field = field;
+ this.dimensions = dimensions;
+ DictionaryModel.this.addDictionaryListener(this);
+ }
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ if (evt.getPropertyName().equals("value")) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("(");
+ for (int i = 0; i < field.length; i++) {
+ sb.append(field[i].getDoubleValue());
+ sb.append(" ");
+ }
+ sb.append(")");
+ dictionary.add(new DimensionedScalar(key, sb.toString(), dimensions));
+ logger.trace("PointDimensionedFieldHandler -> value: {}", dictionary.lookup(key));
+ }
+ }
+
+ @Override
+ public void dictionaryChanged() throws DictionaryError {
+ String value = dictionary.lookup(key);
+ if (value != null) {
+ String[] values = value.trim().substring(1, value.length() - 1).trim().split("\\s+");
+ for (int i = 0; i < values.length; i++) {
+ field[i].setDoubleValue(parseDouble(values[i]));
+ }
+ } else {
+ for (int i = 0; i < field.length; i++) {
+ field[i].setDoubleValue(0);
+ }
+ }
+ logger.trace("PointDimensionedFieldHandler -> value: {}", value);
+ }
+
+ }
+
+ class LabelFieldHandler implements PropertyChangeListener, DictionaryListener {
+ private String key;
+ private StringField field;
+
+ public LabelFieldHandler(String key, StringField field) {
+ this.key = key;
+ this.field = field;
+ DictionaryModel.this.addDictionaryListener(this);
+ }
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ if (evt.getPropertyName().equals("value")) {
+ if (field.getValue() == null) {
+ if (dictionary.found(key))
+ dictionary.remove(key);
+ } else {
+ dictionary.add(key, field.getStringValue());
+ }
+ logger.trace("LabelFieldHandler -> value: {}", dictionary.lookup(key));
+ }
+ }
+
+ @Override
+ public void dictionaryChanged() throws DictionaryError {
+ String value = dictionary.lookup(key);
+ field.setValue(value);
+ logger.trace("LabelFieldHandler -> value: {}", value);
+ }
+ }
+
+ class ListFieldHandler implements PropertyChangeListener, DictionaryListener {
+ private String key;
+ private ListFieldPanel field;
+
+ public ListFieldHandler(String key, ListFieldPanel field) {
+ this.key = key;
+ this.field = field;
+ DictionaryModel.this.addDictionaryListener(this);
+ }
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ if (evt.getPropertyName().equals("value")) {
+ String value = DictionaryUtils.stringArray2String(field.getValues());
+ dictionary.add(key, value);
+ logger.trace("ListFieldHandler -> value: {}", dictionary.lookup(key));
+ }
+ }
+
+ @Override
+ public void dictionaryChanged() throws DictionaryError {
+ if (dictionary.isField(key)) {
+ String value = dictionary.lookup(key);
+ String[] values = DictionaryUtils.string2StringArray(value);
+ field.setValues(values);
+ logger.trace("ListFieldHandler -> value: {}", value);
+ } else {
+ field.setValues(new String[0]);
+ }
+ }
+ }
+
+ class ChoiceFieldHandler implements PropertyChangeListener, DictionaryListener {
+ private String key;
+ private RadioFieldPanel field;
+
+ public ChoiceFieldHandler(String key, RadioFieldPanel field) {
+ this.key = key;
+ this.field = field;
+ DictionaryModel.this.addDictionaryListener(this);
+ }
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ if (evt.getPropertyName().equals("value")) {
+ dictionary.add(key, field.getSelectedKey());
+ logger.trace("ChoiceFieldHandler -> value: {}", dictionary.lookup(key));
+ }
+ }
+
+ @Override
+ public void dictionaryChanged() throws DictionaryError {
+ String value = dictionary.lookup(key);
+ field.select(value);
+ logger.trace("ChoiceFieldHandler -> value: {}", value);
+ }
+ }
+
+ class SpinnerFieldHandler implements PropertyChangeListener, DictionaryListener {
+ public SpinnerFieldHandler(String key, SpinnerField field) {
+ // TODO Auto-generated constructor stub
+ }
+
+ @Override
+ public void dictionaryChanged() throws DictionaryError {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ // TODO Auto-generated method stub
+
+ }
+ }
+
+ class IntFieldHandler implements PropertyChangeListener, DictionaryListener {
+ private String key;
+ private IntegerField field;
+
+ public IntFieldHandler(String key, IntegerField field) {
+ this.key = key;
+ this.field = field;
+ DictionaryModel.this.addDictionaryListener(this);
+ }
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ if (evt.getPropertyName().equals("value")) {
+ if (field.getValue() == null) {
+ if (dictionary.found(key))
+ dictionary.remove(key);
+ } else {
+ dictionary.add(key, Integer.toString(field.getIntValue()));
+ }
+ logger.trace("IntegerFieldHandler -> value: {}", dictionary.lookup(key));
+ }
+ }
+
+ @Override
+ public void dictionaryChanged() throws DictionaryError {
+ String value = dictionary.lookup(key);
+ if (value != null) {
+ field.setIntValue(parseInt(value));
+ } else {
+ field.setValue(null);
+ }
+ logger.trace("IntegerFieldHandler -> value: {}", value);
+ }
+ }
+
+ class IntLevelsFieldHandler implements PropertyChangeListener, DictionaryListener {
+ private String key;
+ private IntegerField field;
+ private String mode;
+
+ public IntLevelsFieldHandler(String key, String mode, IntegerField field) {
+ this.key = key;
+ this.mode = mode;
+ this.field = field;
+ DictionaryModel.this.addDictionaryListener(this);
+ }
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ if (evt.getPropertyName().equals("value")) {
+ String lookupMode = dictionary.lookup("mode");
+ if (mode.equals(lookupMode)) {
+ if (field.getValue() == null) {
+ if (dictionary.found(key))
+ dictionary.remove(key);
+ } else {
+ dictionary.add(key, String.format("(( 1E5 %s ))", Integer.toString(field.getIntValue())));
+ }
+ logger.trace("IntegerFieldHandler -> value: {}", dictionary.lookup(key));
+ }
+ }
+ }
+
+ @Override
+ public void dictionaryChanged() throws DictionaryError {
+ String lookupMode = dictionary.lookup("mode");
+ if (lookupMode != null) {
+ if (mode.equals(lookupMode)) {
+ String value = dictionary.lookup(key);
+ if (value != null && value.length() > 4) {
+ String[] values = value.trim().substring(2, value.length() - 2).trim().split("\\s+");
+ field.setIntValue(parseInt(values[1]));
+ } else {
+ field.setValue(null);
+ }
+ logger.trace("IntegerFieldHandler -> value: {}", value);
+ } else {
+ field.setValue(null);
+ }
+ } else {
+ field.setValue(null);
+ }
+ }
+ }
+
+ class IntPointFieldHandler implements PropertyChangeListener, DictionaryListener {
+ private String key;
+ private IntegerField[] field;
+ private FieldChangeListener listener;
+
+ public IntPointFieldHandler(String key, IntegerField[] field, FieldChangeListener listener) {
+ this.key = key;
+ this.field = field;
+ this.listener = listener;
+ DictionaryModel.this.addDictionaryListener(this);
+ }
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ if (evt.getPropertyName().equals("value")) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("(");
+ for (int i = 0; i < field.length; i++) {
+ if (field[i].getValue() != null) {
+ sb.append(field[i].getIntValue());
+ sb.append(" ");
+ } else {
+ if (dictionary.found(key))
+ dictionary.remove(key);
+ return;
+ }
+ }
+ sb.append(")");
+ dictionary.add(key, sb.toString());
+ logger.trace("PointFieldHandler -> value: {}", dictionary.lookup(key));
+ if (listener != null) {
+ listener.fieldChanged();
+ }
+ }
+ }
+
+ @Override
+ public void dictionaryChanged() throws DictionaryError {
+ String value = dictionary.lookup(key);
+ if (listener != null) {
+ listener.setAdjusting(true);
+ }
+ if (value != null) {
+ String[] values = value.trim().substring(1, value.length() - 1).trim().split("\\s+");
+ for (int i = 0; i < values.length; i++) {
+ field[i].setIntValue(parseInt(values[i]));
+ }
+ logger.trace("PointFieldHandler -> value: {}", value);
+ } else {
+ for (int i = 0; i < field.length; i++) {
+ field[i].setValue(null);
+ }
+ }
+ if (listener != null) {
+ listener.setAdjusting(false);
+ }
+ }
+ }
+
+ class DoubleFieldHandler implements PropertyChangeListener, DictionaryListener {
+ private String key;
+ private DoubleField field;
+ private FieldChangeListener listener;
+
+ public DoubleFieldHandler(String key, DoubleField field, FieldChangeListener listener) {
+ this.key = key;
+ this.field = field;
+ this.listener = listener;
+ DictionaryModel.this.addDictionaryListener(this);
+ }
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ if (evt.getPropertyName().equals("value")) {
+ if (field.getValue() == null) {
+ if (dictionary.found(key))
+ dictionary.remove(key);
+ } else {
+ dictionary.add(key, Double.toString(field.getDoubleValue()));
+ logger.trace("DoubleFieldHandler -> value: {}", dictionary.lookup(key));
+ if (listener != null) {
+ listener.fieldChanged();
+ }
+ }
+ }
+ }
+
+ @Override
+ public void dictionaryChanged() throws DictionaryError {
+ String value = dictionary.lookup(key);
+ if (listener != null)
+ listener.setAdjusting(true);
+ if (value != null) {
+ field.setDoubleValue(parseDouble(value));
+ } else {
+ field.setValue(field.getDefaultValue());
+ }
+ if (listener != null)
+ listener.setAdjusting(false);
+
+ logger.trace("DoubleFieldHandler -> value: {}", value);
+ }
+ }
+
+ class DoubleUniformFieldHandler implements PropertyChangeListener, DictionaryListener {
+ private String key;
+ private DoubleField field;
+
+ public DoubleUniformFieldHandler(String key, DoubleField field) {
+ this.key = key;
+ this.field = field;
+ DictionaryModel.this.addDictionaryListener(this);
+ }
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ if (evt.getPropertyName().equals("value")) {
+ if (!Double.isInfinite(field.getDoubleValue())) {
+ dictionary.add(key, "uniform " + Double.toString(field.getDoubleValue()));
+ logger.trace("DoubleUniformFieldHandler -> value: {}", dictionary.lookup(key));
+ }
+ }
+ }
+
+ @Override
+ public void dictionaryChanged() throws DictionaryError {
+ String value = dictionary.lookup(key); // uniform value
+ logger.trace("DoubleUniformFieldHandler -> value: {}", value);
+ if (value != null) {
+ if (value.startsWith("nonuniform")) {
+ field.setDoubleValue(Double.POSITIVE_INFINITY);
+ } else {
+ value = value.replace("uniform ", "");
+ field.setDoubleValue(parseDouble(value));
+ }
+ } else {
+ field.setDoubleValue(field.getDefaultValue());
+ }
+ }
+ }
+
+ class DoubleUniformNegativeFieldHandler implements PropertyChangeListener, DictionaryListener {
+ private String key;
+ private DoubleField field;
+
+ public DoubleUniformNegativeFieldHandler(String key, DoubleField field) {
+ this.key = key;
+ this.field = field;
+ DictionaryModel.this.addDictionaryListener(this);
+ }
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ if (evt.getPropertyName().equals("value")) {
+ dictionary.add(key, "uniform " + Double.toString(-Math.abs(field.getDoubleValue())));
+ logger.trace("DoubleUniformFieldHandler -> " + dictionary.toString());
+ }
+ }
+
+ @Override
+ public void dictionaryChanged() throws DictionaryError {
+ String value = dictionary.lookup(key); // uniform value
+ logger.trace("DoubleUniformFieldHandler -> value: " + value);
+ if (value != null) {
+ value = value.replace("uniform ", "");
+ field.setDoubleValue(Math.abs(parseDouble(value)));
+ } else {
+ field.setDoubleValue(field.getDefaultValue());
+ }
+ }
+ }
+
+ class DoubleUniformPositiveFieldHandler implements PropertyChangeListener, DictionaryListener {
+ private String key;
+ private DoubleField field;
+
+ public DoubleUniformPositiveFieldHandler(String key, DoubleField field) {
+ this.key = key;
+ this.field = field;
+ DictionaryModel.this.addDictionaryListener(this);
+ }
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ if (evt.getPropertyName().equals("value")) {
+ dictionary.add(key, "uniform " + Double.toString(Math.abs(field.getDoubleValue())));
+ logger.trace("DoubleUniformFieldHandler -> " + dictionary.toString());
+ }
+ }
+
+ @Override
+ public void dictionaryChanged() throws DictionaryError {
+ String value = dictionary.lookup(key); // uniform value
+ logger.trace("DoubleUniformFieldHandler -> value: " + value);
+ if (value != null) {
+ value = value.replace("uniform ", "");
+ field.setDoubleValue(Math.abs(parseDouble(value)));
+ } else {
+ field.setDoubleValue(field.getDefaultValue());
+ }
+ }
+ }
+
+ class DoubleConstantFieldHandler implements PropertyChangeListener, DictionaryListener {
+ private String key;
+ private DoubleField field;
+
+ public DoubleConstantFieldHandler(String key, DoubleField field) {
+ this.key = key;
+ this.field = field;
+ DictionaryModel.this.addDictionaryListener(this);
+ }
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ if (evt.getPropertyName().equals("value")) {
+ dictionary.add(key, "constant " + Double.toString(field.getDoubleValue()));
+ logger.trace("DoubleUniformFieldHandler -> value: {}", dictionary.lookup(key));
+ }
+ }
+
+ @Override
+ public void dictionaryChanged() throws DictionaryError {
+ String value = dictionary.lookup(key); // uniform value
+ logger.trace("DoubleUniformFieldHandler -> value: {}", value);
+ if (value != null) {
+ value = value.replace("constant ", "");
+ field.setDoubleValue(parseDouble(value));
+ } else {
+ field.setDoubleValue(field.getDefaultValue());
+ }
+ }
+ }
+
+ class BooleanFieldHandler implements ActionListener, DictionaryListener {
+
+ private JCheckBox check;
+ private String key;
+ private final boolean def;
+
+ public BooleanFieldHandler(String key, JCheckBox check, boolean def) {
+ this.check = check;
+ this.key = key;
+ this.def = def;
+ DictionaryModel.this.addDictionaryListener(this);
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ boolean selected = check.isSelected();
+ dictionary.add(key, selected ? "true" : "false");
+ logger.trace("BooleanFieldHandler -> value: {}", dictionary.lookup(key));
+ }
+
+ @Override
+ public void dictionaryChanged() throws DictionaryError {
+ String value = dictionary.lookup(key);
+ String correctedForYesNo = value == null ? String.valueOf(def) : value.equals("yes") ? "true" : value.equals("no") ? "false" : value;
+ boolean b = Boolean.parseBoolean(correctedForYesNo);
+ if (b != check.isSelected()) {
+ check.doClick();
+ check.setSelected(b);
+ }
+ logger.trace("BooleanFieldHandler -> value: {}", value);
+ }
+ }
+
+ class BooleanValuesFieldHandler implements ActionListener, DictionaryListener {
+
+ private JCheckBox check;
+ private String key;
+ private final String trueValue;
+ private final String falseValue;
+
+ public BooleanValuesFieldHandler(String key, JCheckBox check, String trueValue, String falseValue) {
+ this.check = check;
+ this.key = key;
+ this.trueValue = trueValue;
+ this.falseValue = falseValue;
+ DictionaryModel.this.addDictionaryListener(this);
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ boolean selected = check.isSelected();
+ dictionary.add(key, selected ? trueValue : falseValue);
+ logger.trace("BooleanValuesFieldHandler -> value: {}", dictionary.lookup(key));
+ }
+
+ @Override
+ public void dictionaryChanged() throws DictionaryError {
+ String value = dictionary.lookup(key);
+ boolean selected = value != null && value.equals(trueValue);
+ if (shouldClick(selected, check.isSelected())) {
+ check.doClick();
+ }
+ logger.trace("BooleanValuesFieldHandler -> value: {}", value);
+ }
+
+ private boolean shouldClick(boolean select, boolean isSelected) {
+ return (isSelected && !select) || (!isSelected && select);
+ }
+ }
+
+ class FileFieldHandler implements PropertyChangeListener, DictionaryListener {
+ private String key;
+ private FileFieldPanel field;
+
+ public FileFieldHandler(String key, FileFieldPanel field) {
+ this.key = key;
+ this.field = field;
+ DictionaryModel.this.addDictionaryListener(this);
+ }
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ if (evt.getPropertyName().equals("value")) {
+ if (field.getFilePath() != null && !field.getFilePath().isEmpty()) {
+ String value = "\"" + field.getFilePath() + "\"";
+ dictionary.add(key, value);
+ logger.trace("FileFieldHandler -> value: {}", dictionary.lookup(key));
+ }
+ }
+ }
+
+ @Override
+ public void dictionaryChanged() throws DictionaryError {
+ loadFromDictionary();
+ }
+
+ private void loadFromDictionary() {
+ String value = dictionary.lookup(key);
+ if (value != null) {
+ value = value.replace("\"", "");
+ File file = new File(value);
+ if (file.exists()) {
+ field.setFile(file);
+ } else {
+ field.setFile(new File(""));
+ // throw new DictionaryError("File doesn't exist: " +
+ // value);
+ }
+ } else {
+ field.setFile(new File(""));
+ }
+ }
+ }
+
+ class PointFieldHandler implements PropertyChangeListener, DictionaryListener {
+ private String key;
+ private DoubleField[] field;
+ private FieldChangeListener listener;
+
+ public PointFieldHandler(String key, DoubleField[] field, FieldChangeListener listener) {
+ this.key = key;
+ this.field = field;
+ this.listener = listener;
+ DictionaryModel.this.addDictionaryListener(this);
+ }
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ if (evt.getPropertyName().equals("value")) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("(");
+ for (int i = 0; i < field.length; i++) {
+ if (field[i].getValue() != null) {
+ sb.append(field[i].getDoubleValue());
+ sb.append(" ");
+ } else {
+ sb.append("0 ");
+ }
+ }
+ sb.append(")");
+ dictionary.add(key, sb.toString());
+ logger.trace("PointFieldHandler -> value: {}", dictionary.lookup(key));
+ if (listener != null) {
+ listener.fieldChanged();
+ }
+ }
+ }
+
+ @Override
+ public void dictionaryChanged() throws DictionaryError {
+ String value = dictionary.lookup(key);
+ if (listener != null)
+ listener.setAdjusting(true);
+ if (value != null && !value.isEmpty()) {
+ try {
+ String[] values = value.trim().substring(1, value.length() - 1).trim().split("\\s+");
+ for (int i = 0; i < values.length; i++) {
+ field[i].setDoubleValue(parseDouble(values[i]));
+ }
+ } catch (ArrayIndexOutOfBoundsException e) {
+ }
+ logger.trace("PointFieldHandler -> value: {}", value);
+ } else {
+ for (int i = 0; i < field.length; i++) {
+ field[i].setDoubleValue(0);
+ }
+ }
+ if (listener != null)
+ listener.setAdjusting(false);
+ }
+ }
+
+ class PointUniformFieldHandler implements PropertyChangeListener, DictionaryListener {
+ private String key;
+ private DoubleField[] field;
+
+ public PointUniformFieldHandler(String key, DoubleField[] field) {
+ this.key = key;
+ this.field = field;
+ DictionaryModel.this.addDictionaryListener(this);
+ }
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ if (evt.getPropertyName().equals("value")) {
+ for (int i = 0; i < field.length; i++) {
+ if (Double.isInfinite(field[i].getDoubleValue())) {
+ return;
+ }
+ }
+ StringBuilder sb = new StringBuilder();
+ sb.append("uniform (");
+ for (int i = 0; i < field.length; i++) {
+ sb.append(field[i].getDoubleValue());
+ sb.append(" ");
+ }
+ sb.append(")");
+ dictionary.add(key, sb.toString());
+ logger.trace("PointFieldHandler -> value: {}", dictionary.lookup(key));
+ }
+ }
+
+ @Override
+ public void dictionaryChanged() throws DictionaryError {
+ String value = dictionary.lookup(key);
+ if (value != null) {
+ if (value.startsWith("nonuniform")) {
+ for (int i = 0; i < field.length; i++) {
+ field[i].setDoubleValue(Double.POSITIVE_INFINITY);
+ }
+ } else {
+ value = value.replace("uniform ", "");
+ String[] values = value.trim().substring(1, value.length() - 1).trim().split("\\s+");
+ for (int i = 0; i < values.length; i++) {
+ field[i].setDoubleValue(parseDouble(values[i]));
+ }
+ }
+ logger.trace("PointFieldHandler -> value: {}", value);
+ } else {
+ for (int i = 0; i < field.length; i++) {
+ field[i].setDoubleValue(0);
+ }
+ }
+ }
+ }
+
+ class SelectFieldHandler implements ActionListener, DictionaryListener {
+
+ private JComboBox> combo;
+ private String key;
+ private SelectionValueConfigurator configurator;
+
+ public SelectFieldHandler(String key, JComboBox> combo, SelectionValueConfigurator configurator) {
+ this.combo = combo;
+ this.key = key;
+ this.configurator = configurator;
+ DictionaryModel.this.addDictionaryListener(this);
+ try {
+ loadFromDictionary();
+ } catch (DictionaryError e) {
+ // e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ Object item;
+ if (combo instanceof JComboBoxController) {
+ item = ((JComboBoxController) combo).getSelectedKey();
+ } else {
+ item = combo.getSelectedItem();
+ }
+ if (item != null && item instanceof String) {
+ String value = (String) item;
+ if (configurator != null)
+ value = configurator.write(value);
+ if (value != null)
+ dictionary.add(key, value);
+ logger.trace("SelectFieldHandler -> value: {}", dictionary.lookup(key));
+ }
+ }
+
+ @Override
+ public void dictionaryChanged() throws DictionaryError {
+ loadFromDictionary();
+ }
+
+ public void loadFromDictionary() throws DictionaryError {
+ if (dictionary.found(key)) {
+ String value = dictionary.lookup(key);
+ if (configurator != null)
+ value = configurator.read(value);
+
+ if (combo instanceof JComboBoxController) {
+ ((JComboBoxController) combo).setSelectedKey(value);
+ } else if (contains(value)) {
+ combo.setSelectedItem(value);
+ } else if (value == null || "".equals(value)) {
+ combo.setSelectedIndex(-1);
+ } else if (combo.getItemCount() > 0) {
+ combo.setSelectedIndex(0);
+ throw new DictionaryError(String.format("Missing %s value. Set to %s", value, combo.getItemAt(0)));
+ }
+
+ logger.trace("SelectFieldHandler -> value: {}", value);
+ } else {
+ combo.setSelectedIndex(-1);
+ // throw new
+ // DictionaryError(String.format("Missing %s key in %s dictionary",
+ // key, dictionary.getName()));
+ }
+ }
+
+ private boolean contains(String value) {
+ for (int i = 0; i < combo.getItemCount(); i++) {
+ if (value.equals(combo.getItemAt(i))) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ }
+
+ public String getKey() {
+ return key != null ? key : String.valueOf(hashCode());
+ }
+
+ private double parseDouble(String value) {
+ try {
+ return Double.parseDouble(value);
+ } catch (Exception e) {
+ return 0;
+ }
+ }
+
+ private int parseInt(String value) {
+ try {
+ return Double.valueOf(value).intValue();
+ } catch (Exception e) {
+ return 0;
+ }
+ }
+}
diff --git a/src/eu/engys/core/dictionary/model/DictionaryPanelBuilder.java b/src/eu/engys/core/dictionary/model/DictionaryPanelBuilder.java
new file mode 100644
index 0000000..eb695b8
--- /dev/null
+++ b/src/eu/engys/core/dictionary/model/DictionaryPanelBuilder.java
@@ -0,0 +1,206 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.dictionary.model;
+
+import static eu.engys.core.dictionary.Dictionary.TYPE;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Stack;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import eu.engys.core.dictionary.Dictionary;
+import eu.engys.util.ui.builder.GroupController;
+import eu.engys.util.ui.builder.PanelBuilder;
+
+public class DictionaryPanelBuilder extends PanelBuilder {
+
+ private static final Logger logger = LoggerFactory.getLogger(DictionaryPanelBuilder.class);
+
+ private DictionaryModel selectedModel;
+ private Map modelsByKey = new HashMap();
+ private Map dictionarySelectors = new HashMap();
+
+ private boolean selectModelAfterSelection = true;
+
+ public DictionaryPanelBuilder() {
+ super();
+ }
+
+ public DictionaryPanelBuilder(String name) {
+ super(name);
+ }
+
+ public void startDictionary(String groupName, DictionaryModel model) {
+ String groupKey = model.getKey();
+
+ startGroup(groupKey, groupName);
+
+ modelsByKey.put(groupKey, model);
+ dictionarySelectors.put(groupKey, new DictionarySelector(controllers, groups));
+
+ checkForParent();
+ }
+
+ public void endDictionary() {
+ modelsByKey.get(groups.peek().groupKey).refresh();
+ endGroup();
+ }
+
+ public DictionaryModel getSelectedModel() {
+ return selectedModel;
+ }
+
+ private void setSelectedModel(DictionaryModel selectedModel) {
+ if (selectedModel != null) {
+ this.selectedModel = selectedModel;
+ }
+ }
+
+ public void selectDictionaries(Dictionary newDictionary, Dictionary newCompanion) {
+ String newName = newDictionary.getName();
+ String newType = newDictionary.lookup(TYPE);
+ String newCompanionType = newCompanion.lookup(TYPE);
+ // System.out.println("ChoicePanelBuilder.selectDictionary() NEW TYPE: "+newType+" NEW NAME: "+newName+" NEW COMPANION TYPE: "+newCompanionType);
+ // System.out.println("-------------------");
+ for (String key : modelsByKey.keySet()) {
+ DictionaryModel model = modelsByKey.get(key);
+ Dictionary oldDictionary = model.getDictionary();
+ if (model.getCompanions().size() > 0) {
+ Dictionary oldCompanion = model.getCompanions().get(0).getDictionary();
+ String oldName = oldDictionary.getName();
+ String oldType = oldDictionary.lookup(TYPE);
+ String oldCompanionType = oldCompanion.lookup(TYPE);
+ // System.out.println("DictionaryPanelBuilder.selectDictionaries() OLD TYPE: "+oldType+" OLD NAME: "+oldName+" OLD COMPANION TYPE: "+oldCompanionType);
+
+ if (newName.equals(oldName) && newType.equals(oldType) && newCompanionType.equals(oldCompanionType)) {
+ // System.out.println("DictionaryPanelBuilder.selectDictionaries() FOUND");
+ dictionarySelectors.get(key).select();
+ selectedModel.setDictionary(newDictionary);
+
+ DictionaryModel companion = selectedModel.getCompanions().get(0);
+ if (companion != null) {
+ companion.setDictionary(newCompanion);
+ }
+ return;
+ }
+ }
+ }
+ // System.out.println("DictionaryPanelBuilder.selectDictionaries() NOT FOUND");
+ }
+
+ public void selectDictionary(Dictionary newDictionary) {
+ if (newDictionary != null /* && newDictionary.found(TYPE) */) {
+ String newName = newDictionary.getName();
+ String newType = newDictionary.lookup(TYPE);
+
+ // System.out.println("DictionaryPanelBuilder.selectDictionary() NEW TYPE: "+newType+" NEW NAME: "+newName);
+ if (newName != null && newType != null) {
+ for (String key : modelsByKey.keySet()) {
+ DictionaryModel model = modelsByKey.get(key);
+ if (model.getCompanions().size() == 0) {
+ Dictionary oldDictionary = model.getDictionary();
+ String oldName = oldDictionary.getName();
+ String oldType = oldDictionary.lookup(TYPE);
+
+ // System.out.println("DictionaryPanelBuilder.selectDictionary() OLD TYPE: "+oldType+" OLD NAME: "+oldName);
+
+ if (newName.equals(oldName) && newType.equals(oldType)) {
+ // System.out.println("DictionaryPanelBuilder.selectDictionary() FOUND");
+ dictionarySelectors.get(key).select();
+ selectedModel.setDictionary(newDictionary);
+ return;
+ }
+ }
+ }
+ logger.warn("NOT FOUND: if the model you are trying to select has a companion, use the metod 'selectDictionaries(dictionary,companion) ' instead");
+ } else {
+ logger.warn("DICTIONARY NAME OR TYPE ARE NULL. NAME: {}, TYPE: {}", newName, newType);
+ }
+ } else {
+ logger.warn("NULL DICTIONARY");
+ }
+ }
+
+ public void setShowing(String hideable, String group) {
+ selectModelAfterSelection = false;
+ super.setShowing(hideable, group);
+ selectModelAfterSelection = true;
+ }
+
+ public void selectDictionaryByModel(DictionaryModel model, Dictionary newDictionary) {
+ String key = model.getKey();
+ dictionarySelectors.get(key).select();
+ selectedModel.setDictionary(newDictionary);
+ }
+
+ public void selectDictionaryByKey(String key, Dictionary newDictionary) {
+ dictionarySelectors.get(key).select();
+ selectedModel.setDictionary(newDictionary);
+ }
+
+ @Override
+ protected void afterSelection(String selectedKey) {
+ super.afterSelection(selectedKey);
+ DictionaryModel model = modelsByKey.get(selectedKey);
+ // System.out.println("DictionaryPanelBuilder.afterSelection() "+selectedKey);
+ if (model != null && selectModelAfterSelection) {
+ setSelectedModel(model);
+ model.refresh();
+ if (model.getCompanions().size() > 0) {
+ model.getCompanions().get(0).refresh();
+ }
+ } else {
+ // System.err.println("setSelectedModel -> -> -> -> -> -> Model is NULLLL");
+ }
+ }
+
+ class DictionarySelector {
+
+ private List controllersStack = new ArrayList();
+ private List groupsStack = new ArrayList();
+
+ public DictionarySelector(Stack controllers, Stack groups) {
+ this.controllersStack.addAll(controllers);
+ this.groupsStack.addAll(groups);
+ }
+
+ public void select() {
+ for (int i = 0; i < controllersStack.size(); i++) {
+ GroupController controller = controllersStack.get(i);
+ KeydRowGroup group = groupsStack.get(i);
+ // System.out.println("DictionaryPanelBuilder.DictionarySelector.select() ["+i+"] "+group.groupKey);
+ controller.setSelectedKey(group.groupKey);
+ }
+ }
+
+ }
+
+}
diff --git a/src/eu/engys/core/dictionary/model/DictionaryTableAdapter.java b/src/eu/engys/core/dictionary/model/DictionaryTableAdapter.java
new file mode 100644
index 0000000..dfbea5a
--- /dev/null
+++ b/src/eu/engys/core/dictionary/model/DictionaryTableAdapter.java
@@ -0,0 +1,62 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.dictionary.model;
+
+import eu.engys.core.dictionary.model.DictionaryModel.DictionaryListener;
+
+public abstract class DictionaryTableAdapter extends AbstractTableAdapter {
+
+ protected DictionaryModel dictionaryModel;
+
+ public DictionaryTableAdapter(DictionaryModel dictionaryModel, String[] columnNames) {
+ super(columnNames);
+ this.dictionaryModel = dictionaryModel;
+ dictionaryModel.addDictionaryListener(new DictionaryListener() {
+ @Override
+ public void dictionaryChanged() {
+ clear();
+ load();
+ }
+ });
+ }
+
+ public DictionaryTableAdapter(DictionaryModel dictionaryModel, String[] columnNames, String rowsLabel, Integer linesToLeave, boolean showColumnNames) {
+ super(columnNames, rowsLabel, linesToLeave, showColumnNames);
+ this.dictionaryModel = dictionaryModel;
+ dictionaryModel.addDictionaryListener(new DictionaryListener() {
+ @Override
+ public void dictionaryChanged() {
+ clear();
+ load();
+ }
+ });
+ }
+
+ public void setDictionaryModel(DictionaryModel dictionaryModel) {
+ this.dictionaryModel = dictionaryModel;
+ }
+
+}
diff --git a/src/eu/engys/core/dictionary/model/EventActionType.java b/src/eu/engys/core/dictionary/model/EventActionType.java
new file mode 100644
index 0000000..086d797
--- /dev/null
+++ b/src/eu/engys/core/dictionary/model/EventActionType.java
@@ -0,0 +1,42 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.dictionary.model;
+
+public enum EventActionType {
+ SHOW, HIDE, REMOVE;
+
+ public void isShow() {
+ this.equals(SHOW);
+ }
+
+ public void isHide() {
+ this.equals(HIDE);
+ }
+
+ public void isRemove() {
+ this.equals(REMOVE);
+ }
+}
diff --git a/src/eu/engys/core/dictionary/model/LevelsTableAdapter.java b/src/eu/engys/core/dictionary/model/LevelsTableAdapter.java
new file mode 100644
index 0000000..4adb732
--- /dev/null
+++ b/src/eu/engys/core/dictionary/model/LevelsTableAdapter.java
@@ -0,0 +1,129 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.core.dictionary.model;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+import javax.swing.JComponent;
+import javax.swing.JTextField;
+
+import eu.engys.core.dictionary.Dictionary;
+import eu.engys.util.ui.textfields.DoubleField;
+import eu.engys.util.ui.textfields.IntegerField;
+
+public class LevelsTableAdapter extends DictionaryTableAdapter {
+
+ protected final String[] columnNames;
+ private static final String DICTKEY = "levels";
+ private static final String MODE = "distance";
+ private final Class>[] type;
+
+ public LevelsTableAdapter(DictionaryModel dictionaryModel, String[] names, final Class>[] type) {
+ super(dictionaryModel, names);
+ this.columnNames = names;
+ this.type = type;
+ }
+
+ @Override
+ protected void addRow() {
+ JTextField[] fields = new JTextField[2];
+ fields[0] = new DoubleField();
+ fields[1] = new IntegerField();
+ addRow(fields);
+ }
+
+ @Override
+ public void load() {
+ Dictionary dictionary = dictionaryModel.getDictionary();
+ if (MODE.equals(dictionary.lookup("mode")) && dictionary.isField(DICTKEY)) {
+ String value = dictionary.lookup(DICTKEY);
+ if (value != null && value.startsWith("(") && value.endsWith(")")) {
+ value = value.substring(1, value.length() - 1);
+ try {
+ Pattern regex = Pattern.compile("\\((\\s*\\d+\\.?\\d+)\\s*(\\d+\\s*)\\)");
+ Matcher regexMatcher = regex.matcher(value);
+ while (regexMatcher.find()) {
+ JTextField[] row = new JTextField[type.length];
+ for (int j = 1; j <= regexMatcher.groupCount(); j++) {
+ String cellValue = regexMatcher.group(j).trim();
+ int i = j - 1;
+ Class> klass = type[i];
+ if (klass == Integer.class) {
+ row[i] = new IntegerField();
+ ((IntegerField) row[i]).setIntValue(Integer.valueOf(cellValue));
+ } else if (klass == Double.class) {
+ row[i] = new DoubleField();
+ ((DoubleField) row[i]).setDoubleValue(Double.valueOf(cellValue));
+ } else {
+ row[i] = new JTextField();
+ }
+ }
+ addRow(row);
+ }
+ } catch (PatternSyntaxException ex) {
+ // Syntax error in the regular expression
+ }
+ }
+ }
+ }
+
+ @Override
+ protected void save() {
+ if (getRowsMap().isEmpty()) {
+ dictionaryModel.getDictionary().remove(DICTKEY);
+ return;
+ }
+ StringBuilder sb = new StringBuilder();
+ sb.append("( ");
+
+ TreeMap orderedMap = getOrderedMap();
+ for (Integer key : orderedMap.descendingKeySet()) {
+ sb.append("( ");
+ sb.append(orderedMap.get(key));
+ sb.append(" ");
+ sb.append(key);
+ sb.append(" )");
+ sb.append(" ");
+ }
+ sb.append(")");
+ dictionaryModel.getDictionary().add(DICTKEY, sb.toString());
+ }
+
+ private TreeMap getOrderedMap() {
+ Map map = new HashMap<>();
+ for (JComponent[] row : getRowsMap().values()) {
+ map.put(((IntegerField) row[1]).getIntValue(), ((DoubleField) row[0]).getDoubleValue());
+ }
+ return new TreeMap(map);
+ }
+
+}
diff --git a/src/eu/engys/core/dictionary/model/LinesTableAdapter.java b/src/eu/engys/core/dictionary/model/LinesTableAdapter.java
new file mode 100644
index 0000000..1dfa915
--- /dev/null
+++ b/src/eu/engys/core/dictionary/model/LinesTableAdapter.java
@@ -0,0 +1,191 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.core.dictionary.model;
+
+import java.awt.BorderLayout;
+import java.awt.Dialog.ModalityType;
+import java.awt.FlowLayout;
+import java.awt.event.ActionEvent;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+import javax.swing.AbstractAction;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JDialog;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextField;
+
+import eu.engys.core.dictionary.Dictionary;
+import eu.engys.util.ui.UiUtil;
+import eu.engys.util.ui.textfields.DoubleField;
+import eu.engys.util.ui.textfields.IntegerField;
+
+public class LinesTableAdapter extends DictionaryTableAdapter {
+
+ private static final String LEVELS = "levels";
+ private static final String LEVEL = "level";
+ private Dictionary lineDictionary;
+ private final Class>[] type;
+
+ public LinesTableAdapter(DictionaryModel dictionaryModel, Dictionary lineDictionary, String[] columnNames, final Class>[] type) {
+ super(dictionaryModel, columnNames, "", LEAVE_ONE_LINE, true);
+ this.lineDictionary = lineDictionary;
+ this.type = type;
+ fixOldStyleLevels();
+ }
+
+ public JButton getButton() {
+ JButton b = new JButton(new AbstractAction("Edit") {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ getDialog().setVisible(true);
+ }
+
+ });
+ return b;
+ }
+
+ private JDialog getDialog() {
+ final JDialog dialog = new JDialog(UiUtil.getActiveWindow(), "Refinement Level", ModalityType.MODELESS);
+ dialog.setName("line.adapter.dialog");
+
+ JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
+ JButton okButton = new JButton(new AbstractAction("OK") {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ save();
+ dialog.setVisible(false);
+ }
+ });
+ okButton.setName("OK");
+ buttonsPanel.add(okButton);
+
+ JPanel mainPanel = new JPanel(new BorderLayout());
+ mainPanel.add(new JScrollPane(this), BorderLayout.CENTER);
+ mainPanel.add(buttonsPanel, BorderLayout.SOUTH);
+
+ dialog.add(mainPanel);
+ dialog.setSize(600, 400);
+ dialog.setLocationRelativeTo(null);
+ dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
+ dialog.getRootPane().setDefaultButton(okButton);
+ return dialog;
+ }
+
+ private void fixOldStyleLevels() {
+ if (lineDictionary.found(LEVEL)) {
+ Dictionary clone = new Dictionary(lineDictionary);
+ String levelValue = clone.lookup(LEVEL);
+ clone.remove(LEVEL);
+ clone.add(LEVELS, "( ( 0.0 " + levelValue + " ) )");
+ this.lineDictionary = clone;
+ }
+ }
+
+ public Dictionary getLineDictionary() {
+ return lineDictionary;
+ }
+
+ @Override
+ protected void addRow() {
+ JTextField[] fields = new JTextField[2];
+ fields[0] = new DoubleField();
+ fields[1] = new IntegerField();
+ addRow(fields);
+ }
+
+ @Override
+ public void load() {
+ String value = lineDictionary.lookup(LEVELS);
+ if (value != null && value.startsWith("(") && value.endsWith(")")) {
+ value = value.substring(1, value.length() - 1);
+ try {
+ Pattern regex = Pattern.compile("\\((\\s*\\d+\\.?\\d+)\\s*(\\d+\\s*)\\)");
+ Matcher regexMatcher = regex.matcher(value);
+ while (regexMatcher.find()) {
+ JTextField[] row = new JTextField[type.length];
+ for (int j = 1; j <= regexMatcher.groupCount(); j++) {
+ String cellValue = regexMatcher.group(j).trim();
+ int i = j - 1;
+ Class> klass = type[i];
+ if (klass == Integer.class) {
+ row[i] = new IntegerField();
+ ((IntegerField) row[i]).setIntValue(Integer.valueOf(cellValue));
+ } else if (klass == Double.class) {
+ row[i] = new DoubleField();
+ ((DoubleField) row[i]).setDoubleValue(Double.valueOf(cellValue));
+ } else {
+ row[i] = new JTextField();
+ }
+ }
+ addRow(row);
+ }
+ } catch (PatternSyntaxException ex) {
+ ex.printStackTrace();
+ }
+ }
+ if (getRowsMap().isEmpty()) {
+ addRow();
+ }
+ }
+
+ @Override
+ protected void save() {
+ if (getRowsMap().isEmpty()) {
+ lineDictionary.remove(LEVELS);
+ return;
+ }
+ StringBuilder sb = new StringBuilder();
+ TreeMap orderedMap = getOrderedMap();
+ sb.append("( ");
+ for (Integer key : orderedMap.descendingKeySet()) {
+ sb.append("( ");
+ sb.append(orderedMap.get(key));
+ sb.append(" ");
+ sb.append(key);
+ sb.append(" )");
+ sb.append(" ");
+ }
+ sb.append(")");
+ lineDictionary.add(LEVELS, sb.toString());
+ }
+
+ private TreeMap getOrderedMap() {
+ Map map = new HashMap<>();
+ for (JComponent[] row : getRowsMap().values()) {
+ map.put(((IntegerField) row[1]).getIntValue(), ((DoubleField) row[0]).getDoubleValue());
+ }
+ return new TreeMap(map);
+ }
+
+}
diff --git a/src/eu/engys/core/dictionary/model/OneDictionaryPerRowTableAdapter.java b/src/eu/engys/core/dictionary/model/OneDictionaryPerRowTableAdapter.java
new file mode 100644
index 0000000..c049afa
--- /dev/null
+++ b/src/eu/engys/core/dictionary/model/OneDictionaryPerRowTableAdapter.java
@@ -0,0 +1,188 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.core.dictionary.model;
+
+import static eu.engys.util.Symbols.DOT;
+
+import javax.swing.JComponent;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+
+import eu.engys.core.dictionary.Dictionary;
+import eu.engys.util.ui.UiUtil;
+import eu.engys.util.ui.textfields.DoubleField;
+import eu.engys.util.ui.textfields.IntegerField;
+import eu.engys.util.ui.textfields.StringField;
+
+public class OneDictionaryPerRowTableAdapter extends DictionaryTableAdapter {
+
+ private final int NAME_COL = 0;
+ protected final String[] columnNames;
+ protected final String[] columnKeys;
+ protected final String[] rowNames;
+ protected final String[] rowKeys;
+ protected final String dictKey;
+
+ protected final Class>[] type;
+
+ public static void main(String[] args) {
+ String[] columnNames = { "Name", "Thickness [m]", "Conductivity [W/K" + DOT + "m]" };
+ String[] columnKeys = { "thickness", "lambda" };
+ Class>[] type = { String.class, Double.class, Double.class };
+
+ JPanel table = new OneDictionaryPerRowTableAdapter(new DictionaryModel(), columnNames, columnKeys, null, null, "layers", type);
+ JFrame f = UiUtil.defaultTestFrame("test", table);
+ f.setSize(600, 600);
+ f.setVisible(true);
+ }
+
+ public OneDictionaryPerRowTableAdapter(DictionaryModel dictionaryModel, String[] columnNames, String[] columnKeys, String[] rowNames, String[] rowKeys, String key, Class>[] type) {
+ super(dictionaryModel, columnNames);
+ this.columnNames = columnNames;
+ this.columnKeys = columnKeys;
+ this.rowNames = rowNames;
+ this.rowKeys = rowKeys;
+ this.dictKey = key;
+ this.type = type;
+
+ setName("one.dict.row");
+
+ if (isStaticTable()) {
+ setRowHeader();
+ hideButtonsPanel();
+ }
+ }
+
+ @Override
+ protected void addRow() {
+ if (!isStaticTable()) {
+ JTextField[] row = new JTextField[type.length];
+ for (int i = 0; i < type.length; i++) {
+ Class> klass = type[i];
+ if (klass == Integer.class) {
+ row[i] = new IntegerField();
+ ((IntegerField) row[i]).setIntValue(Integer.valueOf(0));
+ } else if (klass == Double.class) {
+ row[i] = new DoubleField();
+ ((DoubleField) row[i]).setDoubleValue(Integer.valueOf(0));
+ } else if (klass == String.class) {
+ row[i] = new StringField("name" + (getRowsMap().size() + 1));
+ } else {
+ row[i] = new StringField("");
+ }
+ }
+ addRow(row);
+ }
+ }
+
+ private boolean isStaticTable() {
+ return rowNames != null;
+ }
+
+ public void setRowHeader() {
+ for (int i = 0; i < rowNames.length; i++) {
+ JComponent[] row = new JComponent[columnKeys.length + 1];
+ row[0] = new JLabel(rowNames[i]);
+ for (int j = 1; j < row.length; j++) {
+ Class> klass = type[j];
+ if (klass == Integer.class) {
+ row[j] = new IntegerField();
+ ((IntegerField) row[j]).setIntValue(Integer.valueOf(0));
+ } else if (klass == Double.class) {
+ row[j] = new DoubleField();
+ ((DoubleField) row[j]).setDoubleValue(Double.valueOf(0));
+ } else {
+ row[j] = new JLabel("");
+ }
+ }
+ addRow(row, false);
+ }
+ }
+
+ @Override
+ public void load() {
+ if (dictionaryModel.getDictionary().found(dictKey)) {
+ Dictionary dict = dictionaryModel.getDictionary().subDict(dictKey);
+ if (isStaticTable() && dict.getDictionaries().size() != rowKeys.length) {
+ setRowHeader();
+ } else {
+ int rowIndex = 0;
+ for (Dictionary d : dict.getDictionaries()) {
+ JComponent[] row = new JComponent[columnKeys.length + 1];
+ if (isStaticTable())
+ row[0] = new JLabel(rowKeys[rowIndex]);
+ else
+ row[0] = new StringField(d.getName());
+
+ for (int k = 0; k < columnKeys.length; k++) {
+ String value = d.lookup(columnKeys[k]);
+ int j = k + 1;
+ if (value == null)
+ row[j] = new JTextField("0");
+ else if (type[j] == Double.class) {
+ row[j] = new DoubleField();
+ ((DoubleField) row[j]).setDoubleValue(Double.valueOf(value));
+ } else if (type[j] == Integer.class) {
+ row[j] = new IntegerField();
+ ((IntegerField) row[j]).setIntValue(Integer.valueOf(value));
+ } else {
+ row[j] = new JLabel(value);
+ }
+ }
+ addRow(row);
+ rowIndex++;
+ }
+ }
+ }
+ }
+
+ @Override
+ protected void save() {
+ Dictionary layers = new Dictionary(dictKey);
+ for (int r = 0; r < getRowsMap().values().size(); r++) {
+ String name;
+ if (isStaticTable()) {
+ name = rowKeys[r];
+ } else {
+ JComponent[][] fields = getRowsMap().values().toArray(new JComponent[0][0]);
+ name = String.valueOf(((JTextField) fields[r][NAME_COL]).getText());
+ }
+
+ Dictionary layer = new Dictionary(name);
+ for (int k = 0; k < columnKeys.length; k++) {
+ JComponent[][] fields = getRowsMap().values().toArray(new JComponent[0][0]);
+ String value = String.valueOf(((JTextField) fields[r][k + 1]).getText());
+ layer.add(columnKeys[k], value);
+ }
+ layers.add(layer);
+ }
+ dictionaryModel.getDictionary().add(layers);
+ }
+
+}
diff --git a/src/eu/engys/core/dictionary/model/PatchesMapTableAdapter.java b/src/eu/engys/core/dictionary/model/PatchesMapTableAdapter.java
new file mode 100644
index 0000000..0d1eb13
--- /dev/null
+++ b/src/eu/engys/core/dictionary/model/PatchesMapTableAdapter.java
@@ -0,0 +1,162 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.core.dictionary.model;
+
+import static eu.engys.core.project.system.MapFieldsDict.PATCH_MAP_KEY;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.JComboBox;
+import javax.swing.JOptionPane;
+
+import eu.engys.core.dictionary.DictionaryUtils;
+import eu.engys.core.project.zero.patches.Patch;
+import eu.engys.core.project.zero.patches.Patches;
+import eu.engys.util.ui.UiUtil;
+
+public class PatchesMapTableAdapter extends DictionaryTableAdapter {
+
+ private Patches sourcePatches = new Patches();
+ private Patches targetPatches;
+ private ActionListener sourceListener;
+ private ActionListener targetListener;
+
+ public PatchesMapTableAdapter(DictionaryModel dictionaryModel, Patches targetPatches) {
+ super(dictionaryModel, new String[] { "Source", "Target" });
+ this.targetPatches = targetPatches;
+ this.sourceListener = new SourceComboActionListener();
+ this.targetListener = new TargetComboActionListener();
+ }
+
+ public void updateSourceList(Patches sourcePatches) {
+ this.sourcePatches = sourcePatches;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected void addRow() {
+ JComboBox[] fields = new JComboBox[2];
+ fields[0] = new JComboBox();
+ for (Patch sp : sourcePatches) {
+ fields[0].addItem(sp.getName());
+ }
+ fields[0].setSelectedIndex(-1);
+ fields[0].addActionListener(sourceListener);
+
+ fields[1] = new JComboBox();
+ for (Patch sp : targetPatches) {
+ fields[1].addItem(sp.getName());
+ }
+ fields[1].setSelectedIndex(-1);
+ fields[1].addActionListener(targetListener);
+
+ addRow(fields, false);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void load() {
+ String patchMap = dictionaryModel.getDictionary().lookup(PATCH_MAP_KEY);
+ String[] patches = DictionaryUtils.string2StringArray(patchMap);
+
+ for (int i = 0; i < patches.length; i += 2) {
+ JComboBox[] fields = new JComboBox[2];
+ fields[0] = new JComboBox();
+ fields[0].removeActionListener(sourceListener);
+ for (Patch sp : sourcePatches) {
+ fields[0].addItem(sp.getName());
+ }
+ fields[0].setSelectedItem(patches[i]);
+ fields[0].addActionListener(sourceListener);
+
+ fields[1] = new JComboBox();
+ fields[1].removeActionListener(targetListener);
+ for (Patch sp : targetPatches) {
+ fields[1].addItem(sp.getName());
+ }
+ fields[1].setSelectedItem(patches[i + 1]);
+ fields[1].addActionListener(targetListener);
+
+ addRow(fields, false);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void save() {
+ dictionaryModel.getDictionary().remove(PATCH_MAP_KEY);
+
+ StringBuilder sb = new StringBuilder("(");
+ for (Integer key : getRowsMap().keySet()) {
+ JComboBox[] comps = (JComboBox[]) getRowsMap().get(key);
+ if(comps[0].getSelectedIndex() > -1){
+ sb.append((String) comps[0].getSelectedItem() + " ");
+ sb.append((String) comps[1].getSelectedItem() + " ");
+ }
+ }
+ sb.append(")");
+ dictionaryModel.getDictionary().add(PATCH_MAP_KEY, sb.toString());
+ }
+
+ private class SourceComboActionListener implements ActionListener {
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ JComboBox combo = ((JComboBox) e.getSource());
+ for (Integer key : getRowsMap().keySet()) {
+ JComboBox sourceCombo = (JComboBox) getRowsMap().get(key)[0];
+ if (sourceCombo != combo && sourceCombo.getSelectedItem() !=null && sourceCombo.getSelectedItem().equals(combo.getSelectedItem())) {
+ combo.hidePopup();
+ combo.setSelectedIndex(-1);
+ JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), "Source patch already used", "Fields Map Error", JOptionPane.ERROR_MESSAGE);
+ return;
+ }
+ }
+ }
+ }
+
+ private class TargetComboActionListener implements ActionListener {
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ JComboBox combo = ((JComboBox) e.getSource());
+ for (Integer key : getRowsMap().keySet()) {
+ JComboBox targetCombo = (JComboBox) getRowsMap().get(key)[1];
+ if (targetCombo != combo && targetCombo.getSelectedItem() != null && targetCombo.getSelectedItem().equals(combo.getSelectedItem())) {
+ combo.hidePopup();
+ combo.setSelectedIndex(-1);
+ JOptionPane.showMessageDialog(UiUtil.getActiveWindow(), "Target patch already used", "Fields Map Error", JOptionPane.ERROR_MESSAGE);
+ return;
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/eu/engys/core/dictionary/model/PointInfo.java b/src/eu/engys/core/dictionary/model/PointInfo.java
new file mode 100644
index 0000000..89c0dd8
--- /dev/null
+++ b/src/eu/engys/core/dictionary/model/PointInfo.java
@@ -0,0 +1,64 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.dictionary.model;
+
+import java.awt.Color;
+
+import eu.engys.util.ui.textfields.DoubleField;
+
+public class PointInfo {
+
+ public static final String PROPERTY_NAME = "point.location";
+ public static final String LABEL = "Point ";
+ private DoubleField[] field;
+ private Color color;
+ private String key;
+ private EventActionType action;
+
+ public PointInfo(DoubleField[] field, String key, EventActionType action, Color color) {
+ this.field = field;
+ this.key = key;
+ this.action = action;
+ this.color = color;
+ }
+
+ public DoubleField[] getPoint() {
+ return field;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public EventActionType getAction() {
+ return action;
+ }
+
+ public Color getColor() {
+ return color;
+ }
+
+}
diff --git a/src/eu/engys/core/dictionary/model/PointTableAdapter.java b/src/eu/engys/core/dictionary/model/PointTableAdapter.java
new file mode 100644
index 0000000..aa8c7e2
--- /dev/null
+++ b/src/eu/engys/core/dictionary/model/PointTableAdapter.java
@@ -0,0 +1,175 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.core.dictionary.model;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+import javax.swing.JComponent;
+import javax.swing.JToggleButton;
+
+import eu.engys.util.ColorUtil;
+import eu.engys.util.ui.ComponentsFactory;
+import eu.engys.util.ui.textfields.DoubleField;
+
+public class PointTableAdapter extends DictionaryTableAdapter {
+
+ private String dictKey;
+ private List buttons;
+ private List visibility;
+ private final boolean showPoint;
+
+ public PointTableAdapter(DictionaryModel dictionaryModel, String[] columnNames, String dictKey, int linesToLeave, boolean showPoint) {
+ super(dictionaryModel, columnNames, PointInfo.LABEL, linesToLeave, false);
+ this.dictKey = dictKey;
+ this.showPoint = showPoint;
+ this.buttons = new LinkedList<>();
+ this.visibility = new LinkedList();
+ }
+
+ @Override
+ protected void addRow() {
+ DoubleField[] fields = ComponentsFactory.doublePointField(4);
+ addRow(fields);
+ }
+
+ @Override
+ protected void removeRow() {
+ updateVisibilityList();
+ super.removeRow();
+ visibility.clear();
+ }
+
+ private void updateVisibilityList() {
+ visibility.clear();
+ for (int i = 0; i < buttons.size() - 1; i++) {
+ visibility.add(buttons.get(i).isSelected());
+ }
+ turnOffPointsIn3D();
+ buttons.clear();
+ }
+
+ @Override
+ protected JComponent[] createComponent(final JComponent[] field) {
+ if (showPoint) {
+ List comps = new ArrayList(Arrays.asList(field));
+ JToggleButton showMaterialPoint = null;
+ if (visibility.size() > getRowsMap().size()) {
+ showMaterialPoint = ShowLocationAdapter.newShowPointButton((DoubleField[]) field, getRowsMap().size(), visibility.get(getRowsMap().size()));
+ } else {
+ showMaterialPoint = ShowLocationAdapter.newShowPointButton((DoubleField[]) field, getRowsMap().size(), false);
+ }
+ showMaterialPoint.getAction().addPropertyChangeListener(new PropertyChangeListener() {
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ if(evt.getPropertyName().equals(PointInfo.PROPERTY_NAME)){
+ firePropertyChange(evt.getPropertyName(), evt.getOldValue(), evt.getNewValue());
+ }
+ }
+ });
+
+ buttons.add(showMaterialPoint);
+ comps.add(showMaterialPoint);
+ return comps.toArray(new JComponent[0]);
+ } else {
+ return field;
+ }
+ }
+
+ @Override
+ protected void triggerEventFor3D(JComponent[] comp) {
+ String key = ColorUtil.getColor(getRowsMap().size()).toString();
+ firePropertyChange(PointInfo.PROPERTY_NAME, null, new PointInfo((DoubleField[]) comp, key, EventActionType.REMOVE, null));
+ }
+
+ public void turnOffPointsIn3D() {
+ for (JToggleButton b : buttons) {
+ if (b.isSelected()) {
+ b.doClick();
+ }
+ }
+ }
+
+ @Override
+ public void load() {
+ turnOffPointsIn3D();
+ buttons.clear();
+ String value = dictionaryModel.getDictionary().lookup(dictKey);
+ if (value != null && value.startsWith("(") && value.endsWith(")")) {
+ value = value.substring(1, value.length() - 1).trim();
+ try {
+ Pattern regex = Pattern.compile("(\\([^\\)]*\\))");
+ Matcher regexMatcher = regex.matcher(value);
+
+ while (regexMatcher.find()) {
+ DoubleField[] fields = new DoubleField[3];
+ String row = regexMatcher.group().trim();
+ Pattern rowRegex = Pattern.compile("(\\s*\\-?\\d*\\.?\\d+([eE][-+]?[0-9]+)*\\s*)");
+ Matcher rowRegexMatcher = rowRegex.matcher(row);
+
+ int columnCounter = 0;
+ while (rowRegexMatcher.find()) {
+ fields[columnCounter] = new DoubleField();
+ fields[columnCounter].setDoubleValue(Double.valueOf(rowRegexMatcher.group().trim()));
+ if (columnCounter > fields.length) {
+ break;
+ }
+ columnCounter++;
+ }
+ addRow(fields);
+ }
+ } catch (PatternSyntaxException ex) {
+ // Syntax error in the regular expression
+ }
+ }
+ }
+
+ @Override
+ protected void save() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("( ");
+ for (JComponent[] row : getRowsMap().values()) {
+ sb.append("( ");
+ for (DoubleField doubleField : (DoubleField[]) row) {
+ sb.append(doubleField.getDoubleValue());
+ sb.append(" ");
+ }
+ sb.append(")");
+ sb.append(" ");
+ }
+ sb.append(")");
+ dictionaryModel.getDictionary().add(dictKey, sb.toString());
+ }
+}
diff --git a/src/eu/engys/core/dictionary/model/ShowAxisAdapter.java b/src/eu/engys/core/dictionary/model/ShowAxisAdapter.java
new file mode 100644
index 0000000..f556783
--- /dev/null
+++ b/src/eu/engys/core/dictionary/model/ShowAxisAdapter.java
@@ -0,0 +1,112 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.core.dictionary.model;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.event.ActionEvent;
+import java.beans.PropertyChangeListener;
+
+import javax.swing.AbstractAction;
+import javax.swing.AbstractButton;
+import javax.swing.ImageIcon;
+import javax.swing.JComponent;
+import javax.swing.JPanel;
+import javax.swing.JToggleButton;
+
+import net.java.dev.designgridlayout.Componentizer;
+import eu.engys.util.ui.textfields.DoubleField;
+
+public class ShowAxisAdapter extends JPanel {
+
+ private static final ImageIcon ICON_ON = new ImageIcon(AbstractTableAdapter.class.getClassLoader().getResource("eu/engys/resources/images/lightbulb16.png"));
+ private static final ImageIcon ICON_OFF = new ImageIcon(AbstractTableAdapter.class.getClassLoader().getResource("eu/engys/resources/images/lightbulb_off16.png"));
+
+ private JToggleButton button;
+ private DoubleField[] axis;
+ private DoubleField[] centre;
+
+ public ShowAxisAdapter(DoubleField[] axis, DoubleField[] centre) {
+ super(new BorderLayout());
+ this.axis = axis;
+ this.centre = centre;
+ this.button = newShowAxisButton(false);
+ JComponent component = Componentizer.create().minAndMore(centre).minToPref(button).component();
+ add(component, BorderLayout.CENTER);
+ }
+
+ @Override
+ public void setName(String name) {
+ super.setName(name);
+ button.setName(getName()+".button");
+ axis[0].setName(getName()+".axis.0");
+ axis[1].setName(getName()+".axis.1");
+ axis[2].setName(getName()+".axis.2");
+ centre[0].setName(getName()+".centre.0");
+ centre[1].setName(getName()+".centre.1");
+ centre[2].setName(getName()+".centre.2");
+ }
+
+ @Override
+ public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+ super.addPropertyChangeListener(propertyName, listener);
+ if (propertyName.equals("point.location")) {
+ button.getAction().addPropertyChangeListener(listener);
+ }
+ }
+
+ public void turnOff() {
+ if (button.isSelected()) {
+ button.doClick();
+ }
+ }
+
+ public JToggleButton newShowAxisButton(boolean selected) {
+ final JToggleButton button = new JToggleButton(new AbstractAction() {
+ // private Border originalBorder;
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ AbstractButton b = ((AbstractButton) e.getSource());
+ if (b.isSelected()) {
+ firePropertyChange(PointInfo.PROPERTY_NAME, null, new AxisInfo(axis, centre, EventActionType.SHOW));
+ } else {
+ firePropertyChange(PointInfo.PROPERTY_NAME, null, new AxisInfo(axis, centre, EventActionType.HIDE));
+ }
+ }
+ });
+ if (selected && !button.isSelected() || (!selected && button.isSelected())) {
+ button.doClick();
+ }
+ button.setPreferredSize(new Dimension(22, 22));
+ button.setIcon(ICON_OFF);
+ button.setSelectedIcon(ICON_ON);
+ button.setToolTipText("Click to display this point in the 3D canvas");
+ return button;
+ }
+
+}
diff --git a/src/eu/engys/core/dictionary/model/ShowLocationAdapter.java b/src/eu/engys/core/dictionary/model/ShowLocationAdapter.java
new file mode 100644
index 0000000..72f99f0
--- /dev/null
+++ b/src/eu/engys/core/dictionary/model/ShowLocationAdapter.java
@@ -0,0 +1,125 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.dictionary.model;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.event.ActionEvent;
+import java.beans.PropertyChangeListener;
+
+import javax.swing.AbstractAction;
+import javax.swing.AbstractButton;
+import javax.swing.BorderFactory;
+import javax.swing.Icon;
+import javax.swing.JComponent;
+import javax.swing.JPanel;
+import javax.swing.JToggleButton;
+import javax.swing.border.Border;
+
+import net.java.dev.designgridlayout.Componentizer;
+import eu.engys.util.ColorUtil;
+import eu.engys.util.ui.ResourcesUtil;
+import eu.engys.util.ui.textfields.DoubleField;
+
+public class ShowLocationAdapter extends JPanel {
+
+ private static final Icon ICON_ON = ResourcesUtil.getResourceIcon("eu/engys/resources/images/lightbulb16.png");
+ private static final Icon ICON_OFF = ResourcesUtil.getResourceIcon("eu/engys/resources/images/lightbulb_off16.png");
+
+ private JToggleButton button;
+ private DoubleField[] fields;
+
+ public ShowLocationAdapter(DoubleField[] fields, Color key) {
+ super(new BorderLayout());
+ this.fields = fields;
+ this.button = newShowPointButton(fields, key, false);
+ JComponent component = Componentizer.create().minAndMore(fields).minToPref(button).component();
+ add(component, BorderLayout.CENTER);
+ }
+
+ @Override
+ public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+ super.addPropertyChangeListener(propertyName, listener);
+ if (propertyName.equals(PointInfo.PROPERTY_NAME)) {
+ button.getAction().addPropertyChangeListener(listener);
+ }
+ }
+
+ public void turnMaterialPointsOn() {
+ if (!button.isSelected()) {
+ button.doClick();
+ }
+ }
+
+ public void turnMaterialPointsOff() {
+ if (button.isSelected()) {
+ button.doClick();
+ }
+ }
+
+ public static JToggleButton newShowPointButton(final DoubleField[] locationInMesh, int index, boolean selected) {
+ return newShowPointButton(locationInMesh, ColorUtil.getColor(index), selected);
+ }
+
+ public static JToggleButton newShowPointButton(final DoubleField[] locationInMesh, final Color color, boolean selected) {
+ final JToggleButton button = new JToggleButton(new AbstractAction() {
+ private Border originalBorder;
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ AbstractButton b = ((AbstractButton) e.getSource());
+ if (b.isSelected()) {
+ firePropertyChange(PointInfo.PROPERTY_NAME, null, new PointInfo(locationInMesh, color.toString(), EventActionType.SHOW, color));
+ originalBorder = b.getBorder();
+ b.setBorder(BorderFactory.createLineBorder(color, 2));
+ } else {
+ firePropertyChange(PointInfo.PROPERTY_NAME, null, new PointInfo(locationInMesh, color.toString(), EventActionType.HIDE, color));
+ if (originalBorder != null) {
+ b.setBorder(originalBorder);
+ }
+ }
+ }
+ });
+ if (selected && !button.isSelected() || (!selected && button.isSelected())) {
+ button.doClick();
+ }
+ button.setPreferredSize(new Dimension(22, 22));
+ button.setIcon(ICON_OFF);
+ button.setSelectedIcon(ICON_ON);
+ button.setToolTipText("Click to display this point in the 3D canvas");
+ return button;
+ }
+
+ @Override
+ public void setToolTipText(String text) {
+ super.setToolTipText(text);
+ for (DoubleField f : fields) {
+ f.setToolTipText(text);
+ }
+ }
+
+}
diff --git a/src/eu/engys/core/dictionary/parser/DictionaryReader2.java b/src/eu/engys/core/dictionary/parser/DictionaryReader2.java
new file mode 100644
index 0000000..b02e5b7
--- /dev/null
+++ b/src/eu/engys/core/dictionary/parser/DictionaryReader2.java
@@ -0,0 +1,443 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.core.dictionary.parser;
+
+import static eu.engys.core.dictionary.Dictionary.SPACER;
+import static eu.engys.core.dictionary.Dictionary.VALUE_LINK;
+import static eu.engys.core.dictionary.Dictionary.VALUE_UNIFORM_LINK;
+import static eu.engys.core.dictionary.Dictionary.VERBOSE;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+import eu.engys.core.dictionary.Dictionary;
+import eu.engys.core.dictionary.DictionaryException;
+import eu.engys.core.dictionary.DictionaryLinkResolver;
+import eu.engys.core.dictionary.DimensionedScalar;
+import eu.engys.util.IOUtils;
+
+public class DictionaryReader2 {
+
+ private static final String NAME_WITH_PARENTHESIS_REGEXP = ";\\s([^(\\s]*?\\([^\\s]*?\\)[^)\\s]*?)\\s";
+ static final String LIST_START = "(";
+ static final String LIST_END = ")";
+ // private static final String LIST_START = "!";
+ // private static final String MATRIX_START = "&";
+ // private static final String MATRIX_DELIMITER = "|";
+ static final String FIELD_END = ";";
+ static final String DICTIONARY_END = "}";
+ static final String DICTIONARY_START = "{";
+
+ static final String TOKENS_LIST = DICTIONARY_END + FIELD_END + DICTIONARY_START + LIST_START + LIST_END;// " };{(";
+
+ private static final String COMMENT_REGEX = "/\\*(?:.|[\\n\\r])*?\\*/";
+ private Dictionary dictionary;
+ private DictionaryLinkResolver linkResolver;
+
+ public DictionaryReader2(Dictionary dictionary) {
+ this(dictionary, new DictionaryLinkResolver(dictionary));
+ }
+
+ public DictionaryReader2(Dictionary dictionary, DictionaryLinkResolver linkResolver) {
+ this.dictionary = dictionary;
+ this.linkResolver = linkResolver;
+ }
+
+ public void read(File file) {
+ String text = readFile(file);
+ text = prepareText(text, file);
+ textToDictionary(text);
+ if (dictionary.found("FoamFile"))
+ dictionary.remove("FoamFile");
+ }
+
+ public void read(InputStream is) {
+ String text = readStream(is);
+ text = prepareText(text, null);
+ textToDictionary(text);
+ if (dictionary.found("FoamFile"))
+ dictionary.remove("FoamFile");
+ }
+
+ public void read(String text) {
+ read(text, false);
+ }
+
+ public void read(String text, boolean removeHeader) {
+ text = prepareText(text, null);
+ textToDictionary(text);
+ if (dictionary.found("FoamFile") && removeHeader) {
+ dictionary.remove("FoamFile");
+ }
+ }
+
+ private String readFile(File file) {
+ return IOUtils.readStringFromFile(file);
+ }
+
+ private String readStream(InputStream is) {
+ String text = "";
+ try {
+ text = IOUtils.readStringFromStream(is);
+ } catch (IOException e) {
+ System.err.println("Error reading stream : " + e.getMessage());
+ }
+ return text;
+ }
+
+ private String prepareText(String text, File file) {
+ text = text.replaceAll(COMMENT_REGEX, "");
+ text = text.replaceAll("\t", SPACER);
+
+ StringTokenizer rowTokenizer = new StringTokenizer(text, "\n");
+ StringBuffer sb = new StringBuffer();
+ while (rowTokenizer.hasMoreTokens()) {
+ String token = rowTokenizer.nextToken();
+ token = token.trim();
+ if (token.startsWith("//"))
+ continue;
+ if (token.contains("//")) {
+ token = token.substring(0, token.indexOf("//")).trim();
+ }
+ if (token.startsWith("#include")) {
+ sb.append(importFile(token, file));
+ continue;
+ }
+ sb.append(token);
+ sb.append("\n");
+ }
+ text = sb.toString();
+ return text;
+ }
+
+ private String importFile(String token, File file) {
+ String text = "";
+ if (file != null) {
+ try {
+ Pattern regex = Pattern.compile("#include\\s+\"(.+)\"");
+ Matcher regexMatcher = regex.matcher(token);
+ if (regexMatcher.find() && regexMatcher.groupCount() == 1) {
+ String fileName = regexMatcher.group(1).trim();
+ String parentDir = file.getParent();
+
+ File fileToImport = new File(parentDir, fileName);
+ text = readFile(fileToImport);
+ text = prepareText(text, fileToImport);
+ }
+ } catch (PatternSyntaxException ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ return text;
+ }
+
+ protected void textToDictionary(String text) {
+ text = text.replace("\n", SPACER);
+ text = new Rewriter(NAME_WITH_PARENTHESIS_REGEXP) {
+ public String replacement() {
+ String nameWithParenthesis = group(1);
+ // System.out.println("nameWithParentesis = "+nameWithParenthesis);
+ return FIELD_END + SPACER + nameWithParenthesis.replace("(", "<<").replace(")", ">>") + SPACER;
+ }
+ }.rewrite(text);
+
+ printOut(text);
+
+ text = text.replaceAll("\\{", SPACER + "{" + SPACER);
+ text = text.replaceAll("\\}", SPACER + "}" + SPACER);
+ text = text.replaceAll(";", SPACER + ";" + SPACER);
+ text = text.replaceAll("\\(", SPACER + "(" + SPACER);
+ text = text.replaceAll("\\)", SPACER + ")" + SPACER);
+ text = text.replaceAll("\\s+", SPACER);
+ text = text.replaceAll("<<", "(");
+ text = text.replaceAll(">>", ")");
+
+ printOut(text);
+
+ parseDictionary(text);
+ }
+
+ protected void parseDictionary(String text) {
+ StringTokenizer tokenizer = new StringTokenizer(text, SPACER);
+ Stack stack = new Stack();
+ readDictionary(tokenizer, stack);
+ printOut("##################################\n" + toString());
+ linkResolver.resolve(dictionary);
+ }
+
+ void readDictionary(StringTokenizer st, Stack stack) {
+ while (st.hasMoreTokens()) {
+ String token = st.nextToken();
+ printOut("TOKEN: " + token);
+ stack.push(token);// metto nella pila
+
+ if (stack.peek().equals(DICTIONARY_START)) {
+ stack.pop();
+ String name = stack.pop();
+ Dictionary d = new Dictionary(name);
+ printOut("START DICTIONARY: " + name);
+
+ new DictionaryReader2(d).readDictionary(st, stack);
+
+ if (isMultiple(name)) {
+ String[] names = extractMultipleKeys(name);
+ for (String n : names) {
+ if (isGeneric(withDoubleQuotes(n))) {
+ Dictionary copy = new Dictionary(d);
+ copy.setName(withDoubleQuotes(n));
+ dictionary.addGeneric(copy);
+ } else {
+ Dictionary copy = new Dictionary(d);
+ copy.setName(n);
+ dictionary.add(copy);
+ }
+ }
+ } else if (isGeneric(name)) {
+ dictionary.addGeneric(d);
+ } else {
+ dictionary.add(d);
+ }
+ } else if (stack.peek().equals(DICTIONARY_END)) {
+ // stack.pop();
+ String name = stack.pop();
+ printOut("FINE DICTIONARY: " + name);
+ return;
+ } else if (stack.peek().equals(FIELD_END)) {
+ stack.pop(); // tolgo il ;
+
+ /* in teoria nello stack c'e' tutto il field */
+ if (stack.isEmpty())
+ continue;
+
+ readFields(stack);
+ } else if (stack.peek().equals(LIST_START)) {
+ ListField2 list = listFromStack(stack);
+
+ printOut("START LIST: " + list.getName());
+
+ ListReader2 reader;
+ if (list instanceof ThetaListField2) {
+ reader = new ThetaListReader2((ThetaListField2) list, true);
+ } else {
+ if (dictionary.getFoamFile() != null) {
+ reader = new ListReader2(list, true);
+ } else {
+ reader = new ListReader2(list, false);
+ }
+ }
+
+ if (reader.readList(st, stack)) {
+ dictionary.add(list);
+ } else {
+ List unspecifiedList = new ArrayList<>(stack);
+ String key = list.getName();
+ String value = "";
+ for (String item : unspecifiedList) {
+ value += SPACER + item;
+ }
+ dictionary.add(key, value);
+ }
+ }
+ }
+ }
+
+ private ListField2 listFromStack(Stack stack) {
+ String separator = stack.pop();
+ Stack listStack = new Stack<>();
+ while (!stack.isEmpty() && !isSeparator(stack.peek())) {
+ String pop = stack.pop();
+ listStack.push(pop);
+ }
+ if (listStack.isEmpty()) {
+ stack.push(separator);
+ return new ListField2("");
+ } else {
+ String name = listStack.pop();
+ while (!listStack.isEmpty()) {
+ name += " " + listStack.pop();
+ }
+ stack.push(separator);
+
+ if (name.equals("thetaProperties")) {
+ return new ThetaListField2(name);
+ } else {
+ return new ListField2(name);
+ }
+ }
+ }
+
+ private void readFields(Stack stack) {
+ Stack fieldStack = new Stack<>();
+ while (!stack.isEmpty() && !isSeparator(stack.peek())) {
+ String pop = stack.pop();
+ fieldStack.push(pop);
+ }
+ if (fieldStack.size() == 0) {
+ // do nothing
+ } else if (fieldStack.size() == 1) {
+ dictionary.add(fieldStack.pop(), "");
+ } else if (fieldStack.size() >= 2) {
+ String key = fieldStack.pop();
+ String value = fieldStack.pop();
+ while (!fieldStack.isEmpty()) {
+ value += " " + fieldStack.pop();
+ }
+
+ if (readDimensionedScalar(key + " " + value)) {
+ return;
+ }
+
+ if (isMultiple(key)) {
+ String[] keys = extractMultipleKeys(key);
+ for (String k : keys) {
+ if (isGeneric(withDoubleQuotes(k))) {
+ dictionary.addGeneric(withDoubleQuotes(k), value);
+ } else {
+ dictionary.add(k, value);
+ }
+ }
+ } else if (isGeneric(key)) {
+ dictionary.addGeneric(key, value);
+ } else if (isLink(value)) {
+ extractLink(key, value);
+ } else {
+ dictionary.add(key, value);
+ }
+ }
+ }
+
+ static boolean isSeparator(String token) {
+ return token.equals("{") || token.equals("}") || token.equals("(") || token.equals(")") || token.equals(";");
+ }
+
+ private boolean readDimensionedScalar(String field) {
+ try {
+ dictionary.add(new DimensionedScalar(field));
+ return true;
+ } catch (DictionaryException e) {
+ return false;
+ }
+ }
+
+ private String withDoubleQuotes(String k) {
+ return "\"" + k + "\"";
+ }
+
+ public static String[] extractMultipleKeys(String key) {
+ key = key.replace("\"", "");
+
+ if (key.contains("(") && key.contains(")")) {
+ int start = key.indexOf("(");
+ int end = key.indexOf(")");
+ String header = key.substring(0, start);
+ String footer = key.substring(end + 1, key.length());
+ String core = key.substring(start + 1, end);
+
+ String[] tokens = core.split("\\|");
+
+ String[] keys = new String[tokens.length];
+ for (int i = 0; i < keys.length; i++) {
+ keys[i] = header + tokens[i] + footer;
+ }
+ return keys;
+ } else {
+ String[] tokens = key.split("\\|");
+ return tokens;
+ }
+
+ }
+
+ public String cleanGenericKey(String key) {
+ key = key.substring(1, key.length() - 1);
+ key = key.substring(0, key.indexOf(".*"));
+ return key;
+ }
+
+ public boolean isGeneric(String key) {
+ return key.startsWith("\"") && key.endsWith("\"") && key.contains(".*");
+ }
+
+ public boolean isMultiple(String key) {
+ return key.startsWith("\"") && key.endsWith("\"") && key.contains("|");
+ }
+
+ public boolean isLink(String value) {
+ return !value.startsWith("\"") && value.contains("$");
+ }
+
+ private void extractLink(String key, String value) {
+ if (value.startsWith("uniform")) {
+ String link = value.replace("uniform", "").trim();
+ if (link.startsWith("$")) {
+ dictionary.add(VALUE_UNIFORM_LINK + key, link);
+ }
+ } else if (value.startsWith("$")) {
+ dictionary.add(VALUE_LINK + key, value);
+ }
+ }
+
+ private static void printOut(String msg) {
+ if (VERBOSE)
+ System.out.println("[DICT] " + msg);
+ }
+
+ public static abstract class Rewriter {
+ private Pattern pattern;
+ private Matcher matcher;
+
+ public Rewriter(String regex) {
+ this.pattern = Pattern.compile(regex);
+ }
+
+ public String group(int i) {
+ return matcher.group(i);
+ }
+
+ public abstract String replacement();
+
+ public String rewrite(CharSequence original) {
+ this.matcher = pattern.matcher(original);
+ StringBuffer result = new StringBuffer(original.length());
+ while (matcher.find()) {
+ matcher.appendReplacement(result, "");
+ result.append(replacement());
+ }
+ matcher.appendTail(result);
+ return result.toString();
+ }
+
+ }
+}
diff --git a/src/eu/engys/core/dictionary/parser/ListField2.java b/src/eu/engys/core/dictionary/parser/ListField2.java
new file mode 100644
index 0000000..52a04c1
--- /dev/null
+++ b/src/eu/engys/core/dictionary/parser/ListField2.java
@@ -0,0 +1,361 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.core.dictionary.parser;
+
+import static eu.engys.core.dictionary.Dictionary.SPACER;
+import static eu.engys.core.dictionary.Dictionary.TAB;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import org.apache.commons.lang.math.NumberUtils;
+
+import com.google.common.primitives.Doubles;
+
+import eu.engys.core.dictionary.DefaultElement;
+import eu.engys.core.dictionary.Dictionary;
+import eu.engys.core.dictionary.DictionaryWriter;
+import eu.engys.core.dictionary.FieldElement;
+
+public class ListField2 extends DefaultElement {
+
+ private List listElements = new ArrayList();
+ private int size;
+ private String uniformity = "";
+ private String identifier = "";
+
+ public ListField2(String name) {
+ super(name);
+ decodeName(name);
+ }
+
+ public boolean isEmpty() {
+ return listElements.isEmpty();
+ }
+
+ public ListField2(ListField2 lf) {
+ super(lf.getName());
+ for (DefaultElement el : lf.getListElements()) {
+ if (el instanceof Dictionary) {
+ add(new Dictionary((Dictionary) el));
+ } else if (el instanceof ListField2) {
+ add(new ListField2((ListField2) el));
+ } else if (el instanceof FieldElement) {
+ add(new FieldElement((FieldElement) el));
+ } else {
+ System.err.println("ListField2: only dictionaries are allowed as elements " + el.getName());
+ }
+ }
+ this.size = lf.size;
+ this.uniformity = lf.uniformity;
+ this.identifier = lf.identifier;
+ }
+
+ private void decodeName(String name) {
+ if (name.contains(SPACER)) {
+ StringTokenizer tokenizer = new StringTokenizer(name, SPACER);
+ if (tokenizer.countTokens() == 1) { // internalField (...); oppure
+ // 10 (...);
+// System.out.println("ListField2.decodeName() 1");
+ String token = tokenizer.nextToken();
+ try {
+ this.size = Integer.parseInt(token);
+ setName("");
+ } catch (NumberFormatException ex) {
+ this.size = -1;
+ setName(token);
+ }
+ this.uniformity = "";
+ this.identifier = "";
+ } else if (tokenizer.countTokens() == 2) {// internalField 10 (...);
+ String token1 = tokenizer.nextToken();
+ String token2 = tokenizer.nextToken();
+// System.out.println("ListField2.decodeName() token1: [" + token1 + "], token2: [" + token2 + "]");
+
+ try {
+ this.size = Integer.parseInt(token2);
+ } catch (NumberFormatException ex) {
+ this.size = -1;
+ }
+ if(size < 0){
+ setName(token1 + " " + token2);
+ } else {
+ setName(token1);
+ }
+ this.uniformity = "";
+ this.identifier = "";
+ } else if (tokenizer.countTokens() == 3) {// internalField
+ // nonuniform 0()
+// System.out.println("ListField2.decodeName() 3");
+ String token1 = tokenizer.nextToken();
+ String token2 = tokenizer.nextToken();
+ String token3 = tokenizer.nextToken();
+// System.out.println("ListField2.decodeName() token1 = '" + token1 + "'");
+// System.out.println("ListField2.decodeName() token2 = '" + token2 + "'");
+// System.out.println("ListField2.decodeName() token3 = '" + token3 + "'");
+ try {
+ this.size = Integer.parseInt(token3);
+ } catch (NumberFormatException ex) {
+ this.size = -1;
+ }
+ setName(token1);
+ this.uniformity = token2;
+ this.identifier = "";
+ } else if (tokenizer.countTokens() == 4) { // internalField
+ // nonuniform
+ // List 10
+// System.out.println("ListField2.decodeName() 4");
+ String token1 = tokenizer.nextToken();
+ String token2 = tokenizer.nextToken();
+ String token3 = tokenizer.nextToken();
+ String token4 = tokenizer.nextToken();
+ try {
+ this.size = Integer.parseInt(token4);
+ } catch (NumberFormatException ex) {
+ this.size = -1;
+ }
+ setName(token1);
+ this.uniformity = token2;
+ this.identifier = token3;
+ }
+ } else {
+ try {
+ this.size = Integer.parseInt(name);
+ setName(Integer.toString(hashCode()));
+ } catch (NumberFormatException ex) {
+ this.size = -1;
+ setName(name);
+ }
+ }
+ }
+
+ public void add(DefaultElement element) {
+ listElements.add(element);
+ }
+
+ public void add(Collection elements) {
+ listElements.addAll(elements);
+ }
+
+ public void add(String... values) {
+ for (String value : values) {
+ listElements.add(new FieldElement("", value));
+ }
+ }
+
+ public List getListElements() {
+ return Collections.unmodifiableList(listElements);
+ }
+
+ public void removeTopElements(int n) {
+ for (int i = 0; i < n; i++) {
+ listElements.remove(0);
+ }
+ }
+
+ public void merge(ListField2 l) {
+ for (DefaultElement el : l.getListElements()) {
+ if (!containsElement(el)) {
+ add(el);
+ } else {
+ }
+ }
+ }
+
+ private boolean containsElement(DefaultElement element) {
+ if (element instanceof FieldElement) {
+ return false;
+ }
+ for (DefaultElement e : listElements) {
+ if (haveSameName(element, e) && e.equals(element)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ protected boolean haveSameName(DefaultElement element, DefaultElement e) {
+ return e.getName().equals(element.getName());
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof ListField2) {
+ ListField2 list = (ListField2) obj;
+ boolean haveSameName = haveSameName(this, list);
+// boolean equalCollection = CollectionUtils.isEqualCollection(list.getListElements(), listElements);
+ boolean equalCollection = list.getListElements().containsAll(listElements) && listElements.containsAll(list.getListElements());
+ return haveSameName && equalCollection;
+ }
+ return false;
+ }
+
+ public void writeListField(StringBuffer sb, String rowHeader) {
+// System.out.println("ListField2.writeListField() name: "+getName()+", size: "+size+", uniformity: "+uniformity+", identifier: "+identifier);
+ sb.append("\n");
+ sb.append(rowHeader);
+ sb.append(TAB);
+ writeName(sb);
+ sb.append(SPACER);
+ sb.append(uniformity);
+ sb.append(SPACER);
+ sb.append(identifier);
+ if (size >= 0 && !identifier.isEmpty()) {
+ sb.append(SPACER);
+ sb.append(size);
+ } else if (size == 0 && isNonuniform()) {
+ sb.append(SPACER);
+ sb.append("0();");
+ return;
+ }
+ if (!getName().isEmpty()) {
+ sb.append("\n");
+ sb.append(rowHeader);
+ sb.append(TAB);
+ }
+ sb.append("(");
+ for (DefaultElement el : getListElements()) {
+ DictionaryWriter.writeElement(sb, rowHeader, el);
+ }
+ if (!getName().isEmpty()) {
+ sb.append("\n");
+ sb.append(rowHeader);
+ sb.append(TAB);
+ sb.append(");");
+ } else {
+ sb.append(")");
+ }
+ }
+
+ public boolean nameIsANumber() {
+ String name = getName();
+ return NumberUtils.isNumber(name);
+ }
+
+ private void writeName(StringBuffer sb) {
+ String name = getName();
+ if (NumberUtils.isNumber(name)) {
+ sb.append("");
+ } else {
+ sb.append(name);
+ }
+ }
+
+ public void writeListDict(StringBuffer sb, String rowHeader) {
+ sb.append(uniformity);
+ sb.append(identifier);
+ sb.append("\n");
+ sb.append(rowHeader);
+ writeName(sb);
+ sb.append("\n");
+ sb.append(rowHeader);
+ sb.append(TAB);
+ sb.append(listElements.size());
+ sb.append("\n");
+ sb.append(rowHeader);
+ sb.append(TAB);
+ sb.append("(");
+ for (DefaultElement el : getListElements()) {
+ DictionaryWriter.writeElement(sb, rowHeader, el);
+ }
+ sb.append("\n");
+ sb.append(rowHeader);
+ sb.append(TAB);
+ sb.append(")");
+ }
+
+ public Dictionary getDictionary(String name) {
+ for (DefaultElement e : listElements) {
+ if (e instanceof Dictionary && !e.getName().isEmpty() && e.getName().equals(name)) {
+ return (Dictionary) e;
+ }
+ }
+ return null;
+ }
+
+ public void setListSize(int size2) {
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ writeListField(sb, "");
+ return sb.toString();
+ }
+
+ public boolean isNonuniform() {
+ return uniformity.equals("nonuniform");
+ }
+
+ public static String convertToString(ListField2 listField) {
+ StringBuilder sb = new StringBuilder();
+ convertToString(listField, sb);
+ return sb.toString();
+ }
+
+ private static void convertToString(ListField2 listField, StringBuilder sb) {
+ sb.append("(");
+ for (DefaultElement el : listField.getListElements()) {
+ if(el instanceof FieldElement){
+ sb.append(((FieldElement) el).getValue());
+ sb.append(" ");
+ } else if(el instanceof ListField2){
+ convertToString((ListField2)el, sb);
+ }
+ }
+ sb.append(")");
+ }
+
+ public List getElementsAsScalarList() {
+ List list = new ArrayList<>();
+ for (DefaultElement e : listElements) {
+ if (e instanceof FieldElement && e.getName().isEmpty()) {
+ String value = ((FieldElement) e).getValue();
+ try {
+ list.add(Double.parseDouble(value));
+ } catch (NumberFormatException ex) {
+ }
+ }
+ }
+ return list;
+ }
+
+ public List getElementsAsVectorList() {
+ List list = new ArrayList<>();
+ for (DefaultElement e : listElements) {
+ if (e instanceof ListField2 && e.getName().isEmpty()) {
+ List value = ((ListField2) e).getElementsAsScalarList();
+ list.add(Doubles.toArray(value));
+ }
+ }
+ return list;
+ }
+
+}
diff --git a/src/eu/engys/core/dictionary/parser/ListReader2.java b/src/eu/engys/core/dictionary/parser/ListReader2.java
new file mode 100644
index 0000000..132f7c7
--- /dev/null
+++ b/src/eu/engys/core/dictionary/parser/ListReader2.java
@@ -0,0 +1,420 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+
+package eu.engys.core.dictionary.parser;
+
+import static eu.engys.core.dictionary.Dictionary.VERBOSE;
+import static eu.engys.core.dictionary.parser.DictionaryReader2.DICTIONARY_END;
+import static eu.engys.core.dictionary.parser.DictionaryReader2.DICTIONARY_START;
+import static eu.engys.core.dictionary.parser.DictionaryReader2.FIELD_END;
+import static eu.engys.core.dictionary.parser.DictionaryReader2.LIST_END;
+import static eu.engys.core.dictionary.parser.DictionaryReader2.LIST_START;
+
+import java.util.List;
+import java.util.Stack;
+import java.util.StringTokenizer;
+
+import eu.engys.core.dictionary.Dictionary;
+import eu.engys.core.dictionary.FieldElement;
+
+class ListReader2 {
+
+ private final ListField2 list;
+ private final boolean subList;
+
+ public ListReader2(ListField2 list, boolean subList) {
+ this.list = list;
+ this.subList = subList;
+ }
+
+ public boolean readList(StringTokenizer st, Stack stack) {
+ while (st.hasMoreTokens()) {
+ String token = st.nextToken();
+ stack.push(token);
+
+ printOut("TOKEN: " + token);
+
+ if (stack.peek().equals(DICTIONARY_START)) {
+ stack.pop();
+ String name = (stack.isEmpty() || stack.peek().equals(LIST_START) || stack.peek().equals(LIST_END)) ? "" : stack.pop();
+ Dictionary d = new Dictionary(name);
+ printOut("START LIST DICTIONARY: " + name);
+
+ new DictionaryReader2(d).readDictionary(st, stack);
+ list.add(d);
+ } else if (stack.peek().equals(DICTIONARY_END)) {
+ /* should not happen ! */
+ } else if (stack.peek().equals(LIST_START)) {
+ printOut("START SUB LIST");
+ processStack(stack);
+
+ ListField2 child = new ListField2("");
+ ListReader2 reader = new ListReader2(child, true);
+ reader.readList(st, stack);
+ list.add(child);
+ printOut("ADDING CHILD: " + child);
+ } else if (stack.peek().equals(LIST_END)) {
+ if (subList) {
+ printOut("END SUB LIST");
+ return processStack(stack);
+ }
+ } else if (stack.peek().equals(FIELD_END)) {
+ printOut("FIELD_END");
+ stack.pop(); // ;
+
+ if (stack.peek().equals(LIST_END)) {
+ return processStack(stack);
+ } else {
+ // throw new
+ // RuntimeException("finisce il field ma non la lista");
+ /* forse qui non si arriva mai ? */
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ private boolean processStack(Stack stack) {
+ printOut("-BEGIN PROCESS STACK: " + stackToString(stack));
+ boolean success = false;
+ if (containsBox(stack)) {
+ printOut("-PROCESS STACK BOX");
+ // readBox(stack);
+ success = false;
+ } else if (containsMatrix(stack)) {
+ printOut("-PROCESS STACK MATRIX");
+ readMatrix(stack);
+ success = true;
+ } else if (containsVector(stack)) {
+ printOut("-PROCESS STACK VECTOR");
+ readVector(stack);
+ success = true;
+ } else if (containsScalar(stack)) {
+ printOut("-PROCESS STACK SCALAR");
+ readScalar(stack);
+ success = true;
+ } else if (containsWord(stack)) {
+ printOut("-PROCESS STACK WORD");
+ readWord(stack);
+ success = true;
+ } else if (contains2Words(stack)) {
+ printOut("-PROCESS STACK 2 WORDS");
+ read2Words(stack);
+ success = true;
+ } else if (containsScalarList(stack)) {
+ printOut("-PROCESS STACK SCALAR LIST");
+ readScalarList(stack);
+ success = true;
+ } else {
+ printOut("-PROCESS STACK NOT RECOGNIZED");
+ success = false;
+ }
+ printOut("-END PROCESS STACK");
+ return success;
+ }
+
+ private static boolean isNumeric(String str) {
+ try {
+ Double.parseDouble(str);
+ } catch (NumberFormatException nfe) {
+ return false;
+ }
+ return true;
+ }
+
+ private static boolean isWord(String str) {
+ for (char c : str.toCharArray()) {
+ if(!isValid(c)){
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private static boolean isValid(char c) {
+ return Character.isLetterOrDigit(c) || c == '_' || c == '-';
+ }
+
+ private String stackToString(Stack stack) {
+ StringBuilder sb = new StringBuilder();
+ for (String s : stack) {
+ sb.append(s + ",");
+ }
+ return sb.toString();
+ }
+
+ private boolean containsBox(Stack stack) {
+ int counter = 0, start = 0, end = 0, max = 0;
+ for (int i = stack.size() - 1; i >= 0; i--) {
+ String s = stack.get(i);
+
+ if (s.equals(LIST_START)) {
+ counter--;
+ start++;
+ }
+ if (s.equals(LIST_END)) {
+ counter++;
+ end++;
+ }
+
+ max = Math.max(max, counter);
+
+ if (counter == 0 && max == 1 && start == 2 && end == 2) {
+ printOut("Contains BOX");
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // private void readBox(Stack stack) {
+ // int start = getListStart(stack, 2);
+ // int end = getListEnd(stack, );
+ // List subList = stack.subList(start, end);
+ // for (String item : subList) {
+ // if (item.equals(LIST_START) || item.equals(LIST_END) ) continue;
+ // list.add(new FieldElement("", item));
+ // }
+ // subList.clear();
+ // }
+
+ private boolean containsWord(Stack stack) {
+ String list_start = stack.pop(); // could be a LIST_START
+ String word = stack.pop(); // token to analyze
+ if (!stack.isEmpty() && stack.peek().equals(LIST_START)) {
+ stack.push(word);
+ stack.push(list_start);
+ if (isWord(word)) {
+ printOut("Contains WORD");
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ stack.push(word);
+ stack.push(list_start);
+ return false;
+ }
+ }
+
+ private boolean contains2Words(Stack stack) {
+ String list_start = stack.pop(); // could be a LIST_START
+ String word1 = stack.pop(); // token to analyze
+ if(!stack.isEmpty()){
+ String word2 = stack.pop(); // token to analyze
+ if (!stack.isEmpty() && stack.peek().equals(LIST_START)) {
+ stack.push(word2);
+ stack.push(word1);
+ stack.push(list_start);
+ if (isWord(word1) && isWord(word2)) {
+ printOut("Contains TWO WORDS");
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ stack.push(word2);
+ stack.push(word1);
+ stack.push(list_start);
+ return false;
+ }
+ }
+ stack.push(word1);
+ stack.push(list_start);
+ return false;
+ }
+
+ private boolean containsScalar(Stack stack) {
+ String list_start = stack.pop(); // could be a LIST_START
+ String scalar = stack.pop(); // token to analyze
+ if (!stack.isEmpty() && stack.peek().equals(LIST_START)) {
+ stack.push(scalar);
+ stack.push(list_start);
+ if (isNumeric(scalar)) {
+ printOut("Contains SCALAR");
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ stack.push(scalar);
+ stack.push(list_start);
+ return false;
+ }
+ }
+
+ private void readScalarList(Stack stack) {
+ int start = 1;
+ int end = stack.size() - 1;
+ List subList = stack.subList(start, end);
+ for (String item : subList) {
+ if (item.equals(LIST_START) || item.equals(LIST_END))
+ continue;
+ list.add(new FieldElement("", item));
+ }
+ subList.clear();
+ }
+
+ private void readScalar(Stack stack) {
+ String pop = stack.pop();
+ String s = stack.pop();
+ stack.push(pop);
+ list.add(new FieldElement("", s));
+ }
+
+ private void readWord(Stack stack) {
+ String pop = stack.pop();//should be list start
+ String s = stack.pop();
+ stack.push(pop);
+ list.add(new FieldElement("", s));
+ }
+
+ private void read2Words(Stack stack) {
+ String pop = stack.pop();//should be list start
+ String w1 = stack.pop();
+ String w2 = stack.pop();
+ stack.push(pop);
+ list.add(new FieldElement("", w2));
+ list.add(new FieldElement("", w1));
+ }
+
+ private boolean containsScalarList(List stack) {
+ if (stack.get(0).equals(LIST_START)) {
+ if (stack.get(stack.size() - 1).equals(LIST_START)) {
+ if (stack.size() > 2) {
+ for (int i = stack.size() - 2; i > 0; i--) {
+ if (!isNumeric(stack.get(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ private boolean containsVector(List stack) {
+ int counter = 0, max = 0;
+ for (int i = stack.size() - 1; i >= 0; i--) {
+ String s = stack.get(i);
+
+ if (s.equals(LIST_START))
+ counter--;
+ if (s.equals(LIST_END))
+ counter++;
+
+ max = Math.max(max, counter);
+
+ if (counter == 0 && max == 1) {
+ printOut("-Contains VECTOR");
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void readVector(Stack stack) {
+ int start = getListStart(stack);
+ int end = getListEnd(stack);
+ List subList = stack.subList(start, end);
+ for (String item : subList) {
+ if (item.equals(LIST_START) || item.equals(LIST_END))
+ continue;
+ list.add(new FieldElement("", item));
+ }
+ subList.clear();
+ }
+
+ private int getListStart(List stack) {
+ for (int i = stack.size() - 1; i >= 0; i--) {
+ String s = stack.get(i);
+ if (s.equals(LIST_START))
+ return i;
+ }
+ return -1;
+ }
+
+ private int getListEnd(List stack) {
+ for (int i = stack.size() - 1; i >= 0; i--) {
+ String s = stack.get(i);
+ if (s.equals(LIST_END))
+ return i + 1;
+ }
+ return -1;
+ }
+
+ private boolean containsMatrix(List stack) {
+ int start = 0, end = 0, level = 0, max = 0;
+ for (String s : stack) {
+ if (s.equals(LIST_START)) {
+ start++;
+ level++;
+ }
+ if (s.equals(LIST_END)) {
+ end++;
+ level--;
+ }
+ max = Math.max(max, level);
+ }
+ return start == end && max == 2;
+ }
+
+ private void readMatrix(List stackList) {
+ ListField2 child = null;
+ for (String item : stackList) {
+ if (item.equals(LIST_START) && child == null) {
+ child = new ListField2("");
+ list.add(child);
+ continue;
+ }
+ if (item.equals(LIST_END) && child != null) {
+ child = null;
+ continue;
+ }
+ if (item.equals(LIST_START) || item.equals(LIST_END))
+ continue;
+ child.add(new FieldElement("", item));
+ }
+ }
+
+ private String processField(String field) {
+ if (field.contains("|")) {
+ field = field.replace("|", ") (");
+ }
+ return field;
+ }
+
+ private static void printOut(String msg) {
+ if (VERBOSE)
+ System.out.println("[LIST] " + msg);
+ }
+}
diff --git a/src/eu/engys/core/dictionary/parser/ThetaListField2.java b/src/eu/engys/core/dictionary/parser/ThetaListField2.java
new file mode 100644
index 0000000..3bd9e08
--- /dev/null
+++ b/src/eu/engys/core/dictionary/parser/ThetaListField2.java
@@ -0,0 +1,93 @@
+/*--------------------------------*- Java -*---------------------------------*\
+ | o |
+ | o o | HelyxOS: The Open Source GUI for OpenFOAM |
+ | o O o | Copyright (C) 2012-2016 ENGYS |
+ | o o | http://www.engys.com |
+ | o | |
+ |---------------------------------------------------------------------------|
+ | License |
+ | This file is part of HelyxOS. |
+ | |
+ | HelyxOS 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. |
+ | |
+ | HelyxOS 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 HelyxOS; if not, write to the Free Software Foundation, |
+ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
+\*---------------------------------------------------------------------------*/
+
+package eu.engys.core.dictionary.parser;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import eu.engys.core.dictionary.DefaultElement;
+import eu.engys.core.dictionary.FieldElement;
+import eu.engys.core.dictionary.TableRowElement;
+
+public class ThetaListField2 extends ListField2 {
+
+ public ThetaListField2(String name) {
+ super(name);
+ }
+
+ public ThetaListField2(ThetaListField2 tf) {
+ super(tf.getName());
+ for (DefaultElement el : tf.getListElements()) {
+ if (el instanceof TableRowElement) {
+ add(new TableRowElement((TableRowElement) el));
+ } else {
+ System.err.println("ThetaListField2: only TableRowElement are allowed as elements");
+ }
+ }
+ }
+
+ public void merge(ListField2 l) {
+ if (l instanceof ThetaListField2) {
+ for (DefaultElement el : l.getListElements()) {
+ DefaultElement this_el = containsElement(el);
+
+ if (this_el == null) {
+ add(el);
+ } else {
+ if (this_el instanceof TableRowElement) {
+ if (el instanceof TableRowElement) {
+ ((TableRowElement) this_el).merge((TableRowElement) el);
+ }
+ }
+ }
+ }
+ } else {
+ super.merge(l);
+ }
+ }
+
+ private DefaultElement containsElement(DefaultElement element) {
+ if (element instanceof FieldElement) {
+ return null;
+ }
+ for (DefaultElement e : getListElements()) {
+ if (haveSameName(element, e) && e.equals(element)) {
+ return e;
+ }
+ }
+ return null;
+ }
+
+ public List getRows() {
+ List