diff --git a/de.bmotionstudio.gef.editor/.classpath b/de.bmotionstudio.gef.editor/.classpath new file mode 100644 index 0000000000000000000000000000000000000000..1650e61be9f7cdd29178addcb2696b1962d4e5ef --- /dev/null +++ b/de.bmotionstudio.gef.editor/.classpath @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="src" path="src"/> + <classpathentry exported="true" kind="lib" path="lib/ext/xpp3_min-1.1.4c.jar"/> + <classpathentry exported="true" kind="lib" path="lib/ext/xstream-1.3.1.jar" sourcepath="D:/xstream-distribution-1.3.1-src.zip"/> + <classpathentry exported="true" kind="lib" path="lib/ext/animation-1.2.0.jar"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/de.bmotionstudio.gef.editor/.project b/de.bmotionstudio.gef.editor/.project new file mode 100644 index 0000000000000000000000000000000000000000..5b47a81f892de4a2a747c3084f04e161bff4cb17 --- /dev/null +++ b/de.bmotionstudio.gef.editor/.project @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>de.bmotionstudio.gef.editor</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/de.bmotionstudio.gef.editor/META-INF/MANIFEST.MF b/de.bmotionstudio.gef.editor/META-INF/MANIFEST.MF new file mode 100644 index 0000000000000000000000000000000000000000..5c0dbcd26fb0558ca16469a195dc5a69914746f4 --- /dev/null +++ b/de.bmotionstudio.gef.editor/META-INF/MANIFEST.MF @@ -0,0 +1,60 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: BMotion Studio Editor Plug-in +Bundle-SymbolicName: de.bmotionstudio.gef.editor;singleton:=true +Bundle-Version: 5.2.0 +Bundle-Activator: de.bmotionstudio.gef.editor.BMotionEditorPlugin +Require-Bundle: org.eclipse.ui;bundle-version="[3.5.0,4.0.0)", + org.eclipse.ui.ide;bundle-version="[3.5.0,4.0.0)", + org.eclipse.ui.views;bundle-version="[3.5.0,4.0.0)", + org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", + org.eclipse.jface;bundle-version="[3.5.0,4.0.0)", + org.eclipse.core.databinding;bundle-version="[1.2.0,2.0.0)", + org.eclipse.jface.databinding;bundle-version="[1.2.1,2.0.0)", + org.eclipse.core.databinding.beans;bundle-version="[1.1.1,2.0.0)", + org.eclipse.gef;bundle-version="[3.7.0,4.0.0)", + de.prob.core;bundle-version="[9.1.0,9.2.0)", + org.eventb.core;bundle-version="[2.1.0,2.4.0)" +Bundle-ActivationPolicy: lazy +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Eclipse-BuddyPolicy: registered +Bundle-Vendor: HHU Düsseldorf STUPS Group +Export-Package: com.thoughtworks.xstream, + com.thoughtworks.xstream.alias, + com.thoughtworks.xstream.annotations, + com.thoughtworks.xstream.converters, + com.thoughtworks.xstream.converters.basic, + com.thoughtworks.xstream.converters.collections, + com.thoughtworks.xstream.converters.enums, + com.thoughtworks.xstream.converters.extended, + com.thoughtworks.xstream.converters.javabean, + com.thoughtworks.xstream.converters.reflection, + com.thoughtworks.xstream.core, + com.thoughtworks.xstream.core.util, + com.thoughtworks.xstream.io, + com.thoughtworks.xstream.io.binary, + com.thoughtworks.xstream.io.copy, + com.thoughtworks.xstream.io.json, + com.thoughtworks.xstream.io.path, + com.thoughtworks.xstream.io.xml, + com.thoughtworks.xstream.io.xml.xppdom, + com.thoughtworks.xstream.mapper, + com.thoughtworks.xstream.persistence, + de.bmotionstudio.gef.editor, + de.bmotionstudio.gef.editor.attribute, + de.bmotionstudio.gef.editor.command, + de.bmotionstudio.gef.editor.edit, + de.bmotionstudio.gef.editor.editpolicy, + de.bmotionstudio.gef.editor.figure, + de.bmotionstudio.gef.editor.library, + de.bmotionstudio.gef.editor.eventb, + de.bmotionstudio.gef.editor.model, + de.bmotionstudio.gef.editor.observer, + de.bmotionstudio.gef.editor.part, + de.bmotionstudio.gef.editor.property, + de.bmotionstudio.gef.editor.scheduler, + de.bmotionstudio.gef.editor.util +Bundle-ClassPath: lib/ext/xpp3_min-1.1.4c.jar, + lib/ext/xstream-1.3.1.jar, + lib/ext/animation-1.2.0.jar, + . diff --git a/de.bmotionstudio.gef.editor/build.properties b/de.bmotionstudio.gef.editor/build.properties new file mode 100644 index 0000000000000000000000000000000000000000..f09a47a63b1eb6bf2a17335833018109364659b8 --- /dev/null +++ b/de.bmotionstudio.gef.editor/build.properties @@ -0,0 +1,9 @@ +source.. = src/ +output.. = bin/ +bin.includes = plugin.xml,\ + META-INF/,\ + .,\ + icons/,\ + schema/,\ + lib/ + diff --git a/de.bmotionstudio.gef.editor/icons/icon_add.gif b/de.bmotionstudio.gef.editor/icons/icon_add.gif new file mode 100644 index 0000000000000000000000000000000000000000..1b0630841412d754fd6546e33923ad1ac08a2a9b Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_add.gif differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_ascript.png b/de.bmotionstudio.gef.editor/icons/icon_ascript.png new file mode 100644 index 0000000000000000000000000000000000000000..4cd71dba209ec693a58b14e7351873b374080988 Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_ascript.png differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_bringtobottom.gif b/de.bmotionstudio.gef.editor/icons/icon_bringtobottom.gif new file mode 100644 index 0000000000000000000000000000000000000000..274f6f0dfcb2aa75701585a99b4e03c2289d008f Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_bringtobottom.gif differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_bringtobottomstep.gif b/de.bmotionstudio.gef.editor/icons/icon_bringtobottomstep.gif new file mode 100644 index 0000000000000000000000000000000000000000..80b09d8774d1377f7abbdc59b8421781f306ae0c Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_bringtobottomstep.gif differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_bringtotop.gif b/de.bmotionstudio.gef.editor/icons/icon_bringtotop.gif new file mode 100644 index 0000000000000000000000000000000000000000..20d2a1527a77b343e2fdcc9f5c68ba14ef3713f8 Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_bringtotop.gif differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_bringtotopstep.gif b/de.bmotionstudio.gef.editor/icons/icon_bringtotopstep.gif new file mode 100644 index 0000000000000000000000000000000000000000..a1631a01d725320c62d59798c8c5e80997b74288 Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_bringtotopstep.gif differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_button.gif b/de.bmotionstudio.gef.editor/icons/icon_button.gif new file mode 100644 index 0000000000000000000000000000000000000000..d143fcf6213917833ea4b7a97bc919b3ff390760 Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_button.gif differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_canister.gif b/de.bmotionstudio.gef.editor/icons/icon_canister.gif new file mode 100644 index 0000000000000000000000000000000000000000..f5a20232c661c5afea954c41cb11a8d839e407b2 Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_canister.gif differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_checked.gif b/de.bmotionstudio.gef.editor/icons/icon_checked.gif new file mode 100644 index 0000000000000000000000000000000000000000..736c10c26b6bbff72e95e3948a8393e517e69bb7 Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_checked.gif differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_chop.gif b/de.bmotionstudio.gef.editor/icons/icon_chop.gif new file mode 100644 index 0000000000000000000000000000000000000000..2f31078580a5fd2b14266cdb38113d45edde1860 Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_chop.gif differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_composite.gif b/de.bmotionstudio.gef.editor/icons/icon_composite.gif new file mode 100644 index 0000000000000000000000000000000000000000..3e53cbdc5fc65bfd4f7178bf328195067ae8b7f1 Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_composite.gif differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_connection16.gif b/de.bmotionstudio.gef.editor/icons/icon_connection16.gif new file mode 100644 index 0000000000000000000000000000000000000000..ad8a17bd966f76efbe9858624ba1601b04d58551 Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_connection16.gif differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_connection24.gif b/de.bmotionstudio.gef.editor/icons/icon_connection24.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e7b81bd730dc1d515384d38075f821ed88c0465 Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_connection24.gif differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_delete.gif b/de.bmotionstudio.gef.editor/icons/icon_delete.gif new file mode 100644 index 0000000000000000000000000000000000000000..d30e0a88951416b6abccadc815c3369ad0691538 Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_delete.gif differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_delete21.png b/de.bmotionstudio.gef.editor/icons/icon_delete21.png new file mode 100644 index 0000000000000000000000000000000000000000..1dca7e3b8a598e61b8cdef2d8d8c484a933385f7 Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_delete21.png differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_down.gif b/de.bmotionstudio.gef.editor/icons/icon_down.gif new file mode 100644 index 0000000000000000000000000000000000000000..c595aae874c758052a5960501a8ce3fe6f3cb71b Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_down.gif differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_edit.gif b/de.bmotionstudio.gef.editor/icons/icon_edit.gif new file mode 100644 index 0000000000000000000000000000000000000000..30dfbf3a509ccfe533222d8fd98c48deec2694eb Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_edit.gif differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_ellipse.gif b/de.bmotionstudio.gef.editor/icons/icon_ellipse.gif new file mode 100644 index 0000000000000000000000000000000000000000..03f9cdc690afae277578c05db682257e586d34bd Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_ellipse.gif differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_error.png b/de.bmotionstudio.gef.editor/icons/icon_error.png new file mode 100644 index 0000000000000000000000000000000000000000..b1b788b24ce94febf1b0857cd54274bf75fdeb70 Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_error.png differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_event.png b/de.bmotionstudio.gef.editor/icons/icon_event.png new file mode 100644 index 0000000000000000000000000000000000000000..67de2c6ccbeac17742f56cf7391e72b2bf5033ba Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_event.png differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_fitimage.png b/de.bmotionstudio.gef.editor/icons/icon_fitimage.png new file mode 100644 index 0000000000000000000000000000000000000000..c8b041f3202f0094c7591e713e7b4efc2570f1c9 Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_fitimage.png differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_gif.gif b/de.bmotionstudio.gef.editor/icons/icon_gif.gif new file mode 100644 index 0000000000000000000000000000000000000000..f7c3ddbd01a13f5aaf1f33f8eb796479292d374c Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_gif.gif differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_image.gif b/de.bmotionstudio.gef.editor/icons/icon_image.gif new file mode 100644 index 0000000000000000000000000000000000000000..dc62a3fdb2317025335a438971282867c1149435 Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_image.gif differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_jpg.gif b/de.bmotionstudio.gef.editor/icons/icon_jpg.gif new file mode 100644 index 0000000000000000000000000000000000000000..bfa0f0bf67c1f2797b78af9fafa4f180ebe731cf Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_jpg.gif differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_label.gif b/de.bmotionstudio.gef.editor/icons/icon_label.gif new file mode 100644 index 0000000000000000000000000000000000000000..cf00ad26ffb8b308cd51369b5544187ba14c8002 Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_label.gif differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_library.gif b/de.bmotionstudio.gef.editor/icons/icon_library.gif new file mode 100644 index 0000000000000000000000000000000000000000..c3b6b7c01ab96bdbb102bb4e258e6e47db60505a Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_library.gif differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_list.gif b/de.bmotionstudio.gef.editor/icons/icon_list.gif new file mode 100644 index 0000000000000000000000000000000000000000..bf1274e2bac99a3bed268e6d003319320dbbe756 Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_list.gif differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_loading.gif b/de.bmotionstudio.gef.editor/icons/icon_loading.gif new file mode 100644 index 0000000000000000000000000000000000000000..9ece7202209fcc92c9f7d64c90c7957b32c51b92 Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_loading.gif differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_motion.gif b/de.bmotionstudio.gef.editor/icons/icon_motion.gif new file mode 100644 index 0000000000000000000000000000000000000000..173d240af99eff66594bbefb1d12d16da8d8b548 Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_motion.gif differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_motion_wiz.gif b/de.bmotionstudio.gef.editor/icons/icon_motion_wiz.gif new file mode 100644 index 0000000000000000000000000000000000000000..1e9bf55a7b95055a4cc8bc7646266c58fb28e45f Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_motion_wiz.gif differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_observer.gif b/de.bmotionstudio.gef.editor/icons/icon_observer.gif new file mode 100644 index 0000000000000000000000000000000000000000..5309f4e683ac4870d85c3aa02856562b143e9bcc Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_observer.gif differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_radiobutton_c.gif b/de.bmotionstudio.gef.editor/icons/icon_radiobutton_c.gif new file mode 100644 index 0000000000000000000000000000000000000000..5287f1e1b60c0ffff79fe13f990083317667efa2 Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_radiobutton_c.gif differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_radiobutton_uc.gif b/de.bmotionstudio.gef.editor/icons/icon_radiobutton_uc.gif new file mode 100644 index 0000000000000000000000000000000000000000..47a8f4c0bb19b3c7e364f4f97f6945a025fdbd7e Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_radiobutton_uc.gif differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_rectangle.gif b/de.bmotionstudio.gef.editor/icons/icon_rectangle.gif new file mode 100644 index 0000000000000000000000000000000000000000..d441c8d0e36c99bfec8bdc39f481bc820c1f88cc Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_rectangle.gif differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_rename.png b/de.bmotionstudio.gef.editor/icons/icon_rename.png new file mode 100644 index 0000000000000000000000000000000000000000..c3d245dece91b62437e6bff4c475b2326fd6d57b Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_rename.png differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_run.png b/de.bmotionstudio.gef.editor/icons/icon_run.png new file mode 100644 index 0000000000000000000000000000000000000000..f5808d2dfd5b042b5584ce1c81aa40835ebc8055 Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_run.png differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_screenshot.gif b/de.bmotionstudio.gef.editor/icons/icon_screenshot.gif new file mode 100644 index 0000000000000000000000000000000000000000..176830af2dc8be87218c4dd944ba7dc6ffb79756 Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_screenshot.gif differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_text.gif b/de.bmotionstudio.gef.editor/icons/icon_text.gif new file mode 100644 index 0000000000000000000000000000000000000000..d7fb3db5d67e8313176e5703b4279df19a8d9050 Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_text.gif differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_textfield.gif b/de.bmotionstudio.gef.editor/icons/icon_textfield.gif new file mode 100644 index 0000000000000000000000000000000000000000..cf20952b60e303848367cf5f8ba874246cac6d1f Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_textfield.gif differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_unchecked.gif b/de.bmotionstudio.gef.editor/icons/icon_unchecked.gif new file mode 100644 index 0000000000000000000000000000000000000000..4f08695cf4a49747fe4b182e3c7d7689051e96f7 Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_unchecked.gif differ diff --git a/de.bmotionstudio.gef.editor/icons/icon_up.gif b/de.bmotionstudio.gef.editor/icons/icon_up.gif new file mode 100644 index 0000000000000000000000000000000000000000..23363997b4716905dd7765b2e33e36dd9b4c4e82 Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/icon_up.gif differ diff --git a/de.bmotionstudio.gef.editor/icons/logo_b.gif b/de.bmotionstudio.gef.editor/icons/logo_b.gif new file mode 100644 index 0000000000000000000000000000000000000000..8edac4c3f2cb3d5099e20f72122f635dfb926412 Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/logo_b.gif differ diff --git a/de.bmotionstudio.gef.editor/icons/logo_bmotion.png b/de.bmotionstudio.gef.editor/icons/logo_bmotion.png new file mode 100644 index 0000000000000000000000000000000000000000..2bcb148a75ce4d1f5d9257033306b5b12b5d295d Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/logo_bmotion.png differ diff --git a/de.bmotionstudio.gef.editor/icons/logo_bmotion_64.png b/de.bmotionstudio.gef.editor/icons/logo_bmotion_64.png new file mode 100644 index 0000000000000000000000000000000000000000..917f1edbec667ba7488922b1a6483963a13d306c Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/logo_bmotion_64.png differ diff --git a/de.bmotionstudio.gef.editor/icons/splash.jpg b/de.bmotionstudio.gef.editor/icons/splash.jpg new file mode 100644 index 0000000000000000000000000000000000000000..eda8081079c8b2edf4599d4e0e0b470b85b200cb Binary files /dev/null and b/de.bmotionstudio.gef.editor/icons/splash.jpg differ diff --git a/de.bmotionstudio.gef.editor/lib/ext/animation-1.2.0.jar b/de.bmotionstudio.gef.editor/lib/ext/animation-1.2.0.jar new file mode 100644 index 0000000000000000000000000000000000000000..8b763ca7874bde10b122e7988c525454b04faee1 Binary files /dev/null and b/de.bmotionstudio.gef.editor/lib/ext/animation-1.2.0.jar differ diff --git a/de.bmotionstudio.gef.editor/lib/ext/xpp3_min-1.1.4c.jar b/de.bmotionstudio.gef.editor/lib/ext/xpp3_min-1.1.4c.jar new file mode 100644 index 0000000000000000000000000000000000000000..813a9a830bd0c09bfb45084633ccbe88ba64498f Binary files /dev/null and b/de.bmotionstudio.gef.editor/lib/ext/xpp3_min-1.1.4c.jar differ diff --git a/de.bmotionstudio.gef.editor/lib/ext/xstream-1.3.1.jar b/de.bmotionstudio.gef.editor/lib/ext/xstream-1.3.1.jar new file mode 100644 index 0000000000000000000000000000000000000000..4ef4219c6f62944a898fd5bec4bfeb8671109d5b Binary files /dev/null and b/de.bmotionstudio.gef.editor/lib/ext/xstream-1.3.1.jar differ diff --git a/de.bmotionstudio.gef.editor/plugin.xml b/de.bmotionstudio.gef.editor/plugin.xml new file mode 100644 index 0000000000000000000000000000000000000000..0ee2080e5ad77315a48db9c95a41083dd13e0680 --- /dev/null +++ b/de.bmotionstudio.gef.editor/plugin.xml @@ -0,0 +1,445 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?eclipse version="3.2"?> +<plugin> + <extension-point id="de.bmotionstudio.gef.editor.installActions" name="Install Actions for Editor" schema="schema/de.bmotionstudio.gef.editor.installActions.exsd"/> + <extension-point id="de.bmotionstudio.gef.editor.installMenu" name="Context Menu" schema="schema/de.bmotionstudio.gef.editor.installMenu.exsd"/> + <extension-point id="de.bmotionstudio.gef.editor.control" name="Control" schema="schema/de.bmotionstudio.gef.editor.control.exsd"/> + <extension-point id="de.bmotionstudio.gef.editor.registerImages" name="Register Images" schema="schema/de.bmotionstudio.gef.editor.registerImages.exsd"/> + <extension-point id="de.bmotionstudio.gef.editor.language" name="BMotion Studio Language Loader" schema="schema/de.bmotionstudio.gef.editor.language.exsd"/> + <extension-point id="de.bmotionstudio.gef.editor.schedulerEvent" name="Scheduler Event" schema="schema/de.bmotionstudio.gef.editor.schedulerEvent.exsd"/> + <extension-point id="de.bmotionstudio.gef.editor.observer" name="BMotion Studio Observer" schema="schema/de.bmotionstudio.gef.editor.observer.exsd"/> + <extension-point id="de.bmotionstudio.gef.editor.paletteEntry" name="Add a custom Palette Entry" schema="schema/de.bmotionstudio.gef.editor.paletteEntry.exsd"/> + <extension-point id="de.bmotionstudio.gef.editor.includeObserver" name="Include Observer Extension Point" schema="schema/de.bmotionstudio.gef.editor.includeObserver.exsd"/> + <extension + point="org.eclipse.ui.editors"> + <editor + class="de.bmotionstudio.gef.editor.BMotionStudioEditor" + contributorClass="de.bmotionstudio.gef.editor.BMotionStudioContributor" + default="true" + extensions="bmso" + icon="icons/logo_bmotion.png" + id="de.bmotionstudio.gef.editor.BMotionStudioEditor" + name="BMotion Studio Editor"> + </editor> + </extension> + <extension + point="org.eclipse.ui.newWizards"> + <category + id="de.bmotionstudio.gef.editor.wizards" + name="BMotion Studio"> + </category> + <wizard + category="de.bmotionstudio.gef.editor.wizards" + class="de.bmotionstudio.gef.editor.internal.NewBMotionProjectWizard" + icon="icons/logo_bmotion.png" + id="de.prob.bmotionstudio.NewBMotionProject" + name="BMotion Studio Visualization" + project="false"> + </wizard> + </extension> + <extension + point="org.eclipse.ui.views"> + <category + id="de.bmotionstudio.views" + name="BMotion Studio"> + </category> + <view + allowMultiple="false" + category="de.bmotionstudio.views" + class="de.bmotionstudio.gef.editor.library.LibraryView" + icon="icons/icon_library.gif" + id="de.bmotionstudio.gef.editor.LibraryView" + name="BMS Library"> + </view> + </extension> + <extension + point="org.eclipse.ui.menus"> + <menuContribution + locationURI="menu:org.eclipse.ui.main.menu"> + <menu + id="de.bmotionstudio.gef.editor.menu" + label="BMotion Studio"> + <command + commandId="de.bmotionstudio.gef.editor.command.openBMotionStudioWebsite" + label="Open website" + style="push"> + </command> + <separator + name="group.filter" + visible="true"> + </separator> + <command + commandId="de.bmotionstudio.command.startVisualizationFromEditor" + icon="icons/icon_run.png" + label="Start Visualization" + style="push"> + <visibleWhen + checkEnabled="true"> + <with + variable="activeEditorId"> + <equals + value="de.bmotionstudio.gef.editor.BMotionStudioEditor"> + </equals> + </with> + </visibleWhen> + </command> + </menu> + </menuContribution> + <menuContribution + locationURI="toolbar:org.eclipse.ui.main.toolbar"> + <toolbar + id="de.bmotionstudio.gef.editor.toolbar"> + <command + commandId="de.bmotionstudio.command.startVisualizationFromEditor" + icon="icons/icon_run.png" + label="Start Visualization" + style="push"> + <visibleWhen + checkEnabled="true"> + <with + variable="activeEditorId"> + <equals + value="de.bmotionstudio.gef.editor.BMotionStudioEditor"> + </equals> + </with> + </visibleWhen> + </command> + </toolbar> + </menuContribution> + </extension> + <extension + point="org.eclipse.ui.commands"> + <command + defaultHandler="de.bmotionstudio.gef.editor.internal.OpenWebsiteHandler" + id="de.bmotionstudio.gef.editor.command.openBMotionStudioWebsite" + name="Open website"> + </command> + <command + id="de.bmotionstudio.command.startVisualizationFromEditor" + name="Start Visualization from Editor"> + </command> + <command + defaultHandler="de.bmotionstudio.gef.editor.internal.StartVisualizationFileHandler" + id="de.bmotionstudio.command.startVisualizationFromFile" + name="Start Visualization from File"> + </command> + </extension> + <extension + point="org.eclipse.ui.handlers"> + <handler + class="de.bmotionstudio.gef.editor.internal.StartVisualizationEditorHandler" + commandId="de.bmotionstudio.command.startVisualizationFromEditor"> + <enabledWhen> + <with + variable="activeEditorId"> + <equals + value="de.bmotionstudio.gef.editor.BMotionStudioEditor"> + </equals> + </with> + </enabledWhen> + </handler> + </extension> + <extension + point="de.prob.core.animation"> + <listener + class="de.bmotionstudio.gef.editor.animation.StaticListenerRegistry"> + </listener> + </extension> + <extension + point="de.prob.core.lifecycle"> + <listener + class="de.bmotionstudio.gef.editor.animation.StaticListenerRegistry"> + </listener> + </extension> + <extension + point="de.bmotionstudio.gef.editor.registerImages"> + <registerImages + class="de.bmotionstudio.gef.editor.EditorImageRegistry"> + </registerImages> + </extension> + + <extension + point="de.bmotionstudio.gef.editor.control"> + <group + id="de.bmotionstudio.gef.editor.group.main" + name="Main"> + </group> + <control + groupid="de.bmotionstudio.gef.editor.group.main" + icon="icons/icon_image.gif" + id="de.bmotionstudio.gef.editor.image" + name="Image" + service="de.bmotionstudio.gef.editor.service.BImageService"> + </control> + <control + groupid="de.bmotionstudio.gef.editor.group.main" + icon="icons/icon_button.gif" + id="de.bmotionstudio.gef.editor.button" + name="Button" + service="de.bmotionstudio.gef.editor.service.BButtonService"> + </control> + <control + groupid="de.bmotionstudio.gef.editor.group.main" + icon="icons/icon_radiobutton_c.gif" + id="de.bmotionstudio.gef.editor.radiobutton" + name="Radiobutton" + service="de.bmotionstudio.gef.editor.service.BRadioButtonService"> + </control> + <control + groupid="de.bmotionstudio.gef.editor.group.main" + icon="icons/icon_checked.gif" + id="de.bmotionstudio.gef.editor.checkbox" + name="Checkbox" + service="de.bmotionstudio.gef.editor.service.BCheckboxService"> + </control> + <control + groupid="de.bmotionstudio.gef.editor.group.main" + icon="icons/icon_composite.gif" + id="de.bmotionstudio.gef.editor.composite" + name="Composite" + service="de.bmotionstudio.gef.editor.service.BCompositeService"> + </control> + <control + groupid="de.bmotionstudio.gef.editor.group.main" + icon="icons/icon_text.gif" + id="de.bmotionstudio.gef.editor.text" + name="Text" + service="de.bmotionstudio.gef.editor.service.BTextService"> + </control> + <control + groupid="de.bmotionstudio.gef.editor.group.main" + icon="icons/icon_textfield.gif" + id="de.bmotionstudio.gef.editor.textfield" + name="Textfield" + service="de.bmotionstudio.gef.editor.service.BTextfieldService"> + </control> + <control + groupid="de.bmotionstudio.gef.editor.group.main" + icon="icons/icon_rectangle.gif" + id="de.bmotionstudio.gef.editor.shape" + name="Shape" + service="de.bmotionstudio.gef.editor.service.BShapeService"> + </control> + <control + groupid="de.bmotionstudio.gef.editor.group.main" + icon="icons/icon_connection16.gif" + id="de.bmotionstudio.gef.editor.connection" + name="Connection" + service="de.bmotionstudio.gef.editor.service.BConnectionService"> + </control> + </extension> + <extension + point="de.bmotionstudio.gef.editor.observer"> + <observer + class="de.bmotionstudio.gef.editor.observer.SimpleValueDisplay" + description="Observer for setting up the text value" + name="Simple Value Display"> + </observer> + <observer + class="de.bmotionstudio.gef.editor.observer.SwitchImage" + description="Observer for switching the image of the control" + name="Switch Image"> + </observer> + <observer + class="de.bmotionstudio.gef.editor.observer.SwitchChildCoordinates" + name="Switch Child Coordinates"> + </observer> + <observer + class="de.bmotionstudio.gef.editor.observer.SetAttribute" + description="General observer to set any attribute of the control" + name="Set Attribute"> + </observer> + <observer + class="de.bmotionstudio.gef.editor.observer.ListenOperationByPredicate" + name="Listen Operation"> + </observer> + <observer + class="de.bmotionstudio.gef.editor.observer.SwitchCoordinates" + description="Observer for switching the coordinates of the control" + name="Switch Coordinates"> + </observer> + <observer + class="de.bmotionstudio.gef.editor.observer.CloneObserver" + description="This observer clones the control depending on an expression rule" + name="Clone Observer"> + </observer> + </extension> + <extension + point="de.bmotionstudio.gef.editor.schedulerEvent"> + <schedulerEvent + class="de.bmotionstudio.gef.editor.scheduler.ExecuteOperationByPredicate" + description="Execute an operation" + menu="true" + name="Execute Operation"> + </schedulerEvent> + <schedulerEvent + class="de.bmotionstudio.gef.editor.scheduler.ExecuteAnimationScript" + description="Execute an animation script" + menu="true" + name="Execute Scheduler (Multi)"> + </schedulerEvent> + <schedulerEvent + class="de.bmotionstudio.gef.editor.scheduler.ExecuteOperationByPredicateMulti" + description="Execute an operation by a predicate" + menu="true" + name="Execute Operation (Multi)"> + </schedulerEvent> + </extension> + <extension + point="de.bmotionstudio.gef.editor.installActions"> + <action + class="de.bmotionstudio.gef.editor.InstallActions"> + </action> + </extension> + <extension + point="de.bmotionstudio.gef.editor.installMenu"> + <menu + class="de.bmotionstudio.gef.editor.InstallMenu"> + </menu> + </extension> + <extension + point="de.bmotionstudio.gef.editor.registerImages"> + <registerImages + class="de.bmotionstudio.gef.editor.ImageRegistry"> + </registerImages> + </extension> + <extension + point="de.bmotionstudio.gef.editor.language"> + <language + service="de.bmotionstudio.gef.editor.eventb.EventBLanguageService" + id="EventB"> + </language> + </extension> + <extension + point="de.bmotionstudio.gef.editor.includeObserver"> + <include + language="EventB"> + <observer + id="de.bmotionstudio.gef.editor.observer.ListenOperationByPredicate"> + <control + id="de.bmotionstudio.gef.editor.image"> + </control> + <control + id="de.bmotionstudio.gef.editor.button"> + </control> + <control + id="de.bmotionstudio.gef.editor.composite"> + </control> + <control + id="de.bmotionstudio.gef.editor.text"> + </control> + <control + id="de.bmotionstudio.gef.editor.ellipse"> + </control> + <control + id="de.bmotionstudio.gef.editor.shape"> + </control> + <control + id="de.bmotionstudio.gef.editor.radiobutton"> + </control> + <control + id="de.bmotionstudio.gef.editor.checkbox"> + </control> + <control + id="de.bmotionstudio.gef.editor.connection"> + </control> + </observer> + <observer + id="de.bmotionstudio.gef.editor.observer.CloneObserver"> + <control + id="de.bmotionstudio.gef.editor.composite"> + </control> + <control + id="de.bmotionstudio.gef.editor.visualization"> + </control> + </observer> + <observer + id="de.bmotionstudio.gef.editor.observer.SwitchCoordinates"> + <control + id="de.bmotionstudio.gef.editor.image"> + </control> + <control + id="de.bmotionstudio.gef.editor.button"> + </control> + <control + id="de.bmotionstudio.gef.editor.composite"> + </control> + <control + id="de.bmotionstudio.gef.editor.text"> + </control> + <control + id="de.bmotionstudio.gef.editor.shape"> + </control> + <control + id="de.bmotionstudio.gef.editor.radiobutton"> + </control> + <control + id="de.bmotionstudio.gef.editor.textfield"> + </control> + <control + id="de.bmotionstudio.gef.editor.checkbox"> + </control> + </observer> + <observer + id="de.bmotionstudio.gef.editor.observer.SimpleValueDisplay"> + <control + id="de.bmotionstudio.gef.editor.text"> + </control> + <control + id="de.bmotionstudio.gef.editor.radiobutton"> + </control> + <control + id="de.bmotionstudio.gef.editor.textfield"> + </control> + <control + id="de.bmotionstudio.gef.editor.button"> + </control> + </observer> + <observer + id="de.bmotionstudio.gef.editor.observer.SwitchImage"> + <control + id="de.bmotionstudio.gef.editor.image"> + </control> + <control + id="de.bmotionstudio.gef.editor.composite"> + </control> + </observer> + <observer + id="de.bmotionstudio.gef.editor.observer.SetAttribute"> + <control + id="de.bmotionstudio.gef.editor.image"> + </control> + <control + id="de.bmotionstudio.gef.editor.button"> + </control> + <control + id="de.bmotionstudio.gef.editor.composite"> + </control> + <control + id="de.bmotionstudio.gef.editor.text"> + </control> + <control + id="de.bmotionstudio.gef.editor.shape"> + </control> + <control + id="de.bmotionstudio.gef.editor.radiobutton"> + </control> + <control + id="de.bmotionstudio.gef.editor.checkbox"> + </control> + <control + id="de.bmotionstudio.gef.editor.connection"> + </control> + </observer> + <observer + id="de.bmotionstudio.gef.editor.observer.SwitchChildCoordinates"> + <control + id="de.bmotionstudio.gef.editor.composite"> + </control> + <control + id="de.bmotionstudio.gef.editor.visualization"> + </control> + </observer> + </include> + </extension> +</plugin> diff --git a/de.bmotionstudio.gef.editor/schema/de.bmotionstudio.gef.editor.control.exsd b/de.bmotionstudio.gef.editor/schema/de.bmotionstudio.gef.editor.control.exsd new file mode 100644 index 0000000000000000000000000000000000000000..2582ef9607e1c8b291e739da2243cbffd5a92107 --- /dev/null +++ b/de.bmotionstudio.gef.editor/schema/de.bmotionstudio.gef.editor.control.exsd @@ -0,0 +1,226 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- Schema file written by PDE --> +<schema targetNamespace="de.bmotionstudio.gef.editor" xmlns="http://www.w3.org/2001/XMLSchema"> +<annotation> + <appInfo> + <meta.schema plugin="de.bmotionstudio.gef.editor" id="de.bmotionstudio.gef.editor.control" name="BMotion Studio Control"/> + </appInfo> + <documentation> + [Enter description of this extension point.] + </documentation> + </annotation> + + <element name="extension"> + <annotation> + <appInfo> + <meta.element /> + </appInfo> + </annotation> + <complexType> + <sequence minOccurs="0" maxOccurs="unbounded"> + <element ref="control" minOccurs="0" maxOccurs="1"/> + <element ref="group" minOccurs="0" maxOccurs="1"/> + <element ref="control" minOccurs="0" maxOccurs="1"/> + </sequence> + <attribute name="point" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="id" type="string"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="name" type="string"> + <annotation> + <documentation> + + </documentation> + <appInfo> + <meta.attribute translatable="true"/> + </appInfo> + </annotation> + </attribute> + </complexType> + </element> + + <element name="group"> + <complexType> + <attribute name="id" type="string" use="required"> + <annotation> + <documentation> + The id of the group + </documentation> + </annotation> + </attribute> + <attribute name="name" type="string" use="required"> + <annotation> + <documentation> + The name of the group. The name will be displayed in the palette + </documentation> + </annotation> + </attribute> + </complexType> + </element> + + <element name="control"> + <annotation> + <appInfo> + <meta.element labelAttribute="id" icon="icon"/> + </appInfo> + </annotation> + <complexType> + <sequence> + <element ref="attributes" minOccurs="0" maxOccurs="1"/> + </sequence> + <attribute name="id" type="string" use="required"> + <annotation> + <documentation> + The unique id of the control + </documentation> + </annotation> + </attribute> + <attribute name="name" type="string"> + <annotation> + <documentation> + The name of the control. The name will be displayed in the Palette + </documentation> + </annotation> + </attribute> + <attribute name="groupid" type="string"> + <annotation> + <documentation> + The group id defined in the group element + </documentation> + </annotation> + </attribute> + <attribute name="icon" type="string" use="required"> + <annotation> + <documentation> + The icon of control. The icon will be displayed in the Palette + </documentation> + <appInfo> + <meta.attribute kind="resource"/> + </appInfo> + </annotation> + </attribute> + <attribute name="service" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + <appInfo> + <meta.attribute kind="java" basedOn="de.bmotionstudio.gef.editor.service.AbstractBControlService:de.bmotionstudio.gef.editor.IBControlService"/> + </appInfo> + </annotation> + </attribute> + </complexType> + </element> + + <element name="attribute-string"> + <complexType> + <attribute name="id" type="string" use="required"> + <annotation> + <documentation> + The id of the referenced attribute. Since the same attribute could be assigned to different controls the corresponding attibute is defined in a seperate exention point (de.bmotionstudio.gef.editor.attribute). + </documentation> + </annotation> + </attribute> + <attribute name="default-value" type="string" use="required"> + <annotation> + <documentation> + The default value of this attribute for this control + </documentation> + </annotation> + </attribute> + <attribute name="editable" type="boolean" use="default" value="true"> + <annotation> + <documentation> + Boolean value - Option to decide whenever this attribute should be editable or not. + </documentation> + </annotation> + </attribute> + <attribute name="show" type="boolean" use="default" value="true"> + <annotation> + <documentation> + Boolean value - Option to decide whenever this attribute should be displayed in the properties view. + </documentation> + </annotation> + </attribute> + </complexType> + </element> + + <element name="attribute-java"> + <complexType> + <attribute name="id" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="default-value" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + <appInfo> + <meta.attribute kind="java" basedOn=":de.bmotionstudio.core.IGetDefaultValue"/> + </appInfo> + </annotation> + </attribute> + </complexType> + </element> + + <element name="attributes"> + <complexType> + <sequence> + <element ref="attribute-java" minOccurs="0" maxOccurs="unbounded"/> + <element ref="attribute-string" minOccurs="0" maxOccurs="unbounded"/> + </sequence> + </complexType> + </element> + + <annotation> + <appInfo> + <meta.section type="since"/> + </appInfo> + <documentation> + [Enter the first release in which this extension point appears.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="examples"/> + </appInfo> + <documentation> + [Enter extension point usage example here.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="apiInfo"/> + </appInfo> + <documentation> + [Enter API information here.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="implementation"/> + </appInfo> + <documentation> + [Enter information about supplied implementation of this extension point.] + </documentation> + </annotation> + + +</schema> diff --git a/de.bmotionstudio.gef.editor/schema/de.bmotionstudio.gef.editor.includeObserver.exsd b/de.bmotionstudio.gef.editor/schema/de.bmotionstudio.gef.editor.includeObserver.exsd new file mode 100644 index 0000000000000000000000000000000000000000..42a20dc11a1b04d951c27b1e7aff883084d90fa0 --- /dev/null +++ b/de.bmotionstudio.gef.editor/schema/de.bmotionstudio.gef.editor.includeObserver.exsd @@ -0,0 +1,139 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- Schema file written by PDE --> +<schema targetNamespace="de.bmotionstudio.gef.editor" xmlns="http://www.w3.org/2001/XMLSchema"> +<annotation> + <appInfo> + <meta.schema plugin="de.bmotionstudio.gef.editor" id="de.bmotionstudio.gef.editor.includeObserver" name="Include B-Observer"/> + </appInfo> + <documentation> + [Enter description of this extension point.] + </documentation> + </annotation> + + <element name="extension"> + <annotation> + <appInfo> + <meta.element /> + </appInfo> + </annotation> + <complexType> + <sequence> + <element ref="include" minOccurs="1" maxOccurs="unbounded"/> + </sequence> + <attribute name="point" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="id" type="string"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="name" type="string"> + <annotation> + <documentation> + + </documentation> + <appInfo> + <meta.attribute translatable="true"/> + </appInfo> + </annotation> + </attribute> + </complexType> + </element> + + <element name="control"> + <annotation> + <appInfo> + <meta.element labelAttribute="id"/> + </appInfo> + </annotation> + <complexType> + <attribute name="id" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + </complexType> + </element> + + <element name="observer"> + <annotation> + <appInfo> + <meta.element labelAttribute="observerID"/> + </appInfo> + </annotation> + <complexType> + <sequence minOccurs="1" maxOccurs="unbounded"> + <element ref="control"/> + </sequence> + <attribute name="id" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + </complexType> + </element> + + <element name="include"> + <complexType> + <sequence minOccurs="1" maxOccurs="unbounded"> + <element ref="observer"/> + </sequence> + <attribute name="language" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + </complexType> + </element> + + <annotation> + <appInfo> + <meta.section type="since"/> + </appInfo> + <documentation> + [Enter the first release in which this extension point appears.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="examples"/> + </appInfo> + <documentation> + [Enter extension point usage example here.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="apiinfo"/> + </appInfo> + <documentation> + [Enter API information here.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="implementation"/> + </appInfo> + <documentation> + [Enter information about supplied implementation of this extension point.] + </documentation> + </annotation> + + +</schema> diff --git a/de.bmotionstudio.gef.editor/schema/de.bmotionstudio.gef.editor.installActions.exsd b/de.bmotionstudio.gef.editor/schema/de.bmotionstudio.gef.editor.installActions.exsd new file mode 100644 index 0000000000000000000000000000000000000000..814a71e347315556e6eb1263382273366ed010d1 --- /dev/null +++ b/de.bmotionstudio.gef.editor/schema/de.bmotionstudio.gef.editor.installActions.exsd @@ -0,0 +1,102 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- Schema file written by PDE --> +<schema targetNamespace="de.bmotionstudio.gef.editor" xmlns="http://www.w3.org/2001/XMLSchema"> +<annotation> + <appInfo> + <meta.schema plugin="de.bmotionstudio.gef.editor" id="de.bmotionstudio.gef.editor.installActions" name="Install Actions for Editor"/> + </appInfo> + <documentation> + [Enter description of this extension point.] + </documentation> + </annotation> + + <element name="extension"> + <annotation> + <appInfo> + <meta.element /> + </appInfo> + </annotation> + <complexType> + <sequence> + <element ref="action" minOccurs="1" maxOccurs="unbounded"/> + </sequence> + <attribute name="point" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="id" type="string"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="name" type="string"> + <annotation> + <documentation> + + </documentation> + <appInfo> + <meta.attribute translatable="true"/> + </appInfo> + </annotation> + </attribute> + </complexType> + </element> + + <element name="action"> + <complexType> + <attribute name="class" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + <appInfo> + <meta.attribute kind="java" basedOn="de.bmotionstudio.gef.editor.AbstractInstallActions:de.bmotionstudio.gef.editor.IInstallActions"/> + </appInfo> + </annotation> + </attribute> + </complexType> + </element> + + <annotation> + <appInfo> + <meta.section type="since"/> + </appInfo> + <documentation> + [Enter the first release in which this extension point appears.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="examples"/> + </appInfo> + <documentation> + [Enter extension point usage example here.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="apiinfo"/> + </appInfo> + <documentation> + [Enter API information here.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="implementation"/> + </appInfo> + <documentation> + [Enter information about supplied implementation of this extension point.] + </documentation> + </annotation> + + +</schema> diff --git a/de.bmotionstudio.gef.editor/schema/de.bmotionstudio.gef.editor.installMenu.exsd b/de.bmotionstudio.gef.editor/schema/de.bmotionstudio.gef.editor.installMenu.exsd new file mode 100644 index 0000000000000000000000000000000000000000..e49de0a993e1b9c4d4f77711d9a075a220716705 --- /dev/null +++ b/de.bmotionstudio.gef.editor/schema/de.bmotionstudio.gef.editor.installMenu.exsd @@ -0,0 +1,102 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- Schema file written by PDE --> +<schema targetNamespace="de.bmotionstudio.gef.editor" xmlns="http://www.w3.org/2001/XMLSchema"> +<annotation> + <appInfo> + <meta.schema plugin="de.bmotionstudio.gef.editor" id="de.bmotionstudio.gef.editor.installMenu" name="Context Menu"/> + </appInfo> + <documentation> + [Enter description of this extension point.] + </documentation> + </annotation> + + <element name="extension"> + <annotation> + <appInfo> + <meta.element /> + </appInfo> + </annotation> + <complexType> + <sequence> + <element ref="menu" minOccurs="1" maxOccurs="unbounded"/> + </sequence> + <attribute name="point" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="id" type="string"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="name" type="string"> + <annotation> + <documentation> + + </documentation> + <appInfo> + <meta.attribute translatable="true"/> + </appInfo> + </annotation> + </attribute> + </complexType> + </element> + + <element name="menu"> + <complexType> + <attribute name="class" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + <appInfo> + <meta.attribute kind="java" basedOn=":de.bmotionstudio.gef.editor.IInstallMenu"/> + </appInfo> + </annotation> + </attribute> + </complexType> + </element> + + <annotation> + <appInfo> + <meta.section type="since"/> + </appInfo> + <documentation> + [Enter the first release in which this extension point appears.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="examples"/> + </appInfo> + <documentation> + [Enter extension point usage example here.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="apiinfo"/> + </appInfo> + <documentation> + [Enter API information here.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="implementation"/> + </appInfo> + <documentation> + [Enter information about supplied implementation of this extension point.] + </documentation> + </annotation> + + +</schema> diff --git a/de.bmotionstudio.gef.editor/schema/de.bmotionstudio.gef.editor.language.exsd b/de.bmotionstudio.gef.editor/schema/de.bmotionstudio.gef.editor.language.exsd new file mode 100644 index 0000000000000000000000000000000000000000..f9d646d88a2f4811c3b6c34a65440442b8d1b9c3 --- /dev/null +++ b/de.bmotionstudio.gef.editor/schema/de.bmotionstudio.gef.editor.language.exsd @@ -0,0 +1,109 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- Schema file written by PDE --> +<schema targetNamespace="de.bmotionstudio.gef.editor" xmlns="http://www.w3.org/2001/XMLSchema"> +<annotation> + <appInfo> + <meta.schema plugin="de.bmotionstudio.gef.editor" id="de.bmotionstudio.gef.editor.languageLoader" name="BMotion Studio Language Loader"/> + </appInfo> + <documentation> + [Enter description of this extension point.] + </documentation> + </annotation> + + <element name="extension"> + <annotation> + <appInfo> + <meta.element /> + </appInfo> + </annotation> + <complexType> + <sequence minOccurs="0" maxOccurs="unbounded"> + <element ref="language"/> + </sequence> + <attribute name="point" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="id" type="string"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="name" type="string"> + <annotation> + <documentation> + + </documentation> + <appInfo> + <meta.attribute translatable="true"/> + </appInfo> + </annotation> + </attribute> + </complexType> + </element> + + <element name="language"> + <complexType> + <attribute name="id" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="service" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + <appInfo> + <meta.attribute kind="java" basedOn=":de.bmotionstudio.gef.editor.ILanguageService"/> + </appInfo> + </annotation> + </attribute> + </complexType> + </element> + + <annotation> + <appInfo> + <meta.section type="since"/> + </appInfo> + <documentation> + [Enter the first release in which this extension point appears.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="examples"/> + </appInfo> + <documentation> + [Enter extension point usage example here.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="apiinfo"/> + </appInfo> + <documentation> + [Enter API information here.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="implementation"/> + </appInfo> + <documentation> + [Enter information about supplied implementation of this extension point.] + </documentation> + </annotation> + + +</schema> diff --git a/de.bmotionstudio.gef.editor/schema/de.bmotionstudio.gef.editor.observer.exsd b/de.bmotionstudio.gef.editor/schema/de.bmotionstudio.gef.editor.observer.exsd new file mode 100644 index 0000000000000000000000000000000000000000..87040ac832e0b2bd3fad10f845e379ab0fde437d --- /dev/null +++ b/de.bmotionstudio.gef.editor/schema/de.bmotionstudio.gef.editor.observer.exsd @@ -0,0 +1,121 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- Schema file written by PDE --> +<schema targetNamespace="de.bmotionstudio.gef.editor" xmlns="http://www.w3.org/2001/XMLSchema"> +<annotation> + <appInfo> + <meta.schema plugin="de.bmotionstudio.gef.editor" id="de.bmotionstudio.gef.editor.observer" name="BMotion Studio Observer"/> + </appInfo> + <documentation> + [Enter description of this extension point.] + </documentation> + </annotation> + + <element name="extension"> + <annotation> + <appInfo> + <meta.element /> + </appInfo> + </annotation> + <complexType> + <sequence minOccurs="0" maxOccurs="unbounded"> + <element ref="observer"/> + </sequence> + <attribute name="point" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="id" type="string"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="name" type="string"> + <annotation> + <documentation> + + </documentation> + <appInfo> + <meta.attribute translatable="true"/> + </appInfo> + </annotation> + </attribute> + </complexType> + </element> + + <element name="observer"> + <annotation> + <appInfo> + <meta.element labelAttribute="id"/> + </appInfo> + </annotation> + <complexType> + <attribute name="name" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="class" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + <appInfo> + <meta.attribute kind="java" basedOn="de.bmotionstudio.gef.editor.observer.Observer:"/> + </appInfo> + </annotation> + </attribute> + <attribute name="description" type="string"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + </complexType> + </element> + + <annotation> + <appInfo> + <meta.section type="since"/> + </appInfo> + <documentation> + [Enter the first release in which this extension point appears.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="examples"/> + </appInfo> + <documentation> + [Enter extension point usage example here.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="apiinfo"/> + </appInfo> + <documentation> + [Enter API information here.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="implementation"/> + </appInfo> + <documentation> + [Enter information about supplied implementation of this extension point.] + </documentation> + </annotation> + + +</schema> diff --git a/de.bmotionstudio.gef.editor/schema/de.bmotionstudio.gef.editor.paletteEntry.exsd b/de.bmotionstudio.gef.editor/schema/de.bmotionstudio.gef.editor.paletteEntry.exsd new file mode 100644 index 0000000000000000000000000000000000000000..0e0bc598374bed67d3f0a0d11e2ff649c7faf431 --- /dev/null +++ b/de.bmotionstudio.gef.editor/schema/de.bmotionstudio.gef.editor.paletteEntry.exsd @@ -0,0 +1,102 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- Schema file written by PDE --> +<schema targetNamespace="de.bmotionstudio.gef.editor" xmlns="http://www.w3.org/2001/XMLSchema"> +<annotation> + <appInfo> + <meta.schema plugin="de.bmotionstudio.gef.editor" id="de.bmotionstudio.gef.editor.paletteEntry" name="Add a custom Palette Entry"/> + </appInfo> + <documentation> + [Enter description of this extension point.] + </documentation> + </annotation> + + <element name="extension"> + <annotation> + <appInfo> + <meta.element /> + </appInfo> + </annotation> + <complexType> + <sequence minOccurs="1" maxOccurs="unbounded"> + <element ref="entry"/> + </sequence> + <attribute name="point" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="id" type="string"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="name" type="string"> + <annotation> + <documentation> + + </documentation> + <appInfo> + <meta.attribute translatable="true"/> + </appInfo> + </annotation> + </attribute> + </complexType> + </element> + + <element name="entry"> + <complexType> + <attribute name="class" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + <appInfo> + <meta.attribute kind="java" basedOn=":de.bmotionstudio.gef.editor.IInstallPaletteEntry"/> + </appInfo> + </annotation> + </attribute> + </complexType> + </element> + + <annotation> + <appInfo> + <meta.section type="since"/> + </appInfo> + <documentation> + [Enter the first release in which this extension point appears.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="examples"/> + </appInfo> + <documentation> + [Enter extension point usage example here.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="apiinfo"/> + </appInfo> + <documentation> + [Enter API information here.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="implementation"/> + </appInfo> + <documentation> + [Enter information about supplied implementation of this extension point.] + </documentation> + </annotation> + + +</schema> diff --git a/de.bmotionstudio.gef.editor/schema/de.bmotionstudio.gef.editor.registerImages.exsd b/de.bmotionstudio.gef.editor/schema/de.bmotionstudio.gef.editor.registerImages.exsd new file mode 100644 index 0000000000000000000000000000000000000000..370a01def4d92b72662740e50c26e08dc4faea5b --- /dev/null +++ b/de.bmotionstudio.gef.editor/schema/de.bmotionstudio.gef.editor.registerImages.exsd @@ -0,0 +1,102 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- Schema file written by PDE --> +<schema targetNamespace="de.bmotionstudio.gef.editor" xmlns="http://www.w3.org/2001/XMLSchema"> +<annotation> + <appInfo> + <meta.schema plugin="de.bmotionstudio.gef.editor" id="de.bmotionstudio.gef.editor.registerImages" name="BMotion Studio Register Images"/> + </appInfo> + <documentation> + [Enter description of this extension point.] + </documentation> + </annotation> + + <element name="extension"> + <annotation> + <appInfo> + <meta.element /> + </appInfo> + </annotation> + <complexType> + <sequence minOccurs="0" maxOccurs="unbounded"> + <element ref="registerImages"/> + </sequence> + <attribute name="point" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="id" type="string"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="name" type="string"> + <annotation> + <documentation> + + </documentation> + <appInfo> + <meta.attribute translatable="true"/> + </appInfo> + </annotation> + </attribute> + </complexType> + </element> + + <element name="registerImages"> + <complexType> + <attribute name="class" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + <appInfo> + <meta.attribute kind="java" basedOn=":de.bmotionstudio.gef.editor.IBMotionStudioImageRegistry"/> + </appInfo> + </annotation> + </attribute> + </complexType> + </element> + + <annotation> + <appInfo> + <meta.section type="since"/> + </appInfo> + <documentation> + [Enter the first release in which this extension point appears.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="examples"/> + </appInfo> + <documentation> + [Enter extension point usage example here.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="apiinfo"/> + </appInfo> + <documentation> + [Enter API information here.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="implementation"/> + </appInfo> + <documentation> + [Enter information about supplied implementation of this extension point.] + </documentation> + </annotation> + + +</schema> diff --git a/de.bmotionstudio.gef.editor/schema/de.bmotionstudio.gef.editor.schedulerEvent.exsd b/de.bmotionstudio.gef.editor/schema/de.bmotionstudio.gef.editor.schedulerEvent.exsd new file mode 100644 index 0000000000000000000000000000000000000000..fedd15c305bff1b335d997381489a0ae22e7e0c9 --- /dev/null +++ b/de.bmotionstudio.gef.editor/schema/de.bmotionstudio.gef.editor.schedulerEvent.exsd @@ -0,0 +1,128 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- Schema file written by PDE --> +<schema targetNamespace="de.bmotionstudio.gef.editor" xmlns="http://www.w3.org/2001/XMLSchema"> +<annotation> + <appInfo> + <meta.schema plugin="de.bmotionstudio.gef.editor" id="de.bmotionstudio.gef.editor.schedulerEvent" name="BMotion Studio Scheduler Event"/> + </appInfo> + <documentation> + [Enter description of this extension point.] + </documentation> + </annotation> + + <element name="extension"> + <annotation> + <appInfo> + <meta.element /> + </appInfo> + </annotation> + <complexType> + <sequence minOccurs="1" maxOccurs="unbounded"> + <element ref="schedulerEvent"/> + </sequence> + <attribute name="point" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="id" type="string"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="name" type="string"> + <annotation> + <documentation> + + </documentation> + <appInfo> + <meta.attribute translatable="true"/> + </appInfo> + </annotation> + </attribute> + </complexType> + </element> + + <element name="schedulerEvent"> + <annotation> + <appInfo> + <meta.element labelAttribute="id"/> + </appInfo> + </annotation> + <complexType> + <attribute name="name" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="class" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + <appInfo> + <meta.attribute kind="java" basedOn="de.bmotionstudio.gef.editor.scheduler.SchedulerEvent:"/> + </appInfo> + </annotation> + </attribute> + <attribute name="description" type="string"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="menu" type="boolean" use="required"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + </complexType> + </element> + + <annotation> + <appInfo> + <meta.section type="since"/> + </appInfo> + <documentation> + [Enter the first release in which this extension point appears.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="examples"/> + </appInfo> + <documentation> + [Enter extension point usage example here.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="apiinfo"/> + </appInfo> + <documentation> + [Enter API information here.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="implementation"/> + </appInfo> + <documentation> + [Enter information about supplied implementation of this extension point.] + </documentation> + </annotation> + + +</schema> diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/AbstractBControlService.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/AbstractBControlService.java new file mode 100644 index 0000000000000000000000000000000000000000..5eacc4c6d570539eb13aafaaa034ea4a9924e101 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/AbstractBControlService.java @@ -0,0 +1,43 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor; + +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.gef.palette.CombinedTemplateCreationEntry; +import org.eclipse.gef.palette.ToolEntry; +import org.eclipse.ui.plugin.AbstractUIPlugin; + +import de.bmotionstudio.gef.editor.internal.BControlTemplate; +import de.bmotionstudio.gef.editor.model.Visualization; + +/** + * @author Lukas Ladenberger + * + */ +public abstract class AbstractBControlService { + + public ToolEntry createToolEntry(Visualization visualization, + IConfigurationElement configurationElement) { + String name = configurationElement.getAttribute("name"); + String icon = configurationElement.getAttribute("icon"); + String type = configurationElement.getAttribute("id"); + // Get the source plug-in (from the control extension) + String sourcePluginID = configurationElement.getContributor().getName(); + return new CombinedTemplateCreationEntry(name, + "Create Control " + name, new BControlTemplate(type), + new BControlCreationFactory(type, visualization), + AbstractUIPlugin + .imageDescriptorFromPlugin(sourcePluginID, icon), + AbstractUIPlugin + .imageDescriptorFromPlugin(sourcePluginID, icon)); + } + + public boolean showInPalette() { + return true; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/AbstractExpressionControl.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/AbstractExpressionControl.java new file mode 100644 index 0000000000000000000000000000000000000000..002567c4e6049d89ea2a355d3bb6899205fb6e80 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/AbstractExpressionControl.java @@ -0,0 +1,280 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import de.be4.classicalb.core.parser.exceptions.BException; +import de.bmotionstudio.gef.editor.internal.Animation; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.observer.ObserverEvalObject; +import de.bmotionstudio.gef.editor.part.AppAbstractEditPart; +import de.bmotionstudio.gef.editor.scheduler.SchedulerEvent; +import de.prob.core.command.EvaluationGetValuesCommand; +import de.prob.core.command.GetOperationByPredicateCommand; +import de.prob.core.domainobjects.EvaluationElement; +import de.prob.core.domainobjects.EvaluationStateElement; +import de.prob.core.domainobjects.Operation; +import de.prob.core.domainobjects.State; +import de.prob.exceptions.ProBException; +import de.prob.parserbase.ProBParseException; + +public abstract class AbstractExpressionControl extends BindingObject { + + private static final Pattern PATTERN = Pattern.compile("\\$(.+?)\\$"); + + protected transient String ID; + protected transient String name; + protected transient String description; + protected transient Boolean hasError = false; + private transient static final String DEFAULT_PREDICATE = "1=1"; + private transient static final String DEFAULT_BOOLVAL = "true"; + + public String getID() { + return this.ID; + } + + public String getName() { + return this.name; + } + + public String getDescription() { + return this.description; + } + + public void addError(BControl control, Animation animation, String message) { + // TODO: Implement me! + // History history = animation.getAnimator().getHistory(); + // int currentHistoryPos = history.getCurrentPosition(); + // control.getVisualization().addError( + // new ErrorMessage(history.getAllItems()[currentHistoryPos - 1], + // this, control, message)); + } + + /** + * tbd + * + * @param expressionString + * @param control + * @param animation + * @param obj + * @return true or false + */ + protected String parsePredicate(String expressionString, BControl control, + Animation animation, ObserverEvalObject obj) { + if (expressionString == null || expressionString.trim().length() == 0) + return DEFAULT_BOOLVAL; + return parseExpression(expressionString, true, control, animation, obj, + true); + } + + protected String parseExpression(String expressionString, BControl control, + Animation animation, ObserverEvalObject obj) { + return parseExpression(expressionString, true, control, animation, obj, + false); + } + + protected String parseExpression(final String expressionString, + final boolean evalSingleExpression, final BControl control, + final Animation animation, final ObserverEvalObject obj, + final boolean isPredicate) { + + Map<EvaluationElement, String> evaluationKeys = new HashMap<EvaluationElement, String>(); + + boolean hasSubExpressions = false; + + hasError = false; + + // Find expressions and collect ExpressionEvalElements + final Matcher matcher = PATTERN.matcher(expressionString); + + while (matcher.find()) { + final String subExpr = matcher.group(1); + collectEvalElements(subExpr, "$" + subExpr + "$", isPredicate, + animation, control, evaluationKeys); + hasSubExpressions = true; + } + + // We have only one expression (without "$$") + if (!hasSubExpressions) { + if (evalSingleExpression) { + collectEvalElements(expressionString, expressionString, + isPredicate, animation, control, evaluationKeys); + } else { + return expressionString; + } + } + + // Try to get expression results and parse expression string + Collection<EvaluationStateElement> resultList; + try { + resultList = getExpressionValues(control, animation, + new ArrayList<EvaluationElement>(evaluationKeys.keySet())); + } catch (ProBException e) { + resultList = Collections.emptyList(); + hasError = true; + } + + // If getting ExpressionEvalElement throws no error, try to get + // expression results + String result = expressionString; + if (!hasError) { + for (EvaluationStateElement stateElement : resultList) { + final EvaluationElement evalElement = stateElement.getElement(); + final String text; + if (isPredicate) { + text = stateElement.getResult().isPredicateTrue() ? "true" + : "false"; + } else { + text = stateElement.getText(); + } + final String subExpression = evaluationKeys.get(evalElement); + result = result.replace(subExpression, text); + } + } else { + if (obj != null) + obj.setHasError(true); + addError(control, animation, + "An error occurred while evaluating expression\\predicate value: \"" + + expressionString + + "\". Please check your expression\\predicate."); + } + + return result; + + } + + private void collectEvalElements(final String subexpression, + final String key, final boolean isPredicate, + final Animation animation, final BControl control, + final Map<EvaluationElement, String> evaluationKeys) { + + final String parsedSubexpr = parseControls(subexpression, control); + EvaluationElement evalElement; + try { + evalElement = animation.getCachedEvalElement(parsedSubexpr, + isPredicate); + evaluationKeys.put(evalElement, key); + } catch (UnsupportedOperationException e) { + hasError = true; + } catch (ProBException e) { + hasError = true; + } catch (ProBParseException e) { + addError(control, animation, e.getMessage()); + hasError = true; + } + + } + + protected List<Operation> parseOperation(final String opName, + String opPredicate, int opRandom, final Animation animation, + final String currentState, final BControl control) { + + try { + + if (opPredicate != null && opPredicate.length() > 0) + opPredicate = parseControls(opPredicate, control); + else + opPredicate = DEFAULT_PREDICATE; + + if (opRandom < 1) + opRandom = 1; + + return GetOperationByPredicateCommand.getOperations( + animation.getAnimator(), currentState, opName, opPredicate, + opRandom); + + } catch (ProBException e) { + addError(control, animation, e.getMessage()); + hasError = true; + } catch (BException e) { + addError(control, animation, e.getMessage()); + hasError = true; + } + + return null; + + } + + /** + * This method matches the pattern <i>(\\w+)</i>. This means that the method + * matches alphanumeric words in the given predicate or expression string. + * The method focuses on control id's or the key word <i>this</i>. In the + * first case the method tries to find a reference on the corresponding + * control in the visualization regarding to the matched control id. In the + * second case the method creates a reference to the control which contains + * the observer. In addition in both cases the method returns the value of + * {@link AppAbstractEditPart#getValueOfData()} of the located + * {@link BControl}. + * + * @param expressionString + * @param control + * @return the parsed expression + */ + protected String parseControls(String expressionString, BControl control) { + + List<String> allControlIDs = control.getVisualization() + .getAllBControlNames(); + + // Search for control ids + Pattern cPattern = Pattern.compile("(\\w+)"); + Matcher cMatcher = cPattern.matcher(expressionString); + + while (cMatcher.find()) { + + String controlID = cMatcher.group(1); + + if (controlID.equals("this")) { + + expressionString = expressionString.replace(controlID, control + .getAttributeValue(AttributeConstants.ATTRIBUTE_CUSTOM) + .toString()); + + } else if (allControlIDs.contains(controlID)) { + + expressionString = expressionString.replace(controlID, control + .getVisualization().getBControl(controlID) + .getValueOfData()); + + } else { + // TODO: Return error if no control exists + } + } + + return expressionString; + + } + + protected Collection<EvaluationStateElement> getExpressionValues( + final BControl control, final Animation animation, + final Collection<EvaluationElement> evalElements) + throws ProBException { + final State state = animation.getAnimator().getCurrentState(); + // TODO[DP, 11.04.2011] Add an animator to the parameters! + final Collection<EvaluationStateElement> values = EvaluationGetValuesCommand + .getValuesForExpressionsCached(state, evalElements); + return values; + } + + /** + * This method is invoked before the expression control ({@link IObserver} + * or {@link SchedulerEvent}) will be deleted. + * + * @param control + * which holds the expression control + */ + public void beforeDelete(BControl control) { + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/AbstractInstallActions.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/AbstractInstallActions.java new file mode 100644 index 0000000000000000000000000000000000000000..e7e9ef1718822ec2e71161e5e48e5245db8d11b0 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/AbstractInstallActions.java @@ -0,0 +1,29 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor; + +import java.util.HashMap; + +import org.eclipse.jface.action.Action; + +public class AbstractInstallActions { + + HashMap<String, Action> map; + + public AbstractInstallActions() { + this.map = new HashMap<String, Action>(); + } + + public void installAction(String actionID, Action action) { + this.map.put(actionID, action); + } + + public HashMap<String, Action> getActionMap() { + return this.map; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/AppContextMenuProvider.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/AppContextMenuProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..1cb2efb1c6e01ee3050551cd3871c79a051cc93b --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/AppContextMenuProvider.java @@ -0,0 +1,311 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.IExtensionRegistry; +import org.eclipse.core.runtime.Platform; +import org.eclipse.gef.ContextMenuProvider; +import org.eclipse.gef.EditPartViewer; +import org.eclipse.gef.ui.actions.ActionRegistry; +import org.eclipse.gef.ui.actions.GEFActionConstants; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.actions.ActionFactory; + +import de.bmotionstudio.gef.editor.action.SchedulerEventAction; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.part.AppAbstractEditPart; +import de.bmotionstudio.gef.editor.part.VisualizationPart; +import de.bmotionstudio.gef.editor.scheduler.SchedulerEvent; + +public class AppContextMenuProvider extends ContextMenuProvider { + + private ActionRegistry actionRegistry; + + private IExtensionRegistry registry = Platform.getExtensionRegistry(); + + private String[] eventIDs = { AttributeConstants.EVENT_MOUSECLICK }; + + public AppContextMenuProvider(EditPartViewer viewer, ActionRegistry registry) { + super(viewer); + setActionRegistry(registry); + } + + @Override + public void buildContextMenu(IMenuManager menu) { + + IAction action; + + GEFActionConstants.addStandardActionGroups(menu); + + action = getActionRegistry().getAction(ActionFactory.UNDO.getId()); + menu.appendToGroup(GEFActionConstants.GROUP_UNDO, action); + + action = getActionRegistry().getAction(ActionFactory.REDO.getId()); + menu.appendToGroup(GEFActionConstants.GROUP_UNDO, action); + + action = actionRegistry.getAction(ActionFactory.COPY.getId()); + menu.appendToGroup(GEFActionConstants.GROUP_COPY, action); + + action = actionRegistry.getAction(ActionFactory.PASTE.getId()); + menu.appendToGroup(GEFActionConstants.GROUP_COPY, action); + + action = getActionRegistry().getAction(ActionFactory.DELETE.getId()); + menu.appendToGroup(GEFActionConstants.GROUP_EDIT, action); + + buildCustomMenu(menu); + + buildObserverMenu(menu); + + buildEventMenu(menu); + + } + + private void buildCustomMenu(IMenuManager menu) { + + IExtensionPoint extensionPoint = registry + .getExtensionPoint("de.bmotionstudio.gef.editor.installMenu"); + for (IExtension extension : extensionPoint.getExtensions()) { + for (IConfigurationElement configurationElement : extension + .getConfigurationElements()) { + + if ("menu".equals(configurationElement.getName())) { + + try { + + IInstallMenu installMenuClass = (IInstallMenu) configurationElement + .createExecutableExtension("class"); + + installMenuClass.installMenu(menu, getActionRegistry()); + + } catch (final CoreException e) { + e.printStackTrace(); + } + + } + + } + + } + + } + + private void buildObserverMenu(IMenuManager menu) { + + final MenuManager handleObserverMenu = new MenuManager("Observers", + BMotionStudioImage.getImageDescriptor( + BMotionEditorPlugin.PLUGIN_ID, + "icons/icon_observer.gif"), "observerMenu"); + menu.appendToGroup(GEFActionConstants.GROUP_ADD, handleObserverMenu); + + IStructuredSelection selection = (IStructuredSelection) BMotionEditorPlugin + .getActiveEditor().getEditorSite().getSelectionProvider() + .getSelection(); + + if (selection.getFirstElement() instanceof AppAbstractEditPart) { + + BControl bcontrol = (BControl) ((AppAbstractEditPart) selection + .getFirstElement()).getModel(); + + IExtensionPoint extensionPoint = registry + .getExtensionPoint("de.bmotionstudio.gef.editor.observer"); + for (IExtension extension : extensionPoint.getExtensions()) { + for (IConfigurationElement configurationElement : extension + .getConfigurationElements()) { + + if ("observer".equals(configurationElement.getName())) { + + final String observerClassName = configurationElement + .getAttribute("class"); + final String observerName = configurationElement + .getAttribute("name"); + + if (checkIncludeObserver(observerClassName, bcontrol)) { + + IAction action = getActionRegistry().getAction( + "de.bmotionstudio.gef.editor.observerAction." + + observerClassName); + action.setText(observerName); + action.setToolTipText(observerName); + + if (bcontrol.hasObserver(observerClassName)) { + action.setImageDescriptor(BMotionStudioImage + .getImageDescriptor( + BMotionEditorPlugin.PLUGIN_ID, + "icons/icon_chop.gif")); + } else { + action.setImageDescriptor(null); + } + handleObserverMenu.add(action); + + } + + } + + } + + } + + } + + } + + private boolean checkIncludeObserver(String observerID, BControl control) { + + IExtensionPoint extensionPoint = registry + .getExtensionPoint("de.bmotionstudio.gef.editor.includeObserver"); + + for (IExtension extension : extensionPoint.getExtensions()) { + for (IConfigurationElement configurationElement : extension + .getConfigurationElements()) { + + if ("include".equals(configurationElement.getName())) { + + String langID = configurationElement + .getAttribute("language"); + + if (langID.equals(control.getVisualization().getLanguage())) { + + for (IConfigurationElement cObserver : configurationElement + .getChildren("observer")) { + + String oID = cObserver.getAttribute("id"); + + if (observerID.equals(oID)) { + + for (IConfigurationElement configBControl : cObserver + .getChildren("control")) { + + String bID = configBControl + .getAttribute("id"); + + if (control.getType().equals(bID)) { + return true; + } + + } + + } + + } + + } + + } + + } + } + + return false; + + } + + private void buildEventMenu(IMenuManager menu) { + + MenuManager handleEventMenu = new MenuManager("Events", + BMotionStudioImage.getImageDescriptor( + BMotionEditorPlugin.PLUGIN_ID, "icons/icon_event.png"), + "eventMenu"); + menu.appendToGroup(GEFActionConstants.GROUP_ADD, handleEventMenu); + + IStructuredSelection selection = (IStructuredSelection) BMotionEditorPlugin + .getActiveEditor().getEditorSite().getSelectionProvider() + .getSelection(); + + if ((selection.getFirstElement() instanceof AppAbstractEditPart) + && !(selection.getFirstElement() instanceof VisualizationPart)) { + + BControl bcontrol = (BControl) ((AppAbstractEditPart) selection + .getFirstElement()).getModel(); + + // Has event + if (bcontrol.hasEvent(eventIDs[0])) { + + SchedulerEvent event = bcontrol.getEvent(eventIDs[0]); + + SchedulerEventAction action = (SchedulerEventAction) getActionRegistry() + .getAction( + "de.bmotionstudio.gef.editor.SchedulerEventAction." + + event.getID()); + action.setEventID(eventIDs[0]); + action.setText(event.getName()); + action.setImageDescriptor(BMotionStudioImage + .getImageDescriptor(BMotionEditorPlugin.PLUGIN_ID, + "icons/icon_chop.gif")); + handleEventMenu.add(action); + + } else { // Has no event + + IExtensionPoint schedulerExtensionPoint = registry + .getExtensionPoint("de.bmotionstudio.gef.editor.schedulerEvent"); + for (IExtension schedulerExtension : schedulerExtensionPoint + .getExtensions()) { + for (IConfigurationElement configSchedulerElement : schedulerExtension + .getConfigurationElements()) { + + if ("schedulerEvent".equals(configSchedulerElement + .getName())) { + + String sClassName = configSchedulerElement + .getAttribute("class"); + Boolean show = Boolean + .valueOf(configSchedulerElement + .getAttribute("menu")); + + if (show) { + + SchedulerEventAction action = (SchedulerEventAction) getActionRegistry() + .getAction( + "de.bmotionstudio.gef.editor.SchedulerEventAction." + + sClassName); + action.setEventID(eventIDs[0]); + action.setText(configSchedulerElement + .getAttribute("name")); + + // if (bcontrol.hasEvent(eventIDs[0])) { + // action + // .setImageDescriptor(BMotionStudioImage + // .getImageDescriptor( + // BMotionEditorPlugin.PLUGIN_ID, + // "icons/icon_chop.gif")); + // } else { + + action.setImageDescriptor(null); + + // } + + handleEventMenu.add(action); + + } + + } + + } + + } + + } + + } + + } + + private ActionRegistry getActionRegistry() { + return actionRegistry; + } + + private void setActionRegistry(ActionRegistry registry) { + actionRegistry = registry; + } + +} \ No newline at end of file diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/AttributeConstants.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/AttributeConstants.java new file mode 100644 index 0000000000000000000000000000000000000000..5fb0bfdd4b5195d6a1f2c6666ced65362a3911e3 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/AttributeConstants.java @@ -0,0 +1,60 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor; + +public final class AttributeConstants { + + public static final String ATTRIBUTE_X = "de.bmotionstudio.gef.editor.attribute.BAttributeX"; + public static final String ATTRIBUTE_Y = "de.bmotionstudio.gef.editor.attribute.BAttributeY"; + public static final String ATTRIBUTE_WIDTH = "de.bmotionstudio.gef.editor.attribute.BAttributeWidth"; + public static final String ATTRIBUTE_HEIGHT = "de.bmotionstudio.gef.editor.attribute.BAttributeHeight"; + public static final String ATTRIBUTE_CUSTOM = "de.bmotionstudio.gef.editor.attribute.BAttributeCustom"; + public static final String ATTRIBUTE_ID = "de.bmotionstudio.gef.editor.attribute.BAttributeID"; + public static final String ATTRIBUTE_VISIBLE = "de.bmotionstudio.gef.editor.attribute.BAttributeVisible"; + + public static final String ATTRIBUTE_BACKGROUND_IMAGE = "de.bmotionstudio.gef.editor.attribute.BAttributeImage"; + public static final String ATTRIBUTE_BACKGROUND_COLOR = "de.bmotionstudio.gef.editor.attribute.BAttributeBackgroundColor"; + public static final String ATTRIBUTE_FOREGROUND_COLOR = "de.bmotionstudio.gef.editor.attribute.BAttributeForegroundColor"; + public static final String ATTRIBUTE_BACKGROUND_VISIBLE = "de.bmotionstudio.gef.editor.attribute.BAttributeBackgroundVisible"; + public static final String ATTRIBUTE_IMAGE = "de.bmotionstudio.gef.editor.attribute.BAttributeImage"; + public static final String ATTRIBUTE_TEXT = "de.bmotionstudio.gef.editor.attribute.BAttributeText"; + public static final String ATTRIBUTE_TEXT_COLOR = "de.bmotionstudio.gef.editor.attribute.BAttributeTextColor"; + public static final String ATTRIBUTE_FILL_HEIGHT = "de.bmotionstudio.gef.editor.attribute.BAttributeFillHeight"; + public static final String ATTRIBUTE_FILL_COLOR = "de.bmotionstudio.gef.editor.attribute.BAttributeFillColor"; + public static final String ATTRIBUTE_SHOWS_MEASURE = "de.bmotionstudio.gef.editor.attribute.BAttributeShowMeasure"; + public static final String ATTRIBUTE_MEASURE_MAXPOS = "de.bmotionstudio.gef.editor.attribute.BAttributeMeasureMaxPos"; + public static final String ATTRIBUTE_MEASURE_INTERVAL = "de.bmotionstudio.gef.editor.attribute.BAttributeMeasureInterval"; + public static final String ATTRIBUTE_ALPHA = "de.bmotionstudio.gef.editor.attribute.BAttributeAlpha"; + public static final String ATTRIBUTE_OUTLINEALPHA = "de.bmotionstudio.gef.editor.attribute.BAttributeOutlineAlpha"; + public static final String ATTRIBUTE_FONT = "de.bmotionstudio.gef.editor.attribute.BAttributeFont"; + public static final String ATTRIBUTE_ENABLED = "de.bmotionstudio.gef.editor.attribute.BAttributeEnabled"; + public static final String ATTRIBUTE_CHECKED = "de.bmotionstudio.gef.editor.attribute.BAttributeChecked"; + public static final String ATTRIBUTE_VALUE = "de.bmotionstudio.gef.editor.attribute.BAttributeValue"; + public static final String ATTRIBUTE_BUTTONGROUP = "de.bmotionstudio.gef.editor.attribute.BAttributeButtonGroup"; + public static final String ATTRIBUTE_SHAPE = "de.bmotionstudio.gef.editor.attribute.BAttributeShape"; + public static final String ATTRIBUTE_ORIENTATION = "de.bmotionstudio.gef.editor.attribute.BAttributeOrientation"; + public static final String ATTRIBUTE_DIRECTION = "de.bmotionstudio.gef.editor.attribute.BAttributeDirection"; + public static final String ATTRIBUTE_FILLTYPE = "de.bmotionstudio.gef.editor.attribute.BAttributeFillType"; + public static final String ATTRIBUTE_LINEWIDTH = "de.bmotionstudio.gef.editor.attribute.BAttributeLineWidth"; + public static final String ATTRIBUTE_LINESTYLE = "de.bmotionstudio.gef.editor.attribute.BAttributeLineStyle"; + public static final String ATTRIBUTE_TRUEVALUE = "de.bmotionstudio.gef.editor.attribute.BAttributeTrueValue"; + public static final String ATTRIBUTE_FALSEVALUE = "de.bmotionstudio.gef.editor.attribute.BAttributeFalseValue"; + public static final String ATTRIBUTE_LABEL = "de.bmotionstudio.gef.editor.attribute.BAttributeLabel"; + public static final String ATTRIBUTE_OFFSET_H = "de.bmotionstudio.gef.editor.attribute.BAttributeOffsetH"; + public static final String ATTRIBUTE_OFFSET_V = "de.bmotionstudio.gef.editor.attribute.BAttributeOffsetV"; + public static final String ATTRIBUTE_CONNECTION_SOURCE_DECORATION = "de.bmotionstudio.gef.editor.attribute.BAttributeConnectionSourceDecoration"; + public static final String ATTRIBUTE_CONNECTION_TARGET_DECORATION = "de.bmotionstudio.gef.editor.attribute.BAttributeConnectionTargetDecoration"; + + public static final String ATTRIBUTE_SIZE = "de.bmotionstudio.gef.editor.attribute.BAttributeSize"; + public static final String ATTRIBUTE_COORDINATES = "de.bmotionstudio.gef.editor.attribute.BAttributeCoordinates"; + public static final String ATTRIBUTE_MISC = "de.bmotionstudio.gef.editor.attribute.BAttributeMisc"; + public static final String ATTRIBUTE_MAIN = "de.bmotionstudio.gef.editor.attribute.BAttributeMain"; + + public static final String EVENT_MOUSECLICK = "de.bmotionstudio.gef.editor.event.OnClickEvent"; + public static final String EVENT_MOUSEDBLCLICK = "de.bmotionstudio.gef.editor.event.OnDblClickEvent"; + +} \ No newline at end of file diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/BControlCreationFactory.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/BControlCreationFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..f94182dcb703ac07236ce66209167035b84edd4c --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/BControlCreationFactory.java @@ -0,0 +1,45 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.gef.requests.CreationFactory; + +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.model.Visualization; + +public class BControlCreationFactory implements CreationFactory { + + private Visualization visualization; + private String type; + + public BControlCreationFactory(String type, Visualization visualization) { + this.type = type; + this.visualization = visualization; + } + + @Override + public Object getNewObject() { + BControl control = null; + try { + IBControlService service = (IBControlService) BMotionEditorPlugin + .getControlServices().get(type) + .createExecutableExtension("service"); + control = service.createControl(visualization); + } catch (CoreException e) { + e.printStackTrace(); + } + // TODO: check if control == null + return control; + } + + @Override + public Object getObjectType() { + return BControl.class; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/BMotionEditorPlugin.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/BMotionEditorPlugin.java new file mode 100644 index 0000000000000000000000000000000000000000..554ef61e747e60b621229afe145c0082055a7c25 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/BMotionEditorPlugin.java @@ -0,0 +1,221 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor; + +import java.util.ArrayList; +import java.util.HashMap; + +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.IExtensionRegistry; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +import com.thoughtworks.xstream.XStream; + +import de.bmotionstudio.gef.editor.internal.BControlListConverter; +import de.bmotionstudio.gef.editor.model.BConnection; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.model.BControlList; +import de.bmotionstudio.gef.editor.model.BMotionGuide; +import de.bmotionstudio.gef.editor.model.Visualization; + +/** + * The activator class controls the plug-in life cycle + */ +public class BMotionEditorPlugin extends AbstractUIPlugin { + + // The plug-in ID + public static final String PLUGIN_ID = "de.bmotionstudio.gef.editor"; + + public static final String FILEEXT_STUDIO = "bmso"; + + // The shared instance + private static BMotionEditorPlugin plugin; + + private static HashMap<String, IConfigurationElement> controlExtensions = new HashMap<String, IConfigurationElement>(); + + private static HashMap<String, IConfigurationElement> observerExtensions = new HashMap<String, IConfigurationElement>(); + + private static HashMap<String, IConfigurationElement> schedulerExtensions = new HashMap<String, IConfigurationElement>(); + + private static HashMap<String, IConfigurationElement> controlServices = new HashMap<String, IConfigurationElement>(); + + IExtensionRegistry registry = Platform.getExtensionRegistry(); + + static BMotionStudioEditorPage activeBMotionStudioEditor = null; + + /** + * The constructor + */ + public BMotionEditorPlugin() { + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext + * ) + */ + @Override + public void start(final BundleContext context) throws Exception { + super.start(context); + plugin = this; + initExtensionClasses(); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext + * ) + */ + @Override + public void stop(final BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static BMotionEditorPlugin getDefault() { + return plugin; + } + + /** + * Returns an image descriptor for the image file at the given plug-in + * relative path + * + * @param path + * the path + * @return the image descriptor + */ + public static ImageDescriptor getImageDescriptor(final String path) { + return imageDescriptorFromPlugin(PLUGIN_ID, path); + } + + /** + * Get the active workbench page. + * + * @return current active workbench page + */ + public static IWorkbenchPage getActivePage() { + return getDefault().internalGetActivePage(); + } + + /** + * Get the active editor. + * + * @return current active editor + */ + public static BMotionStudioEditor getActiveEditor() { + if (getActivePage() != null) { + if (getActivePage().getActiveEditor() instanceof BMotionStudioEditor) + return (BMotionStudioEditor) getActivePage().getActiveEditor(); + } + return null; + } + + /** + * Getting the current active page from the active workbench window. + * <p> + * + * @return current active workbench page + */ + private IWorkbenchPage internalGetActivePage() { + return getWorkbench().getActiveWorkbenchWindow().getActivePage(); + } + + private void initExtensionClass(String extensionPointID, + ArrayList<String> elementIDs, String getAttribute, + HashMap<String, IConfigurationElement> hashMap) { + + IExtensionPoint extensionPoint = registry + .getExtensionPoint(extensionPointID); + for (IExtension extension : extensionPoint.getExtensions()) { + + for (IConfigurationElement configurationElement : extension + .getConfigurationElements()) { + + if (elementIDs.contains(configurationElement.getName())) { + + String atr = configurationElement + .getAttribute(getAttribute); + + hashMap.put(atr, configurationElement); + + } + + } + + } + + } + + private void initExtensionClasses() { + + ArrayList<String> elementIDs = new ArrayList<String>(); + elementIDs.add("control"); + initExtensionClass("de.bmotionstudio.gef.editor.control", elementIDs, + "id", controlExtensions); + + elementIDs.clear(); + elementIDs.add("control"); + initExtensionClass("de.bmotionstudio.gef.editor.control", elementIDs, + "id", controlServices); + + elementIDs.clear(); + elementIDs.add("observer"); + initExtensionClass("de.bmotionstudio.gef.editor.observer", elementIDs, + "class", observerExtensions); + + elementIDs.clear(); + elementIDs.add("schedulerEvent"); + initExtensionClass("de.bmotionstudio.gef.editor.schedulerEvent", + elementIDs, "class", schedulerExtensions); + + } + + public static IConfigurationElement getControlExtension(String ident) { + return controlExtensions.get(ident); + } + + public static IConfigurationElement getObserverExtension(String ident) { + return observerExtensions.get(ident); + } + + public static IConfigurationElement getSchedulerExtension(String ident) { + return schedulerExtensions.get(ident); + } + + public static HashMap<String, IConfigurationElement> getSchedulerExtensions() { + return schedulerExtensions; + } + + public static HashMap<String, IConfigurationElement> getControlServices() { + return controlServices; + } + + public static void setAliases(XStream xstream) { + xstream.registerConverter(new BControlListConverter()); + xstream.alias("control", BControl.class); + xstream.alias("visualization", Visualization.class); + xstream.alias("guide", BMotionGuide.class); + xstream.alias("connection", BConnection.class); + xstream.alias("children", BControlList.class); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/BMotionSelectionSynchronizer.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/BMotionSelectionSynchronizer.java new file mode 100644 index 0000000000000000000000000000000000000000..3bf703a63778ad8c668afb657a682a507cc22e94 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/BMotionSelectionSynchronizer.java @@ -0,0 +1,45 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor; + +import org.eclipse.gef.EditPart; +import org.eclipse.gef.EditPartViewer; +import org.eclipse.gef.ui.parts.ScrollingGraphicalViewer; +import org.eclipse.gef.ui.parts.SelectionSynchronizer; +import org.eclipse.gef.ui.parts.TreeViewer; + +import de.bmotionstudio.gef.editor.model.BControl; + +public class BMotionSelectionSynchronizer extends SelectionSynchronizer { + + private BMotionStudioEditor editor; + + public BMotionSelectionSynchronizer(BMotionStudioEditor editor) { + this.editor = editor; + } + + protected EditPart convert(EditPartViewer viewer, EditPart part) { + + if (viewer instanceof ScrollingGraphicalViewer + || viewer instanceof TreeViewer) { + BControl control = (BControl) part.getModel(); + String id = control.getID(); + BControl editControl = editor.getEditPage().getVisualization() + .getBControl(id); + Object temp = viewer.getEditPartRegistry().get(editControl); + EditPart newPart = null; + if (temp != null) { + newPart = (EditPart) temp; + } + return newPart; + } else { + return super.convert(viewer, part); + } + + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/BMotionStudioContributor.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/BMotionStudioContributor.java new file mode 100644 index 0000000000000000000000000000000000000000..5ad0698027a155b9edb6288be6e889ff5490110a --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/BMotionStudioContributor.java @@ -0,0 +1,107 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor; + +import org.eclipse.gef.ui.actions.ActionBarContributor; +import org.eclipse.gef.ui.actions.DeleteRetargetAction; +import org.eclipse.gef.ui.actions.GEFActionConstants; +import org.eclipse.gef.ui.actions.RedoRetargetAction; +import org.eclipse.gef.ui.actions.UndoRetargetAction; +import org.eclipse.gef.ui.actions.ZoomComboContributionItem; +import org.eclipse.gef.ui.actions.ZoomInRetargetAction; +import org.eclipse.gef.ui.actions.ZoomOutRetargetAction; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IContributionItem; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.actions.ActionFactory; +import org.eclipse.ui.actions.RetargetAction; + +public class BMotionStudioContributor extends ActionBarContributor { + + @Override + protected void buildActions() { + IWorkbenchWindow iww = getPage().getWorkbenchWindow(); + + addRetargetAction(new UndoRetargetAction()); + addRetargetAction(new RedoRetargetAction()); + + addRetargetAction(new DeleteRetargetAction()); + + addRetargetAction((RetargetAction) ActionFactory.COPY.create(iww)); + addRetargetAction((RetargetAction) ActionFactory.PASTE.create(iww)); + + addRetargetAction(new ZoomInRetargetAction()); + addRetargetAction(new ZoomOutRetargetAction()); + + addRetargetAction(new RetargetAction( + GEFActionConstants.TOGGLE_RULER_VISIBILITY, "Ruler", + IAction.AS_CHECK_BOX)); + + addRetargetAction(new RetargetAction( + GEFActionConstants.TOGGLE_GRID_VISIBILITY, "Grid", + IAction.AS_CHECK_BOX)); + + addRetargetAction(new RetargetAction( + GEFActionConstants.TOGGLE_SNAP_TO_GEOMETRY, "Snap to Geometry", + IAction.AS_CHECK_BOX)); + } + + @Override + public void contributeToToolBar(IToolBarManager toolBarManager) { + toolBarManager.add(getAction(ActionFactory.DELETE.getId())); + toolBarManager.add(getAction(ActionFactory.COPY.getId())); + toolBarManager.add(getAction(ActionFactory.PASTE.getId())); + toolBarManager.add(new Separator()); + toolBarManager.add(getAction(GEFActionConstants.ZOOM_IN)); + toolBarManager.add(getAction(GEFActionConstants.ZOOM_OUT)); + toolBarManager.add(new ZoomComboContributionItem(getPage())); + } + + @Override + protected void declareGlobalActionKeys() { + } + + @Override + public void contributeToMenu(IMenuManager menuManager) { + + super.contributeToMenu(menuManager); + + IContributionItem bMenu = menuManager + .find("de.bmotionstudio.gef.editor.menu"); + if (bMenu != null) { + + IMenuManager bmotionMenu = (IMenuManager) bMenu; + MenuManager viewMenu = new MenuManager("Editor"); + viewMenu.add(getAction(GEFActionConstants.ZOOM_IN)); + viewMenu.add(getAction(GEFActionConstants.ZOOM_OUT)); + viewMenu.add(new Separator()); + viewMenu.add(getAction(GEFActionConstants.TOGGLE_RULER_VISIBILITY)); + viewMenu.add(getAction(GEFActionConstants.TOGGLE_GRID_VISIBILITY)); + viewMenu.add(getAction(GEFActionConstants.TOGGLE_SNAP_TO_GEOMETRY)); + bmotionMenu + .insertAfter( + "de.bmotionstudio.gef.editor.command.openBMotionStudioWebsite", + viewMenu); + + } + + } + + public void setActiveEditor(IEditorPart editor) { + if (editor instanceof BMotionStudioEditor) { + super.setActiveEditor(((BMotionStudioEditor) editor).getEditPage()); + } else { + super.setActiveEditor(editor); + } + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/BMotionStudioEditor.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/BMotionStudioEditor.java new file mode 100644 index 0000000000000000000000000000000000000000..aea1df6d56a4a9813ebfe1dafb4608409a6faeda --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/BMotionStudioEditor.java @@ -0,0 +1,293 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IEditorSite; +import org.eclipse.ui.IFileEditorInput; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.WorkbenchException; +import org.eclipse.ui.part.MultiPageEditorPart; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.mapper.MapperWrapper; + +import de.bmotionstudio.gef.editor.animation.StaticListenerRegistry; +import de.bmotionstudio.gef.editor.internal.Animation; +import de.bmotionstudio.gef.editor.internal.BMSConverter512; +import de.bmotionstudio.gef.editor.model.Visualization; +import de.prob.core.ILifecycleListener; +import de.prob.logging.Logger; + +public class BMotionStudioEditor extends MultiPageEditorPart implements + ILifecycleListener { + + private BMotionStudioEditorPage editPage; + + private BMotionStudioRunPage runPage; + + private Visualization visualization; + + private Animation animation; + + private ArrayList<IRunPageListener> runPageListener = new ArrayList<IRunPageListener>(); + + @Override + protected void createPages() { + createEditPage(); + } + + private void createEditPage() { + editPage = new BMotionStudioEditorPage(getVisualization(), this); + try { + int index = addPage(editPage, getEditorInput()); + setPageText(index, "Edit"); + } catch (PartInitException e) { + e.printStackTrace(); + } + } + + public void createRunPage(Visualization visualization, Animation animation) { + StaticListenerRegistry.registerListener(this); + this.animation = animation; + + if (runPage != null) + runPage.dispose(); + + runPage = new BMotionStudioRunPage(visualization); + try { + int index = addPage(runPage, getEditorInput()); + setPageText(index, "Run"); + setActivePage(index); + fireRunPageCreatedListener(); + } catch (PartInitException e) { + } + } + + public void removeRunPage() { + fireRunPageRemovedListener(); + if (runPage != null) { + Display.getDefault().asyncExec(new Runnable() { + public void run() { + removePage(1); + } + }); + } + unregister(); + } + + private void fireRunPageCreatedListener() { + for (IRunPageListener listener : runPageListener) { + listener.runPageCreated(runPage); + } + } + + private void fireRunPageRemovedListener() { + for (IRunPageListener listener : runPageListener) { + listener.runPageRemoved(runPage); + } + } + + @Override + public void dispose() { + unregister(); + super.dispose(); + } + + public Visualization getVisualization() { + return visualization; + } + + public void setDirty(boolean dirty) { + editPage.setDirty(dirty); + } + + /** + * @see org.eclipse.ui.IEditorPart#init(IEditorSite, IEditorInput) + **/ + @Override + public void init(IEditorSite iSite, IEditorInput iInput) + throws PartInitException { + + super.init(iSite, iInput); + + IFile file = ((IFileEditorInput) iInput).getFile(); + + try { + + // ------------------------------------------------------- + + DocumentBuilderFactory dbFactory = DocumentBuilderFactory + .newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + Document doc = dBuilder.parse(file.getContents()); + NodeList nList = doc.getElementsByTagName("version"); + if (nList.item(0) != null) { + Element versionElement = (Element) nList.item(0); + String version = versionElement.getTextContent(); + if (version.equals("5.1.2")) { + new BMSConverter512(file); + } + } else { + new BMSConverter512(file); + } + + // ------------------------------------------------------- + + InputStream inputStream = file.getContents(); + + XStream xstream = new XStream() { + @Override + protected MapperWrapper wrapMapper(final MapperWrapper next) { + return new MapperWrapper(next) { + @Override + public boolean shouldSerializeMember( + @SuppressWarnings("rawtypes") final Class definedIn, + final String fieldName) { + if (definedIn == Object.class) + return false; + return super.shouldSerializeMember(definedIn, + fieldName); + } + }; + } + }; + + BMotionEditorPlugin.setAliases(xstream); + + visualization = (Visualization) xstream.fromXML(inputStream); + visualization.setProjectFile(((IFileEditorInput) getEditorInput()) + .getFile()); + // initLanguage(visualization); + + } catch (SAXException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (CoreException e) { + e.printStackTrace(); + } catch (ParserConfigurationException e) { + e.printStackTrace(); + } + + } + + @Override + public String getPartName() { + return visualization.getProjectFile().getName().replace(".bmso", "") + + " (" + getVisualization().getMachineName() + " - " + + getVisualization().getLanguage() + ")"; + } + + @Override + public void doSave(final IProgressMonitor monitor) { + editPage.doSave(monitor); + } + + @Override + public void doSaveAs() { + // Nothing to do here, this is never allowed + throw new IllegalAccessError("No way to enter this method."); + } + + @Override + public boolean isSaveAsAllowed() { + return false; + } + + @Override + protected void pageChange(int newPageIndex) { + String newPageString = getPageText(newPageIndex); + if (newPageString.equals("Run")) { + switchPerspective("de.bmotionstudio.perspective.run"); + } else { + switchPerspective("de.bmotionstudio.perspective.edit"); + } + } + + private void switchPerspective(String id) { + IWorkbench workbench = PlatformUI.getWorkbench(); + try { + workbench.showPerspective(id, workbench.getActiveWorkbenchWindow()); + } catch (WorkbenchException e) { + Logger.notifyUser( + "An error occured while trying to switch the perspective.", + e); + } + } + + public BMotionStudioEditorPage getEditPage() { + return this.editPage; + } + + public BMotionStudioRunPage getRunPage() { + return this.runPage; + } + + public void reset() { + removeRunPage(); + } + + private void unregister() { + getVisualization().setIsRunning(false); + StaticListenerRegistry.unregisterListener(this); + if (animation != null) { + animation.unregister(); + } + } + + public IEditorPart getCurrentPage() { + return getActiveEditor(); + } + + public void addRunPageListener(IRunPageListener listener) { + this.runPageListener.add(listener); + } + + public void removeRunPageListener(IRunPageListener listener) { + this.runPageListener.remove(listener); + } + + public double getZoomFactor() { + switch (getActivePage()) { + case 0: + return editPage.getRootEditPart().getZoomManager().getZoom(); + case 1: + return runPage.getRootEditPart().getZoomManager().getZoom(); + default: + return 1; + } + } + + @Override + protected void setActivePage(int pageIndex) { + super.setActivePage(pageIndex); + // TODO: This is a hack for fixing the selection bug in the editor! + getSite().setSelectionProvider( + editPage.getSite().getSelectionProvider()); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/BMotionStudioEditorPage.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/BMotionStudioEditorPage.java new file mode 100644 index 0000000000000000000000000000000000000000..3caccfa2fa3e71f4136f9672be62a451150ecf89 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/BMotionStudioEditorPage.java @@ -0,0 +1,810 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.util.ArrayList; +import java.util.EventObject; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.IExtensionRegistry; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.Platform; +import org.eclipse.draw2d.FigureCanvas; +import org.eclipse.draw2d.LightweightSystem; +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.draw2d.Viewport; +import org.eclipse.draw2d.parts.ScrollableThumbnail; +import org.eclipse.gef.ContextMenuProvider; +import org.eclipse.gef.DefaultEditDomain; +import org.eclipse.gef.KeyHandler; +import org.eclipse.gef.KeyStroke; +import org.eclipse.gef.LayerConstants; +import org.eclipse.gef.MouseWheelHandler; +import org.eclipse.gef.MouseWheelZoomHandler; +import org.eclipse.gef.SnapToGeometry; +import org.eclipse.gef.SnapToGrid; +import org.eclipse.gef.commands.CommandStack; +import org.eclipse.gef.commands.CommandStackListener; +import org.eclipse.gef.dnd.TemplateTransferDragSourceListener; +import org.eclipse.gef.editparts.ScalableRootEditPart; +import org.eclipse.gef.editparts.ZoomManager; +import org.eclipse.gef.palette.PaletteRoot; +import org.eclipse.gef.rulers.RulerProvider; +import org.eclipse.gef.ui.actions.ActionRegistry; +import org.eclipse.gef.ui.actions.GEFActionConstants; +import org.eclipse.gef.ui.actions.SelectionAction; +import org.eclipse.gef.ui.actions.ToggleGridAction; +import org.eclipse.gef.ui.actions.ToggleRulerVisibilityAction; +import org.eclipse.gef.ui.actions.ToggleSnapToGeometryAction; +import org.eclipse.gef.ui.actions.ZoomInAction; +import org.eclipse.gef.ui.actions.ZoomOutAction; +import org.eclipse.gef.ui.palette.FlyoutPaletteComposite; +import org.eclipse.gef.ui.palette.PaletteViewer; +import org.eclipse.gef.ui.palette.PaletteViewerProvider; +import org.eclipse.gef.ui.parts.ContentOutlinePage; +import org.eclipse.gef.ui.parts.GraphicalEditorWithFlyoutPalette; +import org.eclipse.gef.ui.parts.GraphicalViewerKeyHandler; +import org.eclipse.gef.ui.parts.ScrollingGraphicalViewer; +import org.eclipse.gef.ui.parts.SelectionSynchronizer; +import org.eclipse.gef.ui.parts.TreeViewer; +import org.eclipse.gef.ui.rulers.RulerComposite; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.SashForm; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IEditorSite; +import org.eclipse.ui.IFileEditorInput; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.actions.ActionFactory; +import org.eclipse.ui.part.IPageSite; +import org.eclipse.ui.views.contentoutline.IContentOutlinePage; +import org.eclipse.ui.views.properties.IPropertySheetPage; + +import com.thoughtworks.xstream.XStream; + +import de.bmotionstudio.gef.editor.action.CopyAction; +import de.bmotionstudio.gef.editor.action.ObserverAction; +import de.bmotionstudio.gef.editor.action.PasteAction; +import de.bmotionstudio.gef.editor.action.SchedulerEventAction; +import de.bmotionstudio.gef.editor.internal.BControlTransferDropTargetListener; +import de.bmotionstudio.gef.editor.library.AttributeTransferDropTargetListener; +import de.bmotionstudio.gef.editor.model.BMotionRuler; +import de.bmotionstudio.gef.editor.model.BMotionRulerProvider; +import de.bmotionstudio.gef.editor.model.Visualization; +import de.bmotionstudio.gef.editor.part.AppEditPartFactory; +import de.bmotionstudio.gef.editor.part.AppTreeEditPartFactory; + +public class BMotionStudioEditorPage extends GraphicalEditorWithFlyoutPalette { + + public final static String ID = "de.bmotionstudio.gef.editor"; + + private boolean isDirty; + + private KeyHandler sharedKeyHandler; + + private Visualization visualization; + + private RulerComposite rulerComp; + + // private BControl editArea; + + private BMotionStudioEditor bmotionStudioEditor; + + private BMotionSelectionSynchronizer bmotionSelectionSynchronizer; + + /** Palette component, holding the tools and b-controls. */ + private PaletteRoot palette; + + public BMotionStudioEditorPage(Visualization visualization, + BMotionStudioEditor bmotionStudioEditor) { + this.visualization = visualization; + this.bmotionStudioEditor = bmotionStudioEditor; + setEditDomain(new DefaultEditDomain(this)); + } + + @Override + public void selectionChanged(IWorkbenchPart part, ISelection selection) { + // If not the active editor, ignore selection changed. + if (getBMotionStudioEditor().equals( + getSite().getPage().getActiveEditor())) + updateActions(getSelectionActions()); + } + + /** + * @see org.eclipse.ui.IEditorPart#init(IEditorSite, IEditorInput) + **/ + public void init(IEditorSite iSite, IEditorInput iInput) + throws PartInitException { + super.init(iSite, iInput); + setSite(iSite); + // add CommandStackListener + getCommandStack().addCommandStackListener(getCommandStackListener()); + } + + /** + * @see org.eclipse.gef.ui.parts.GraphicalEditor#initializeGraphicalViewer() + **/ + protected void initializeGraphicalViewer() { + + super.initializeGraphicalViewer(); + + getGraphicalViewer().setContents(getVisualization()); + + getGraphicalViewer().addDropTargetListener( + new BControlTransferDropTargetListener(getGraphicalViewer(), + visualization)); + getGraphicalViewer().addDropTargetListener( + new AttributeTransferDropTargetListener(getGraphicalViewer(), + getSite().getPart())); + + getPalettePreferences().setPaletteState( + FlyoutPaletteComposite.STATE_PINNED_OPEN); + + } + + @Override + protected PaletteViewerProvider createPaletteViewerProvider() { + return new PaletteViewerProvider(getEditDomain()) { + protected void configurePaletteViewer(PaletteViewer viewer) { + super.configurePaletteViewer(viewer); + viewer.addDragSourceListener(new TemplateTransferDragSourceListener( + viewer)); + } + + protected void hookPaletteViewer(PaletteViewer viewer) { + super.hookPaletteViewer(viewer); + } + }; + } + + /** + * @see org.eclipse.ui.IEditorPart#isSaveAsAllowed() + **/ + public boolean isSaveAsAllowed() { + return true; + } + + /** + * Creates an appropriate output stream and writes the activity diagram out + * to this stream. + * + * @param os + * the base output stream + * @throws IOException + */ + protected void createOutputStream(OutputStream os) throws IOException { + OutputStreamWriter writer = new OutputStreamWriter(os, "UTF8"); + XStream xstream = new XStream(); + BMotionEditorPlugin.setAliases(xstream); + xstream.toXML(visualization, writer); + } + + /** + * @see org.eclipse.ui.IEditorPart#doSave(IProgressMonitor) + **/ + public void doSave(IProgressMonitor iMonitor) { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + try { + saveProperties(); + createOutputStream(out); + IFile file = ((IFileEditorInput) getEditorInput()).getFile(); + file.setContents(new ByteArrayInputStream(out.toByteArray()), true, + false, iMonitor); + getCommandStack().markSaveLocation(); + } catch (CoreException ce) { + ce.printStackTrace(); + } catch (IOException ioe) { + ioe.printStackTrace(); + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.IWorkbenchPart#dispose() + */ + public void dispose() { + // remove CommandStackListener + getCommandStack().removeCommandStackListener(getCommandStackListener()); + // important: always call super implementation of dispose + super.dispose(); + } + + /** + * @see org.eclipse.ui.IEditorPart#doSaveAs() + **/ + public void doSaveAs() { + // Nothing to do here, this is never allowed + throw new IllegalAccessError("No way to enter this method."); + } + + @Override + public Object getAdapter(@SuppressWarnings("rawtypes") Class type) { + if (type == ZoomManager.class) + return ((ScalableRootEditPart) getGraphicalViewer() + .getRootEditPart()).getZoomManager(); + if (type == IContentOutlinePage.class) + return new BMotionOutlinePage(); + if (type == IPropertySheetPage.class) { + BMotionStudioPropertySheet page = new BMotionStudioPropertySheet(); + page.setRootEntry(new CustomSortPropertySheetEntry( + getCommandStack())); + return page; + } + return super.getAdapter(type); + } + + /** + * @see org.eclipse.ui.IEditorPart#gotoMarker(IMarker) + **/ + public void gotoMarker(IMarker iMarker) { + } + + /** + * Returns the KeyHandler with common bindings for both the Outline and + * Graphical Views. For example, delete is a common action. + */ + protected KeyHandler getCommonKeyHandler() { + if (sharedKeyHandler == null) { + sharedKeyHandler = new KeyHandler(); + sharedKeyHandler.put( + KeyStroke.getPressed(SWT.F2, 0), + getActionRegistry().getAction( + GEFActionConstants.DIRECT_EDIT)); + sharedKeyHandler + .put(KeyStroke.getPressed(SWT.DEL, 127, 0), + getActionRegistry().getAction( + ActionFactory.DELETE.getId())); + + sharedKeyHandler.put(KeyStroke.getPressed('+', SWT.KEYPAD_ADD, 0), + getActionRegistry().getAction(GEFActionConstants.ZOOM_IN)); + + sharedKeyHandler.put( + KeyStroke.getPressed('-', SWT.KEYPAD_SUBTRACT, 0), + getActionRegistry().getAction(GEFActionConstants.ZOOM_OUT)); + + sharedKeyHandler.put( + KeyStroke.getPressed(SWT.F2, 0), + getActionRegistry().getAction( + GEFActionConstants.DIRECT_EDIT)); + } + return sharedKeyHandler; + } + + public void setDirty(boolean dirty) { + if (isDirty() != dirty) { + isDirty = dirty; + firePropertyChange(IEditorPart.PROP_DIRTY); + } + } + + /* + * @see EditorPart#isDirty + */ + @Override + public boolean isDirty() { + return isDirty; + } + + @SuppressWarnings("unchecked") + public void createActions() { + + super.createActions(); + + ActionRegistry registry = getActionRegistry(); + + installCustomActions(); + + IAction action = new CopyAction(this); + registry.registerAction(action); + getSelectionActions().add(action.getId()); + + action = new PasteAction(this); + registry.registerAction(action); + getSelectionActions().add(action.getId()); + + installObserverActions(); + installSchedulerActions(); + + } + + @SuppressWarnings("unchecked") + private void installObserverActions() { + + IAction action; + ActionRegistry registry = getActionRegistry(); + + IExtensionRegistry reg = Platform.getExtensionRegistry(); + IExtensionPoint extensionPoint = reg + .getExtensionPoint("de.bmotionstudio.gef.editor.observer"); + for (IExtension extension : extensionPoint.getExtensions()) { + for (IConfigurationElement configurationElement : extension + .getConfigurationElements()) { + + if ("observer".equals(configurationElement.getName())) { + + String observerClassName = configurationElement + .getAttribute("class"); + + action = new ObserverAction(this); + action.setId("de.bmotionstudio.gef.editor.observerAction." + + observerClassName); + ((ObserverAction) action).setClassName(observerClassName); + registry.registerAction(action); + getSelectionActions().add( + "de.bmotionstudio.gef.editor.observerAction." + + observerClassName); + + } + + } + + } + + } + + @SuppressWarnings("unchecked") + private void installSchedulerActions() { + + IAction action; + ActionRegistry registry = getActionRegistry(); + + IExtensionRegistry reg = Platform.getExtensionRegistry(); + IExtensionPoint extensionPoint = reg + .getExtensionPoint("de.bmotionstudio.gef.editor.schedulerEvent"); + for (IExtension extension : extensionPoint.getExtensions()) { + for (IConfigurationElement configurationElement : extension + .getConfigurationElements()) { + + if ("schedulerEvent".equals(configurationElement.getName())) { + + String sClassName = configurationElement + .getAttribute("class"); + + action = new SchedulerEventAction(this); + action.setId("de.bmotionstudio.gef.editor.SchedulerEventAction." + + sClassName); + ((SchedulerEventAction) action).setClassName(sClassName); + registry.registerAction(action); + getSelectionActions().add( + "de.bmotionstudio.gef.editor.SchedulerEventAction." + + sClassName); + + } + + } + + } + + } + + @SuppressWarnings("unchecked") + private void installCustomActions() { + + ActionRegistry registry = getActionRegistry(); + + IExtensionRegistry reg = Platform.getExtensionRegistry(); + IExtensionPoint extensionPoint = reg + .getExtensionPoint("de.bmotionstudio.gef.editor.installActions"); + for (IExtension extension : extensionPoint.getExtensions()) { + for (IConfigurationElement configurationElement : extension + .getConfigurationElements()) { + + if ("action".equals(configurationElement.getName())) { + + try { + + IInstallActions installActionsClass = (IInstallActions) configurationElement + .createExecutableExtension("class"); + + installActionsClass.installActions(this); + HashMap<String, Action> actionMap = installActionsClass + .getActionMap(); + + for (Map.Entry<String, Action> entry : actionMap + .entrySet()) { + + registry.registerAction(entry.getValue()); + if (entry.getValue() instanceof SelectionAction) + getSelectionActions().add(entry.getKey()); + + } + + } catch (final CoreException e) { + e.printStackTrace(); + } + + } + + } + + } + + } + + protected Control getGraphicalControl() { + return rulerComp; + } + + protected void createGraphicalViewer(Composite parent) { + rulerComp = new RulerComposite(parent, SWT.NONE); + super.createGraphicalViewer(rulerComp); + rulerComp + .setGraphicalViewer((ScrollingGraphicalViewer) getGraphicalViewer()); + } + + /** + * @see org.eclipse.gef.ui.parts.GraphicalEditor#configureGraphicalViewer() + **/ + protected void configureGraphicalViewer() { + + double[] zoomLevels; + + super.configureGraphicalViewer(); + ScrollingGraphicalViewer viewer = (ScrollingGraphicalViewer) getGraphicalViewer(); + + viewer.setEditPartFactory(new AppEditPartFactory()); + + ScalableRootEditPart rootEditPart = new ScalableRootEditPart(); + viewer.setRootEditPart(rootEditPart); + + ZoomManager manager = rootEditPart.getZoomManager(); + getActionRegistry().registerAction(new ZoomInAction(manager)); + getActionRegistry().registerAction(new ZoomOutAction(manager)); + + zoomLevels = new double[] { 0.25, 0.5, 0.75, 1.0, 1.5, 2.0, 2.5, 3.0, + 4.0, 5.0, 10.0, 20.0 }; + manager.setZoomLevels(zoomLevels); + ArrayList<String> zoomContributions = new ArrayList<String>(); + zoomContributions.add(ZoomManager.FIT_ALL); + zoomContributions.add(ZoomManager.FIT_HEIGHT); + zoomContributions.add(ZoomManager.FIT_WIDTH); + manager.setZoomLevelContributions(zoomContributions); + + viewer.setProperty(MouseWheelHandler.KeyGenerator.getKey(SWT.NONE), + MouseWheelZoomHandler.SINGLETON); + + // viewer.setKeyHandler(keyHandler); + + viewer.setKeyHandler(new GraphicalViewerKeyHandler(viewer) + .setParent(getCommonKeyHandler())); + + loadProperties(); + + getActionRegistry().registerAction( + new ToggleRulerVisibilityAction(getGraphicalViewer())); + getActionRegistry().registerAction( + new ToggleSnapToGeometryAction(getGraphicalViewer())); + getActionRegistry().registerAction( + new ToggleGridAction(getGraphicalViewer())); + + ContextMenuProvider provider = new AppContextMenuProvider(viewer, + getActionRegistry()); + viewer.setContextMenu(provider); + + } + + protected void loadProperties() { + + // Ruler properties + BMotionRuler ruler = getVisualization() + .getRuler(PositionConstants.WEST); + RulerProvider provider = null; + if (ruler != null) { + provider = new BMotionRulerProvider(ruler); + } + getGraphicalViewer().setProperty(RulerProvider.PROPERTY_VERTICAL_RULER, + provider); + ruler = getVisualization().getRuler(PositionConstants.NORTH); + provider = null; + if (ruler != null) { + provider = new BMotionRulerProvider(ruler); + } + getGraphicalViewer().setProperty( + RulerProvider.PROPERTY_HORIZONTAL_RULER, provider); + getGraphicalViewer().setProperty( + RulerProvider.PROPERTY_RULER_VISIBILITY, + getVisualization().getRulerVisibility()); + getGraphicalViewer().setProperty(SnapToGeometry.PROPERTY_SNAP_ENABLED, + getVisualization().isSnapToGeometryEnabled()); + getGraphicalViewer().setProperty(SnapToGrid.PROPERTY_GRID_ENABLED, + getVisualization().isGridEnabled()); + getGraphicalViewer().setProperty(SnapToGrid.PROPERTY_GRID_VISIBLE, + getVisualization().isGridEnabled()); + + getPalettePreferences().setPaletteState( + FlyoutPaletteComposite.STATE_PINNED_OPEN); + + } + + protected void saveProperties() { + getVisualization().setRulerVisibility( + ((Boolean) getGraphicalViewer().getProperty( + RulerProvider.PROPERTY_RULER_VISIBILITY)) + .booleanValue()); + getVisualization().setGridEnabled( + ((Boolean) getGraphicalViewer().getProperty( + SnapToGrid.PROPERTY_GRID_ENABLED)).booleanValue()); + getVisualization().setSnapToGeometry( + ((Boolean) getGraphicalViewer().getProperty( + SnapToGeometry.PROPERTY_SNAP_ENABLED)).booleanValue()); + } + + /** + * The <code>CommandStackListener</code> that listens for + * <code>CommandStack </code>changes. + */ + private CommandStackListener commandStackListener = new CommandStackListener() { + public void commandStackChanged(EventObject event) { + setDirty(getCommandStack().isDirty()); + } + }; + + /** + * Returns the <code>CommandStack</code> of this editor's + * <code>EditDomain</code>. + * + * @return the <code>CommandStack</code> + */ + @Override + public CommandStack getCommandStack() { + return getEditDomain().getCommandStack(); + } + + /** + * Returns the <code>CommandStackListener</code>. + * + * @return the <code>CommandStackListener</code> + */ + protected CommandStackListener getCommandStackListener() { + return commandStackListener; + } + + /** + * Returns the palette root. + */ + protected PaletteRoot getPaletteRoot() { + if (palette == null) { + palette = new EditorPaletteFactory().createPalette(visualization); + } + return palette; + } + + protected FigureCanvas getEditor() { + return (FigureCanvas) getGraphicalViewer().getControl(); + } + + @Override + public SelectionSynchronizer getSelectionSynchronizer() { + if (bmotionSelectionSynchronizer == null) + bmotionSelectionSynchronizer = new BMotionSelectionSynchronizer( + bmotionStudioEditor); + return bmotionSelectionSynchronizer; + } + + protected class BMotionOutlinePage extends ContentOutlinePage { + + private SashForm sash; + + private ScrollableThumbnail thumbnail; + private DisposeListener disposeListener; + + public BMotionOutlinePage() { + super(new TreeViewer()); + } + + public void init(IPageSite pageSite) { + super.init(pageSite); + IActionBars bars = pageSite.getActionBars(); + ActionRegistry ar = getActionRegistry(); + bars.setGlobalActionHandler(ActionFactory.UNDO.getId(), + ar.getAction(ActionFactory.UNDO.getId())); + bars.setGlobalActionHandler(ActionFactory.REDO.getId(), + ar.getAction(ActionFactory.REDO.getId())); + bars.setGlobalActionHandler(ActionFactory.DELETE.getId(), + ar.getAction(ActionFactory.DELETE.getId())); + bars.setGlobalActionHandler(ActionFactory.COPY.getId(), + ar.getAction(ActionFactory.COPY.getId())); + bars.setGlobalActionHandler(ActionFactory.PASTE.getId(), + ar.getAction(ActionFactory.PASTE.getId())); + buildCustomActions(bars, ar); + bars.updateActionBars(); + } + + protected void configureOutlineViewer() { + getViewer().setEditDomain(getEditDomain()); + getViewer().setEditPartFactory(new AppTreeEditPartFactory()); + ContextMenuProvider provider = new AppContextMenuProvider( + getViewer(), getActionRegistry()); + getViewer().setContextMenu(provider); + getViewer().setKeyHandler(getCommonKeyHandler()); + } + + protected void initializeOutlineViewer() { + setContents(getVisualization()); + } + + public void setContents(Object contents) { + getViewer().setContents(contents); + } + + protected void hookOutlineViewer() { + getSelectionSynchronizer().addViewer(getViewer()); + } + + protected void unhookOutlineViewer() { + getSelectionSynchronizer().removeViewer(getViewer()); + if (getGraphicalViewer().getControl() != null + && !getGraphicalViewer().getControl().isDisposed()) + getGraphicalViewer().getControl().removeDisposeListener( + disposeListener); + } + + @Override + public void createControl(Composite parent) { + initializeOverview(parent); + getGraphicalViewer().getControl().addDisposeListener( + disposeListener); + configureOutlineViewer(); + hookOutlineViewer(); + initializeOutlineViewer(); + createMenu(); + } + + /** + * + */ + private void createMenu() { + + Action expandAllAction = new Action("Expand All") { + + @Override + public void run() { + for (TreeItem item : ((Tree) getViewer().getControl()) + .getItems()) { + item.setExpanded(true); + } + } + + }; + + Action collapseAllAction = new Action("Collapse All") { + + @Override + public void run() { + for (TreeItem item : ((Tree) getViewer().getControl()) + .getItems()) { + item.setExpanded(false); + } + } + + }; + // collapseAllAction + // .setImageDescriptor(ImageDescriptor + // .createFromImage(PlatformUI + // .getWorkbench() + // .getSharedImages() + // .getImage( + // ISharedImages.IMG_ELCL_COLLAPSEALL))); + + getSite().getActionBars().getMenuManager().add(expandAllAction); + getSite().getActionBars().getMenuManager().add(collapseAllAction); + + } + + protected void initializeOverview(Composite parent) { + sash = new SashForm(parent, SWT.VERTICAL); + + getViewer().createControl(sash); + + Canvas canvas = new Canvas(sash, SWT.BORDER); + canvas.setBackground(Display.getDefault().getSystemColor( + SWT.COLOR_WHITE)); + LightweightSystem lws = new LightweightSystem(canvas); + + thumbnail = new ScrollableThumbnail( + (Viewport) ((ScalableRootEditPart) getGraphicalViewer() + .getRootEditPart()).getFigure()); + thumbnail.setSource(((ScalableRootEditPart) getGraphicalViewer() + .getRootEditPart()) + .getLayer(LayerConstants.PRINTABLE_LAYERS)); + + lws.setContents(thumbnail); + + disposeListener = new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + if (thumbnail != null) { + thumbnail.deactivate(); + thumbnail = null; + } + } + }; + } + + public Control getControl() { + return sash; + } + + public void dispose() { + unhookOutlineViewer(); + super.dispose(); + } + + } + + private void buildCustomActions(IActionBars bars, ActionRegistry ar) { + + IExtensionRegistry reg = Platform.getExtensionRegistry(); + IExtensionPoint extensionPoint = reg + .getExtensionPoint("de.bmotionstudio.gef.editor.installMenu"); + for (IExtension extension : extensionPoint.getExtensions()) { + for (IConfigurationElement configurationElement : extension + .getConfigurationElements()) { + + if ("menu".equals(configurationElement.getName())) { + + try { + + IInstallMenu installMenuClass = (IInstallMenu) configurationElement + .createExecutableExtension("class"); + + installMenuClass.installBar(bars, getActionRegistry()); + + } catch (final CoreException e) { + e.printStackTrace(); + } + + } + + } + + } + + } + + public Visualization getVisualization() { + return visualization; + } + + public void setBMotionStudioEditor(BMotionStudioEditor bmotionStudioEditor) { + this.bmotionStudioEditor = bmotionStudioEditor; + } + + public BMotionStudioEditor getBMotionStudioEditor() { + return bmotionStudioEditor; + } + + public ScalableRootEditPart getRootEditPart() { + return (ScalableRootEditPart) getGraphicalViewer().getRootEditPart(); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/BMotionStudioImage.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/BMotionStudioImage.java new file mode 100644 index 0000000000000000000000000000000000000000..b3eaa999e181a45a3691bf94e1324dbf3d46834f --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/BMotionStudioImage.java @@ -0,0 +1,136 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.IExtensionRegistry; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.ImageRegistry; +import org.eclipse.swt.graphics.Image; +import org.eclipse.ui.plugin.AbstractUIPlugin; + +public class BMotionStudioImage { + + private static ImageRegistry imageReg = new ImageRegistry(); + private static boolean isInit = false; + + public static final String IMG_LOGO_B = "logo_b"; + public static final String IMG_LOGO_BMOTION = "logo_bmotion"; + public static final String IMG_LOGO_BMOTION64 = "logo_bmotion64"; + + public static final String IMG_ICON_MOTION = "icon_motion"; + public static final String IMG_ICON_MOTION_WIZ = "icon_motion_wiz"; + + public static ImageDescriptor getImageDescriptor(final String path) { + return getImageDescriptor(BMotionEditorPlugin.PLUGIN_ID, path); + } + + public static ImageDescriptor getImageDescriptor(final String pluginID, + final String path) { + return AbstractUIPlugin.imageDescriptorFromPlugin(pluginID, path); + } + + public static void registerImage(final String key, final String path) { + ImageDescriptor desc = getImageDescriptor(path); + imageReg.put(key, desc); + } + + public static void registerImage(final String key, final String pluginID, + final String path) { + ImageDescriptor desc = getImageDescriptor(pluginID, path); + imageReg.put(key, desc); + } + + public static Image getImage(final String key) { + if (!isInit) + initializeImageRegistry(); + return imageReg.get(key); + } + + public static Image getBControlImage(final String bcontrolID) { + if (!isInit) + initializeImageRegistry(); + return getImage("icon_control_" + bcontrolID); + } + + private static void initializeImageRegistry() { + + registerImage(IMG_LOGO_B, "icons/logo_b.gif"); + registerImage(IMG_LOGO_BMOTION, "icons/logo_bmotion.png"); + registerImage(IMG_LOGO_BMOTION64, "icons/logo_bmotion_64.png"); + registerImage(IMG_ICON_MOTION, "icons/icon_motion.gif"); + registerImage(IMG_ICON_MOTION_WIZ, "icons/icon_motion_wiz.gif"); + + registerBControlImages(); + + final IExtensionRegistry reg = Platform.getExtensionRegistry(); + final IExtensionPoint extensionPoint = reg + .getExtensionPoint("de.bmotionstudio.gef.editor.registerImages"); + + for (final IExtension extension : extensionPoint.getExtensions()) { + for (final IConfigurationElement configurationElement : extension + .getConfigurationElements()) { + + if ("registerImages".equals(configurationElement.getName())) { + + try { + + IBMotionStudioImageRegistry imageReg = (IBMotionStudioImageRegistry) configurationElement + .createExecutableExtension("class"); + + imageReg.registerImages(); + + } catch (CoreException e) { + e.printStackTrace(); + } + + } + + } + + } + + isInit = true; + + } + + private static void registerBControlImages() { + + final IExtensionRegistry registry = Platform.getExtensionRegistry(); + final IExtensionPoint extensionPoint = registry + .getExtensionPoint("de.bmotionstudio.gef.editor.control"); + + for (final IExtension extension : extensionPoint.getExtensions()) { + + for (final IConfigurationElement configurationElement : extension + .getConfigurationElements()) { + + if ("control".equals(configurationElement.getName())) { + + final String icon = configurationElement + .getAttribute("icon"); + final String ID = configurationElement.getAttribute("id"); + final String sourcePluginID = configurationElement + .getContributor().getName(); + + final String key = "icon_control_" + ID; + + registerImage(key, sourcePluginID, icon); + + } + + } + + } + + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/BMotionStudioPropertySheet.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/BMotionStudioPropertySheet.java new file mode 100644 index 0000000000000000000000000000000000000000..64eb3321564db5a6915c5bd80557728b72a3e203 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/BMotionStudioPropertySheet.java @@ -0,0 +1,35 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor; + +import org.eclipse.ui.views.properties.IPropertySheetEntry; +import org.eclipse.ui.views.properties.PropertySheetPage; +import org.eclipse.ui.views.properties.PropertySheetSorter; + +/** + * @author Lukas Ladenberger + * + */ +public class BMotionStudioPropertySheet extends PropertySheetPage { + + public BMotionStudioPropertySheet() { + super(); + setSorter(new PropertySheetSorter() { + @Override + public int compare(IPropertySheetEntry entryA, + IPropertySheetEntry entryB) { + return getCollator() + .compare( + ((CustomSortPropertySheetEntry) entryA) + .getFullDisplayName(), + ((CustomSortPropertySheetEntry) entryB) + .getFullDisplayName()); + } + }); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/BMotionStudioRunPage.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/BMotionStudioRunPage.java new file mode 100644 index 0000000000000000000000000000000000000000..36b084166896ebf03787820cba0f5221acd09430 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/BMotionStudioRunPage.java @@ -0,0 +1,194 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor; + +import java.util.ArrayList; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.gef.DefaultEditDomain; +import org.eclipse.gef.GraphicalViewer; +import org.eclipse.gef.KeyHandler; +import org.eclipse.gef.KeyStroke; +import org.eclipse.gef.MouseWheelHandler; +import org.eclipse.gef.MouseWheelZoomHandler; +import org.eclipse.gef.SnapToGeometry; +import org.eclipse.gef.SnapToGrid; +import org.eclipse.gef.editparts.ScalableRootEditPart; +import org.eclipse.gef.editparts.ZoomManager; +import org.eclipse.gef.rulers.RulerProvider; +import org.eclipse.gef.ui.actions.GEFActionConstants; +import org.eclipse.gef.ui.actions.ZoomInAction; +import org.eclipse.gef.ui.actions.ZoomOutAction; +import org.eclipse.gef.ui.parts.GraphicalEditor; +import org.eclipse.gef.ui.parts.ScrollingGraphicalViewer; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.SWT; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.actions.ActionFactory; + +import de.bmotionstudio.gef.editor.model.Visualization; +import de.bmotionstudio.gef.editor.part.AppEditPartFactory; + +public class BMotionStudioRunPage extends GraphicalEditor { + + private Visualization visualization; + + private KeyHandler keyHandler; + + // private final Cursor cursor = new Cursor(Display.getCurrent(), + // SWT.CURSOR_HAND); + + public BMotionStudioRunPage(Visualization visualization) { + setEditDomain(new DefaultEditDomain(this)); + this.visualization = visualization; + } + + @Override + public Object getAdapter(@SuppressWarnings("rawtypes") Class type) { + if (type == ZoomManager.class) + return ((ScalableRootEditPart) getGraphicalViewer() + .getRootEditPart()).getZoomManager(); + return super.getAdapter(type); + } + + public void selectionChanged(IWorkbenchPart part, ISelection selection) { + // ignore selection changed. + } + + @Override + protected void initializeGraphicalViewer() { + + final GraphicalViewer viewer = getGraphicalViewer(); + + viewer.setContents(getVisualization()); + + // viewer.getControl().addMouseMoveListener(new MouseMoveListener() { + // + // public void mouseMove(MouseEvent e) { + // + // EditPart part = viewer.findObjectAt(new Point(e.x, e.y)); + // if (part instanceof AppAbstractEditPart) { + // AppAbstractEditPart bpart = (AppAbstractEditPart) viewer + // .findObjectAt(new Point(e.x, e.y)); + // + // BControl bcontrol = (BControl) bpart.getModel(); + // if (bcontrol.hasEvent(AttributeConstants.EVENT_MOUSECLICK)) + // bpart.getFigure().setCursor(cursor); + // } + // + // } + // + // }); + // viewer.getControl().addMouseListener(new MouseListener() { + // + // public void mouseDoubleClick(final MouseEvent e) { + // EditPart part = viewer.findObjectAt(new Point(e.x, e.y)); + // if (part instanceof AppAbstractEditPart) { + // AppAbstractEditPart bpart = (AppAbstractEditPart) viewer + // .findObjectAt(new Point(e.x, e.y)); + // bpart.executeEvent(AttributeConstants.EVENT_MOUSEDBLCLICK, + // e); + // } + // } + // + // public void mouseDown(final MouseEvent e) { + // EditPart part = viewer.findObjectAt(new Point(e.x, e.y)); + // if (part instanceof AppAbstractEditPart) { + // AppAbstractEditPart bpart = (AppAbstractEditPart) viewer + // .findObjectAt(new Point(e.x, e.y)); + // bpart.executeEvent(AttributeConstants.EVENT_MOUSECLICK, e); + // } + // } + // + // public void mouseUp(final MouseEvent e) { + // } + // + // }); + + } + + public Visualization getVisualization() { + return this.visualization; + } + + /** + * @see org.eclipse.gef.ui.parts.GraphicalEditor#configureGraphicalViewer() + **/ + protected void configureGraphicalViewer() { + + double[] zoomLevels; + + super.configureGraphicalViewer(); + ScrollingGraphicalViewer viewer = (ScrollingGraphicalViewer) getGraphicalViewer(); + + viewer.setEditPartFactory(new AppEditPartFactory()); + + ScalableRootEditPart rootEditPart = new ScalableRootEditPart(); + viewer.setRootEditPart(rootEditPart); + + ZoomManager manager = rootEditPart.getZoomManager(); + getActionRegistry().registerAction(new ZoomInAction(manager)); + getActionRegistry().registerAction(new ZoomOutAction(manager)); + + zoomLevels = new double[] { 0.25, 0.5, 0.75, 1.0, 1.5, 2.0, 2.5, 3.0, + 4.0, 5.0, 10.0, 20.0 }; + manager.setZoomLevels(zoomLevels); + ArrayList<String> zoomContributions = new ArrayList<String>(); + zoomContributions.add(ZoomManager.FIT_ALL); + zoomContributions.add(ZoomManager.FIT_HEIGHT); + zoomContributions.add(ZoomManager.FIT_WIDTH); + manager.setZoomLevelContributions(zoomContributions); + + keyHandler = new KeyHandler(); + + keyHandler.put(KeyStroke.getPressed(SWT.DEL, 127, 0), + getActionRegistry().getAction(ActionFactory.DELETE.getId())); + + keyHandler.put(KeyStroke.getPressed('+', SWT.KEYPAD_ADD, 0), + getActionRegistry().getAction(GEFActionConstants.ZOOM_IN)); + + keyHandler.put(KeyStroke.getPressed('-', SWT.KEYPAD_SUBTRACT, 0), + getActionRegistry().getAction(GEFActionConstants.ZOOM_OUT)); + + viewer.setProperty(MouseWheelHandler.KeyGenerator.getKey(SWT.NONE), + MouseWheelZoomHandler.SINGLETON); + + viewer.setKeyHandler(keyHandler); + + loadProperties(); + + } + + @Override + public void doSave(IProgressMonitor monitor) { + // Nothing to do here, this is never allowed + throw new IllegalAccessError("No way to enter this method."); + } + + protected void loadProperties() { + getGraphicalViewer().setProperty( + RulerProvider.PROPERTY_RULER_VISIBILITY, false); + getGraphicalViewer().setProperty(SnapToGeometry.PROPERTY_SNAP_ENABLED, + false); + getGraphicalViewer().setProperty(SnapToGrid.PROPERTY_GRID_ENABLED, + false); + getGraphicalViewer().setProperty(SnapToGrid.PROPERTY_GRID_VISIBLE, + false); + } + + public ScalableRootEditPart getRootEditPart() { + return (ScalableRootEditPart) getGraphicalViewer().getRootEditPart(); + } + + /** + * The run page editor should be never dirty! + */ + public boolean isDirty() { + return false; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/BMotionStudioSWTConstants.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/BMotionStudioSWTConstants.java new file mode 100644 index 0000000000000000000000000000000000000000..df47b4a385b8ac3d3f3e4019ceb49e2106b20f0b --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/BMotionStudioSWTConstants.java @@ -0,0 +1,31 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ +package de.bmotionstudio.gef.editor; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.widgets.Display; + +/** + * @author Lukas Ladenberger + * + */ +public class BMotionStudioSWTConstants { + + public static final String RODIN_FONT_KEY = "org.rodinp.keyboard.textFont"; + + public final static Color containerHighlighting1 = new Color(null, 200, + 200, 240); + + public final static Color containerHighlighting2 = new Color(null, 200, + 240, 200); + + public final static Font fontArial10 = new Font(Display.getDefault(), + new FontData("Arial", 10, SWT.NONE)); + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/BindingObject.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/BindingObject.java new file mode 100644 index 0000000000000000000000000000000000000000..e4338e73da0878fe9fdf154b6386acdae9b90f15 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/BindingObject.java @@ -0,0 +1,64 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor; + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; + +/** + * + * @author Lukas Ladenberger + * + */ +public abstract class BindingObject implements Cloneable { + + private transient PropertyChangeSupport propertyChangeSupport; + + public void addPropertyChangeListener(PropertyChangeListener listener) { + getPropertyChangeSupport().addPropertyChangeListener(listener); + } + + public void addPropertyChangeListener(String propertyName, + PropertyChangeListener listener) { + getPropertyChangeSupport().addPropertyChangeListener(propertyName, + listener); + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + getPropertyChangeSupport().removePropertyChangeListener(listener); + } + + public void removePropertyChangeListener(String propertyName, + PropertyChangeListener listener) { + getPropertyChangeSupport().removePropertyChangeListener(propertyName, + listener); + } + + protected void firePropertyChange(String propertyName, Object oldValue, + Object newValue) { + getPropertyChangeSupport().firePropertyChange(propertyName, oldValue, + newValue); + } + + public void setPropertyChangeSupport( + PropertyChangeSupport propertyChangeSupport) { + this.propertyChangeSupport = propertyChangeSupport; + } + + public PropertyChangeSupport getPropertyChangeSupport() { + if (propertyChangeSupport == null) + propertyChangeSupport = new PropertyChangeSupport(this); + return propertyChangeSupport; + } + + public BindingObject clone() throws CloneNotSupportedException { + BindingObject clone = (BindingObject) super.clone(); + clone.setPropertyChangeSupport(null); + return clone; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/ButtonGroupHelper.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/ButtonGroupHelper.java new file mode 100644 index 0000000000000000000000000000000000000000..802557645e171563ed1c1f936f59a82199cb4a5c --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/ButtonGroupHelper.java @@ -0,0 +1,41 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; + +import de.bmotionstudio.gef.editor.model.BControl; + +public class ButtonGroupHelper { + + private static HashMap<String, Collection<BControl>> map = new HashMap<String, Collection<BControl>>(); + + public ButtonGroupHelper() { + } + + public static Collection<BControl> getButtonGroup(String buttonGroupID) { + return map.get(buttonGroupID); + } + + public static void addToButtonGroup(String buttonGroupID, BControl control) { + Collection<BControl> group; + if (!map.containsKey(buttonGroupID)) { + group = new ArrayList<BControl>(); + map.put(buttonGroupID, group); + } else { + group = map.get(buttonGroupID); + } + group.add(control); + } + + public static void removeButtonGroup(String buttonGroupID) { + map.remove(buttonGroupID); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/CustomSortPropertySheetEntry.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/CustomSortPropertySheetEntry.java new file mode 100644 index 0000000000000000000000000000000000000000..41ffbc617ba79ea37ce2b14eaf28c0badc6bf3b4 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/CustomSortPropertySheetEntry.java @@ -0,0 +1,53 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor; + +import org.eclipse.gef.commands.CommandStack; +import org.eclipse.gef.ui.properties.UndoablePropertySheetEntry; +import org.eclipse.ui.views.properties.PropertySheetEntry; + +/** + * Overridden to allow specific ordering of properties. Order can be forced by + * prepending text followed by a ':' for example: + * + * a1:id a2:x a3:y a4:width a5:height + * + * forces the above order. + * + * When the name is displayed, the getDisplayName method removes the prefix. + * + * Any number of colons maybe used, for example: + * + * bean:property:x bean:eventset:action bean:property:y + * + * (not a real, applicable example, but it gets the idea across) + * + */ +public class CustomSortPropertySheetEntry extends UndoablePropertySheetEntry { + + public CustomSortPropertySheetEntry(CommandStack stack) { + super(stack); + } + + protected PropertySheetEntry createChildEntry() { + return new CustomSortPropertySheetEntry(getCommandStack()); + } + + @Override + public String getDisplayName() { + String displayName = super.getDisplayName(); + int colon = displayName.lastIndexOf(':'); + if (colon != -1) + displayName = displayName.substring(colon + 1); + return displayName; + } + + public String getFullDisplayName() { + return getDescriptor().getDisplayName(); + } + +} \ No newline at end of file diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/EditorImageRegistry.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/EditorImageRegistry.java new file mode 100644 index 0000000000000000000000000000000000000000..145934f51895ba39a4d5ffabf34bd293aab14f24 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/EditorImageRegistry.java @@ -0,0 +1,76 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor; + +public class EditorImageRegistry implements IBMotionStudioImageRegistry { + + public static final String IMG_ICON_ADD = "icon_add"; + public static final String IMG_ICON_CHOP = "icon_chop"; + public static final String IMG_ICON_DELETE = "icon_delete"; + public static final String IMG_ICON_DELETE21 = "icon_delete21"; + public static final String IMG_ICON_EDIT = "icon_edit"; + public static final String IMG_ICON_CHECKED = "icon_checked"; + public static final String IMG_ICON_UNCHECKED = "icon_unchecked"; + public static final String IMG_ICON_OBSERVER = "icon_observer"; + public static final String IMG_ICON_LOADING = "icon_loading"; + public static final String IMG_ICON_LIBRARY = "icon_library"; + public static final String IMG_ICON_ASCRIPT = "icon_ascript"; + public static final String IMG_ICON_UP = "icon_up"; + public static final String IMG_ICON_DOWN = "icon_down"; + public static final String IMG_ICON_CONNECTION16 = "icon_connection16"; + public static final String IMG_ICON_CONNECTION24 = "icon_connection24"; + + public static final String IMG_ICON_JPG = "icon_jpg"; + public static final String IMG_ICON_GIF = "icon_gif"; + + public static final String IMG_SPLASH = "splash"; + + public void registerImages() { + + BMotionStudioImage.registerImage(IMG_ICON_ADD, + BMotionEditorPlugin.PLUGIN_ID, "icons/icon_add.gif"); + BMotionStudioImage.registerImage(IMG_ICON_CHOP, + BMotionEditorPlugin.PLUGIN_ID, "icons/icon_chop.gif"); + BMotionStudioImage.registerImage(IMG_ICON_DELETE, + BMotionEditorPlugin.PLUGIN_ID, "icons/icon_delete.gif"); + BMotionStudioImage.registerImage(IMG_ICON_DELETE21, + BMotionEditorPlugin.PLUGIN_ID, "icons/icon_delete21.png"); + BMotionStudioImage.registerImage(IMG_ICON_CHECKED, + BMotionEditorPlugin.PLUGIN_ID, "icons/icon_checked.gif"); + BMotionStudioImage.registerImage(IMG_ICON_UNCHECKED, + BMotionEditorPlugin.PLUGIN_ID, "icons/icon_unchecked.gif"); + BMotionStudioImage.registerImage(IMG_ICON_EDIT, + BMotionEditorPlugin.PLUGIN_ID, "icons/icon_edit.gif"); + BMotionStudioImage.registerImage(IMG_ICON_LOADING, + BMotionEditorPlugin.PLUGIN_ID, "icons/icon_loading.gif"); + BMotionStudioImage.registerImage(IMG_ICON_LIBRARY, + BMotionEditorPlugin.PLUGIN_ID, "icons/icon_library.gif"); + BMotionStudioImage.registerImage(IMG_ICON_ASCRIPT, + BMotionEditorPlugin.PLUGIN_ID, "icons/icon_ascript.png"); + BMotionStudioImage.registerImage(IMG_ICON_UP, + BMotionEditorPlugin.PLUGIN_ID, "icons/icon_up.gif"); + BMotionStudioImage.registerImage(IMG_ICON_DOWN, + BMotionEditorPlugin.PLUGIN_ID, "icons/icon_down.gif"); + BMotionStudioImage.registerImage(IMG_ICON_CONNECTION16, + BMotionEditorPlugin.PLUGIN_ID, "icons/icon_connection16.gif"); + BMotionStudioImage.registerImage(IMG_ICON_CONNECTION24, + BMotionEditorPlugin.PLUGIN_ID, "icons/icon_connection24.gif"); + + BMotionStudioImage.registerImage(IMG_ICON_JPG, + BMotionEditorPlugin.PLUGIN_ID, "icons/icon_jpg.gif"); + BMotionStudioImage.registerImage(IMG_ICON_GIF, + BMotionEditorPlugin.PLUGIN_ID, "icons/icon_gif.gif"); + + BMotionStudioImage.registerImage(IMG_ICON_OBSERVER, + BMotionEditorPlugin.PLUGIN_ID, "icons/icon_observer.gif"); + + BMotionStudioImage.registerImage(IMG_SPLASH, + BMotionEditorPlugin.PLUGIN_ID, "icons/splash.jpg"); + + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/EditorPaletteFactory.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/EditorPaletteFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..64af86839a8e7ca1c79fb9e7e5392b91bfbec180 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/EditorPaletteFactory.java @@ -0,0 +1,179 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.IExtensionRegistry; +import org.eclipse.core.runtime.Platform; +import org.eclipse.gef.palette.ConnectionCreationToolEntry; +import org.eclipse.gef.palette.MarqueeToolEntry; +import org.eclipse.gef.palette.PaletteContainer; +import org.eclipse.gef.palette.PaletteDrawer; +import org.eclipse.gef.palette.PaletteRoot; +import org.eclipse.gef.palette.PaletteToolbar; +import org.eclipse.gef.palette.PanningSelectionToolEntry; +import org.eclipse.gef.palette.ToolEntry; + +import de.bmotionstudio.gef.editor.model.BConnection; +import de.bmotionstudio.gef.editor.model.Visualization; + +public class EditorPaletteFactory { + + private HashMap<String, PaletteDrawer> groupMap = new HashMap<String, PaletteDrawer>(); + + /** + * Creates the PaletteRoot and adds all palette elements. Use this factory + * method to create a new palette for your graphical editor. + * + * @param visualization + * + * @param editor + * + * @return a new PaletteRoot + */ + public PaletteRoot createPalette(Visualization visualization) { + PaletteRoot palette = new PaletteRoot(); + palette.add(createToolsGroup(palette, visualization)); + createControls(palette, visualization); + createFromExtension(palette, visualization); + return palette; + } + + private void createFromExtension(PaletteRoot palette, + Visualization visualization) { + IExtensionRegistry registry = Platform.getExtensionRegistry(); + IExtensionPoint extensionPoint = registry + .getExtensionPoint("de.bmotionstudio.gef.editor.paletteEntry"); + // Iterate over controls + for (IExtension extension : extensionPoint.getExtensions()) { + for (IConfigurationElement configurationElement : extension + .getConfigurationElements()) { + if ("entry".equals(configurationElement.getName())) { + try { + IInstallPaletteEntry entry = (IInstallPaletteEntry) configurationElement + .createExecutableExtension("class"); + entry.installPaletteEntry(palette, groupMap); + } catch (CoreException e) { + e.printStackTrace(); + } + } + } + } + } + + private void createControls(PaletteRoot palette, Visualization visualization) { + + IExtensionRegistry registry = Platform.getExtensionRegistry(); + IExtensionPoint extensionPoint = registry + .getExtensionPoint("de.bmotionstudio.gef.editor.control"); + + // Iterate over groups + for (IExtension extension : extensionPoint.getExtensions()) { + + for (IConfigurationElement configurationElement : extension + .getConfigurationElements()) { + + if ("group".equals(configurationElement.getName())) { + + String groupID = configurationElement.getAttribute("id"); + String groupName = configurationElement + .getAttribute("name"); + + PaletteDrawer componentsDrawer = new PaletteDrawer( + groupName); + if (!groupMap.containsKey(groupID)) + groupMap.put(groupID, componentsDrawer); + + } + + } + + } + + // Iterate over controls + for (IExtension extension : extensionPoint.getExtensions()) { + + for (IConfigurationElement configurationElement : extension + .getConfigurationElements()) { + + if ("control".equals(configurationElement.getName())) { + + String groupID = configurationElement + .getAttribute("groupid"); + PaletteDrawer groupDrawer = groupMap.get(groupID); + + if (groupDrawer != null) { + + // boolean createDefaultToolEntry = true; + + try { + IBControlService service = (IBControlService) configurationElement + .createExecutableExtension("service"); + if (service.showInPalette()) { + ToolEntry toolEntry = service.createToolEntry( + visualization, configurationElement); + if (toolEntry != null) { + groupDrawer.add(toolEntry); + } + } + } catch (CoreException e) { + // I think we can ignore the exception since + // we create a default tool entry which is + // independent from the configuration + // element + } + + // if (createDefaultToolEntry) + // groupDrawer.add(createDefaultToolEntry(type, + // visualization, configurationElement)); + + } + + } + + } + + } + + for (Map.Entry<String, PaletteDrawer> entry : groupMap.entrySet()) { + if (entry.getValue().getChildren().size() > 0) + palette.add(entry.getValue()); + } + + } + + /** + * Create the "Tools" group. + * + * @param visualization + */ + private PaletteContainer createToolsGroup(PaletteRoot palette, + Visualization visualization) { + PaletteToolbar toolbar = new PaletteToolbar("Tools"); + // Add a selection tool to the group + ToolEntry tool = new PanningSelectionToolEntry(); + toolbar.add(tool); + palette.setDefaultEntry(tool); + // Add a marquee tool to the group + toolbar.add(new MarqueeToolEntry()); + // Add connector tool to the group + toolbar.add(new ConnectionCreationToolEntry("Connection", + "Universal Connector", new BControlCreationFactory( + BConnection.TYPE, visualization), BMotionStudioImage + .getImageDescriptor("icons/icon_connection16.gif"), + BMotionStudioImage + .getImageDescriptor("icons/icon_connection24.gif"))); + return toolbar; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/IAddErrorListener.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/IAddErrorListener.java new file mode 100644 index 0000000000000000000000000000000000000000..56541669bf2d5b35ef446a59aba23d5b9a641516 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/IAddErrorListener.java @@ -0,0 +1,13 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor; + +public interface IAddErrorListener { + + public Object errorsAdded(); + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/IBControlService.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/IBControlService.java new file mode 100644 index 0000000000000000000000000000000000000000..832bd0c1df5d40bcba75a573b11c182aff40a13c --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/IBControlService.java @@ -0,0 +1,31 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor; + +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.gef.palette.ToolEntry; + +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.model.Visualization; +import de.bmotionstudio.gef.editor.part.AppAbstractEditPart; + +/** + * @author Lukas Ladenberger + * + */ +public interface IBControlService { + + public BControl createControl(Visualization visualization); + + public AppAbstractEditPart createEditPart(); + + public ToolEntry createToolEntry(Visualization visualization, + IConfigurationElement configurationElement); + + public boolean showInPalette(); + +} \ No newline at end of file diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/IBMotionStudioImageRegistry.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/IBMotionStudioImageRegistry.java new file mode 100644 index 0000000000000000000000000000000000000000..af1e8d11b27e568982a619a4e3cecc0652421e4c --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/IBMotionStudioImageRegistry.java @@ -0,0 +1,14 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor; + + +public interface IBMotionStudioImageRegistry { + + public void registerImages(); + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/IInstallActions.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/IInstallActions.java new file mode 100644 index 0000000000000000000000000000000000000000..e05735f5b237801e2c2f90dbdf3208a810736673 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/IInstallActions.java @@ -0,0 +1,20 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor; + +import java.util.HashMap; + +import org.eclipse.jface.action.Action; +import org.eclipse.ui.part.WorkbenchPart; + +public interface IInstallActions { + + public void installActions(WorkbenchPart part); + + public HashMap<String, Action> getActionMap(); + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/IInstallMenu.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/IInstallMenu.java new file mode 100644 index 0000000000000000000000000000000000000000..657394603e154102c4d6bccabdf569bba1641289 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/IInstallMenu.java @@ -0,0 +1,19 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor; + +import org.eclipse.gef.ui.actions.ActionRegistry; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.ui.IActionBars; + +public interface IInstallMenu { + + public void installMenu(IMenuManager menu, ActionRegistry regitry); + + public void installBar(IActionBars bars, ActionRegistry regitry); + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/IInstallPaletteEntry.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/IInstallPaletteEntry.java new file mode 100644 index 0000000000000000000000000000000000000000..a0853bb532dfe2d587cac80846b35e0a389b564e --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/IInstallPaletteEntry.java @@ -0,0 +1,22 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ +package de.bmotionstudio.gef.editor; + +import java.util.HashMap; + +import org.eclipse.gef.palette.PaletteDrawer; +import org.eclipse.gef.palette.PaletteRoot; + +/** + * @author Lukas Ladenberger + * + */ +public interface IInstallPaletteEntry { + + public void installPaletteEntry(PaletteRoot palette, + HashMap<String, PaletteDrawer> groups); + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/ILanguageService.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/ILanguageService.java new file mode 100644 index 0000000000000000000000000000000000000000..324da6b21c2977c1955a44005473e140c5211106 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/ILanguageService.java @@ -0,0 +1,24 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor; + +import org.eclipse.core.resources.IFile; + +import de.bmotionstudio.gef.editor.model.Visualization; +import de.prob.exceptions.ProBException; + +/** + * @author Lukas Ladenberger + * + */ +public interface ILanguageService { + + public void startProBAnimator(Visualization v) throws ProBException; + + public boolean isLanguageFile(IFile f); + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/IRunPageListener.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/IRunPageListener.java new file mode 100644 index 0000000000000000000000000000000000000000..dddb30c73081c565438f4ff71d2239cc98a7fc14 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/IRunPageListener.java @@ -0,0 +1,15 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor; + +public interface IRunPageListener { + + public void runPageCreated(BMotionStudioRunPage runPage); + + public void runPageRemoved(BMotionStudioRunPage runPage); + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/ImageRegistry.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/ImageRegistry.java new file mode 100644 index 0000000000000000000000000000000000000000..cbde859b3df750fb34ebd9268e5f09735322504b --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/ImageRegistry.java @@ -0,0 +1,25 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor; + + +public class ImageRegistry implements IBMotionStudioImageRegistry { + + public static final String IMG_RADIOBUTTON_CHECKED = "img_radiobutton_checked"; + public static final String IMG_RADIOBUTTON_UNCHECKED = "img_radiobutton_unchecked"; + + public void registerImages() { + + BMotionStudioImage.registerImage(IMG_RADIOBUTTON_CHECKED, + BMotionEditorPlugin.PLUGIN_ID, "icons/icon_radiobutton_c.gif"); + + BMotionStudioImage.registerImage(IMG_RADIOBUTTON_UNCHECKED, + BMotionEditorPlugin.PLUGIN_ID, "icons/icon_radiobutton_uc.gif"); + + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/InstallActions.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/InstallActions.java new file mode 100644 index 0000000000000000000000000000000000000000..feb252464e08a8aa477585bf5566ac775067d677 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/InstallActions.java @@ -0,0 +1,31 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor; + +import org.eclipse.ui.part.WorkbenchPart; + +import de.bmotionstudio.gef.editor.action.BringToBottomAction; +import de.bmotionstudio.gef.editor.action.BringToBottomStepAction; +import de.bmotionstudio.gef.editor.action.BringToTopAction; +import de.bmotionstudio.gef.editor.action.BringToTopStepAction; +import de.bmotionstudio.gef.editor.action.FitImageAction; +import de.bmotionstudio.gef.editor.action.RenameAction; + +public class InstallActions extends AbstractInstallActions implements + IInstallActions { + + public void installActions(final WorkbenchPart part) { + installAction(RenameAction.ID, new RenameAction(part)); + installAction(FitImageAction.ID, new FitImageAction(part)); + installAction(BringToTopAction.ID, new BringToTopAction(part)); + installAction(BringToBottomAction.ID, new BringToBottomAction(part)); + installAction(BringToTopStepAction.ID, new BringToTopStepAction(part)); + installAction(BringToBottomStepAction.ID, new BringToBottomStepAction( + part)); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/InstallMenu.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/InstallMenu.java new file mode 100644 index 0000000000000000000000000000000000000000..b2c38c70835292ddb6582fb6a91301eac596504a --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/InstallMenu.java @@ -0,0 +1,56 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor; + +import org.eclipse.gef.ui.actions.ActionRegistry; +import org.eclipse.gef.ui.actions.GEFActionConstants; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.ui.IActionBars; + +import de.bmotionstudio.gef.editor.action.BringToBottomAction; +import de.bmotionstudio.gef.editor.action.BringToBottomStepAction; +import de.bmotionstudio.gef.editor.action.BringToTopAction; +import de.bmotionstudio.gef.editor.action.BringToTopStepAction; +import de.bmotionstudio.gef.editor.action.FitImageAction; +import de.bmotionstudio.gef.editor.action.RenameAction; + +public class InstallMenu implements IInstallMenu { + + public void installMenu(IMenuManager menu, ActionRegistry regitry) { + + IAction action; + + action = regitry.getAction(FitImageAction.ID); + menu.appendToGroup(GEFActionConstants.GROUP_EDIT, action); + action = regitry.getAction(RenameAction.ID); + menu.appendToGroup(GEFActionConstants.GROUP_EDIT, action); + + // menu.appendToGroup(GEFActionConstants.GROUP_EDIT, new Separator( + // "de.bmotionstudio.gef.BringToGroup")); + + MenuManager adjustmentMenu = new MenuManager("Adjustment"); + menu.appendToGroup(GEFActionConstants.GROUP_EDIT, adjustmentMenu); + + action = regitry.getAction(BringToTopAction.ID); + adjustmentMenu.add(action); + action = regitry.getAction(BringToBottomAction.ID); + adjustmentMenu.add(action); + action = regitry.getAction(BringToTopStepAction.ID); + adjustmentMenu.add(action); + action = regitry.getAction(BringToBottomStepAction.ID); + adjustmentMenu.add(action); + + } + + public void installBar(IActionBars bars, ActionRegistry regitry) { + // bars.setGlobalActionHandler(ActionFactory.RENAME.getId(), regitry + // .getAction(ActionFactory.RENAME.getId())); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/BMotionAbstractWizard.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/BMotionAbstractWizard.java new file mode 100644 index 0000000000000000000000000000000000000000..98e609d9ea41bb4efcf1b01105a84a77efcee808 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/BMotionAbstractWizard.java @@ -0,0 +1,106 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.action; + +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.wizard.IWizard; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Cursor; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.ToolBar; +import org.eclipse.swt.widgets.ToolItem; +import org.eclipse.ui.IWorkbenchPart; + +import de.bmotionstudio.gef.editor.BMotionStudioImage; +import de.bmotionstudio.gef.editor.EditorImageRegistry; + +public abstract class BMotionAbstractWizard extends WizardDialog { + + public static final int DELETE = 3; + + private IWorkbenchPart workbenchPart; + + private String deleteToolTip; + + public BMotionAbstractWizard(IWorkbenchPart workbenchPart, IWizard newWizard) { + super(workbenchPart.getSite().getShell(), newWizard); + this.workbenchPart = workbenchPart; + } + + @Override + protected Control createButtonBar(Composite parent) { + Composite composite = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.marginWidth = 0; + layout.marginHeight = 0; + layout.horizontalSpacing = 0; + composite.setLayout(layout); + composite + .setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); + composite.setFont(parent.getFont()); + + // create help control if needed + if (isHelpAvailable()) { + Control helpControl = createHelpControl(composite); + ((GridData) helpControl.getLayoutData()).horizontalIndent = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN); + } + + Control deleteControl = createDeleteControl(composite); + ((GridData) deleteControl.getLayoutData()).horizontalIndent = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN); + setHelpAvailable(false); + Control buttonSection = super.createButtonBar(composite); + ((GridData) buttonSection.getLayoutData()).grabExcessHorizontalSpace = true; + return composite; + } + + private Control createDeleteControl(Composite parent) { + return createDeleteImageButton(parent, BMotionStudioImage + .getImage(EditorImageRegistry.IMG_ICON_DELETE21)); + } + + private ToolBar createDeleteImageButton(Composite parent, Image image) { + ToolBar toolBar = new ToolBar(parent, SWT.FLAT | SWT.NO_FOCUS); + ((GridLayout) parent.getLayout()).numColumns++; + toolBar.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER)); + final Cursor cursor = new Cursor(parent.getDisplay(), SWT.CURSOR_HAND); + toolBar.setCursor(cursor); + toolBar.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + cursor.dispose(); + } + }); + ToolItem deleteToolItem = new ToolItem(toolBar, SWT.NONE); + deleteToolItem.setImage(image); + deleteToolItem.setToolTipText(deleteToolTip); + deleteToolItem.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + deletePressed(); + } + }); + return toolBar; + } + + protected abstract void deletePressed(); + + public IWorkbenchPart getWorkbenchPart() { + return workbenchPart; + } + + protected void setDeleteToolTip(String msg) { + this.deleteToolTip = msg; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/BMotionObserverWizard.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/BMotionObserverWizard.java new file mode 100644 index 0000000000000000000000000000000000000000..f385883576b9241e707232328193850be4a09baa --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/BMotionObserverWizard.java @@ -0,0 +1,33 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.action; + +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.wizard.IWizard; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IWorkbenchPart; + +public class BMotionObserverWizard extends BMotionAbstractWizard { + + public BMotionObserverWizard(IWorkbenchPart workbenchPart, IWizard newWizard) { + super(workbenchPart, newWizard); + setDeleteToolTip("Delete Observer"); + } + + @Override + protected void deletePressed() { + + if (MessageDialog.openConfirm(Display.getDefault().getActiveShell(), + "Do you really want to delete this Observer?", + "Do you really want to delete this Observer?")) { + setReturnCode(DELETE); + close(); + } + + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/BMotionSchedulerEventWizard.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/BMotionSchedulerEventWizard.java new file mode 100644 index 0000000000000000000000000000000000000000..4f2b28f2412d0f2ce6e4f69bb8b3426735d452ce --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/BMotionSchedulerEventWizard.java @@ -0,0 +1,41 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.action; + +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.wizard.IWizard; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IWorkbenchPart; + +import de.bmotionstudio.gef.editor.scheduler.SchedulerWizard; + +public class BMotionSchedulerEventWizard extends BMotionAbstractWizard { + + public BMotionSchedulerEventWizard(IWorkbenchPart workbenchPart, + IWizard newWizard) { + super(workbenchPart, newWizard); + setDeleteToolTip("Delete Event"); + } + + @Override + protected void deletePressed() { + + if (MessageDialog.openConfirm(Display.getDefault().getActiveShell(), + "Do you really want to delete this Event?", + "Do you really want to delete this Event?")) { + RemoveSchedulerEventAction action = new RemoveSchedulerEventAction( + getWorkbenchPart()); + action.setControl(((SchedulerWizard) getWizard()).getBControl()); + action.setSchedulerEvent(((SchedulerWizard) getWizard()) + .getScheduler()); + action.run(); + setReturnCode(DELETE); + close(); + } + + } +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/BringToBottomAction.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/BringToBottomAction.java new file mode 100644 index 0000000000000000000000000000000000000000..a194b704361fe7ee5e5d63f1ad3de237c467e43d --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/BringToBottomAction.java @@ -0,0 +1,79 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.action; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.gef.ui.actions.SelectionAction; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.plugin.AbstractUIPlugin; + +import de.bmotionstudio.gef.editor.BMotionEditorPlugin; +import de.bmotionstudio.gef.editor.command.BringToBottomCommand; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.part.AppAbstractEditPart; +import de.bmotionstudio.gef.editor.part.VisualizationPart; + +public class BringToBottomAction extends SelectionAction { + + public final static String ID = "de.bmotionstudio.gef.editor.action.bringToBottom"; + + public BringToBottomAction(final IWorkbenchPart part) { + super(part); + setLazyEnablementCalculation(false); + } + + protected void init() { + setText("Bring to bottom"); + setToolTipText("Bring to bottom"); + setId(ID); + ImageDescriptor icon = AbstractUIPlugin.imageDescriptorFromPlugin( + BMotionEditorPlugin.PLUGIN_ID, "icons/icon_bringtobottom.gif"); + if (icon != null) { + setImageDescriptor(icon); + } + setEnabled(false); + } + + @Override + protected boolean calculateEnabled() { + List<?> selectedObjects = getSelectedObjects(); + if (selectedObjects.size() == 1) { + if (selectedObjects.get(0) instanceof VisualizationPart) { + return false; + } + } + return true; + } + + public BringToBottomCommand createBringToBottomCommand( + List<BControl> modelList) { + BringToBottomCommand command = new BringToBottomCommand(); + command.setControlList(modelList); + return command; + } + + public void run() { + + List<BControl> modelList = new ArrayList<BControl>(); + + List<?> selectedObjects = getSelectedObjects(); + + for (Object obj : selectedObjects) { + if (obj instanceof AppAbstractEditPart) { + modelList + .add((BControl) ((AppAbstractEditPart) obj).getModel()); + } + } + + execute(createBringToBottomCommand(modelList)); + + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/BringToBottomStepAction.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/BringToBottomStepAction.java new file mode 100644 index 0000000000000000000000000000000000000000..07da88c2c8a32fbd45ad7273437fbbebbe4ca6ef --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/BringToBottomStepAction.java @@ -0,0 +1,80 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.action; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.gef.ui.actions.SelectionAction; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.plugin.AbstractUIPlugin; + +import de.bmotionstudio.gef.editor.BMotionEditorPlugin; +import de.bmotionstudio.gef.editor.command.BringToBottomStepCommand; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.part.AppAbstractEditPart; +import de.bmotionstudio.gef.editor.part.VisualizationPart; + +public class BringToBottomStepAction extends SelectionAction { + + public final static String ID = "de.bmotionstudio.gef.editor.action.bringToBottomStep"; + + public BringToBottomStepAction(final IWorkbenchPart part) { + super(part); + setLazyEnablementCalculation(false); + } + + protected void init() { + setText("Bring to bottom (Step)"); + setToolTipText("Bring to bottom (Step)"); + setId(ID); + ImageDescriptor icon = AbstractUIPlugin.imageDescriptorFromPlugin( + BMotionEditorPlugin.PLUGIN_ID, + "icons/icon_bringtobottomstep.gif"); + if (icon != null) { + setImageDescriptor(icon); + } + setEnabled(false); + } + + @Override + protected boolean calculateEnabled() { + List<?> selectedObjects = getSelectedObjects(); + if (selectedObjects.size() == 1) { + if (selectedObjects.get(0) instanceof VisualizationPart) { + return false; + } + } + return true; + } + + public BringToBottomStepCommand createBringToBottomStepCommand( + List<BControl> modelList) { + BringToBottomStepCommand command = new BringToBottomStepCommand(); + command.setControlList(modelList); + return command; + } + + public void run() { + + List<BControl> modelList = new ArrayList<BControl>(); + + List<?> selectedObjects = getSelectedObjects(); + + for (Object obj : selectedObjects) { + if (obj instanceof AppAbstractEditPart) { + modelList + .add((BControl) ((AppAbstractEditPart) obj).getModel()); + } + } + + execute(createBringToBottomStepCommand(modelList)); + + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/BringToTopAction.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/BringToTopAction.java new file mode 100644 index 0000000000000000000000000000000000000000..002d611a260f932bc22897493a7170681bdcf7b3 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/BringToTopAction.java @@ -0,0 +1,73 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.action; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.gef.ui.actions.SelectionAction; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.plugin.AbstractUIPlugin; + +import de.bmotionstudio.gef.editor.BMotionEditorPlugin; +import de.bmotionstudio.gef.editor.command.BringToTopCommand; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.part.AppAbstractEditPart; +import de.bmotionstudio.gef.editor.part.VisualizationPart; + +public class BringToTopAction extends SelectionAction { + + public final static String ID = "de.bmotionstudio.gef.editor.action.bringToTop"; + + public BringToTopAction(final IWorkbenchPart part) { + super(part); + setLazyEnablementCalculation(false); + } + + protected void init() { + setText("Bring to top"); + setToolTipText("Bring to top"); + setId(ID); + ImageDescriptor icon = AbstractUIPlugin.imageDescriptorFromPlugin( + BMotionEditorPlugin.PLUGIN_ID, "icons/icon_bringtotop.gif"); + if (icon != null) { + setImageDescriptor(icon); + } + setEnabled(false); + } + + @Override + protected boolean calculateEnabled() { + List<?> selectedObjects = getSelectedObjects(); + if (selectedObjects.size() == 1) { + if (selectedObjects.get(0) instanceof VisualizationPart) { + return false; + } + } + return true; + } + + public BringToTopCommand createBringToTopCommand(List<BControl> controlList) { + BringToTopCommand command = new BringToTopCommand(); + command.setControlList(controlList); + return command; + } + + public void run() { + List<BControl> controlList = new ArrayList<BControl>(); + List<?> selectedObjects = getSelectedObjects(); + for (Object obj : selectedObjects) { + if (obj instanceof AppAbstractEditPart) { + controlList.add((BControl) ((AppAbstractEditPart) obj) + .getModel()); + } + } + execute(createBringToTopCommand(controlList)); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/BringToTopStepAction.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/BringToTopStepAction.java new file mode 100644 index 0000000000000000000000000000000000000000..7b1c8e97c08c96a1abdec0970cbe27b5546adbfc --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/BringToTopStepAction.java @@ -0,0 +1,79 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.action; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.gef.ui.actions.SelectionAction; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.plugin.AbstractUIPlugin; + +import de.bmotionstudio.gef.editor.BMotionEditorPlugin; +import de.bmotionstudio.gef.editor.command.BringToTopStepCommand; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.part.AppAbstractEditPart; +import de.bmotionstudio.gef.editor.part.VisualizationPart; + +public class BringToTopStepAction extends SelectionAction { + + public final static String ID = "de.bmotionstudio.gef.editor.action.bringToTopStep"; + + public BringToTopStepAction(final IWorkbenchPart part) { + super(part); + setLazyEnablementCalculation(false); + } + + protected void init() { + setText("Bring to top (Step)"); + setToolTipText("Bring to top (Step)"); + setId(ID); + ImageDescriptor icon = AbstractUIPlugin.imageDescriptorFromPlugin( + BMotionEditorPlugin.PLUGIN_ID, "icons/icon_bringtotopstep.gif"); + if (icon != null) { + setImageDescriptor(icon); + } + setEnabled(false); + } + + @Override + protected boolean calculateEnabled() { + List<?> selectedObjects = getSelectedObjects(); + if (selectedObjects.size() == 1) { + if (selectedObjects.get(0) instanceof VisualizationPart) { + return false; + } + } + return true; + } + + public BringToTopStepCommand createBringToTopStepCommand( + List<BControl> modelList) { + BringToTopStepCommand command = new BringToTopStepCommand(); + command.setControlList(modelList); + return command; + } + + public void run() { + + List<BControl> modelList = new ArrayList<BControl>(); + + List<?> selectedObjects = getSelectedObjects(); + + for (Object obj : selectedObjects) { + if (obj instanceof AppAbstractEditPart) { + modelList + .add((BControl) ((AppAbstractEditPart) obj).getModel()); + } + } + + execute(createBringToTopStepCommand(modelList)); + + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/CopyAction.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/CopyAction.java new file mode 100644 index 0000000000000000000000000000000000000000..0e0984a6654e422c6b5fadc8c42d80b1f6644799 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/CopyAction.java @@ -0,0 +1,84 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.action; + +import java.util.Iterator; +import java.util.List; + +import org.eclipse.gef.EditPart; +import org.eclipse.gef.commands.Command; +import org.eclipse.gef.ui.actions.SelectionAction; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.actions.ActionFactory; + +import de.bmotionstudio.gef.editor.command.CopyCommand; +import de.bmotionstudio.gef.editor.model.BControl; + +public class CopyAction extends SelectionAction { + + public CopyAction(IWorkbenchPart part) { + super(part); + // force calculateEnabled() to be called in every context + setLazyEnablementCalculation(true); + } + + @Override + protected void init() { + super.init(); + ISharedImages sharedImages = PlatformUI.getWorkbench() + .getSharedImages(); + setText("Copy"); + setId(ActionFactory.COPY.getId()); + setHoverImageDescriptor(sharedImages + .getImageDescriptor(ISharedImages.IMG_TOOL_COPY)); + setImageDescriptor(sharedImages + .getImageDescriptor(ISharedImages.IMG_TOOL_COPY)); + setDisabledImageDescriptor(sharedImages + .getImageDescriptor(ISharedImages.IMG_TOOL_COPY_DISABLED)); + setEnabled(false); + } + + private Command createCopyCommand(List<Object> selectedObjects) { + if (selectedObjects == null || selectedObjects.isEmpty()) + return null; + CopyCommand cmd = new CopyCommand(); + Iterator<Object> it = selectedObjects.iterator(); + while (it.hasNext()) { + Object nextElement = it.next(); + if (nextElement instanceof EditPart) { + EditPart ep = (EditPart) nextElement; + BControl node = (BControl) ep.getModel(); + if (!cmd.isCopyableControl(node)) + return null; + cmd.addElement(node); + } + + } + return cmd; + } + + @SuppressWarnings("unchecked") + @Override + protected boolean calculateEnabled() { + Command cmd = createCopyCommand(getSelectedObjects()); + if (cmd == null) + return false; + return cmd.canExecute(); + } + + @SuppressWarnings("unchecked") + @Override + public void run() { + Command cmd = createCopyCommand(getSelectedObjects()); + if (cmd != null && cmd.canExecute()) { + cmd.execute(); + } + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/FitImageAction.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/FitImageAction.java new file mode 100644 index 0000000000000000000000000000000000000000..ec7bd7f0c8cac4d6aa79b94fde6f690424e1b7f6 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/FitImageAction.java @@ -0,0 +1,144 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.action; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.resources.IFile; +import org.eclipse.gef.EditPart; +import org.eclipse.gef.ui.actions.SelectionAction; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.plugin.AbstractUIPlugin; + +import de.bmotionstudio.gef.editor.AttributeConstants; +import de.bmotionstudio.gef.editor.BMotionEditorPlugin; +import de.bmotionstudio.gef.editor.command.FitImageCommand; +import de.bmotionstudio.gef.editor.model.BControl; + +public class FitImageAction extends SelectionAction { + + public final static String ID = "de.bmotionstudio.gef.editor.action.fitImage"; + + public FitImageAction(final IWorkbenchPart part) { + super(part); + setLazyEnablementCalculation(false); + } + + protected void init() { + setText("Fit size to image"); + setToolTipText("Fit size to image"); + setId(ID); + ImageDescriptor icon = AbstractUIPlugin.imageDescriptorFromPlugin( + BMotionEditorPlugin.PLUGIN_ID, "icons/icon_fitimage.png"); + if (icon != null) { + setImageDescriptor(icon); + } + setEnabled(false); + } + + @Override + protected boolean calculateEnabled() { + List<?> selectedObjects = getSelectedObjects(); + for (Object obj : selectedObjects) { + if (obj instanceof EditPart) { + EditPart part = (EditPart) obj; + BControl bcontrol = (BControl) part.getModel(); + if (bcontrol + .getAttributeValue(AttributeConstants.ATTRIBUTE_IMAGE) != null) { + return true; + } + } + } + return false; + } + + public FitImageCommand createFitImageCommand(List<BControl> modelList, + Map<BControl, org.eclipse.draw2d.geometry.Rectangle> newSizeMap) { + FitImageCommand command = new FitImageCommand(); + command.setModelList(modelList); + command.setNewSizeMap(newSizeMap); + return command; + } + + public void run() { + + List<BControl> modelList = new ArrayList<BControl>(); + Map<BControl, org.eclipse.draw2d.geometry.Rectangle> newSizeMap = new HashMap<BControl, org.eclipse.draw2d.geometry.Rectangle>(); + + List<?> selectedObjects = getSelectedObjects(); + + for (Object obj : selectedObjects) { + + if (obj instanceof EditPart) { + + EditPart part = (EditPart) obj; + BControl control = (BControl) part.getModel(); + + Object imgAttribute = control + .getAttributeValue(AttributeConstants.ATTRIBUTE_IMAGE); + + if (imgAttribute != null) { + + String imagePath = control.getAttributeValue( + AttributeConstants.ATTRIBUTE_IMAGE).toString(); + + Rectangle imageBounds = null; + Image img = null; + + IFile pFile = control.getVisualization().getProjectFile(); + + if (pFile != null) { + final String myPath = (pFile.getProject().getLocation() + + "/images/" + imagePath).replace("file:", ""); + if (new File(myPath).exists() && imagePath.length() > 0) { + img = new Image(Display.getCurrent(), myPath); + imageBounds = img.getBounds(); + } + } + + if (imageBounds != null) { + + modelList.add(control); + newSizeMap + .put(control, + new org.eclipse.draw2d.geometry.Rectangle( + Integer.valueOf(control + .getAttributeValue( + AttributeConstants.ATTRIBUTE_X) + .toString()), + Integer.valueOf(control + .getAttributeValue( + AttributeConstants.ATTRIBUTE_Y) + .toString()), + imageBounds.width, + imageBounds.height)); + + } + + if (img != null) { + img.dispose(); + } + + } + + } + + } + + execute(createFitImageCommand(modelList, newSizeMap)); + + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/ObserverAction.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/ObserverAction.java new file mode 100644 index 0000000000000000000000000000000000000000..d0dcaa4f1e540c0133efb16d77615b3952f0c185 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/ObserverAction.java @@ -0,0 +1,166 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.action; + +import java.util.List; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.gef.EditPart; +import org.eclipse.gef.ui.actions.SelectionAction; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.ui.IWorkbenchPart; + +import de.bmotionstudio.gef.editor.AttributeConstants; +import de.bmotionstudio.gef.editor.BMotionEditorPlugin; +import de.bmotionstudio.gef.editor.BMotionStudioImage; +import de.bmotionstudio.gef.editor.command.ObserverCommand; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.observer.Observer; +import de.bmotionstudio.gef.editor.observer.ObserverWizard; +import de.prob.logging.Logger; + +public class ObserverAction extends SelectionAction { + + private String className; + private Observer clonedObserver; + private Observer newObserver; + + public ObserverAction(IWorkbenchPart part) { + super(part); + setLazyEnablementCalculation(true); + } + + @Override + protected void init() { + setEnabled(false); + } + + @Override + protected boolean calculateEnabled() { + return true; + } + + public void run() { + + clonedObserver = null; + + if (getControl() != null) { + + newObserver = getControl().getObserver(getClassName()); + + // Add Observer + if (newObserver == null) { + + try { + newObserver = (Observer) BMotionEditorPlugin + .getObserverExtension(getClassName()) + .createExecutableExtension("class"); + } catch (CoreException e) { + } + + } else { // Edit Observer + + // Clone Observer + try { + clonedObserver = newObserver.clone(); + } catch (CloneNotSupportedException e) { + } + + } + + ObserverWizard wizard = newObserver.getWizard(getControl()); + + if (wizard != null) { + + BMotionObserverWizard dialog = new BMotionObserverWizard( + getWorkbenchPart(), wizard); + dialog.create(); + dialog.getShell().setSize(wizard.getSize()); + String title = "Observer: " + + newObserver.getName() + + " Control: " + + getControl().getAttributeValue( + AttributeConstants.ATTRIBUTE_ID); + wizard.setWindowTitle("BMotion Studio Observer Wizard"); + dialog.setTitle(title); + dialog.setMessage(newObserver.getDescription()); + dialog.setTitleImage(BMotionStudioImage + .getImage(BMotionStudioImage.IMG_LOGO_BMOTION64)); + int status = dialog.open(); + + if (status == WizardDialog.OK) { + + ObserverCommand observerCommand = createObserverCommandCommand(); + observerCommand.setNewObserver(newObserver); + + if (wizard.isObserverDelete()) { + + RemoveObserverAction action = new RemoveObserverAction( + getWorkbenchPart()); + action.setControl(getControl()); + action.setObserver(newObserver); + action.run(); + + } else { + if (clonedObserver != null) { + observerCommand.setClonedObserver(clonedObserver); + } + execute(observerCommand); + } + + } else if (status == WizardDialog.CANCEL) { + + if (clonedObserver != null) + getControl().addObserver(clonedObserver); + + } else if (status == BMotionObserverWizard.DELETE) { + RemoveObserverAction action = new RemoveObserverAction( + getWorkbenchPart()); + action.setControl(getControl()); + action.setObserver(newObserver); + action.run(); + } + + } else { + Logger.notifyUserWithoutBugreport("The Observer \"" + + newObserver.getName() + + "\" does not support a wizard."); + } + } + + } + + public ObserverCommand createObserverCommandCommand() { + ObserverCommand command = new ObserverCommand(); + command.setClassName(getClassName()); + command.setControl(getControl()); + return command; + } + + public void setClassName(String className) { + this.className = className; + } + + public String getClassName() { + return className; + } + + protected BControl getControl() { + + List<?> objects = getSelectedObjects(); + + if (objects.isEmpty()) + return null; + + if ((objects.get(0) instanceof EditPart)) { + EditPart part = (EditPart) objects.get(0); + return (BControl) part.getModel(); + } + return null; + + } +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/PasteAction.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/PasteAction.java new file mode 100644 index 0000000000000000000000000000000000000000..bebe030a39054980809c4ab90abb7bfb07a45e3a --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/PasteAction.java @@ -0,0 +1,58 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.action; + +import org.eclipse.gef.commands.Command; +import org.eclipse.gef.ui.actions.SelectionAction; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.actions.ActionFactory; + +import de.bmotionstudio.gef.editor.command.PasteCommand; + +public class PasteAction extends SelectionAction { + + public PasteAction(IWorkbenchPart part) { + super(part); + // force calculateEnabled() to be called in every context + setLazyEnablementCalculation(true); + } + + protected void init() { + super.init(); + ISharedImages sharedImages = PlatformUI.getWorkbench() + .getSharedImages(); + setText("Paste"); + setId(ActionFactory.PASTE.getId()); + setHoverImageDescriptor(sharedImages + .getImageDescriptor(ISharedImages.IMG_TOOL_PASTE)); + setImageDescriptor(sharedImages + .getImageDescriptor(ISharedImages.IMG_TOOL_PASTE)); + setDisabledImageDescriptor(sharedImages + .getImageDescriptor(ISharedImages.IMG_TOOL_PASTE_DISABLED)); + setEnabled(false); + } + + private PasteCommand createPasteCommand() { + return new PasteCommand(); + } + + @Override + protected boolean calculateEnabled() { + Command command = createPasteCommand(); + return command != null && command.canExecute(); + } + + @Override + public void run() { + PasteCommand command = createPasteCommand(); + if (command != null && command.canExecute()) + execute(command); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/RemoveObserverAction.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/RemoveObserverAction.java new file mode 100644 index 0000000000000000000000000000000000000000..8474eccb6a34aef526df013fabb298dbeae5cbf2 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/RemoveObserverAction.java @@ -0,0 +1,50 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.action; + +import org.eclipse.gef.ui.actions.WorkbenchPartAction; +import org.eclipse.ui.IWorkbenchPart; + +import de.bmotionstudio.gef.editor.command.RemoveObserverCommand; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.observer.Observer; + +public class RemoveObserverAction extends WorkbenchPartAction { + + private Observer observer; + private BControl control; + + public RemoveObserverAction(IWorkbenchPart workbenchPart) { + super(workbenchPart); + } + + @Override + protected boolean calculateEnabled() { + return true; + } + + public void run() { + execute(createRemoveObserverCommand()); + } + + public RemoveObserverCommand createRemoveObserverCommand() { + RemoveObserverCommand command = new RemoveObserverCommand(); + command.setControl(this.control); + command.setObserver(this.observer); + return command; + } + + public void setControl(BControl control) { + this.control = control; + + } + + public void setObserver(Observer observer) { + this.observer = observer; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/RemoveSchedulerEventAction.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/RemoveSchedulerEventAction.java new file mode 100644 index 0000000000000000000000000000000000000000..04d00c4216cb2721d1b044cd3f9826a1b4709d3c --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/RemoveSchedulerEventAction.java @@ -0,0 +1,50 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.action; + +import org.eclipse.gef.ui.actions.WorkbenchPartAction; +import org.eclipse.ui.IWorkbenchPart; + +import de.bmotionstudio.gef.editor.command.RemoveSchedulerEventCommand; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.scheduler.SchedulerEvent; + +public class RemoveSchedulerEventAction extends WorkbenchPartAction { + + private SchedulerEvent schedulerEvent; + private BControl control; + + public RemoveSchedulerEventAction(IWorkbenchPart workbenchPart) { + super(workbenchPart); + } + + @Override + protected boolean calculateEnabled() { + return true; + } + + public void run() { + execute(createRemoveSchedulerEventCommand()); + } + + public RemoveSchedulerEventCommand createRemoveSchedulerEventCommand() { + RemoveSchedulerEventCommand command = new RemoveSchedulerEventCommand(); + command.setControl(this.control); + command.setSchedulerEvent(this.schedulerEvent); + return command; + } + + public void setControl(BControl control) { + this.control = control; + + } + + public void setSchedulerEvent(SchedulerEvent schedulerEvent) { + this.schedulerEvent = schedulerEvent; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/RenameAction.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/RenameAction.java new file mode 100644 index 0000000000000000000000000000000000000000..ab551e14c0e97659ed8bbcbcfcee88c2b44872e8 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/RenameAction.java @@ -0,0 +1,103 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.action; + +import java.util.HashMap; +import java.util.List; + +import org.eclipse.gef.EditPart; +import org.eclipse.gef.Request; +import org.eclipse.gef.commands.Command; +import org.eclipse.gef.ui.actions.SelectionAction; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.actions.ActionFactory; +import org.eclipse.ui.plugin.AbstractUIPlugin; + +import de.bmotionstudio.gef.editor.AttributeConstants; +import de.bmotionstudio.gef.editor.BMotionEditorPlugin; +import de.bmotionstudio.gef.editor.internal.RenameWizard; +import de.bmotionstudio.gef.editor.model.BControl; + +public class RenameAction extends SelectionAction { + + public final static String ID = ActionFactory.RENAME.getId(); + + public RenameAction(final IWorkbenchPart part) { + super(part); + setLazyEnablementCalculation(false); + } + + protected void init() { + setText("Rename..."); + setToolTipText("Rename"); + setId(ID); + ImageDescriptor icon = AbstractUIPlugin.imageDescriptorFromPlugin( + BMotionEditorPlugin.PLUGIN_ID, "icons/icon_rename.png"); + if (icon != null) { + setImageDescriptor(icon); + } + setEnabled(false); + } + + @Override + protected boolean calculateEnabled() { + Command cmd = createRenameCommand(""); + if (cmd == null) { + return false; + } + return true; + } + + public Command createRenameCommand(final String name) { + Request renameReq = new Request("rename"); + + HashMap<String, String> reqData = new HashMap<String, String>(); + reqData.put("newName", name); + renameReq.setExtendedData(reqData); + + if (getSelectedObjects().size() > 0) { + if (getSelectedObjects().get(0) instanceof EditPart) { + EditPart object = (EditPart) getSelectedObjects().get(0); + Command cmd = object.getCommand(renameReq); + return cmd; + } + } + + return null; + } + + public void run() { + BControl bcontrol = getSelectedBControl(); + RenameWizard wizard = new RenameWizard(bcontrol.getAttributeValue( + AttributeConstants.ATTRIBUTE_TEXT).toString()); + WizardDialog dialog = new WizardDialog(getWorkbenchPart().getSite() + .getShell(), wizard); + dialog.create(); + dialog.getShell().setSize(400, 315); + dialog.getShell().setText("BMotion Studio Rename Wizard"); + + if (dialog.open() == WizardDialog.OK) { + String name = wizard.getRenameValue(); + execute(createRenameCommand(name)); + } + } + + private BControl getSelectedBControl() { + List<?> objects = getSelectedObjects(); + if (objects.isEmpty()) { + return null; + } + if (!(objects.get(0) instanceof EditPart)) { + return null; + } + EditPart part = (EditPart) objects.get(0); + return (BControl) part.getModel(); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/SchedulerEventAction.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/SchedulerEventAction.java new file mode 100644 index 0000000000000000000000000000000000000000..eebbb8f3405ef42d1fa48bfbbcc62a4e6f9372ed --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/action/SchedulerEventAction.java @@ -0,0 +1,174 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.action; + +import java.util.List; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.gef.EditPart; +import org.eclipse.gef.ui.actions.SelectionAction; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.ui.IWorkbenchPart; + +import de.bmotionstudio.gef.editor.AttributeConstants; +import de.bmotionstudio.gef.editor.BMotionEditorPlugin; +import de.bmotionstudio.gef.editor.BMotionStudioImage; +import de.bmotionstudio.gef.editor.command.SchedulerEventCommand; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.scheduler.SchedulerEvent; +import de.bmotionstudio.gef.editor.scheduler.SchedulerWizard; +import de.prob.logging.Logger; + +public class SchedulerEventAction extends SelectionAction { + + private String className; + private String eventID; + private SchedulerEvent clonedSchedulerEvent; + + public SchedulerEventAction(IWorkbenchPart part) { + super(part); + setLazyEnablementCalculation(true); + } + + protected void init() { + setEnabled(false); + } + + @Override + protected boolean calculateEnabled() { + return true; + } + + public void run() { + + BControl bcontrol = getControl(); + clonedSchedulerEvent = null; + + if (bcontrol != null) { + + SchedulerEvent newSchedulerEvent = bcontrol.getEvent(getEventID()); + + // Add Scheduler Event + if (newSchedulerEvent == null) { + + try { + newSchedulerEvent = (SchedulerEvent) BMotionEditorPlugin + .getSchedulerExtension(getClassName()) + .createExecutableExtension("class"); + } catch (CoreException e) { + } + + } else { // Edit Scheduler Event + + // Clone Scheduler Event + try { + clonedSchedulerEvent = newSchedulerEvent.clone(); + } catch (CloneNotSupportedException e) { + } + + } + + if (newSchedulerEvent != null) { + + newSchedulerEvent.setEventID(getEventID()); + SchedulerWizard wizard = newSchedulerEvent.getWizard(bcontrol); + + if (wizard != null) { + + BMotionSchedulerEventWizard dialog = new BMotionSchedulerEventWizard( + getWorkbenchPart(), wizard); + dialog.create(); + dialog.getShell().setSize(wizard.getSize()); + String title = "Scheduler Event: " + + newSchedulerEvent.getName() + + " Control: " + + bcontrol + .getAttributeValue(AttributeConstants.ATTRIBUTE_ID); + wizard.setWindowTitle("BMotion Studio Scheduler Event Wizard"); + dialog.setTitle(title); + dialog.setMessage(newSchedulerEvent.getDescription()); + dialog.setTitleImage(BMotionStudioImage + .getImage(BMotionStudioImage.IMG_LOGO_BMOTION64)); + int status = dialog.open(); + + if (status == WizardDialog.OK) { + + SchedulerEventCommand schedulerEventCommand = createSchedulerEventCommand(); + schedulerEventCommand + .setNewSchedulerEvent(newSchedulerEvent); + + if (wizard.isEventDelete()) { + + RemoveSchedulerEventAction action = new RemoveSchedulerEventAction( + getWorkbenchPart()); + action.setControl(getControl()); + action.setSchedulerEvent(clonedSchedulerEvent); + action.run(); + + } else { + if (clonedSchedulerEvent != null) { + schedulerEventCommand + .setClonedSchedulerEvent(clonedSchedulerEvent); + } + execute(schedulerEventCommand); + } + + } else if (status == WizardDialog.CANCEL) { + if (clonedSchedulerEvent != null) + bcontrol.addEvent(getEventID(), + clonedSchedulerEvent); + } + + } else { + Logger.notifyUserWithoutBugreport("The Scheduler Event \"" + + newSchedulerEvent.getName() + + "\" does not support a wizard."); + } + + } else { + // TODO: Error message?! + } + + } + + } + + public SchedulerEventCommand createSchedulerEventCommand() { + SchedulerEventCommand command = new SchedulerEventCommand(); + command.setClassName(getClassName()); + command.setEventID(getEventID()); + command.setControl(getControl()); + return command; + } + + public void setClassName(String className) { + this.className = className; + } + + public String getClassName() { + return this.className; + } + + public void setEventID(String eventID) { + this.eventID = eventID; + } + + public String getEventID() { + return eventID; + } + + protected BControl getControl() { + List<?> objects = getSelectedObjects(); + if (objects.isEmpty()) + return null; + if (!(objects.get(0) instanceof EditPart)) + return null; + EditPart part = (EditPart) objects.get(0); + return (BControl) part.getModel(); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/animation/AnimationMove.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/animation/AnimationMove.java new file mode 100644 index 0000000000000000000000000000000000000000..c0a26f986af914db8ff304e31681264a89e9bca2 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/animation/AnimationMove.java @@ -0,0 +1,72 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.animation; + +import java.util.ArrayList; + +import org.eclipse.draw2d.geometry.Point; + +import com.jgoodies.animation.AbstractAnimation; +import com.jgoodies.animation.AnimationFunction; +import com.jgoodies.animation.AnimationFunctions; +import com.jgoodies.animation.Animator; + +import de.bmotionstudio.gef.editor.AttributeConstants; +import de.bmotionstudio.gef.editor.model.BControl; + +public class AnimationMove extends AbstractAnimation { + + private AnimationFunction af; + + private ArrayList<Point> points = new ArrayList<Point>(); + + private Animator animator; + + private BControl control; + + public AnimationMove(long duration, boolean freezed, BControl control, + Integer toX, Integer toY) { + super(duration, freezed); + + this.control = control; + + Integer fromX = Integer.valueOf(control.getAttributeValue( + AttributeConstants.ATTRIBUTE_X).toString()); + Integer fromY = Integer.valueOf(control.getAttributeValue( + AttributeConstants.ATTRIBUTE_Y).toString()); + + Bresenham br = new Bresenham(); + br.plot(fromX, fromY, toX, toY); + + points.clear(); + + while (br.next()) { + Point pt = new Point(br.getX(), br.getY()); + points.add(pt); + } + + af = AnimationFunctions.discrete(duration(), points + .toArray(new Point[points.size()])); + } + + public void start() { + if (points != null) { + if (points.size() > 0) { + animator = new Animator(this, 30); + animator.start(); + } else { + fireAnimationStopped(30); + } + } + } + + protected void applyEffect(long time) { + Point pt = (Point) af.valueAt(time); + control.setLocation(pt); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/animation/Bresenham.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/animation/Bresenham.java new file mode 100644 index 0000000000000000000000000000000000000000..cd8105223e258f374e98d8cdde0369079a2130b9 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/animation/Bresenham.java @@ -0,0 +1,200 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.animation; + +public final class Bresenham { + + /** The start and end of the line */ + // private int x1, y1, x2, y2; + + /** Used for calculation */ + private int dx, dy, error, x_inc, y_inc, xx, yy, length, count; + + /** General case algorithm */ + private static final Bresenham bresenham = new Bresenham(); + + /** + * Construct a Bresenham algorithm. + */ + public Bresenham() { + } + + /** + * Plot a line between (x1,y1) and (x2,y2). To step through the line use + * next(). + * + * @return the length of the line (which will be 1 more than you are + * expecting). + */ + public int plot(int x1, int y1, int x2, int y2) { + // this.x1 = x1; + // this.x2 = x2; + // this.y1 = y1; + // this.y2 = y2; + + // compute horizontal and vertical deltas + dx = x2 - x1; + dy = y2 - y1; + + // test which direction the line is going in i.e. slope angle + if (dx >= 0) { + x_inc = 1; + } else { + x_inc = -1; + dx = -dx; // need absolute value + } + + // test y component of slope + + if (dy >= 0) { + y_inc = 1; + } else { + y_inc = -1; + dy = -dy; // need absolute value + } + + xx = x1; + yy = y1; + + if (dx > 0) + error = dx >> 1; + else + error = dy >> 1; + + count = 0; + length = Math.max(dx, dy) + 1; + return length; + } + + /** + * Get the next point in the line. You must not call next() if the previous + * invocation of next() returned false. + * + * Retrieve the X and Y coordinates of the line with getX() and getY(). + * + * @return true if there is another point to come. + */ + public boolean next() { + // now based on which delta is greater we can draw the line + if (dx > dy) { + // adjust the error term + error += dy; + + // test if error has overflowed + if (error >= dx) { + error -= dx; + + // move to next line + yy += y_inc; + } + + // move to the next pixel + xx += x_inc; + } else { + // adjust the error term + error += dx; + + // test if error overflowed + if (error >= dy) { + error -= dy; + + // move to next line + xx += x_inc; + } + + // move to the next pixel + yy += y_inc; + } + + count++; + return count < length; + } + + /** + * @return the current X coordinate + */ + public int getX() { + return xx; + } + + /** + * @return the current Y coordinate + */ + public int getY() { + return yy; + } + + /** + * Plot a line between (x1,y1) and (x2,y2). The results are placed in x[] + * and y[], which must be large enough. + * + * @return the length of the line or the length of x[]/y[], whichever is + * smaller + */ + public static final int plot(final int x1, final int y1, final int x2, + final int y2, final int x[], final int y[]) { + + int length = Math.min(x.length, Math.min(y.length, bresenham.plot(x1, + y1, x2, y2))); + for (int i = 0; i < length; i++) { + bresenham.next(); + x[i] = bresenham.getX(); + y[i] = bresenham.getY(); + } + + return length; + + /* + * + * int dx; // difference in x's int dy; // difference in y's int error = + * 0; // the discriminant i.e. error i.e. decision variable int x_inc; + * int y_inc; int index; // used for looping + * + * // compute horizontal and vertical deltas dx = x2 - x1; dy = y2 - y1; + * + * // test which direction the line is going in i.e. slope angle if (dx + * >= 0) { x_inc = 1; } else { x_inc = -1; dx = -dx; // need absolute + * value + * + * } + * + * // test y component of slope + * + * if (dy >= 0) { y_inc = 1; } else { y_inc = -1; dy = -dy; // need + * absolute value + * + * } + * + * int xx = x1, yy = y1; + * + * // now based on which delta is greater we can draw the line if (dx > + * dy) { error = dx >> 1; // draw the line for (index = 0; index <= dx + * && index < x.length; index++) { // remember the point x[index] = xx; + * y[index] = yy; + * + * // adjust the error term error += dy; + * + * // test if error has overflowed if (error >= dx) { error -= dx; + * + * // move to next line yy += y_inc; } + * + * // move to the next pixel xx += x_inc; } return Math.min(x.length, + * dx); } else { error = dy >> 1; // draw the line for (index = 0; index + * <= dy && index < y.length; index++) { // remember the point x[index] + * = xx; y[index] = yy; + * + * // adjust the error term error += dx; + * + * // test if error overflowed if (error >= dy) { error -= dy; + * + * // move to next line xx += x_inc; } + * + * // move to the next pixel yy += y_inc; } return Math.min(y.length, + * dy); } + */ + } +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/animation/StaticListenerRegistry.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/animation/StaticListenerRegistry.java new file mode 100644 index 0000000000000000000000000000000000000000..1e2a30b7a9a74ef566ba838a5f13d32c1f66a4ec --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/animation/StaticListenerRegistry.java @@ -0,0 +1,67 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.animation; + +import java.util.HashSet; +import java.util.Set; + +import de.prob.core.IAnimationListener; +import de.prob.core.IComputationListener; +import de.prob.core.ILifecycleListener; +import de.prob.core.domainobjects.Operation; +import de.prob.core.domainobjects.State; + +public class StaticListenerRegistry implements ILifecycleListener, + IComputationListener, IAnimationListener { + + private static final Set<ILifecycleListener> lifeCycleListeners = new HashSet<ILifecycleListener>(); + private static final Set<IComputationListener> computationListeners = new HashSet<IComputationListener>(); + private static final Set<IAnimationListener> animationListeners = new HashSet<IAnimationListener>(); + + public static void registerListener(final ILifecycleListener listener) { + lifeCycleListeners.add(listener); + } + + public static void unregisterListener(final ILifecycleListener listener) { + lifeCycleListeners.remove(listener); + } + + public static void registerListener(final IComputationListener listener) { + computationListeners.add(listener); + } + + public static void unregisterListener(final IComputationListener listener) { + computationListeners.remove(listener); + } + + public static void registerListener(final IAnimationListener listener) { + animationListeners.add(listener); + } + + public static void unregisterListener(final IAnimationListener listener) { + animationListeners.remove(listener); + } + + public void reset() { + for (final ILifecycleListener listener : lifeCycleListeners) { + listener.reset(); + } + } + + public void computedState(final State state) { + for (final IComputationListener listener : computationListeners) { + listener.computedState(state); + } + } + + public void currentStateChanged(final State currentState, + final Operation operation) { + for (final IAnimationListener listener : animationListeners) { + listener.currentStateChanged(currentState, operation); + } + } +} \ No newline at end of file diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/AbstractAttribute.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/AbstractAttribute.java new file mode 100644 index 0000000000000000000000000000000000000000..952e2adb8c611e94217b02f9d0921cfa6542d26c --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/AbstractAttribute.java @@ -0,0 +1,199 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import java.util.ArrayList; +import java.util.HashMap; + +import org.eclipse.jface.viewers.ICellEditorValidator; +import org.eclipse.ui.views.properties.IPropertyDescriptor; +import org.eclipse.ui.views.properties.IPropertySource; +import org.eclipse.ui.views.properties.PropertyDescriptor; + +import de.bmotionstudio.gef.editor.model.BControl; + +/** + * + * Represents an attribute of a {@link BControl}. + * + * @author Lukas Ladenberger + * + */ +public abstract class AbstractAttribute implements IPropertySource, Cloneable { + + public static final String ROOT = "de.bmotionstudio.gef.editor.attribute.BAttributeRoot"; + + private transient HashMap<String, AbstractAttribute> children; + private transient BControl control; + private String group; + private boolean editable; + private boolean show; + private Object value; + + private transient PropertyDescriptor propertyDescriptor; + private transient Object initValue; + + public AbstractAttribute(Object value) { + this.value = value; + this.initValue = value; + this.editable = true; + this.show = true; + } + + private Object readResolve() { + this.initValue = this.value; + return this; + } + + public void addChild(AbstractAttribute atr) { + if (!getChildren().containsKey(atr.getID())) { + getChildren().put(atr.getID(), atr); + } + } + + public Boolean hasChildren() { + return !getChildren().isEmpty(); + } + + public PropertyDescriptor getPropertyDescriptor() { + propertyDescriptor = new PropertyDescriptor(getID(), getName()); + if (editable) { + propertyDescriptor = preparePropertyDescriptor(); + if (propertyDescriptor != null) { + propertyDescriptor.setValidator(new ICellEditorValidator() { + public String isValid(Object value) { + return validateValue(value, control); + } + }); + } + } + return propertyDescriptor; + } + + protected abstract PropertyDescriptor preparePropertyDescriptor(); + + public Object unmarshal(String s) { + return s; + } + + public String getID() { + return getClass().getName(); + } + + public abstract String getName(); + + public void setGroup(AbstractAttribute group) { + setGroup(group.getClass().getName()); + } + + public void setGroup(String group) { + this.group = group; + } + + public String getGroup() { + return group; + } + + public Object getEditableValue() { + return this; + } + + public IPropertyDescriptor[] getPropertyDescriptors() { + ArrayList<IPropertyDescriptor> descriptor = new ArrayList<IPropertyDescriptor>(); + for (AbstractAttribute atr : getChildren().values()) { + descriptor.add(atr.getPropertyDescriptor()); + } + return descriptor.toArray(new IPropertyDescriptor[0]); + } + + public Object getPropertyValue(Object attrID) { + AbstractAttribute atr = getChildren().get(attrID); + if (atr.hasChildren()) { + return atr; + } else { + return atr.getValue(); + } + } + + public boolean isPropertySet(Object id) { + return false; + } + + public void resetPropertyValue(Object id) { + } + + public void setPropertyValue(Object id, Object value) { + AbstractAttribute atr = children.get(id); + atr.setValue(value); + } + + public void setValue(Object value) { + setValue(value, true); + } + + public void setValue(Object value, Boolean firePropertyChange) { + Object oldVal = this.value; + this.value = value; + if (firePropertyChange && control != null) + control.getListeners().firePropertyChange(getID(), oldVal, value); + } + + public void restoreValue() { + Object oldVal = this.value; + this.value = this.initValue; + if (control != null) + control.getListeners().firePropertyChange(getID(), oldVal, value); + } + + public Object getValue() { + return this.value; + } + + public Object getInitValue() { + return initValue; + } + + public HashMap<String, AbstractAttribute> getChildren() { + if (children == null) + children = new HashMap<String, AbstractAttribute>(); + return children; + } + + @Override + public AbstractAttribute clone() throws CloneNotSupportedException { + return (AbstractAttribute) super.clone(); + } + + public void setEditable(boolean editable) { + this.editable = editable; + } + + public boolean isEditable() { + return editable; + } + + public String validateValue(Object value, BControl control) { + return null; + } + + public void setShow(boolean show) { + this.show = show; + } + + public boolean show() { + return show; + } + + public BControl getControl() { + return control; + } + + public void setControl(BControl control) { + this.control = control; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeAlpha.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeAlpha.java new file mode 100644 index 0000000000000000000000000000000000000000..ced44636ecd9f445c0418cb1e6064b28bcff8ac2 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeAlpha.java @@ -0,0 +1,49 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.ui.views.properties.PropertyDescriptor; + +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.property.SliderPropertyDescriptor; + +public class BAttributeAlpha extends AbstractAttribute { + + public BAttributeAlpha(Object value) { + super(value); + } + + public PropertyDescriptor preparePropertyDescriptor() { + SliderPropertyDescriptor descriptor = new SliderPropertyDescriptor( + getID(), getName()); + return descriptor; + } + + @Override + public String validateValue(Object value, BControl control) { + if (!(String.valueOf(value)).trim().matches("\\d*")) { + return "Value must be a number"; + } + + if ((String.valueOf(value)).trim().length() == 0) { + return "Value must not be empty string"; + } + + if (Integer.valueOf(value.toString()) > 255 + || Integer.valueOf(value.toString()) < 0) { + return "Only a range from 0 to 255 is allowed"; + } + + return null; + } + + @Override + public String getName() { + return "Alpha"; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeBackgroundColor.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeBackgroundColor.java new file mode 100644 index 0000000000000000000000000000000000000000..72d0ad68e8060f0add59abcfb971d8d1fe4461c3 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeBackgroundColor.java @@ -0,0 +1,55 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.swt.graphics.RGB; +import org.eclipse.ui.views.properties.ColorPropertyDescriptor; +import org.eclipse.ui.views.properties.PropertyDescriptor; + +import de.bmotionstudio.gef.editor.model.BControl; + +public class BAttributeBackgroundColor extends AbstractAttribute { + + public BAttributeBackgroundColor(Object value) { + super(value); + } + + public PropertyDescriptor preparePropertyDescriptor() { + return new ColorPropertyDescriptor(getID(), getName()); + } + + @Override + public String validateValue(Object value, BControl control) { + // TODO: Implement me! + return null; + } + + @Override + public String getName() { + return "Background-Color"; + } + + @Override + public Object unmarshal(String s) { + + String colorStr = s.toLowerCase().replace(" ", ""); + colorStr = colorStr.replace("rgb", ""); + colorStr = colorStr.replace("}", ""); + colorStr = colorStr.replace("{", ""); + String[] str = String.valueOf(colorStr).split("\\,"); + if (str.length == 3) { + int red = Integer.valueOf(str[0]); + int green = Integer.valueOf(str[1]); + int blue = Integer.valueOf(str[2]); + return new RGB(red, green, blue); + } else { + return new RGB(192, 192, 192); + } + + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeBackgroundVisible.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeBackgroundVisible.java new file mode 100644 index 0000000000000000000000000000000000000000..2fe7e5f98645f83461e615a4987962f3ab205895 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeBackgroundVisible.java @@ -0,0 +1,44 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.ui.views.properties.PropertyDescriptor; + +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.property.CheckboxPropertyDescriptor; + +public class BAttributeBackgroundVisible extends AbstractAttribute { + + public BAttributeBackgroundVisible(Object value) { + super(value); + } + + public PropertyDescriptor preparePropertyDescriptor() { + return new CheckboxPropertyDescriptor(getID(), getName()); + } + + @Override + public String validateValue(Object value, BControl control) { + if ((String.valueOf(value)).trim().equalsIgnoreCase("true") + || (String.valueOf(value)).trim().equalsIgnoreCase("false")) { + return null; + } else { + return "Value must be a Boolean value (\"true\" or \"false\")"; + } + } + + @Override + public String getName() { + return "Visible"; + } + + @Override + public Object unmarshal(String s) { + return Boolean.valueOf(s); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeButtonGroup.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeButtonGroup.java new file mode 100644 index 0000000000000000000000000000000000000000..dea0957c61f2d6b3111d9d87110af87cec8c2cf8 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeButtonGroup.java @@ -0,0 +1,28 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.ui.views.properties.PropertyDescriptor; +import org.eclipse.ui.views.properties.TextPropertyDescriptor; + +public class BAttributeButtonGroup extends AbstractAttribute { + + public BAttributeButtonGroup(Object value) { + super(value); + } + + @Override + protected PropertyDescriptor preparePropertyDescriptor() { + return new TextPropertyDescriptor(getID(), getName()); + } + + @Override + public String getName() { + return "Button"; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeChecked.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeChecked.java new file mode 100644 index 0000000000000000000000000000000000000000..d3013220cac3d2a736d85297118267822590618b --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeChecked.java @@ -0,0 +1,45 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.ui.views.properties.PropertyDescriptor; + +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.property.CheckboxPropertyDescriptor; + +public class BAttributeChecked extends AbstractAttribute { + + public BAttributeChecked(Object value) { + super(value); + } + + @Override + protected PropertyDescriptor preparePropertyDescriptor() { + return new CheckboxPropertyDescriptor(getID(), getName()); + } + + @Override + public String validateValue(Object value, BControl control) { + if ((String.valueOf(value)).trim().equalsIgnoreCase("true") + || (String.valueOf(value)).trim().equalsIgnoreCase("false")) { + return null; + } else { + return "Value must be a Boolean value (\"true\" or \"false\")"; + } + } + + @Override + public String getName() { + return "Checked"; + } + + @Override + public Object unmarshal(String s) { + return Boolean.valueOf(s); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeConnection.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeConnection.java new file mode 100644 index 0000000000000000000000000000000000000000..5d7aff929acc4395d610c75945511ae82148f23e --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeConnection.java @@ -0,0 +1,27 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.ui.views.properties.PropertyDescriptor; + +public class BAttributeConnection extends AbstractAttribute { + + public BAttributeConnection(Object value) { + super(value); + } + + @Override + public PropertyDescriptor preparePropertyDescriptor() { + return new PropertyDescriptor(getID(), getName()); + } + + @Override + public String getName() { + return "Connection"; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeConnectionSourceDecoration.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeConnectionSourceDecoration.java new file mode 100644 index 0000000000000000000000000000000000000000..89a5c58c734618d066772afe071dc0d56dfee25b --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeConnectionSourceDecoration.java @@ -0,0 +1,32 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.ui.views.properties.ComboBoxPropertyDescriptor; +import org.eclipse.ui.views.properties.PropertyDescriptor; + +public class BAttributeConnectionSourceDecoration extends AbstractAttribute { + + public static int DECORATION_NONE = 0; + public static int DECORATION_TRIANGLE = 1; + + public BAttributeConnectionSourceDecoration(Object value) { + super(value); + } + + @Override + protected PropertyDescriptor preparePropertyDescriptor() { + return new ComboBoxPropertyDescriptor(getID(), getName(), new String[] { + "None", "Triangle" }); + } + + @Override + public String getName() { + return "Connection-Source-Decoration"; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeConnectionTargetDecoration.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeConnectionTargetDecoration.java new file mode 100644 index 0000000000000000000000000000000000000000..fc9f9353cddc3a0533becdac8368e2e67909b373 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeConnectionTargetDecoration.java @@ -0,0 +1,32 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.ui.views.properties.ComboBoxPropertyDescriptor; +import org.eclipse.ui.views.properties.PropertyDescriptor; + +public class BAttributeConnectionTargetDecoration extends AbstractAttribute { + + public static int DECORATION_NONE = 0; + public static int DECORATION_TRIANGLE = 1; + + public BAttributeConnectionTargetDecoration(Object value) { + super(value); + } + + @Override + protected PropertyDescriptor preparePropertyDescriptor() { + return new ComboBoxPropertyDescriptor(getID(), getName(), new String[] { + "None", "Triangle" }); + } + + @Override + public String getName() { + return "Connection-Target-Decoration"; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeCoordinates.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeCoordinates.java new file mode 100644 index 0000000000000000000000000000000000000000..e251e8320a94782e62777ac6740322abe0c12d3e --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeCoordinates.java @@ -0,0 +1,54 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.ui.views.properties.PropertyDescriptor; + +import de.bmotionstudio.gef.editor.AttributeConstants; + +public class BAttributeCoordinates extends AbstractAttribute { + + public BAttributeCoordinates(Object value) { + super(value); + } + + @Override + public PropertyDescriptor preparePropertyDescriptor() { + PropertyDescriptor descriptor = new PropertyDescriptor(getID(), + getName()); + descriptor.setLabelProvider(new LabelProvider() { + public String getText(Object element) { + Point point = (Point) element; + StringBuffer buf = new StringBuffer(); + buf.append("["); + buf.append(point.x); + buf.append(", "); + buf.append(point.y); + buf.append("]"); + return buf.toString(); + } + }); + return descriptor; + } + + @Override + public Object getEditableValue() { + int x = Integer.valueOf(getChildren() + .get(AttributeConstants.ATTRIBUTE_X).getValue().toString()); + int y = Integer.valueOf(getChildren() + .get(AttributeConstants.ATTRIBUTE_Y).getValue().toString()); + return new Point(x, y); + } + + @Override + public String getName() { + return "a4:Coordinates"; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeCustom.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeCustom.java new file mode 100644 index 0000000000000000000000000000000000000000..a2ff6fa20caa0970d0519bad991a4f0b1a0f93c6 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeCustom.java @@ -0,0 +1,28 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.ui.views.properties.PropertyDescriptor; +import org.eclipse.ui.views.properties.TextPropertyDescriptor; + +public class BAttributeCustom extends AbstractAttribute { + + public BAttributeCustom(Object value) { + super(value); + } + + @Override + public PropertyDescriptor preparePropertyDescriptor() { + return new TextPropertyDescriptor(getID(), getName()); + } + + @Override + public String getName() { + return "a2:This"; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeDirection.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeDirection.java new file mode 100644 index 0000000000000000000000000000000000000000..899f70124e929d6150108db251f236ec33856895 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeDirection.java @@ -0,0 +1,34 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.ui.views.properties.ComboBoxPropertyDescriptor; +import org.eclipse.ui.views.properties.PropertyDescriptor; + +public class BAttributeDirection extends AbstractAttribute { + + public static final int NORTH = 0; + public static final int SOUTH = 1; + public static final int WEST = 2; + public static final int EAST = 3; + + public BAttributeDirection(Object value) { + super(value); + } + + @Override + protected PropertyDescriptor preparePropertyDescriptor() { + return new ComboBoxPropertyDescriptor(getID(), getName(), new String[] { + "NORTH", "SOUTH", "WEST", "EAST" }); + } + + @Override + public String getName() { + return "Direction"; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeEnabled.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeEnabled.java new file mode 100644 index 0000000000000000000000000000000000000000..90e17ef0f039ba5e219e2213aafc74a6b01b88df --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeEnabled.java @@ -0,0 +1,44 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.ui.views.properties.PropertyDescriptor; + +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.property.CheckboxPropertyDescriptor; + +public class BAttributeEnabled extends AbstractAttribute { + + public BAttributeEnabled(Object value) { + super(value); + } + + public PropertyDescriptor preparePropertyDescriptor() { + return new CheckboxPropertyDescriptor(getID(), getName()); + } + + @Override + public String validateValue(final Object value, BControl control) { + if ((String.valueOf(value)).trim().equalsIgnoreCase("true") + || (String.valueOf(value)).trim().equalsIgnoreCase("false")) { + return null; + } else { + return "Value must be a Boolean value (\"true\" or \"false\")"; + } + } + + @Override + public String getName() { + return "Enabled"; + } + + @Override + public Object unmarshal(String s) { + return Boolean.valueOf(s); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeFalseValue.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeFalseValue.java new file mode 100644 index 0000000000000000000000000000000000000000..74a13b83fc362de800c0fcc8f04be96177e67318 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeFalseValue.java @@ -0,0 +1,22 @@ +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.ui.views.properties.PropertyDescriptor; +import org.eclipse.ui.views.properties.TextPropertyDescriptor; + +public class BAttributeFalseValue extends AbstractAttribute { + + public BAttributeFalseValue(Object value) { + super(value); + } + + @Override + public PropertyDescriptor preparePropertyDescriptor() { + return new TextPropertyDescriptor(getID(), getName()); + } + + @Override + public String getName() { + return "False-Value"; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeFillColor.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeFillColor.java new file mode 100644 index 0000000000000000000000000000000000000000..f9ad86fc83d0eed452a95766ce6b7dad9730bcf0 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeFillColor.java @@ -0,0 +1,47 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.swt.graphics.RGB; +import org.eclipse.ui.views.properties.ColorPropertyDescriptor; +import org.eclipse.ui.views.properties.PropertyDescriptor; + +public class BAttributeFillColor extends AbstractAttribute { + + public BAttributeFillColor(Object value) { + super(value); + } + + public PropertyDescriptor preparePropertyDescriptor() { + return new ColorPropertyDescriptor(getID(), getName()); + } + + @Override + public String getName() { + return "Fill-Color"; + } + + @Override + public Object unmarshal(String s) { + + String colorStr = s.toLowerCase().replace(" ", ""); + colorStr = colorStr.replace("rgb", ""); + colorStr = colorStr.replace("}", ""); + colorStr = colorStr.replace("{", ""); + String[] str = String.valueOf(colorStr).split("\\,"); + if (str.length == 3) { + int red = Integer.valueOf(str[0]); + int green = Integer.valueOf(str[1]); + int blue = Integer.valueOf(str[2]); + return new RGB(red, green, blue); + } else { + return new RGB(192, 192, 192); + } + + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeFillHeight.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeFillHeight.java new file mode 100644 index 0000000000000000000000000000000000000000..30e0b429641a6912797422e6e31d5cfea752b016 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeFillHeight.java @@ -0,0 +1,27 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.ui.views.properties.PropertyDescriptor; +import org.eclipse.ui.views.properties.TextPropertyDescriptor; + +public class BAttributeFillHeight extends AbstractAttribute { + + public BAttributeFillHeight(Object value) { + super(value); + } + + public PropertyDescriptor preparePropertyDescriptor() { + return new TextPropertyDescriptor(getID(), getName()); + } + + @Override + public String getName() { + return "Fill-Height"; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeFillType.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeFillType.java new file mode 100644 index 0000000000000000000000000000000000000000..81abe496879115fa02f1c2bf99682cd727f57344 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeFillType.java @@ -0,0 +1,34 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.ui.views.properties.ComboBoxPropertyDescriptor; +import org.eclipse.ui.views.properties.PropertyDescriptor; + +public class BAttributeFillType extends AbstractAttribute { + + public static final int FILLED = 0; + public static final int EMPTY = 1; + public static final int SHADED = 2; + public static final int GRADIENT = 3; + + public BAttributeFillType(Object value) { + super(value); + } + + @Override + protected PropertyDescriptor preparePropertyDescriptor() { + return new ComboBoxPropertyDescriptor(getID(), getName(), new String[] { + "Filled", "Empty", "Shaded", "Gradient" }); + } + + @Override + public String getName() { + return "Fill-Type"; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeFont.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeFont.java new file mode 100644 index 0000000000000000000000000000000000000000..9f8c3d87d53b33eeacc2cc82402a5a971d55a400 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeFont.java @@ -0,0 +1,28 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.ui.views.properties.PropertyDescriptor; + +import de.bmotionstudio.gef.editor.property.FontPropertyDescriptor; + +public class BAttributeFont extends AbstractAttribute { + + public BAttributeFont(Object value) { + super(value); + } + + public PropertyDescriptor preparePropertyDescriptor() { + return new FontPropertyDescriptor(getID(), getName()); + } + + @Override + public String getName() { + return "Font"; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeForegroundColor.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeForegroundColor.java new file mode 100644 index 0000000000000000000000000000000000000000..cf4abf23f94cd929925ae936b74ba1c6aeae5888 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeForegroundColor.java @@ -0,0 +1,55 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.swt.graphics.RGB; +import org.eclipse.ui.views.properties.ColorPropertyDescriptor; +import org.eclipse.ui.views.properties.PropertyDescriptor; + +import de.bmotionstudio.gef.editor.model.BControl; + +public class BAttributeForegroundColor extends AbstractAttribute { + + public BAttributeForegroundColor(Object value) { + super(value); + } + + public PropertyDescriptor preparePropertyDescriptor() { + return new ColorPropertyDescriptor(getID(), getName()); + } + + @Override + public String validateValue(Object value, BControl control) { + // TODO: Implement me! + return null; + } + + @Override + public String getName() { + return "Foreground-Color"; + } + + @Override + public Object unmarshal(String s) { + + String colorStr = s.toLowerCase().replace(" ", ""); + colorStr = colorStr.replace("rgb", ""); + colorStr = colorStr.replace("}", ""); + colorStr = colorStr.replace("{", ""); + String[] str = String.valueOf(colorStr).split("\\,"); + if (str.length == 3) { + int red = Integer.valueOf(str[0]); + int green = Integer.valueOf(str[1]); + int blue = Integer.valueOf(str[2]); + return new RGB(red, green, blue); + } else { + return new RGB(192, 192, 192); + } + + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeHeight.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeHeight.java new file mode 100644 index 0000000000000000000000000000000000000000..a4eec8e565146d2ea80384a8f9878286e95a3deb --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeHeight.java @@ -0,0 +1,42 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.ui.views.properties.PropertyDescriptor; + +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.property.IntegerPropertyDescriptor; + +public class BAttributeHeight extends AbstractAttribute { + + public BAttributeHeight(Object value) { + super(value); + } + + public PropertyDescriptor preparePropertyDescriptor() { + IntegerPropertyDescriptor descriptor = new IntegerPropertyDescriptor( + getID(), getName()); + return descriptor; + } + + @Override + public String validateValue(Object value, BControl control) { + if (!(String.valueOf(value)).trim().matches("\\d*")) { + return "Value must be a number"; + } + if ((String.valueOf(value)).trim().length() == 0) { + return "Value must not be empty string"; + } + return null; + } + + @Override + public String getName() { + return "Height"; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeID.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeID.java new file mode 100644 index 0000000000000000000000000000000000000000..21ce6046376c7d88e8275147f5984fe8ec02ac4b --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeID.java @@ -0,0 +1,45 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.ui.views.properties.PropertyDescriptor; +import org.eclipse.ui.views.properties.TextPropertyDescriptor; + +import de.bmotionstudio.gef.editor.model.BControl; + +public class BAttributeID extends AbstractAttribute { + + public BAttributeID(Object value) { + super(value); + } + + public PropertyDescriptor preparePropertyDescriptor() { + TextPropertyDescriptor descriptor = new TextPropertyDescriptor(getID(), + getName()); + return descriptor; + } + + @Override + public String validateValue(Object value, BControl control) { + if (((String) value).trim().length() == 0) { + return "Value must not be empty string"; + } + if (!(String.valueOf(value)).trim().matches("^[a-zA-Z_0-9]*")) { + return "Special characters are not allowed."; + } + if (control.getVisualization().checkIfIdExists((String) value)) { + return "ID already exists"; + } + return null; + } + + @Override + public String getName() { + return "a1:ID"; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeImage.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeImage.java new file mode 100644 index 0000000000000000000000000000000000000000..d17d58ffc6b6362ec480380b5f2d126026a800d6 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeImage.java @@ -0,0 +1,45 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import java.io.File; + +import org.eclipse.core.resources.IFile; +import org.eclipse.ui.views.properties.PropertyDescriptor; + +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.property.ImagePropertyDescriptor; + +public class BAttributeImage extends AbstractAttribute { + + public BAttributeImage(Object value) { + super(value); + } + + public PropertyDescriptor preparePropertyDescriptor() { + return new ImagePropertyDescriptor(getID(), getName()); + } + + public String validateValue(Object value, BControl control) { + if (value != null) { + String fImage = value.toString(); + IFile pFile = control.getVisualization().getProjectFile(); + String myPath = (pFile.getProject().getLocation() + "/images/" + fImage) + .replace("file:", ""); + if (!new File(myPath).exists()) { + return "No such image in your library: " + fImage; + } + } + return null; + } + + @Override + public String getName() { + return "Image"; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeLabel.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeLabel.java new file mode 100644 index 0000000000000000000000000000000000000000..a3f962a2702da02a2554dd4cb6f2b2476904edda --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeLabel.java @@ -0,0 +1,28 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.ui.views.properties.PropertyDescriptor; +import org.eclipse.ui.views.properties.TextPropertyDescriptor; + +public class BAttributeLabel extends AbstractAttribute { + + public BAttributeLabel(Object value) { + super(value); + } + + @Override + protected PropertyDescriptor preparePropertyDescriptor() { + return new TextPropertyDescriptor(getID(), getName()); + } + + @Override + public String getName() { + return "Label"; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeLineStyle.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeLineStyle.java new file mode 100644 index 0000000000000000000000000000000000000000..9e0132d7d607e9eb4d1f08f382ea7894a5489e9b --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeLineStyle.java @@ -0,0 +1,35 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.ui.views.properties.ComboBoxPropertyDescriptor; +import org.eclipse.ui.views.properties.PropertyDescriptor; + +public class BAttributeLineStyle extends AbstractAttribute { + + public static final int SOLID_CONNECTION = 0; + public static final int DASHED_CONNECTION = 1; + public static final int DOTTED_CONNECTION = 2; + public static final int DASHED_DOTTED_CONNECTION = 3; + public static final int DASHED_DOTTED_DOTTED_CONNECTION = 4; + + public BAttributeLineStyle(Object value) { + super(value); + } + + @Override + protected PropertyDescriptor preparePropertyDescriptor() { + return new ComboBoxPropertyDescriptor(getID(), getName(), new String[] { + "Solid", "Dash", "Dot", "Dash Dot", "Dash Dot Dot" }); + } + + @Override + public String getName() { + return "Line-Style"; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeLineWidth.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeLineWidth.java new file mode 100644 index 0000000000000000000000000000000000000000..b9503fbf6287dbbfeb8d0729fd759c842cb9e728 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeLineWidth.java @@ -0,0 +1,36 @@ +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.ui.views.properties.PropertyDescriptor; + +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.property.IntegerPropertyDescriptor; + +public class BAttributeLineWidth extends AbstractAttribute { + + public BAttributeLineWidth(Object value) { + super(value); + } + + public PropertyDescriptor preparePropertyDescriptor() { + IntegerPropertyDescriptor descriptor = new IntegerPropertyDescriptor( + getID(), getName()); + return descriptor; + } + + @Override + public String validateValue(Object value, BControl control) { + if (!(String.valueOf(value)).trim().matches("\\d*")) { + return "Value must be a number"; + } + if ((String.valueOf(value)).trim().length() == 0) { + return "Value must not be empty string"; + } + return null; + } + + @Override + public String getName() { + return "Line-Width"; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeMain.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeMain.java new file mode 100644 index 0000000000000000000000000000000000000000..2870f97b871646f1bc141b5c33f76b3dde21b219 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeMain.java @@ -0,0 +1,35 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.ui.views.properties.PropertyDescriptor; + +public class BAttributeMain extends AbstractAttribute { + + public BAttributeMain(Object value) { + super(value); + } + + @Override + public PropertyDescriptor preparePropertyDescriptor() { + PropertyDescriptor descriptor = new PropertyDescriptor(getID(), + getName()); + descriptor.setLabelProvider(new LabelProvider() { + public String getText(Object element) { + return ""; + } + }); + return descriptor; + } + + @Override + public String getName() { + return "Main"; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeMeasureInterval.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeMeasureInterval.java new file mode 100644 index 0000000000000000000000000000000000000000..d9892f8a1ec20736b6078974084a56626faf9f6f --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeMeasureInterval.java @@ -0,0 +1,27 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.ui.views.properties.PropertyDescriptor; +import org.eclipse.ui.views.properties.TextPropertyDescriptor; + +public class BAttributeMeasureInterval extends AbstractAttribute { + + public BAttributeMeasureInterval(Object value) { + super(value); + } + + public PropertyDescriptor preparePropertyDescriptor() { + return new TextPropertyDescriptor(getID(), getName()); + } + + @Override + public String getName() { + return "Measure-Interval"; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeMeasureMaxPos.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeMeasureMaxPos.java new file mode 100644 index 0000000000000000000000000000000000000000..dbe52aadb25e6504823b03951e61d9f771aac772 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeMeasureMaxPos.java @@ -0,0 +1,27 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.ui.views.properties.PropertyDescriptor; +import org.eclipse.ui.views.properties.TextPropertyDescriptor; + +public class BAttributeMeasureMaxPos extends AbstractAttribute { + + public BAttributeMeasureMaxPos(Object value) { + super(value); + } + + public PropertyDescriptor preparePropertyDescriptor() { + return new TextPropertyDescriptor(getID(), getName()); + } + + @Override + public String getName() { + return "Measure-Max-Pos"; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeMisc.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeMisc.java new file mode 100644 index 0000000000000000000000000000000000000000..658f9e91b231ea21d6383cc32298f73424977693 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeMisc.java @@ -0,0 +1,35 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.ui.views.properties.PropertyDescriptor; + +public class BAttributeMisc extends AbstractAttribute { + + public BAttributeMisc(Object value) { + super(value); + } + + @Override + public PropertyDescriptor preparePropertyDescriptor() { + PropertyDescriptor descriptor = new PropertyDescriptor(getID(), + getName()); + descriptor.setLabelProvider(new LabelProvider() { + public String getText(Object element) { + return ""; + } + }); + return descriptor; + } + + @Override + public String getName() { + return "Misc"; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeOffsetH.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeOffsetH.java new file mode 100644 index 0000000000000000000000000000000000000000..f173bbfb605a0c922380c2e9db6bae83e9eba08f --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeOffsetH.java @@ -0,0 +1,42 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.ui.views.properties.PropertyDescriptor; + +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.property.IntegerPropertyDescriptor; + +public class BAttributeOffsetH extends AbstractAttribute { + + public BAttributeOffsetH(Object value) { + super(value); + } + + public PropertyDescriptor preparePropertyDescriptor() { + IntegerPropertyDescriptor descriptor = new IntegerPropertyDescriptor( + getID(), getName()); + return descriptor; + } + + @Override + public String validateValue(Object value, BControl control) { + if (!(String.valueOf(value)).trim().matches("\\d*")) { + return "Value must be a number"; + } + if ((String.valueOf(value)).trim().length() == 0) { + return "Value must not be empty string"; + } + return null; + } + + @Override + public String getName() { + return "Offset-H"; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeOffsetV.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeOffsetV.java new file mode 100644 index 0000000000000000000000000000000000000000..9fafedfc1c7588060e666ac95d51344bc3c9dfc5 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeOffsetV.java @@ -0,0 +1,42 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.ui.views.properties.PropertyDescriptor; + +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.property.IntegerPropertyDescriptor; + +public class BAttributeOffsetV extends AbstractAttribute { + + public BAttributeOffsetV(Object value) { + super(value); + } + + public PropertyDescriptor preparePropertyDescriptor() { + IntegerPropertyDescriptor descriptor = new IntegerPropertyDescriptor( + getID(), getName()); + return descriptor; + } + + @Override + public String validateValue(Object value, BControl control) { + if (!(String.valueOf(value)).trim().matches("\\d*")) { + return "Value must be a number"; + } + if ((String.valueOf(value)).trim().length() == 0) { + return "Value must not be empty string"; + } + return null; + } + + @Override + public String getName() { + return "Offset-V"; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeOrientation.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeOrientation.java new file mode 100644 index 0000000000000000000000000000000000000000..365995bcfef2ae6b62f13a29989d01d5e38d0856 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeOrientation.java @@ -0,0 +1,26 @@ +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.ui.views.properties.ComboBoxPropertyDescriptor; +import org.eclipse.ui.views.properties.PropertyDescriptor; + +public class BAttributeOrientation extends AbstractAttribute { + + public static final int HORIZONTAL = 0; + public static final int VERTICAL = 1; + + public BAttributeOrientation(Object value) { + super(value); + } + + @Override + protected PropertyDescriptor preparePropertyDescriptor() { + return new ComboBoxPropertyDescriptor(getID(), getName(), new String[] { + "HORIZONTAL", "VERTICAL" }); + } + + @Override + public String getName() { + return "Orientation"; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeOutlineAlpha.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeOutlineAlpha.java new file mode 100644 index 0000000000000000000000000000000000000000..dd3ce6d151ad5b70e2e2f2af0578049f3136ab73 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeOutlineAlpha.java @@ -0,0 +1,50 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.ui.views.properties.PropertyDescriptor; + +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.property.SliderPropertyDescriptor; + +public class BAttributeOutlineAlpha extends AbstractAttribute { + + public BAttributeOutlineAlpha(Object value) { + super(value); + } + + public PropertyDescriptor preparePropertyDescriptor() { + SliderPropertyDescriptor descriptor = new SliderPropertyDescriptor( + getID(), getName()); + return descriptor; + } + + public String validateValue(Object value, BControl control) { + + if (!(String.valueOf(value)).trim().matches("\\d*")) { + return "Value must be a number"; + } + + if ((String.valueOf(value)).trim().length() == 0) { + return "Value must not be empty string"; + } + + if (Integer.valueOf(value.toString()) > 255 + || Integer.valueOf(value.toString()) < 0) { + return "Only a range from 0 to 255 is allowed"; + } + + return null; + + } + + @Override + public String getName() { + return "Outline-Alpha"; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeShape.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeShape.java new file mode 100644 index 0000000000000000000000000000000000000000..b2200082614890de744321a1e8f86a278dcead36 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeShape.java @@ -0,0 +1,34 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.ui.views.properties.ComboBoxPropertyDescriptor; +import org.eclipse.ui.views.properties.PropertyDescriptor; + +public class BAttributeShape extends AbstractAttribute { + + public static final int SHAPE_RECTANGLE = 0; + public static final int SHAPE_OVAL = 1; + public static final int SHAPE_TRIANGLE = 2; + public static final int SHAPE_DIAMOND = 3; + + public BAttributeShape(Object value) { + super(value); + } + + @Override + protected PropertyDescriptor preparePropertyDescriptor() { + return new ComboBoxPropertyDescriptor(getID(), getName(), new String[] { + "Rectangle", "Oval", "Triangle", "Diamond" }); + } + + @Override + public String getName() { + return "Shape"; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeShowMeasure.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeShowMeasure.java new file mode 100644 index 0000000000000000000000000000000000000000..e5aa9cb4ea0402e7081b9747059b567822dabc2f --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeShowMeasure.java @@ -0,0 +1,44 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.ui.views.properties.PropertyDescriptor; + +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.property.CheckboxPropertyDescriptor; + +public class BAttributeShowMeasure extends AbstractAttribute { + + public BAttributeShowMeasure(Object value) { + super(value); + } + + public PropertyDescriptor preparePropertyDescriptor() { + return new CheckboxPropertyDescriptor(getID(), getName()); + } + + @Override + public String validateValue(Object value, BControl control) { + if ((String.valueOf(value)).trim().equalsIgnoreCase("true") + || (String.valueOf(value)).trim().equalsIgnoreCase("false")) { + return null; + } else { + return "Value must be a Boolean value (\"true\" or \"false\")"; + } + } + + @Override + public String getName() { + return "Show-Measure"; + } + + @Override + public Object unmarshal(String s) { + return Boolean.valueOf(s); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeSize.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeSize.java new file mode 100644 index 0000000000000000000000000000000000000000..5024a0e35ed468e15de2807dc4867e7b634c1d27 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeSize.java @@ -0,0 +1,55 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.ui.views.properties.PropertyDescriptor; + +import de.bmotionstudio.gef.editor.AttributeConstants; + +public class BAttributeSize extends AbstractAttribute { + + public BAttributeSize(Object value) { + super(value); + } + + @Override + public PropertyDescriptor preparePropertyDescriptor() { + PropertyDescriptor descriptor = new PropertyDescriptor(getID(), + getName()); + descriptor.setLabelProvider(new LabelProvider() { + public String getText(Object element) { + Point point = (Point) element; + StringBuffer buf = new StringBuffer(); + buf.append("["); + buf.append(point.x); + buf.append(", "); + buf.append(point.y); + buf.append("]"); + return buf.toString(); + } + }); + return descriptor; + } + + @Override + public Object getEditableValue() { + int width = Integer.valueOf(getChildren() + .get(AttributeConstants.ATTRIBUTE_WIDTH).getValue().toString()); + int height = Integer + .valueOf(getChildren().get(AttributeConstants.ATTRIBUTE_HEIGHT) + .getValue().toString()); + return new Point(width, height); + } + + @Override + public String getName() { + return "a5:Size"; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeText.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeText.java new file mode 100644 index 0000000000000000000000000000000000000000..d9d0ab66bd3b789452376e3505bca4542a911033 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeText.java @@ -0,0 +1,27 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.ui.views.properties.PropertyDescriptor; +import org.eclipse.ui.views.properties.TextPropertyDescriptor; + +public class BAttributeText extends AbstractAttribute { + + public BAttributeText(Object value) { + super(value); + } + + public PropertyDescriptor preparePropertyDescriptor() { + return new TextPropertyDescriptor(getID(), getName()); + } + + @Override + public String getName() { + return "Text"; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeTextColor.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeTextColor.java new file mode 100644 index 0000000000000000000000000000000000000000..4e2da94ca5f29e91e6425ae3d25b9f36acfcfa69 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeTextColor.java @@ -0,0 +1,55 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.swt.graphics.RGB; +import org.eclipse.ui.views.properties.ColorPropertyDescriptor; +import org.eclipse.ui.views.properties.PropertyDescriptor; + +import de.bmotionstudio.gef.editor.model.BControl; + +public class BAttributeTextColor extends AbstractAttribute { + + public BAttributeTextColor(Object value) { + super(value); + } + + public PropertyDescriptor preparePropertyDescriptor() { + return new ColorPropertyDescriptor(getID(), getName()); + } + + @Override + public String validateValue(Object value, BControl control) { + // TODO: Implement me! + return null; + } + + @Override + public String getName() { + return "Text-Color"; + } + + @Override + public Object unmarshal(String s) { + + String colorStr = s.toLowerCase().replace(" ", ""); + colorStr = colorStr.replace("rgb", ""); + colorStr = colorStr.replace("}", ""); + colorStr = colorStr.replace("{", ""); + String[] str = String.valueOf(colorStr).split("\\,"); + if (str.length == 3) { + int red = Integer.valueOf(str[0]); + int green = Integer.valueOf(str[1]); + int blue = Integer.valueOf(str[2]); + return new RGB(red, green, blue); + } else { + return new RGB(192, 192, 192); + } + + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeTrueValue.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeTrueValue.java new file mode 100644 index 0000000000000000000000000000000000000000..3d58d1fbd9b9645fb4df65b4b0ed72f3ee1adb24 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeTrueValue.java @@ -0,0 +1,28 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.ui.views.properties.PropertyDescriptor; +import org.eclipse.ui.views.properties.TextPropertyDescriptor; + +public class BAttributeTrueValue extends AbstractAttribute { + + public BAttributeTrueValue(Object value) { + super(value); + } + + @Override + public PropertyDescriptor preparePropertyDescriptor() { + return new TextPropertyDescriptor(getID(), getName()); + } + + @Override + public String getName() { + return "True-Value"; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeValue.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeValue.java new file mode 100644 index 0000000000000000000000000000000000000000..2b0aaf110088d54fde29b51a5fc1f5125ba80b54 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeValue.java @@ -0,0 +1,28 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.ui.views.properties.PropertyDescriptor; +import org.eclipse.ui.views.properties.TextPropertyDescriptor; + +public class BAttributeValue extends AbstractAttribute { + + public BAttributeValue(Object value) { + super(value); + } + + @Override + protected PropertyDescriptor preparePropertyDescriptor() { + return new TextPropertyDescriptor(getID(), getName()); + } + + @Override + public String getName() { + return "Value"; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeVisible.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeVisible.java new file mode 100644 index 0000000000000000000000000000000000000000..96961a53dab4e56bb39a99a59c2d84b93aea36fe --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeVisible.java @@ -0,0 +1,44 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.ui.views.properties.PropertyDescriptor; + +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.property.CheckboxPropertyDescriptor; + +public class BAttributeVisible extends AbstractAttribute { + + public BAttributeVisible(Object value) { + super(value); + } + + public PropertyDescriptor preparePropertyDescriptor() { + return new CheckboxPropertyDescriptor(getID(), getName()); + } + + @Override + public String validateValue(Object value, BControl control) { + if ((String.valueOf(value)).trim().equalsIgnoreCase("true") + || (String.valueOf(value)).trim().equalsIgnoreCase("false")) { + return null; + } else { + return "Value must be a Boolean value (\"true\" or \"false\")"; + } + } + + @Override + public String getName() { + return "a3:Visible"; + } + + @Override + public Object unmarshal(String s) { + return Boolean.valueOf(s); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeWidth.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeWidth.java new file mode 100644 index 0000000000000000000000000000000000000000..bcb310e77a51b6c9f68576b6de16f70a6c2dd351 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeWidth.java @@ -0,0 +1,42 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.ui.views.properties.PropertyDescriptor; + +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.property.IntegerPropertyDescriptor; + +public class BAttributeWidth extends AbstractAttribute { + + public BAttributeWidth(Object value) { + super(value); + } + + public PropertyDescriptor preparePropertyDescriptor() { + IntegerPropertyDescriptor descriptor = new IntegerPropertyDescriptor( + getID(), getName()); + return descriptor; + } + + @Override + public String validateValue(Object value, BControl control) { + if (!(String.valueOf(value)).trim().matches("\\d*")) { + return "Value must be a number"; + } + if ((String.valueOf(value)).trim().length() == 0) { + return "Value must not be empty string"; + } + return null; + } + + @Override + public String getName() { + return "Width"; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeX.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeX.java new file mode 100644 index 0000000000000000000000000000000000000000..2ff72c75024892ef73ef0c1edcde72af764a319a --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeX.java @@ -0,0 +1,42 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.ui.views.properties.PropertyDescriptor; + +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.property.IntegerPropertyDescriptor; + +public class BAttributeX extends AbstractAttribute { + + public BAttributeX(Object value) { + super(value); + } + + public PropertyDescriptor preparePropertyDescriptor() { + IntegerPropertyDescriptor descriptor = new IntegerPropertyDescriptor( + getID(), getName()); + return descriptor; + } + + @Override + public String validateValue(Object value, BControl control) { + if (!(String.valueOf(value)).trim().matches("\\d*")) { + return "Value must be a number"; + } + if ((String.valueOf(value)).trim().length() == 0) { + return "Value must not be empty string"; + } + return null; + } + + @Override + public String getName() { + return "X"; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeY.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeY.java new file mode 100644 index 0000000000000000000000000000000000000000..a48a0e28ef74a9324e999255f6c93cf1f8a85385 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/attribute/BAttributeY.java @@ -0,0 +1,42 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.attribute; + +import org.eclipse.ui.views.properties.PropertyDescriptor; + +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.property.IntegerPropertyDescriptor; + +public class BAttributeY extends AbstractAttribute { + + public BAttributeY(Object value) { + super(value); + } + + public PropertyDescriptor preparePropertyDescriptor() { + IntegerPropertyDescriptor descriptor = new IntegerPropertyDescriptor( + getID(), getName()); + return descriptor; + } + + @Override + public String validateValue(Object value, BControl control) { + if (!(String.valueOf(value)).trim().matches("\\d*")) { + return "Value must be a number"; + } + if ((String.valueOf(value)).trim().length() == 0) { + return "Value must not be empty string"; + } + return null; + } + + @Override + public String getName() { + return "Y"; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/AbstractBringToCommand.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/AbstractBringToCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..d5d52472ba652177fb241cd61ce2abada17d1ca9 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/AbstractBringToCommand.java @@ -0,0 +1,53 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.command; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.gef.commands.Command; + +import de.bmotionstudio.gef.editor.model.BControl; + +public abstract class AbstractBringToCommand extends Command { + + private List<BControl> controlList = new ArrayList<BControl>(); + private Map<BControl, Integer> oldIndexMap = new HashMap<BControl, Integer>(); + + public void setControlList(List<BControl> controlList) { + this.controlList = controlList; + } + + public List<BControl> getControlList() { + return controlList; + } + + @Override + public boolean canExecute() { + if (controlList.isEmpty()) + return false; + return true; + } + + @Override + public boolean canUndo() { + if (controlList.isEmpty() || oldIndexMap.isEmpty()) + return false; + return true; + } + + public Map<BControl, Integer> getOldIndexMap() { + return oldIndexMap; + } + + public void setOldIndexMap(HashMap<BControl, Integer> oldIndexMap) { + this.oldIndexMap = oldIndexMap; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/AbstractLayoutCommand.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/AbstractLayoutCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..231e1866e27fa4ebb0e85cde44ebf48ab03ad703 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/AbstractLayoutCommand.java @@ -0,0 +1,18 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.command; + +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.gef.commands.Command; + +public abstract class AbstractLayoutCommand extends Command { + + public abstract void setConstraint(Rectangle rect); + + public abstract void setModel(Object model); + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/BControlChangeLayoutCommand.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/BControlChangeLayoutCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..0362ff942c735c321c4302bd39ce36c6ecf03621 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/BControlChangeLayoutCommand.java @@ -0,0 +1,37 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.command; + +import org.eclipse.draw2d.geometry.Rectangle; + +import de.bmotionstudio.gef.editor.model.BControl; + +public class BControlChangeLayoutCommand extends AbstractLayoutCommand { + + private BControl control; + private Rectangle newLayout; + private Rectangle oldLayout; + + public void execute() { + control.setLayout(newLayout); + } + + public void setConstraint(Rectangle rect) { + newLayout = rect; + } + + public void setModel(Object model) { + control = (BControl) model; + oldLayout = control.getLayout(); + } + + @Override + public void undo() { + control.setLayout(oldLayout); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/BringToBottomCommand.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/BringToBottomCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..124b9b8f3aae619fc782a0835d6c2eec20da22b5 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/BringToBottomCommand.java @@ -0,0 +1,36 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.command; + +import de.bmotionstudio.gef.editor.model.BControl; + +public class BringToBottomCommand extends AbstractBringToCommand { + + public void execute() { + for (BControl control : getControlList()) { + BControl parent = control.getParent(); + Integer oldIndex = parent.getChildrenArray().indexOf(control); + getOldIndexMap().put(control, oldIndex); + parent.getChildrenArray().remove(control); + parent.getChildrenArray().add(0, control); + parent.getListeners().firePropertyChange(BControl.PROPERTY_ADD, + null, null); + } + } + + public void undo() { + for (BControl control : getControlList()) { + BControl parent = control.getParent(); + parent.getChildrenArray().remove(control); + parent.getChildrenArray().add(getOldIndexMap().get(control), + control); + parent.getListeners().firePropertyChange(BControl.PROPERTY_ADD, + null, null); + } + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/BringToBottomStepCommand.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/BringToBottomStepCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..45368b844f6c1880871fc8667b7c29016601753b --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/BringToBottomStepCommand.java @@ -0,0 +1,38 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.command; + +import de.bmotionstudio.gef.editor.model.BControl; + +public class BringToBottomStepCommand extends AbstractBringToCommand { + + public void execute() { + for (BControl control : getControlList()) { + BControl parent = control.getParent(); + Integer oldIndex = parent.getChildrenArray().indexOf(control); + getOldIndexMap().put(control, oldIndex); + if (oldIndex > 0) { + parent.getChildrenArray().remove(control); + parent.getChildrenArray().add(oldIndex - 1, control); + parent.getListeners().firePropertyChange(BControl.PROPERTY_ADD, + null, null); + } + } + } + + public void undo() { + for (BControl control : getControlList()) { + BControl parent = control.getParent(); + parent.getChildrenArray().remove(control); + parent.getChildrenArray().add(getOldIndexMap().get(control), + control); + parent.getListeners().firePropertyChange(BControl.PROPERTY_ADD, + null, null); + } + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/BringToTopCommand.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/BringToTopCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..38c7631409f6d1db88c653fcde2bdf0ec93995f0 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/BringToTopCommand.java @@ -0,0 +1,37 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.command; + +import de.bmotionstudio.gef.editor.model.BControl; + +public class BringToTopCommand extends AbstractBringToCommand { + + public void execute() { + for (BControl control : getControlList()) { + BControl parent = control.getParent(); + Integer oldIndex = parent.getChildrenArray().indexOf(control); + getOldIndexMap().put(control, oldIndex); + parent.getChildrenArray().remove(control); + parent.getChildrenArray().add(parent.getChildrenArray().size(), + control); + parent.getListeners().firePropertyChange(BControl.PROPERTY_ADD, + null, null); + } + } + + public void undo() { + for (BControl control : getControlList()) { + BControl parent = control.getParent(); + parent.getChildrenArray().remove(control); + parent.getChildrenArray().add(getOldIndexMap().get(control), + control); + parent.getListeners().firePropertyChange(BControl.PROPERTY_ADD, + null, null); + } + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/BringToTopStepCommand.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/BringToTopStepCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..5e82ce35d56b96bb6a1fa30ea1741c9bcb93979e --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/BringToTopStepCommand.java @@ -0,0 +1,38 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.command; + +import de.bmotionstudio.gef.editor.model.BControl; + +public class BringToTopStepCommand extends AbstractBringToCommand { + + public void execute() { + for (BControl control : getControlList()) { + BControl parent = control.getParent(); + Integer oldIndex = parent.getChildrenArray().indexOf(control); + getOldIndexMap().put(control, oldIndex); + if (oldIndex < parent.getChildrenArray().size() - 1) { + parent.getChildrenArray().remove(control); + parent.getChildrenArray().add(oldIndex + 1, control); + parent.getListeners().firePropertyChange(BControl.PROPERTY_ADD, + null, null); + } + } + } + + public void undo() { + for (BControl control : getControlList()) { + BControl parent = control.getParent(); + parent.getChildrenArray().remove(control); + parent.getChildrenArray().add(getOldIndexMap().get(control), + control); + parent.getListeners().firePropertyChange(BControl.PROPERTY_ADD, + null, null); + } + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/ChangeGuideCommand.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/ChangeGuideCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..fc87321d42881e9a6f9467d1396c7010a456960a --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/ChangeGuideCommand.java @@ -0,0 +1,66 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.command; + +import org.eclipse.gef.commands.Command; + +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.model.BMotionGuide; + +public class ChangeGuideCommand extends Command { + + private BControl part; + private BMotionGuide oldGuide, newGuide; + private int oldAlign, newAlign; + private boolean horizontal; + + public ChangeGuideCommand(BControl part, boolean horizontalGuide) { + super(); + this.part = part; + horizontal = horizontalGuide; + } + + protected void changeGuide(BMotionGuide oldGuide, BMotionGuide newGuide, + int newAlignment) { + + if (oldGuide != null && oldGuide != newGuide) { + oldGuide.detachPart(part); + } + // You need to re-attach the part even if the oldGuide and the + // newGuide + // are the same + // because the alignment could have changed + if (newGuide != null) { + newGuide.attachPart(part, newAlignment); + } + + } + + public void execute() { + // Cache the old values + oldGuide = horizontal ? part.getHorizontalGuide() : part + .getVerticalGuide(); + if (oldGuide != null) + oldAlign = oldGuide.getAlignment(part); + + redo(); + } + + public void redo() { + changeGuide(oldGuide, newGuide, newAlign); + } + + public void setNewGuide(BMotionGuide guide, int alignment) { + newGuide = guide; + newAlign = alignment; + } + + public void undo() { + changeGuide(newGuide, oldGuide, oldAlign); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/ConnectionCreateCommand.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/ConnectionCreateCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..f9893ed87ffd0cfe0466f7bb8b99d16b94279f89 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/ConnectionCreateCommand.java @@ -0,0 +1,152 @@ +/******************************************************************************* + * Copyright (c) 2004, 2005 Elias Volanakis and others. +�* All rights reserved. This program and the accompanying materials +�* are made available under the terms of the Eclipse Public License v1.0 +�* which accompanies this distribution, and is available at +�* http://www.eclipse.org/legal/epl-v10.html +�* +�* Contributors: +�*����Elias Volanakis - initial API and implementation +�*******************************************************************************/ +package de.bmotionstudio.gef.editor.command; + +import java.util.Iterator; + +import org.eclipse.gef.commands.Command; + +import de.bmotionstudio.gef.editor.model.BConnection; +import de.bmotionstudio.gef.editor.model.BControl; + +/** + * A command to create a connection between two shapes. The command can be + * undone or redone. + * <p> + * This command is designed to be used together with a GraphicalNodeEditPolicy. + * To use this command properly, following steps are necessary: + * </p> + * <ol> + * <li>Create a subclass of GraphicalNodeEditPolicy.</li> + * <li>Override the <tt>getConnectionCreateCommand(...)</tt> method, to create a + * new instance of this class and put it into the CreateConnectionRequest.</li> + * <li>Override the <tt>getConnectionCompleteCommand(...)</tt> method, to obtain + * the Command from the ConnectionRequest, call setTarget(...) to set the target + * endpoint of the connection and return this command instance.</li> + * </ol> + * + * @see org.eclipse.gef.examples.shapes.parts.ShapeEditPart#createEditPolicies() + * for an example of the above procedure. + * @see org.eclipse.gef.editpolicies.GraphicalNodeEditPolicy + * @author Elias Volanakis + */ +public class ConnectionCreateCommand extends Command { + /** The connection instance. */ + private BConnection connection; + + /** Start endpoint for the connection. */ + private final BControl source; + /** Target endpoint for the connection. */ + private BControl target; + + /** + * Instantiate a command that can create a connection between two shapes. + * + * @param source + * the source endpoint (a non-null Shape instance) + * @param lineStyle + * the desired line style. See Connection#setLineStyle(int) for + * details + * @throws IllegalArgumentException + * if source is null + * @see Connection#setLineStyle(int) + */ + public ConnectionCreateCommand(BControl source) { + if (source == null) { + throw new IllegalArgumentException(); + } + setLabel("connection creation"); + this.source = source; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.gef.commands.Command#canExecute() + */ + public boolean canExecute() { + // disallow source -> source connections + if (source.equals(target)) { + return false; + } + // return false, if the source -> target connection exists already + for (Iterator<BConnection> iter = source.getSourceConnections() + .iterator(); iter.hasNext();) { + BConnection conn = (BConnection) iter.next(); + if (conn.getTarget().equals(target)) { + return false; + } + } + return true; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.gef.commands.Command#execute() + */ + public void execute() { + // create a new connection between source and target + connection.setSource(source); + connection.setTarget(target); + connection.reconnect(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.gef.commands.Command#redo() + */ + public void redo() { + connection.reconnect(); + } + + /** + * Set the target endpoint for the connection. + * + * @param target + * that target endpoint (a non-null Shape instance) + * @throws IllegalArgumentException + * if target is null + */ + public void setTarget(BControl target) { + if (target == null) { + throw new IllegalArgumentException(); + } + this.target = target; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.gef.commands.Command#undo() + */ + public void undo() { + connection.disconnect(); + } + + public void setConnection(BConnection con) { + this.connection = con; + } + + public BConnection getConnection() { + return this.connection; + } + + public BControl getSource() { + return this.source; + } + + public BControl getTarget() { + return this.target; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/ConnectionDeleteCommand.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/ConnectionDeleteCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..09edf327f0d0a3371deeac2e0a94dc541a7e3661 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/ConnectionDeleteCommand.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2004, 2005 Elias Volanakis and others. +�* All rights reserved. This program and the accompanying materials +�* are made available under the terms of the Eclipse Public License v1.0 +�* which accompanies this distribution, and is available at +�* http://www.eclipse.org/legal/epl-v10.html +�* +�* Contributors: +�*����Elias Volanakis - initial API and implementation +�*******************************************************************************/ +package de.bmotionstudio.gef.editor.command; + +import org.eclipse.gef.commands.Command; + +import de.bmotionstudio.gef.editor.model.BConnection; + +/** + * A command to disconnect (remove) a connection from its endpoints. The command + * can be undone or redone. + * + * @author Elias Volanakis + */ +public class ConnectionDeleteCommand extends Command { + + /** Connection instance to disconnect. */ + private final BConnection connection; + + /** + * Create a command that will disconnect a connection from its endpoints. + * + * @param conn + * the connection instance to disconnect (non-null) + * @throws IllegalArgumentException + * if conn is null + */ + public ConnectionDeleteCommand(BConnection conn) { + if (conn == null) { + throw new IllegalArgumentException(); + } + setLabel("connection deletion"); + this.connection = conn; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.gef.commands.Command#execute() + */ + public void execute() { + connection.disconnect(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.gef.commands.Command#undo() + */ + public void undo() { + connection.reconnect(); + } +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/ConnectionReconnectCommand.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/ConnectionReconnectCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..93de1bffc1bf3c7ebb9871a3f5ab8c5bb069e7d5 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/ConnectionReconnectCommand.java @@ -0,0 +1,208 @@ +/******************************************************************************* + * Copyright (c) 2004, 2005 Elias Volanakis and others. +�* All rights reserved. This program and the accompanying materials +�* are made available under the terms of the Eclipse Public License v1.0 +�* which accompanies this distribution, and is available at +�* http://www.eclipse.org/legal/epl-v10.html +�* +�* Contributors: +�*����Elias Volanakis - initial API and implementation +�*******************************************************************************/ +package de.bmotionstudio.gef.editor.command; + +import java.util.Iterator; + +import org.eclipse.gef.commands.Command; + +import de.bmotionstudio.gef.editor.model.BConnection; +import de.bmotionstudio.gef.editor.model.BControl; + +/** + * A command to reconnect a connection to a different start point or end point. + * The command can be undone or redone. + * <p> + * This command is designed to be used together with a GraphicalNodeEditPolicy. + * To use this command propertly, following steps are necessary: + * </p> + * <ol> + * <li>Create a subclass of GraphicalNodeEditPolicy.</li> + * <li>Override the <tt>getReconnectSourceCommand(...)</tt> method. Here you + * need to obtain the Connection model element from the ReconnectRequest, create + * a new ConnectionReconnectCommand, set the new connection <i>source</i> by + * calling the <tt>setNewSource(Shape)</tt> method and return the command + * instance. + * <li>Override the <tt>getReconnectTargetCommand(...)</tt> method.</li> + * Here again you need to obtain the Connection model element from the + * ReconnectRequest, create a new ConnectionReconnectCommand, set the new + * connection <i>target</i> by calling the <tt>setNewTarget(Shape)</tt> method + * and return the command instance.</li> + * </ol> + * + * @see org.eclipse.gef.examples.shapes.parts.ShapeEditPart#createEditPolicies() + * for an example of the above procedure. + * @see org.eclipse.gef.editpolicies.GraphicalNodeEditPolicy + * @see #setNewSource(Shape) + * @see #setNewTarget(Shape) + * @author Elias Volanakis + */ +public class ConnectionReconnectCommand extends Command { + + /** The connection instance to reconnect. */ + private BConnection connection; + /** The new source endpoint. */ + private BControl newSource; + /** The new target endpoint. */ + private BControl newTarget; + /** The original source endpoint. */ + private BControl oldSource; + /** The original target endpoint. */ + private BControl oldTarget; + + /* + * (non-Javadoc) + * + * @see org.eclipse.gef.commands.Command#canExecute() + */ + public boolean canExecute() { + if (newSource != null) { + return checkSourceReconnection(); + } else if (newTarget != null) { + return checkTargetReconnection(); + } + return false; + } + + /** + * Return true, if reconnecting the connection-instance to newSource is + * allowed. + */ + private boolean checkSourceReconnection() { + // connection endpoints must be different Shapes + if (newSource.equals(oldTarget)) { + return false; + } + // return false, if the connection exists already + for (Iterator<BConnection> iter = newSource.getSourceConnections() + .iterator(); iter.hasNext();) { + BConnection conn = (BConnection) iter.next(); + // return false if a newSource -> oldTarget connection exists + // already + // and it is a different instance than the connection-field + if (conn.getTarget().equals(oldTarget) && !conn.equals(connection)) { + return false; + } + } + return true; + } + + /** + * Return true, if reconnecting the connection-instance to newTarget is + * allowed. + */ + private boolean checkTargetReconnection() { + // connection endpoints must be different Shapes + if (newTarget.equals(oldSource)) { + return false; + } + // return false, if the connection exists already + for (Iterator<BConnection> iter = newTarget.getTargetConnections() + .iterator(); iter.hasNext();) { + BConnection conn = (BConnection) iter.next(); + // return false if a oldSource -> newTarget connection exists + // already + // and it is a differenct instance that the connection-field + if (conn.getSource().equals(oldSource) && !conn.equals(connection)) { + return false; + } + } + return true; + } + + /** + * Reconnect the connection to newSource (if setNewSource(...) was invoked + * before) or newTarget (if setNewTarget(...) was invoked before). + */ + public void execute() { + if (newSource != null) { + connection.reconnect(newSource, oldTarget); + } else if (newTarget != null) { + connection.reconnect(oldSource, newTarget); + } else { + throw new IllegalStateException("Should not happen"); + } + } + + /** + * Set a new source endpoint for this connection. When execute() is invoked, + * the source endpoint of the connection will be attached to the supplied + * Shape instance. + * <p> + * Note: Calling this method, deactivates reconnection of the <i>target</i> + * endpoint. A single instance of this command can only reconnect either the + * source or the target endpoint. + * </p> + * + * @param connectionSource + * a non-null Shape instance, to be used as a new source endpoint + * @throws IllegalArgumentException + * if connectionSource is null + */ + public void setNewSource(BControl connectionSource) { + if (connectionSource == null) { + throw new IllegalArgumentException(); + } + setLabel("move connection startpoint"); + newSource = connectionSource; + newTarget = null; + } + + public BControl getNewSource() { + return this.newSource; + } + + /** + * Set a new target endpoint for this connection When execute() is invoked, + * the target endpoint of the connection will be attached to the supplied + * Shape instance. + * <p> + * Note: Calling this method, deactivates reconnection of the <i>source</i> + * endpoint. A single instance of this command can only reconnect either the + * source or the target endpoint. + * </p> + * + * @param connectionTarget + * a non-null Shape instance, to be used as a new target endpoint + * @throws IllegalArgumentException + * if connectionTarget is null + */ + public void setNewTarget(BControl connectionTarget) { + if (connectionTarget == null) { + throw new IllegalArgumentException(); + } + setLabel("move connection endpoint"); + newSource = null; + newTarget = connectionTarget; + } + + public BControl getNewTarget() { + return this.newTarget; + } + + /** + * Reconnect the connection to its original source and target endpoints. + */ + public void undo() { + connection.reconnect(oldSource, oldTarget); + } + + public void setConnection(BConnection conn) { + this.connection = conn; + this.oldSource = conn.getSource(); + this.oldTarget = conn.getTarget(); + } + + public BConnection getConnection() { + return this.connection; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/CopyCommand.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/CopyCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..a61c0006d13c1ca8eab443da6a991f83019ab537 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/CopyCommand.java @@ -0,0 +1,59 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.command; + +import java.util.ArrayList; +import java.util.Iterator; + +import org.eclipse.gef.commands.Command; +import org.eclipse.gef.ui.actions.Clipboard; + +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.model.Visualization; + +public class CopyCommand extends Command { + + private ArrayList<BControl> list = new ArrayList<BControl>(); + + public boolean addElement(BControl control) { + if (!list.contains(control)) { + return list.add(control); + } + return false; + } + + @Override + public boolean canExecute() { + if (list == null || list.isEmpty()) + return false; + Iterator<BControl> it = list.iterator(); + while (it.hasNext()) { + if (!isCopyableControl(it.next())) + return false; + } + return true; + } + + @Override + public void execute() { + if (canExecute()) { + Clipboard.getDefault().setContents(new CopyPasteHelper(list, 10)); + } + } + + @Override + public boolean canUndo() { + return false; + } + + public boolean isCopyableControl(BControl control) { + if (!(control instanceof Visualization)) + return true; + return false; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/CopyPasteHelper.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/CopyPasteHelper.java new file mode 100644 index 0000000000000000000000000000000000000000..5d23251fd161bf8658b9517cebb05da2113aa460 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/CopyPasteHelper.java @@ -0,0 +1,39 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.command; + +import java.util.ArrayList; + +import de.bmotionstudio.gef.editor.model.BControl; + +public class CopyPasteHelper { + + private ArrayList<BControl> list = new ArrayList<BControl>(); + private int distance = 10; + + public CopyPasteHelper(ArrayList<BControl> list, int distance) { + this.list = list; + this.setDistance(distance); + } + + public void setList(ArrayList<BControl> list) { + this.list = list; + } + + public ArrayList<BControl> getList() { + return list; + } + + public void setDistance(int distance) { + this.distance = distance; + } + + public int getDistance() { + return distance; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/CreateCommand.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/CreateCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..e895d1f98ce6b77b92c103372c27b08cfdd641e9 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/CreateCommand.java @@ -0,0 +1,60 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.command; + +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.gef.commands.Command; + +import de.bmotionstudio.gef.editor.model.BControl; + +public class CreateCommand extends Command { + + private BControl parent; + private BControl child; + private int index = -1; + + public CreateCommand(BControl child, BControl parent) { + super(); + this.parent = parent; + this.child = child; + } + + public void setLayout(Rectangle r) { + if (child == null) + return; + child.setLayout(r); + } + + @Override + public boolean canExecute() { + if (parent == null || child == null) + return false; + return true; + } + + @Override + public void execute() { + parent.addChild(child, index); + } + + @Override + public boolean canUndo() { + if (parent == null || child == null) + return false; + return parent.contains(child); + } + + @Override + public void undo() { + parent.removeChild(child); + } + + public void setIndex(int index) { + this.index = index; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/CreateGuideCommand.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/CreateGuideCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..f3d2f445b9b42811a8533b2ad1041491101eb85a --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/CreateGuideCommand.java @@ -0,0 +1,41 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.command; + +import org.eclipse.gef.commands.Command; + +import de.bmotionstudio.gef.editor.model.BMotionGuide; +import de.bmotionstudio.gef.editor.model.BMotionRuler; + +public class CreateGuideCommand extends Command { + + private BMotionGuide guide; + private BMotionRuler parent; + private int position; + + public CreateGuideCommand(BMotionRuler parent, int position) { + super("Create Guide"); + this.parent = parent; + this.position = position; + } + + public boolean canUndo() { + return true; + } + + public void execute() { + if (guide == null) + guide = new BMotionGuide(!parent.isHorizontal()); + guide.setPosition(position); + parent.addGuide(guide); + } + + public void undo() { + parent.removeGuide(guide); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/DeleteCommand.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/DeleteCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..a4db8f4ea11f5f0032076c8abb7f1aabd29bd547 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/DeleteCommand.java @@ -0,0 +1,47 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.command; + +import org.eclipse.gef.commands.Command; + +import de.bmotionstudio.gef.editor.model.BControl; + +public class DeleteCommand extends Command { + + private BControl control; + private BControl parent; + + public DeleteCommand(BControl control, BControl parent) { + this.control = control; + this.parent = parent; + } + + @Override + public boolean canExecute() { + if (parent == null || control == null || !parent.contains(control)) + return false; + return true; + } + + @Override + public boolean canUndo() { + if (parent == null || control == null) + return false; + return !parent.contains(control); + } + + @Override + public void execute() { + this.parent.removeChild(control); + } + + @Override + public void undo() { + this.parent.addChild(control); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/DeleteGuideCommand.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/DeleteGuideCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..9870617b91747248c17940b59d0be6a4b281c7e1 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/DeleteGuideCommand.java @@ -0,0 +1,52 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.command; + +import java.util.HashMap; +import java.util.Iterator; + +import org.eclipse.gef.commands.Command; + +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.model.BMotionGuide; +import de.bmotionstudio.gef.editor.model.BMotionRuler; + +public class DeleteGuideCommand extends Command { + + private BMotionRuler parent; + private BMotionGuide guide; + private HashMap<BControl, Integer> oldParts; + + public DeleteGuideCommand(BMotionGuide guide, BMotionRuler parent) { + super("Delete Guide"); + this.guide = guide; + this.parent = parent; + } + + public boolean canUndo() { + return true; + } + + public void execute() { + oldParts = new HashMap<BControl, Integer>(guide.getMap()); + Iterator<BControl> iter = oldParts.keySet().iterator(); + while (iter.hasNext()) { + guide.detachPart((BControl) iter.next()); + } + parent.removeGuide(guide); + } + + public void undo() { + parent.addGuide(guide); + Iterator<BControl> iter = oldParts.keySet().iterator(); + while (iter.hasNext()) { + BControl part = (BControl) iter.next(); + guide.attachPart(part, ((Integer) oldParts.get(part)).intValue()); + } + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/FitImageCommand.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/FitImageCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..7f2b875d316e7426f97e2c3dc7cbdda17e3adb62 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/FitImageCommand.java @@ -0,0 +1,71 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.command; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.gef.commands.Command; + +import de.bmotionstudio.gef.editor.AttributeConstants; +import de.bmotionstudio.gef.editor.model.BControl; + +public class FitImageCommand extends Command { + + private List<BControl> modelList = new ArrayList<BControl>(); + private Map<BControl, Rectangle> oldSizeMap = new HashMap<BControl, Rectangle>(); + private Map<BControl, Rectangle> newSizeMap = new HashMap<BControl, Rectangle>(); + + @Override + public boolean canExecute() { + return check(); + } + + @Override + public void execute() { + for (BControl control : modelList) { + oldSizeMap.put(control, control.getLayout()); + control.setLayout(newSizeMap.get(control)); + } + } + + @Override + public boolean canUndo() { + if (oldSizeMap.isEmpty()) + return false; + return check(); + } + + @Override + public void undo() { + for (BControl control : this.modelList) { + control.setLayout(oldSizeMap.get(control)); + } + } + + public void setModelList(List<BControl> modelList) { + this.modelList = modelList; + } + + public void setNewSizeMap(Map<BControl, Rectangle> newSizeMap) { + this.newSizeMap = newSizeMap; + } + + private boolean check() { + if (modelList.isEmpty() || newSizeMap.isEmpty()) + return false; + for (BControl control : modelList) { + if (!control.hasAttribute(AttributeConstants.ATTRIBUTE_IMAGE)) + return false; + } + return true; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/MoveGuideCommand.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/MoveGuideCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..bcc1e2fe70e1359dc24414ef3cb7f88e115f38fa --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/MoveGuideCommand.java @@ -0,0 +1,61 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.command; + +import java.util.Iterator; + +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.gef.commands.Command; + +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.model.BMotionGuide; + +public class MoveGuideCommand extends Command { + + private int pDelta; + private BMotionGuide guide; + + public MoveGuideCommand(BMotionGuide guide, int positionDelta) { + super("Move Guide"); + this.guide = guide; + pDelta = positionDelta; + } + + public void execute() { + + guide.setPosition(guide.getPosition() + pDelta); + + Iterator<BControl> iter = guide.getParts().iterator(); + while (iter.hasNext()) { + BControl part = (BControl) iter.next(); + Point location = part.getLocation().getCopy(); + if (guide.isHorizontal()) { + location.y += pDelta; + } else { + location.x += pDelta; + } + part.setLocation(location); + } + + } + + public void undo() { + guide.setPosition(guide.getPosition() - pDelta); + Iterator<BControl> iter = guide.getParts().iterator(); + while (iter.hasNext()) { + BControl part = (BControl) iter.next(); + Point location = part.getLocation().getCopy(); + if (guide.isHorizontal()) { + location.y -= pDelta; + } else { + location.x -= pDelta; + } + part.setLocation(location); + } + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/ObserverCommand.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/ObserverCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..b27dd0d833d937e1c2d39fbd37043cd6c41c5a91 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/ObserverCommand.java @@ -0,0 +1,85 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.command; + +import org.eclipse.gef.commands.Command; + +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.observer.Observer; + +public class ObserverCommand extends Command { + + private String className; + private Observer clonedObserver; + private Observer newObserver; + private Observer clonedNewObserver; + private BControl control; + + public void execute() { + + try { + clonedNewObserver = newObserver.clone(); + } catch (CloneNotSupportedException e) { + e.printStackTrace(); + } + + control.addObserver(newObserver); + + } + + public boolean canExecute() { + return true; + } + + public void undo() { + + // Remove completely new Observer + if (clonedObserver == null) { + control.removeObserver(getClassName()); + } else { // Reset Observer + control.addObserver(clonedObserver); + } + + } + + public void redo() { + control.addObserver(clonedNewObserver); + } + + public void setClassName(String className) { + this.className = className; + } + + public String getClassName() { + return className; + } + + public void setControl(BControl control) { + this.control = control; + } + + public BControl getControl() { + return this.control; + } + + public Observer getClonedObserver() { + return clonedObserver; + } + + public void setClonedObserver(Observer clonedObserver) { + this.clonedObserver = clonedObserver; + } + + public Observer getNewObserver() { + return newObserver; + } + + public void setNewObserver(Observer newObserver) { + this.newObserver = newObserver; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/PasteCommand.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/PasteCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..6e3b670111ebf3432feb6661ddde0f22e7f9feb2 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/PasteCommand.java @@ -0,0 +1,109 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.command; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; + +import org.eclipse.gef.commands.Command; +import org.eclipse.gef.ui.actions.Clipboard; + +import de.bmotionstudio.gef.editor.AttributeConstants; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.model.Visualization; + +public class PasteCommand extends Command { + + private CopyPasteHelper cHelper; + + private HashMap<BControl, BControl> list = new HashMap<BControl, BControl>(); + + @Override + public boolean canExecute() { + cHelper = (CopyPasteHelper) Clipboard.getDefault().getContents(); + if (cHelper == null) + return false; + ArrayList<BControl> myList = cHelper.getList(); + if (myList.isEmpty()) + return false; + Iterator<?> it = myList.iterator(); + while (it.hasNext()) { + BControl node = (BControl) it.next(); + if (isPastableNode(node)) { + list.put(node, null); + } + } + return true; + } + + @Override + public void execute() { + if (!canExecute()) + return; + Iterator<BControl> it = list.keySet().iterator(); + while (it.hasNext()) { + BControl control = (BControl) it.next(); + try { + BControl clone = (BControl) control.clone(); + int x = Integer.valueOf(Integer.valueOf(clone + .getAttributeValue(AttributeConstants.ATTRIBUTE_X) + .toString())); + int y = Integer.valueOf(Integer.valueOf(clone + .getAttributeValue(AttributeConstants.ATTRIBUTE_Y) + .toString())); + clone.setAttributeValue(AttributeConstants.ATTRIBUTE_X, x + + cHelper.getDistance()); + clone.setAttributeValue(AttributeConstants.ATTRIBUTE_Y, y + + cHelper.getDistance()); + list.put(control, clone); + cHelper.setDistance(cHelper.getDistance() + 10); + } catch (CloneNotSupportedException e) { + e.printStackTrace(); + } + } + redo(); + } + + @Override + public void redo() { + Iterator<BControl> it = list.values().iterator(); + while (it.hasNext()) { + BControl control = it.next(); + if (isPastableNode(control)) { + control.getParent().addChild(control); + } + } + } + + @Override + public boolean canUndo() { + return !(list.isEmpty()); + } + + @Override + public void undo() { + Iterator<BControl> it = list.values().iterator(); + while (it.hasNext()) { + BControl bcontrol = it.next(); + if (isPastableNode(bcontrol)) { + bcontrol.getParent().removeChild(bcontrol); + } + } + } + + public boolean isPastableNode(BControl control) { + if (control instanceof Visualization) + return false; + return true; + } + + public HashMap<BControl, BControl> getList() { + return this.list; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/RemoveObserverCommand.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/RemoveObserverCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..e1b703e321e681f65257c67d14a13338a85d583f --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/RemoveObserverCommand.java @@ -0,0 +1,47 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.command; + +import org.eclipse.gef.commands.Command; + +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.observer.Observer; + +public class RemoveObserverCommand extends Command { + + private BControl control; + private Observer observer; + + public void execute() { + control.removeObserver(observer.getID()); + } + + public boolean canExecute() { + return true; + } + + public void undo() { + control.addObserver(observer); + } + + public void setControl(BControl control) { + this.control = control; + } + + public BControl getControl() { + return control; + } + + public void setObserver(Observer observer) { + this.observer = observer; + } + + public Observer getObserver() { + return observer; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/RemoveSchedulerEventCommand.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/RemoveSchedulerEventCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..804d579c122c9bfbd95d0db2ab9585fa64c4f87b --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/RemoveSchedulerEventCommand.java @@ -0,0 +1,47 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.command; + +import org.eclipse.gef.commands.Command; + +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.scheduler.SchedulerEvent; + +public class RemoveSchedulerEventCommand extends Command { + + private BControl control; + private SchedulerEvent schedulerEvent; + + public void execute() { + control.removeEvent(schedulerEvent.getEventID()); + } + + public boolean canExecute() { + return true; + } + + public void undo() { + control.addEvent(schedulerEvent.getEventID(), schedulerEvent); + } + + public void setControl(BControl control) { + this.control = control; + } + + public BControl getControl() { + return control; + } + + public void setSchedulerEvent(SchedulerEvent schedulerEvent) { + this.schedulerEvent = schedulerEvent; + } + + public SchedulerEvent getSchedulerEvent() { + return this.schedulerEvent; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/RenameCommand.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/RenameCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..0f0ffbc055eabc3596b19b2f64f38e9ba6af52f4 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/RenameCommand.java @@ -0,0 +1,61 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.command; + +import org.eclipse.gef.commands.Command; + +import de.bmotionstudio.gef.editor.AttributeConstants; +import de.bmotionstudio.gef.editor.model.BControl; + +public class RenameCommand extends Command { + + private BControl control; + private String oldString; + private String newString; + + public void setControl(BControl control) { + this.control = control; + } + + public void setNewString(String newString) { + this.newString = newString; + } + + @Override + public boolean canExecute() { + return checkControl(); + } + + @Override + public boolean canUndo() { + if (oldString == null) + return false; + return checkControl(); + } + + private boolean checkControl() { + if (control == null || newString == null + || !control.hasAttribute(AttributeConstants.ATTRIBUTE_TEXT)) + return false; + return true; + } + + @Override + public void execute() { + this.oldString = control.getAttributeValue( + AttributeConstants.ATTRIBUTE_TEXT).toString(); + this.control.setAttributeValue(AttributeConstants.ATTRIBUTE_TEXT, + newString); + } + + @Override + public void undo() { + this.control.setAttributeValue(AttributeConstants.ATTRIBUTE_TEXT, + oldString); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/SchedulerEventCommand.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/SchedulerEventCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..8f4465cb39d2e8c7a9cf9358bb6a1873a3fe0b20 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/command/SchedulerEventCommand.java @@ -0,0 +1,95 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.command; + +import org.eclipse.gef.commands.Command; + +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.scheduler.SchedulerEvent; + +public class SchedulerEventCommand extends Command { + + private String className; + private String eventID; + private SchedulerEvent clonedSchedulerEvent; + private SchedulerEvent newSchedulerEvent; + private SchedulerEvent clonedNewSchedulerEvent; + private BControl control; + + public void execute() { + + try { + clonedNewSchedulerEvent = newSchedulerEvent.clone(); + } catch (CloneNotSupportedException e) { + } + + if (clonedSchedulerEvent == null) { + control.addEvent(eventID, newSchedulerEvent); + } + + } + + public boolean canExecute() { + return true; + } + + public void undo() { + + // Remove completely new Observer + if (clonedSchedulerEvent == null) { + control.removeEvent(eventID); + } else { // Reset Observer + control.addEvent(eventID, clonedSchedulerEvent); + } + + } + + public void redo() { + control.addEvent(eventID, clonedNewSchedulerEvent); + } + + public void setClassName(String className) { + this.className = className; + } + + public String getClassName() { + return className; + } + + public void setControl(BControl control) { + this.control = control; + } + + public BControl getControl() { + return this.control; + } + + public String getEventID() { + return eventID; + } + + public void setEventID(String eventID) { + this.eventID = eventID; + } + + public SchedulerEvent getClonedSchedulerEvent() { + return clonedSchedulerEvent; + } + + public void setClonedSchedulerEvent(SchedulerEvent clonedSchedulerEvent) { + this.clonedSchedulerEvent = clonedSchedulerEvent; + } + + public SchedulerEvent getNewSchedulerEvent() { + return newSchedulerEvent; + } + + public void setNewSchedulerEvent(SchedulerEvent newSchedulerEvent) { + this.newSchedulerEvent = newSchedulerEvent; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/AttributeExpressionEdittingSupport.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/AttributeExpressionEdittingSupport.java new file mode 100644 index 0000000000000000000000000000000000000000..ebc3a32805b076afca2705f6509e8420019dadfd --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/AttributeExpressionEdittingSupport.java @@ -0,0 +1,108 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.edit; + +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ColumnViewer; +import org.eclipse.jface.viewers.EditingSupport; +import org.eclipse.jface.viewers.TextCellEditor; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.views.properties.PropertyDescriptor; + +import de.bmotionstudio.gef.editor.attribute.AbstractAttribute; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.observer.ObserverEvalObject; + +public class AttributeExpressionEdittingSupport extends EditingSupport { + + private CellEditor cellEditor; + + private BControl control; + + private String stdAttribute; + + public AttributeExpressionEdittingSupport(ColumnViewer viewer, + BControl control) { + this(viewer, control, null); + } + + public AttributeExpressionEdittingSupport(ColumnViewer viewer, + BControl control, String stdAttribute) { + super(viewer); + this.control = control; + this.stdAttribute = stdAttribute; + } + + @Override + protected boolean canEdit(Object element) { + return true; + } + + @Override + protected Object getValue(Object element) { + ObserverEvalObject evalObject = (ObserverEvalObject) element; + return evalObject.getValue(); + } + + @Override + protected void setValue(Object element, Object value) { + if (value == null) + return; + ((ObserverEvalObject) element).setValue(value); + } + + @Override + protected CellEditor getCellEditor(Object element) { + + ObserverEvalObject obj = ((ObserverEvalObject) element); + + if (obj.isExpressionMode()) { + if (cellEditor == null) { + cellEditor = new TextCellEditor((Composite) getViewer() + .getControl()); + } + return cellEditor; + } else { + + String atrID = stdAttribute; + + if (atrID == null) + atrID = obj.getAttribute(); + + if (atrID != null) { + if (atrID.length() > 0) { + AbstractAttribute atr = getControl().getAttributes().get( + atrID); + PropertyDescriptor desc = atr.getPropertyDescriptor(); + return desc.createPropertyEditor((Composite) getViewer() + .getControl()); + } + } + + } + + return null; + + } + + public void setControl(BControl control) { + this.control = control; + } + + public BControl getControl() { + return control; + } + + public void setStdAttribute(String stdAttribute) { + this.stdAttribute = stdAttribute; + } + + public String getStdAttribute() { + return stdAttribute; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/IPopupListener.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/IPopupListener.java new file mode 100644 index 0000000000000000000000000000000000000000..b52aeba1b30c996e86ff3714963a81b661bbd015 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/IPopupListener.java @@ -0,0 +1,15 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.edit; + +public interface IPopupListener { + + public void popupOpened(); + + public void popupClosed(); + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/IntEditingSupport.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/IntEditingSupport.java new file mode 100644 index 0000000000000000000000000000000000000000..6444776b7a9ce6fc20ad45b5b367ea5bf04649e4 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/IntEditingSupport.java @@ -0,0 +1,64 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.edit; + +import org.eclipse.core.databinding.DataBindingContext; +import org.eclipse.core.databinding.beans.BeansObservables; +import org.eclipse.core.databinding.observable.value.IObservableValue; +import org.eclipse.jface.databinding.swt.SWTObservables; +import org.eclipse.jface.databinding.viewers.ObservableValueEditingSupport; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TextCellEditor; +import org.eclipse.jface.viewers.ViewerCell; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; + +public class IntEditingSupport extends ObservableValueEditingSupport { + + private CellEditor cellEditor; + private String atr; + + public IntEditingSupport(TableViewer tv, DataBindingContext dbc, String atr) { + super(tv, dbc); + this.atr = atr; + cellEditor = new TextCellEditor((Composite) tv.getControl()); + cellEditor.getControl().addListener(SWT.Verify, new Listener() { + public void handleEvent(Event e) { + String string = e.text; + char[] chars = new char[string.length()]; + string.getChars(0, chars.length, chars, 0); + for (int i = 0; i < chars.length; i++) { + if (!('0' <= chars[i] && chars[i] <= '9')) { + e.doit = false; + return; + } + } + } + }); + } + + @Override + protected IObservableValue doCreateCellEditorObservable( + CellEditor cellEditor) { + return SWTObservables.observeText(cellEditor.getControl(), SWT.Modify); + } + + @Override + protected IObservableValue doCreateElementObservable(Object element, + ViewerCell cell) { + return BeansObservables.observeValue(element, atr); + } + + @Override + protected CellEditor getCellEditor(Object element) { + return cellEditor; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/IsExpressionModeEditingSupport.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/IsExpressionModeEditingSupport.java new file mode 100644 index 0000000000000000000000000000000000000000..e24284f8a551278d12a408e59e4f5097e9561352 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/IsExpressionModeEditingSupport.java @@ -0,0 +1,75 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.edit; + +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.CheckboxCellEditor; +import org.eclipse.jface.viewers.ColumnViewer; +import org.eclipse.jface.viewers.EditingSupport; +import org.eclipse.swt.widgets.Composite; + +import de.bmotionstudio.gef.editor.attribute.AbstractAttribute; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.observer.ObserverEvalObject; + +public class IsExpressionModeEditingSupport extends EditingSupport { + + private CellEditor cellEditor; + + private BControl control; + + public IsExpressionModeEditingSupport(ColumnViewer viewer, BControl control) { + super(viewer); + this.control = control; + } + + @Override + protected void setValue(Object element, Object value) { + Boolean bol = Boolean.valueOf(String.valueOf(value)); + ObserverEvalObject obj = (ObserverEvalObject) element; + obj.setIsExpressionMode(bol); + if (obj.getAttribute() != null) { + AbstractAttribute atr = getControl().getAttributes().get( + obj.getAttribute()); + if (atr != null) { + if (!bol) { + obj.setValue(atr.getValue()); + } else { + obj.setValue(atr.getValue().toString()); + } + } + } + } + + @Override + protected Object getValue(Object element) { + Boolean b = ((ObserverEvalObject) element).isExpressionMode(); + return b != null ? b : false; + } + + @Override + protected CellEditor getCellEditor(Object element) { + if (cellEditor == null) + cellEditor = new CheckboxCellEditor((Composite) getViewer() + .getControl()); + return cellEditor; + } + + @Override + protected boolean canEdit(Object element) { + return true; + } + + public void setControl(BControl control) { + this.control = control; + } + + public BControl getControl() { + return control; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/OperationValueEditingSupport.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/OperationValueEditingSupport.java new file mode 100644 index 0000000000000000000000000000000000000000..e43a212823e03438925b4383dcd2c57492640f4e --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/OperationValueEditingSupport.java @@ -0,0 +1,74 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.edit; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.databinding.observable.list.ComputedList; +import org.eclipse.jface.databinding.viewers.ObservableListContentProvider; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ComboBoxViewerCellEditor; +import org.eclipse.jface.viewers.EditingSupport; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; + +import de.bmotionstudio.gef.editor.eventb.EventBHelper; +import de.bmotionstudio.gef.editor.eventb.MachineContentObject; +import de.bmotionstudio.gef.editor.eventb.MachineOperation; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.scheduler.PredicateOperation; + +public class OperationValueEditingSupport extends EditingSupport { + + private ComboBoxViewerCellEditor cellEditor = null; + + private BControl control; + + public OperationValueEditingSupport(TableViewer cv, BControl control) { + super(cv); + this.control = control; + } + + @Override + protected boolean canEdit(Object element) { + return true; + } + + @Override + protected Object getValue(Object element) { + return ((PredicateOperation) element).getOperationName(); + } + + @Override + protected void setValue(Object element, Object value) { + if (value != null) + ((PredicateOperation) element).setOperationName(value.toString()); + } + + @Override + protected CellEditor getCellEditor(Object element) { + if (cellEditor == null) { + cellEditor = new ComboBoxViewerCellEditor((Composite) getViewer() + .getControl(), SWT.READ_ONLY); + cellEditor.setContentProvider(new ObservableListContentProvider()); + cellEditor.setInput(new ComputedList() { + @Override + protected List<String> calculate() { + ArrayList<String> tmpList = new ArrayList<String>(); + for (MachineContentObject op : EventBHelper + .getOperations(control.getVisualization())) { + tmpList.add(((MachineOperation) op).getLabel()); + } + return tmpList; + } + }); + } + return cellEditor; + } +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/PopupCellEditor.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/PopupCellEditor.java new file mode 100644 index 0000000000000000000000000000000000000000..ce154fa7e7444987cdbadaa417965323746e67c4 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/PopupCellEditor.java @@ -0,0 +1,78 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ +package de.bmotionstudio.gef.editor.edit; + +import org.eclipse.jface.viewers.TextCellEditor; +import org.eclipse.jface.window.Window; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Shell; + +/** + * @author Lukas Ladenberger + * + */ +public class PopupCellEditor extends TextCellEditor { + + private Shell parentShell; + private TextEditorWindow dialog; + // private int test = 0; + private boolean isOpen = false; + private int counter = 0; + + public PopupCellEditor(Composite parent, Shell parentShell) { + super(parent); + this.parentShell = parentShell; + text.addFocusListener(new FocusListener() { + @Override + public void focusLost(FocusEvent evt) { + } + + @Override + public void focusGained(FocusEvent evt) { + if (!isOpen && counter == 0) { + counter = counter + 1; + openDialogBox(); + } else if (counter == 1) { + counter = 0; + } + } + }); + } + + protected void openDialogBox() { + dialog = new TextEditorWindow(this.parentShell, text); + dialog.addPopupListener(new IPopupListener() { + @Override + public void popupOpened() { + isOpen = true; + } + + @Override + public void popupClosed() { + isOpen = false; + } + }); + PopupResult result = dialog.openPopup(); + if (result.getReturncode() == Window.OK) { + setValue(result.getValue()); + } else if (result.getReturncode() == Window.CANCEL) { + } + } + + @Override + protected void focusLost() { + if (!isOpen) + super.focusLost(); + } + + @Override + protected boolean dependsOnExternalFocusListener() { + return false; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/PopupResult.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/PopupResult.java new file mode 100644 index 0000000000000000000000000000000000000000..14d87a770d015f00473261e0222a5f5266e7a92e --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/PopupResult.java @@ -0,0 +1,33 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ +package de.bmotionstudio.gef.editor.edit; + +/** + * @author Lukas Ladenberger + * + */ +public class PopupResult { + + private String value; + private int returncode; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public void setReturncode(int returncode) { + this.returncode = returncode; + } + + public int getReturncode() { + return returncode; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/PredicateEditingSupport.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/PredicateEditingSupport.java new file mode 100644 index 0000000000000000000000000000000000000000..3c75bf5e8ea491138b3e0d1ce43c8f71a8ca6a34 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/PredicateEditingSupport.java @@ -0,0 +1,57 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ +package de.bmotionstudio.gef.editor.edit; + +import org.eclipse.core.databinding.DataBindingContext; +import org.eclipse.core.databinding.beans.BeansObservables; +import org.eclipse.core.databinding.observable.value.IObservableValue; +import org.eclipse.jface.databinding.swt.SWTObservables; +import org.eclipse.jface.databinding.viewers.ObservableValueEditingSupport; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TextCellEditor; +import org.eclipse.jface.viewers.ViewerCell; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Shell; + +import de.bmotionstudio.gef.editor.model.Visualization; + +/** + * @author Lukas Ladenberger + * + */ +public class PredicateEditingSupport extends ObservableValueEditingSupport { + + private TextCellEditor cellEditor; + private String property; + + public PredicateEditingSupport(TableViewer viewer, DataBindingContext dbc, + String property, Visualization visualization, Shell shell) { + super(viewer, dbc); + this.property = property; + this.cellEditor = new PopupCellEditor((Composite) getViewer() + .getControl(), shell); + } + + @Override + protected IObservableValue doCreateCellEditorObservable( + CellEditor cellEditor) { + return SWTObservables.observeText(cellEditor.getControl(), SWT.Modify); + } + + @Override + protected IObservableValue doCreateElementObservable(Object element, + ViewerCell cell) { + return BeansObservables.observeValue(element, property); + } + + @Override + protected CellEditor getCellEditor(Object element) { + return cellEditor; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/TextCellEditorLocator.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/TextCellEditorLocator.java new file mode 100644 index 0000000000000000000000000000000000000000..ff822972b3615762b319ee29b5eb33d936c10de9 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/TextCellEditorLocator.java @@ -0,0 +1,42 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.edit; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.gef.tools.CellEditorLocator; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.swt.widgets.Text; + +public class TextCellEditorLocator implements CellEditorLocator { + + private IFigure textField; + + public TextCellEditorLocator(IFigure textField) { + setTextField(textField); + } + + public void relocate(CellEditor celleditor) { + Text text = (Text) celleditor.getControl(); + Rectangle rect = textField.getClientArea(); + textField.translateToAbsolute(rect); + org.eclipse.swt.graphics.Rectangle trim = text.computeTrim(0, 0, 0, 0); + rect.translate(trim.x, trim.y); + rect.width += trim.width; + rect.height += trim.height; + text.setBounds(rect.x, rect.y, rect.width, rect.height); + } + + protected IFigure getTextField() { + return textField; + } + + protected void setTextField(IFigure textField) { + this.textField = textField; + } + +} \ No newline at end of file diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/TextCellEditorWithContentProposal.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/TextCellEditorWithContentProposal.java new file mode 100644 index 0000000000000000000000000000000000000000..285034bd2235f71373d4128e903eceda1e2e4780 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/TextCellEditorWithContentProposal.java @@ -0,0 +1,86 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ +package de.bmotionstudio.gef.editor.edit; + +import org.eclipse.jface.bindings.keys.KeyStroke; +import org.eclipse.jface.fieldassist.ContentProposalAdapter; +import org.eclipse.jface.fieldassist.IContentProposalListener2; +import org.eclipse.jface.fieldassist.IContentProposalProvider; +import org.eclipse.jface.fieldassist.TextContentAdapter; +import org.eclipse.jface.viewers.TextCellEditor; +import org.eclipse.swt.widgets.Composite; + +/** + * @author Lukas Ladenberger + * + */ +public class TextCellEditorWithContentProposal extends TextCellEditor { + + private ContentProposalAdapter contentProposalAdapter; + private boolean popupOpen = false; // true, iff popup is currently open + + public TextCellEditorWithContentProposal(Composite parent, + IContentProposalProvider contentProposalProvider, + KeyStroke keyStroke, char[] autoActivationCharacters) { + super(parent); + + enableContentProposal(contentProposalProvider, keyStroke, + autoActivationCharacters); + } + + private void enableContentProposal( + IContentProposalProvider contentProposalProvider, + KeyStroke keyStroke, char[] autoActivationCharacters) { + contentProposalAdapter = new ContentProposalAdapter(text, + new TextContentAdapter(), contentProposalProvider, keyStroke, + autoActivationCharacters); + + // Listen for popup open/close events to be able to handle focus events + // correctly + contentProposalAdapter + .addContentProposalListener(new IContentProposalListener2() { + + public void proposalPopupClosed( + ContentProposalAdapter adapter) { + popupOpen = false; + } + + public void proposalPopupOpened( + ContentProposalAdapter adapter) { + popupOpen = true; + } + }); + } + + /** + * Return the {@link ContentProposalAdapter} of this cell editor. + * + * @return the {@link ContentProposalAdapter} + */ + public ContentProposalAdapter getContentProposalAdapter() { + return contentProposalAdapter; + } + + protected void focusLost() { + if (!popupOpen) { + // Focus lost deactivates the cell editor. + // This must not happen if focus lost was caused by activating + // the completion proposal popup. + super.focusLost(); + } + } + + protected boolean dependsOnExternalFocusListener() { + // Always return false; + // Otherwise, the ColumnViewerEditor will install an additional focus + // listener + // that cancels cell editing on focus lost, even if focus gets lost due + // to + // activation of the completion proposal popup. See also bug 58777. + return false; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/TextEditManager.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/TextEditManager.java new file mode 100644 index 0000000000000000000000000000000000000000..0cf46e1173cd1ad8eea0498f3cc4a728ca1efdc8 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/TextEditManager.java @@ -0,0 +1,156 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.edit; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.gef.editparts.ZoomListener; +import org.eclipse.gef.editparts.ZoomManager; +import org.eclipse.gef.tools.CellEditorLocator; +import org.eclipse.gef.tools.DirectEditManager; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.TextCellEditor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.actions.ActionFactory; +import org.eclipse.ui.part.CellEditorActionHandler; + +import de.bmotionstudio.gef.editor.AttributeConstants; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.part.AppAbstractEditPart; + +public class TextEditManager extends DirectEditManager { + + private IActionBars actionBars; + private CellEditorActionHandler actionHandler; + private IAction copy, cut, paste, undo, redo, find, selectAll, delete; + private double cachedZoom = -1.0; + private Font scaledFont; + private ZoomListener zoomListener = new ZoomListener() { + public void zoomChanged(double newZoom) { + updateScaledFont(newZoom); + } + }; + + public TextEditManager(AppAbstractEditPart source, CellEditorLocator locator) { + super(source, null, locator); + } + + /** + * @see org.eclipse.gef.tools.DirectEditManager#bringDown() + */ + protected void bringDown() { + ZoomManager zoomMgr = (ZoomManager) getEditPart().getViewer() + .getProperty(ZoomManager.class.toString()); + if (zoomMgr != null) + zoomMgr.removeZoomListener(zoomListener); + + if (actionHandler != null) { + actionHandler.dispose(); + actionHandler = null; + } + if (actionBars != null) { + restoreSavedActions(actionBars); + actionBars.updateActionBars(); + actionBars = null; + } + + super.bringDown(); + // dispose any scaled fonts that might have been created + disposeScaledFont(); + } + + protected CellEditor createCellEditorOn(Composite composite) { + return new TextCellEditor(composite, SWT.NONE); + } + + private void disposeScaledFont() { + if (scaledFont != null) { + scaledFont.dispose(); + scaledFont = null; + } + } + + protected void initCellEditor() { + // update text + IFigure figure = (IFigure) getEditPart().getFigure(); + getCellEditor().setValue( + ((BControl) getEditPart().getModel()) + .getAttributeValue(AttributeConstants.ATTRIBUTE_TEXT)); + // update font + ZoomManager zoomMgr = (ZoomManager) getEditPart().getViewer() + .getProperty(ZoomManager.class.toString()); + if (zoomMgr != null) { + // this will force the font to be set + cachedZoom = -1.0; + updateScaledFont(zoomMgr.getZoom()); + zoomMgr.addZoomListener(zoomListener); + } else { + getCellEditor().getControl().setFont(figure.getFont()); + } + + // Hook the cell editor's copy/paste actions to the actionBars so that + // they can + // be invoked via keyboard shortcuts. + actionBars = PlatformUI.getWorkbench().getActiveWorkbenchWindow() + .getActivePage().getActiveEditor().getEditorSite() + .getActionBars(); + saveCurrentActions(actionBars); + actionHandler = new CellEditorActionHandler(actionBars); + actionHandler.addCellEditor(getCellEditor()); + actionBars.updateActionBars(); + } + + private void restoreSavedActions(IActionBars actionBars) { + actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(), copy); + actionBars.setGlobalActionHandler(ActionFactory.PASTE.getId(), paste); + actionBars.setGlobalActionHandler(ActionFactory.DELETE.getId(), delete); + actionBars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(), + selectAll); + actionBars.setGlobalActionHandler(ActionFactory.CUT.getId(), cut); + actionBars.setGlobalActionHandler(ActionFactory.FIND.getId(), find); + actionBars.setGlobalActionHandler(ActionFactory.UNDO.getId(), undo); + actionBars.setGlobalActionHandler(ActionFactory.REDO.getId(), redo); + } + + private void saveCurrentActions(IActionBars actionBars) { + copy = actionBars.getGlobalActionHandler(ActionFactory.COPY.getId()); + paste = actionBars.getGlobalActionHandler(ActionFactory.PASTE.getId()); + delete = actionBars + .getGlobalActionHandler(ActionFactory.DELETE.getId()); + selectAll = actionBars.getGlobalActionHandler(ActionFactory.SELECT_ALL + .getId()); + cut = actionBars.getGlobalActionHandler(ActionFactory.CUT.getId()); + find = actionBars.getGlobalActionHandler(ActionFactory.FIND.getId()); + undo = actionBars.getGlobalActionHandler(ActionFactory.UNDO.getId()); + redo = actionBars.getGlobalActionHandler(ActionFactory.REDO.getId()); + } + + private void updateScaledFont(double zoom) { + if (cachedZoom == zoom) + return; + + Text text = (Text) getCellEditor().getControl(); + Font font = getEditPart().getFigure().getFont(); + + disposeScaledFont(); + cachedZoom = zoom; + if (zoom == 1.0) + text.setFont(font); + else { + FontData fd = font.getFontData()[0]; + fd.setHeight((int) (fd.getHeight() * zoom)); + text.setFont(scaledFont = new Font(null, fd)); + } + } + +} \ No newline at end of file diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/TextEditingSupport.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/TextEditingSupport.java new file mode 100644 index 0000000000000000000000000000000000000000..0611ec38b21290ead142d869f0924cd1b29ff4d8 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/TextEditingSupport.java @@ -0,0 +1,53 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.edit; + +import org.eclipse.core.databinding.DataBindingContext; +import org.eclipse.core.databinding.beans.BeansObservables; +import org.eclipse.core.databinding.observable.value.IObservableValue; +import org.eclipse.jface.databinding.swt.SWTObservables; +import org.eclipse.jface.databinding.viewers.ObservableValueEditingSupport; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ColumnViewer; +import org.eclipse.jface.viewers.TextCellEditor; +import org.eclipse.jface.viewers.ViewerCell; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; + +public class TextEditingSupport extends ObservableValueEditingSupport { + + private TextCellEditor cellEditor; + private String property; + + public TextEditingSupport(ColumnViewer viewer, DataBindingContext dbc, + String property) { + super(viewer, dbc); + this.property = property; + } + + @Override + protected IObservableValue doCreateCellEditorObservable( + CellEditor cellEditor) { + return SWTObservables.observeText(cellEditor.getControl(), SWT.Modify); + } + + @Override + protected IObservableValue doCreateElementObservable(Object element, + ViewerCell cell) { + return BeansObservables.observeValue(element, property); + } + + @Override + protected CellEditor getCellEditor(Object element) { + if (cellEditor == null) { + cellEditor = new TextCellEditor((Composite) getViewer() + .getControl()); + } + return cellEditor; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/TextEditorWindow.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/TextEditorWindow.java new file mode 100644 index 0000000000000000000000000000000000000000..f32d117991de9e35d54393b021320b6e72efb1f8 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/TextEditorWindow.java @@ -0,0 +1,127 @@ +package de.bmotionstudio.gef.editor.edit; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.window.IShellProvider; +import org.eclipse.jface.window.SameShellProvider; +import org.eclipse.jface.window.Window; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ShellAdapter; +import org.eclipse.swt.events.ShellEvent; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +import de.bmotionstudio.gef.editor.BMotionStudioSWTConstants; + +public class TextEditorWindow extends Window { + + private String value; + private Point position; + private Text text; + private PopupResult result = new PopupResult(); + private List<IPopupListener> popupListener = new ArrayList<IPopupListener>(); + + protected TextEditorWindow(Shell parentShell, Text text) { + this(new SameShellProvider(parentShell), text); + } + + protected TextEditorWindow(IShellProvider parentShell, Text text) { + super(parentShell); + this.value = text.getText(); + this.position = text.toDisplay(0, 0); + this.result.setReturncode(getReturnCode()); + setShellStyle(SWT.ON_TOP); + setBlockOnOpen(true); + } + + @Override + protected Control createContents(Composite parent) { + Composite composite = new Composite(parent, 0); + FillLayout layout = new FillLayout(); + composite.setLayout(layout); + composite.setLayoutData(new GridData(GridData.FILL_BOTH)); + text = new Text(composite, SWT.MULTI | SWT.WRAP); + text.setText(value); + text.selectAll(); + text.setFont(BMotionStudioSWTConstants.fontArial10); + return composite; + } + + @Override + protected Point getInitialSize() { + return new Point(500, 200); + } + + @Override + protected Point getInitialLocation(Point initialSize) { + return position; + } + + @Override + protected void configureShell(Shell newShell) { + newShell.addShellListener(new ShellAdapter() { + @Override + public void shellDeactivated(ShellEvent e) { + setReturnCode(OK); + close(); + } + }); + super.configureShell(newShell); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.window.Window#setReturnCode(int) + */ + @Override + protected void setReturnCode(int code) { + result.setReturncode(code); + super.setReturnCode(code); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.window.Window#close() + */ + @Override + public boolean close() { + result.setValue(text.getText()); + notifyPopupClosed(); + boolean b = super.close(); + return b; + } + + public PopupResult openPopup() { + notifyPopupOpened(); + int i = super.open(); + result.setReturncode(i); + return result; + } + + public void notifyPopupOpened() { + for (IPopupListener l : popupListener) + l.popupOpened(); + } + + public void notifyPopupClosed() { + for (IPopupListener l : popupListener) + l.popupClosed(); + } + + public void addPopupListener(IPopupListener l) { + this.popupListener.add(l); + } + + public void removePopupListener(IPopupListener l) { + this.popupListener.remove(l); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/TypeEditingSupport.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/TypeEditingSupport.java new file mode 100644 index 0000000000000000000000000000000000000000..80867c619fabdbd39c019522e2163f99b9696312 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/edit/TypeEditingSupport.java @@ -0,0 +1,55 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.edit; + +import org.eclipse.core.databinding.DataBindingContext; +import org.eclipse.core.databinding.beans.BeansObservables; +import org.eclipse.core.databinding.observable.value.IObservableValue; +import org.eclipse.jface.databinding.swt.SWTObservables; +import org.eclipse.jface.databinding.viewers.ObservableValueEditingSupport; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ColumnViewer; +import org.eclipse.jface.viewers.ComboBoxCellEditor; +import org.eclipse.jface.viewers.ViewerCell; +import org.eclipse.swt.widgets.Composite; + +import de.be4.classicalb.core.parser.BParser; + +public class TypeEditingSupport extends ObservableValueEditingSupport { + + private CellEditor cellEditor; + private String propertyName; + + public TypeEditingSupport(ColumnViewer viewer, DataBindingContext dbc, + String propertyName) { + super(viewer, dbc); + this.propertyName = propertyName; + } + + @Override + protected IObservableValue doCreateCellEditorObservable( + CellEditor cellEditor) { + return SWTObservables.observeSelection(cellEditor.getControl()); + } + + @Override + protected IObservableValue doCreateElementObservable(Object element, + ViewerCell cell) { + return BeansObservables.observeValue(element, propertyName); + } + + @Override + protected CellEditor getCellEditor(Object element) { + if (cellEditor == null) { + cellEditor = new ComboBoxCellEditor((Composite) getViewer() + .getControl(), new String[] { BParser.PREDICATE_PREFIX, + BParser.EXPRESSION_PREFIX }); + } + return cellEditor; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/editpolicy/AppDeletePolicy.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/editpolicy/AppDeletePolicy.java new file mode 100644 index 0000000000000000000000000000000000000000..05cdf766042d0c2428057ed1b90aacc4fbfdd74d --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/editpolicy/AppDeletePolicy.java @@ -0,0 +1,24 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.editpolicy; + +import org.eclipse.gef.commands.Command; +import org.eclipse.gef.editpolicies.ComponentEditPolicy; +import org.eclipse.gef.requests.GroupRequest; + +import de.bmotionstudio.gef.editor.command.DeleteCommand; +import de.bmotionstudio.gef.editor.model.BControl; + +public class AppDeletePolicy extends ComponentEditPolicy { + + protected Command createDeleteCommand(GroupRequest deleteRequest) { + DeleteCommand command = new DeleteCommand((BControl) getHost() + .getModel(), (BControl) getHost().getParent().getModel()); + return command; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/editpolicy/AppEditLayoutPolicy.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/editpolicy/AppEditLayoutPolicy.java new file mode 100644 index 0000000000000000000000000000000000000000..6d8080f8a487911ec7ae0e5888adccb572e17898 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/editpolicy/AppEditLayoutPolicy.java @@ -0,0 +1,233 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.editpolicy; + +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.gef.EditPart; +import org.eclipse.gef.EditPolicy; +import org.eclipse.gef.Request; +import org.eclipse.gef.SnapToGuides; +import org.eclipse.gef.commands.Command; +import org.eclipse.gef.editpolicies.ResizableEditPolicy; +import org.eclipse.gef.editpolicies.XYLayoutEditPolicy; +import org.eclipse.gef.requests.ChangeBoundsRequest; +import org.eclipse.gef.requests.CreateRequest; +import org.eclipse.gef.rulers.RulerProvider; + +import de.bmotionstudio.gef.editor.AttributeConstants; +import de.bmotionstudio.gef.editor.attribute.BAttributeHeight; +import de.bmotionstudio.gef.editor.attribute.BAttributeWidth; +import de.bmotionstudio.gef.editor.command.BControlChangeLayoutCommand; +import de.bmotionstudio.gef.editor.command.CreateCommand; +import de.bmotionstudio.gef.editor.command.ChangeGuideCommand; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.model.BMotionGuide; +import de.bmotionstudio.gef.editor.part.AppAbstractEditPart; + +public class AppEditLayoutPolicy extends XYLayoutEditPolicy { + + @Override + protected Command createChangeConstraintCommand(EditPart child, + Object constraint) { + return null; + } + + @Override + protected Command createChangeConstraintCommand( + ChangeBoundsRequest request, EditPart child, Object constraint) { + + BControlChangeLayoutCommand cmd = new BControlChangeLayoutCommand(); + BControl part = (BControl) child.getModel(); + cmd.setModel(child.getModel()); + cmd.setConstraint((Rectangle) constraint); + Command result = cmd; + + if ((request.getResizeDirection() & PositionConstants.NORTH_SOUTH) != 0) { + Integer guidePos = (Integer) request.getExtendedData().get( + SnapToGuides.KEY_HORIZONTAL_GUIDE); + if (guidePos != null) { + result = chainGuideAttachmentCommand(request, part, result, + true); + } else if (part.getHorizontalGuide() != null) { + // SnapToGuides didn't provide a horizontal guide, but this part + // is attached + // to a horizontal guide. Now we check to see if the part is + // attached to + // the guide along the edge being resized. If that is the case, + // we need to + // detach the part from the guide; otherwise, we leave it alone. + int alignment = part.getHorizontalGuide().getAlignment(part); + int edgeBeingResized = 0; + if ((request.getResizeDirection() & PositionConstants.NORTH) != 0) + edgeBeingResized = -1; + else + edgeBeingResized = 1; + if (alignment == edgeBeingResized) + result = result.chain(new ChangeGuideCommand(part, true)); + } + } + + if ((request.getResizeDirection() & PositionConstants.EAST_WEST) != 0) { + Integer guidePos = (Integer) request.getExtendedData().get( + SnapToGuides.KEY_VERTICAL_GUIDE); + if (guidePos != null) { + result = chainGuideAttachmentCommand(request, part, result, + false); + } else if (part.getVerticalGuide() != null) { + int alignment = part.getVerticalGuide().getAlignment(part); + int edgeBeingResized = 0; + if ((request.getResizeDirection() & PositionConstants.WEST) != 0) + edgeBeingResized = -1; + else + edgeBeingResized = 1; + if (alignment == edgeBeingResized) + result = result.chain(new ChangeGuideCommand(part, false)); + } + } + + if (request.getType().equals(REQ_MOVE_CHILDREN) + || request.getType().equals(REQ_ALIGN_CHILDREN)) { + result = chainGuideAttachmentCommand(request, part, result, true); + result = chainGuideAttachmentCommand(request, part, result, false); + result = chainGuideDetachmentCommand(request, part, result, true); + result = chainGuideDetachmentCommand(request, part, result, false); + } + + return result; + } + + @Override + protected EditPolicy createChildEditPolicy(EditPart child) { + + BControl control = (BControl) child.getModel(); + + ResizableEditPolicy policy = new ResizableEditPolicy(); + + BAttributeWidth atrWidth = (BAttributeWidth) control.getAttributes() + .get(AttributeConstants.ATTRIBUTE_WIDTH); + BAttributeHeight atrHeight = (BAttributeHeight) control.getAttributes() + .get(AttributeConstants.ATTRIBUTE_HEIGHT); + + if (atrWidth.isEditable() && atrHeight.isEditable()) + return policy; + + if (atrWidth.isEditable()) { + policy.setResizeDirections(PositionConstants.EAST_WEST); + return policy; + } + + if (atrHeight.isEditable()) { + policy.setResizeDirections(PositionConstants.NORTH_SOUTH); + return policy; + } + + policy.setResizeDirections(0); + + return policy; + + } + + @Override + protected Command getCreateCommand(CreateRequest request) { + + if (request.getType() == REQ_CREATE + && getHost() instanceof AppAbstractEditPart) { + + if (((BControl) ((AppAbstractEditPart) getHost()).getModel()) + .canHaveChildren()) { + + BControl newObj = (BControl) request.getNewObject(); + + CreateCommand createCmd = new CreateCommand( + newObj, (BControl) getHost().getModel()); + + Rectangle constraint = (Rectangle) getConstraintFor(request); + constraint.x = (constraint.x < 0) ? 0 : constraint.x; + constraint.y = (constraint.y < 0) ? 0 : constraint.y; + + BAttributeWidth atrWidth = (BAttributeWidth) newObj + .getAttributes() + .get(AttributeConstants.ATTRIBUTE_WIDTH); + BAttributeHeight atrHeight = (BAttributeHeight) newObj + .getAttributes().get( + AttributeConstants.ATTRIBUTE_HEIGHT); + + if (atrWidth != null) { + constraint.width = Integer.valueOf(atrWidth.getValue() + .toString()); + } else { + constraint.width = (constraint.width <= 0) ? 100 + : constraint.width; + } + + if (atrHeight != null) { + constraint.height = Integer.valueOf(atrHeight.getValue() + .toString()); + } else { + constraint.height = (constraint.height <= 0) ? 100 + : constraint.height; + } + + createCmd.setLayout(constraint); + + Command cmd = chainGuideAttachmentCommand(request, newObj, + createCmd, true); + return chainGuideAttachmentCommand(request, newObj, cmd, false); + + } + + } + + return null; + + } + + protected Command chainGuideAttachmentCommand(Request request, + BControl part, Command cmd, boolean horizontal) { + Command result = cmd; + + // Attach to guide, if one is given + Integer guidePos = (Integer) request.getExtendedData().get( + horizontal ? SnapToGuides.KEY_HORIZONTAL_GUIDE + : SnapToGuides.KEY_VERTICAL_GUIDE); + if (guidePos != null) { + int alignment = ((Integer) request.getExtendedData().get( + horizontal ? SnapToGuides.KEY_HORIZONTAL_ANCHOR + : SnapToGuides.KEY_VERTICAL_ANCHOR)).intValue(); + ChangeGuideCommand cgm = new ChangeGuideCommand(part, horizontal); + cgm.setNewGuide(findGuideAt(guidePos.intValue(), horizontal), + alignment); + result = result.chain(cgm); + } + + return result; + } + + protected Command chainGuideDetachmentCommand(Request request, + BControl part, Command cmd, boolean horizontal) { + Command result = cmd; + + // Detach from guide, if none is given + Integer guidePos = (Integer) request.getExtendedData().get( + horizontal ? SnapToGuides.KEY_HORIZONTAL_GUIDE + : SnapToGuides.KEY_VERTICAL_GUIDE); + if (guidePos == null) + result = result.chain(new ChangeGuideCommand(part, horizontal)); + + return result; + } + + protected BMotionGuide findGuideAt(int pos, boolean horizontal) { + RulerProvider provider = ((RulerProvider) getHost().getViewer() + .getProperty( + horizontal ? RulerProvider.PROPERTY_VERTICAL_RULER + : RulerProvider.PROPERTY_HORIZONTAL_RULER)); + return (BMotionGuide) provider.getGuideAt(pos); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/editpolicy/BMotionNodeEditPolicy.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/editpolicy/BMotionNodeEditPolicy.java new file mode 100644 index 0000000000000000000000000000000000000000..eceaa531a7c6b1803f0af7d91b8359121dba944c --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/editpolicy/BMotionNodeEditPolicy.java @@ -0,0 +1,85 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.editpolicy; + +import org.eclipse.gef.commands.Command; +import org.eclipse.gef.editpolicies.GraphicalNodeEditPolicy; +import org.eclipse.gef.requests.CreateConnectionRequest; +import org.eclipse.gef.requests.ReconnectRequest; + +import de.bmotionstudio.gef.editor.command.ConnectionCreateCommand; +import de.bmotionstudio.gef.editor.command.ConnectionReconnectCommand; +import de.bmotionstudio.gef.editor.model.BConnection; +import de.bmotionstudio.gef.editor.model.BControl; + +public class BMotionNodeEditPolicy extends GraphicalNodeEditPolicy { + + /* + * (non-Javadoc) + * + * @see org.eclipse.gef.editpolicies.GraphicalNodeEditPolicy# + * getConnectionCompleteCommand + * (org.eclipse.gef.requests.CreateConnectionRequest) + */ + protected Command getConnectionCompleteCommand( + CreateConnectionRequest request) { + ConnectionCreateCommand cmd = (ConnectionCreateCommand) request + .getStartCommand(); + cmd.setTarget((BControl) getHost().getModel()); + return cmd; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.gef.editpolicies.GraphicalNodeEditPolicy# + * getConnectionCreateCommand + * (org.eclipse.gef.requests.CreateConnectionRequest) + */ + protected Command getConnectionCreateCommand(CreateConnectionRequest request) { + BControl source = (BControl) getHost().getModel(); + ConnectionCreateCommand cmd = new ConnectionCreateCommand(source); + BConnection con = (BConnection) request.getNewObject(); + con.setVisualization(source.getVisualization()); + cmd.setConnection(con); + request.setStartCommand(cmd); + return cmd; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.gef.editpolicies.GraphicalNodeEditPolicy# + * getReconnectSourceCommand (org.eclipse.gef.requests.ReconnectRequest) + */ + protected Command getReconnectSourceCommand(ReconnectRequest request) { + BConnection conn = (BConnection) request.getConnectionEditPart() + .getModel(); + BControl newSource = (BControl) getHost().getModel(); + ConnectionReconnectCommand cmd = new ConnectionReconnectCommand(); + cmd.setNewSource(newSource); + cmd.setConnection(conn); + return cmd; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.gef.editpolicies.GraphicalNodeEditPolicy# + * getReconnectTargetCommand (org.eclipse.gef.requests.ReconnectRequest) + */ + protected Command getReconnectTargetCommand(ReconnectRequest request) { + BConnection conn = (BConnection) request.getConnectionEditPart() + .getModel(); + BControl newTarget = (BControl) getHost().getModel(); + ConnectionReconnectCommand cmd = new ConnectionReconnectCommand(); + cmd.setNewTarget(newTarget); + cmd.setConnection(conn); + return cmd; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/editpolicy/ChangeAttributePolicy.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/editpolicy/ChangeAttributePolicy.java new file mode 100644 index 0000000000000000000000000000000000000000..cfeb087846f7263a215af10a187f2999a7eca1d9 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/editpolicy/ChangeAttributePolicy.java @@ -0,0 +1,49 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.editpolicy; + +import org.eclipse.gef.EditPart; +import org.eclipse.gef.Request; +import org.eclipse.gef.commands.Command; +import org.eclipse.gef.editpolicies.AbstractEditPolicy; + +import de.bmotionstudio.gef.editor.library.AbstractLibraryCommand; +import de.bmotionstudio.gef.editor.library.AttributeRequest; +import de.bmotionstudio.gef.editor.part.AppAbstractEditPart; + +public class ChangeAttributePolicy extends AbstractEditPolicy { + + public static final String CHANGE_ATTRIBUTE_POLICY = "ChangeAttributePolicy"; + + @Override + public Command getCommand(Request request) { + if ("change attribute" == request.getType() + && request instanceof AttributeRequest) { + AttributeRequest changeAttributeReq = (AttributeRequest) request; + if (changeAttributeReq.getAttributeTransferObject() != null) { + AbstractLibraryCommand command = ((AppAbstractEditPart) getHost()) + .getLibraryCommand(changeAttributeReq); + if (command != null) { + command.setEditPart(getHost()); + command.setAttributeTransferObject(changeAttributeReq + .getAttributeTransferObject()); + command.setDropLocation(changeAttributeReq + .getDropLocation()); + } + return command; + } + } + return null; + } + + public EditPart getTargetEditPart(Request request) { + if ("change attribute" == request.getType()) + return getHost(); + return null; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/editpolicy/CustomDirectEditPolicy.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/editpolicy/CustomDirectEditPolicy.java new file mode 100644 index 0000000000000000000000000000000000000000..c653ae10b5395880bc01730652e9933ef04765eb --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/editpolicy/CustomDirectEditPolicy.java @@ -0,0 +1,39 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.editpolicy; + +import org.eclipse.gef.commands.Command; +import org.eclipse.gef.editpolicies.DirectEditPolicy; +import org.eclipse.gef.requests.DirectEditRequest; + +import de.bmotionstudio.gef.editor.command.RenameCommand; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.part.AppAbstractEditPart; + +public class CustomDirectEditPolicy extends DirectEditPolicy { + + /** + * @see CustomDirectEditPolicy#getDirectEditCommand(DirectEditRequest) + */ + protected Command getDirectEditCommand(DirectEditRequest edit) { + String labelText = (String) edit.getCellEditor().getValue(); + AppAbstractEditPart label = (AppAbstractEditPart) getHost(); + RenameCommand command = new RenameCommand(); + command.setControl((BControl) label.getModel()); + command.setNewString(labelText); + return command; + } + + /** + * @see CustomDirectEditPolicy#showCurrentEditValue(DirectEditRequest) + */ + protected void showCurrentEditValue(DirectEditRequest request) { + // String value = (String) request.getCellEditor().getValue(); + getHostFigure().getUpdateManager().performUpdate(); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/editpolicy/RenamePolicy.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/editpolicy/RenamePolicy.java new file mode 100644 index 0000000000000000000000000000000000000000..3d555a6708d99ab15db3c1ab83d02026af54cd34 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/editpolicy/RenamePolicy.java @@ -0,0 +1,33 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.editpolicy; + +import org.eclipse.gef.Request; +import org.eclipse.gef.commands.Command; +import org.eclipse.gef.editpolicies.AbstractEditPolicy; + +import de.bmotionstudio.gef.editor.command.RenameCommand; +import de.bmotionstudio.gef.editor.model.BControl; + +public class RenamePolicy extends AbstractEditPolicy { + + @Override + public Command getCommand(Request request) { + if (request.getType().equals("rename")) + return createRenameCommand(request); + return null; + } + + protected Command createRenameCommand(Request renameRequest) { + RenameCommand command = new RenameCommand(); + command.setControl(((BControl) getHost().getModel())); + command.setNewString(((String) renameRequest.getExtendedData().get( + "newName"))); + return command; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/eventb/EventBHelper.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/eventb/EventBHelper.java new file mode 100644 index 0000000000000000000000000000000000000000..8e38321cd1a05a202ef222c752bcd764c728ffc3 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/eventb/EventBHelper.java @@ -0,0 +1,199 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.eventb; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.eclipse.core.resources.IFile; +import org.eventb.core.IMachineRoot; +import org.eventb.core.ISCConstant; +import org.eventb.core.ISCEvent; +import org.eventb.core.ISCGuard; +import org.eventb.core.ISCInternalContext; +import org.eventb.core.ISCInvariant; +import org.eventb.core.ISCMachineRoot; +import org.eventb.core.ISCParameter; +import org.eventb.core.ISCVariable; +import org.rodinp.core.IRodinFile; +import org.rodinp.core.IRodinProject; +import org.rodinp.core.RodinCore; +import org.rodinp.core.RodinDBException; + +import de.bmotionstudio.gef.editor.model.Visualization; +import de.prob.logging.Logger; + +public final class EventBHelper { + + public static ISCMachineRoot getCorrespondingFile(IFile file, + String machineFileName) { + IRodinProject rProject = RodinCore.valueOf(file.getProject()); + ISCMachineRoot machineRoot = null; + if (rProject != null) { + IRodinFile rFile = rProject.getRodinFile(machineFileName); + if (rFile != null && rFile.getRoot() instanceof IMachineRoot) + machineRoot = ((IMachineRoot) rFile.getRoot()) + .getSCMachineRoot(); + } + return machineRoot; + } + + public static List<MachineOperation> getOperations( + Visualization visualization) { + + ArrayList<MachineOperation> tmpSet = new ArrayList<MachineOperation>(); + + if (visualization.getLanguage().equals("EventB")) { + + ISCMachineRoot machineRoot = null; + machineRoot = getCorrespondingFile(visualization.getProjectFile(), + visualization.getMachineName()); + + if (machineRoot != null) { + + try { + + ISCEvent[] events = machineRoot.getSCEvents(); + + for (ISCEvent event : events) { + + List<String> parSet = new ArrayList<String>(); + List<String> guardSet = new ArrayList<String>(); + + for (ISCParameter par : event.getSCParameters()) + parSet.add(par.getIdentifierString()); + + for (ISCGuard guard : event.getSCGuards()) + guardSet.add(guard.getPredicateString()); + + MachineOperation op = new MachineOperation( + event.getLabel(), parSet, guardSet); + tmpSet.add(op); + + } + + } catch (RodinDBException e) { + String message = "Rodin DB Exception while getting operations: " + + e.getLocalizedMessage(); + Logger.notifyUser(message, e); + return Collections + .unmodifiableList(new ArrayList<MachineOperation>()); + } + + } + + } else if (visualization.getLanguage().equals("ClassicalB")) { + // TODO: Implement me!!! + } + + return tmpSet; + + } + + public static List<MachineContentObject> getVariables( + Visualization visualization) { + + ISCMachineRoot machineRoot = null; + + machineRoot = getCorrespondingFile(visualization.getProjectFile(), + visualization.getMachineName()); + + ISCVariable[] vars = null; + ArrayList<MachineContentObject> tmpSet = new ArrayList<MachineContentObject>(); + + try { + vars = machineRoot.getSCVariables(); + + for (ISCVariable var : vars) { + + MachineContentObject machinevar = new MachineContentObject( + var.getIdentifierString()); + tmpSet.add(machinevar); + + } + } catch (RodinDBException e) { + String message = "Rodin DB Exception while getting variables: " + + e.getLocalizedMessage(); + Logger.notifyUser(message, e); + return Collections + .unmodifiableList(new ArrayList<MachineContentObject>()); + } + + return tmpSet; + + } + + public static List<MachineContentObject> getInvariants( + Visualization visualization) { + + ISCMachineRoot machineRoot = null; + + machineRoot = getCorrespondingFile(visualization.getProjectFile(), + visualization.getMachineName()); + + ISCInvariant[] invariants = null; + ArrayList<MachineContentObject> tmpSet = new ArrayList<MachineContentObject>(); + + try { + invariants = machineRoot.getSCInvariants(); + + for (ISCInvariant inv : invariants) { + + MachineContentObject machineinv = new MachineContentObject( + inv.getPredicateString()); + tmpSet.add(machineinv); + + } + } catch (RodinDBException e) { + String message = "Rodin DB Exception while getting invariants: " + + e.getLocalizedMessage(); + Logger.notifyUser(message, e); + return Collections + .unmodifiableList(new ArrayList<MachineContentObject>()); + } + + return tmpSet; + } + + public static List<MachineContentObject> getConstants( + Visualization visualization) { + + ISCMachineRoot machineRoot = null; + + machineRoot = getCorrespondingFile(visualization.getProjectFile(), + visualization.getMachineName()); + + ArrayList<MachineContentObject> tmpSet = new ArrayList<MachineContentObject>(); + + try { + + ISCInternalContext[] seenContexts = machineRoot.getSCSeenContexts(); + for (ISCInternalContext context : seenContexts) { + + for (ISCConstant constant : context.getSCConstants()) { + + MachineContentObject machineinv = new MachineContentObject( + constant.getIdentifierString()); + tmpSet.add(machineinv); + + } + + } + + } catch (RodinDBException e) { + String message = "Rodin DB Exception while getting constants: " + + e.getLocalizedMessage(); + Logger.notifyUser(message, e); + return Collections + .unmodifiableList(new ArrayList<MachineContentObject>()); + } + + return tmpSet; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/eventb/EventBLanguageService.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/eventb/EventBLanguageService.java new file mode 100644 index 0000000000000000000000000000000000000000..35dd823a1a34c023287d9cfa9fa6647e827a62d5 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/eventb/EventBLanguageService.java @@ -0,0 +1,53 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.eventb; + +import org.eclipse.core.resources.IFile; +import org.eventb.core.IContextRoot; +import org.eventb.core.IEventBRoot; +import org.eventb.core.IMachineRoot; +import org.rodinp.core.IRodinFile; +import org.rodinp.core.IRodinProject; +import org.rodinp.core.RodinCore; + +import de.bmotionstudio.gef.editor.ILanguageService; +import de.bmotionstudio.gef.editor.model.Visualization; +import de.prob.core.command.LoadEventBModelCommand; +import de.prob.exceptions.ProBException; + +/** + * @author Lukas Ladenberger + * + */ +public class EventBLanguageService implements ILanguageService { + + private IEventBRoot getCorrespondingFile(IFile file, String machineFileName) { + IRodinProject rProject = RodinCore.valueOf(file.getProject()); + IRodinFile rFile = rProject.getRodinFile(machineFileName); + IEventBRoot eventbRoot = (IEventBRoot) rFile.getRoot(); + return eventbRoot; + } + + @Override + public void startProBAnimator(Visualization v) throws ProBException { + IEventBRoot modelRoot = getCorrespondingFile(v.getProjectFile(), + v.getMachineName()); + LoadEventBModelCommand.load(v.getAnimation().getAnimator(), modelRoot); + } + + @Override + public boolean isLanguageFile(IFile f) { + IRodinProject rProject = RodinCore.valueOf(f.getProject()); + IRodinFile rFile = rProject.getRodinFile(f.getName()); + if (rFile != null + && ((rFile.getRoot() instanceof IMachineRoot) || (rFile + .getRoot() instanceof IContextRoot))) + return true; + return false; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/eventb/MachineContentObject.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/eventb/MachineContentObject.java new file mode 100644 index 0000000000000000000000000000000000000000..d032677402fc822500ba698ee4874eb6de46e371 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/eventb/MachineContentObject.java @@ -0,0 +1,32 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.eventb; + +import de.bmotionstudio.gef.editor.BindingObject; + + +public class MachineContentObject extends BindingObject { + + private String label; + + public MachineContentObject(String label) { + this.setLabel(label); + } + + public void setLabel(String label) { + this.label = label; + } + + public String getLabel() { + return label; + } + + public String toString() { + return this.label; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/eventb/MachineOperation.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/eventb/MachineOperation.java new file mode 100644 index 0000000000000000000000000000000000000000..60dfda23926c777d1b50371ae9d01371eb0c7a82 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/eventb/MachineOperation.java @@ -0,0 +1,44 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.eventb; + +import java.util.ArrayList; +import java.util.List; + +public class MachineOperation extends MachineContentObject { + + private List<String> parameters; + private List<String> guards; + + public MachineOperation(String label, List<String> parameters, + List<String> guards) { + super(label); + this.parameters = parameters; + this.guards = guards; + } + + public MachineOperation(String label) { + super(label); + } + + public List<String> getParameters() { + return this.parameters; + } + + public List<String> getGuards() { + return guards; + } + + public void setParameters(ArrayList<String> parameters) { + this.parameters = parameters; + } + + public void setGuards(ArrayList<String> guards) { + this.guards = guards; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/AbstractBMotionFigure.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/AbstractBMotionFigure.java new file mode 100644 index 0000000000000000000000000000000000000000..7a9ea7ccf8c5887fad3db417e81377301f4b970a --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/AbstractBMotionFigure.java @@ -0,0 +1,23 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.figure; + +import org.eclipse.draw2d.Clickable; + +/** + * @author Lukas Ladenberger + * + */ +public class AbstractBMotionFigure extends Clickable { + + public void deactivateFigure() { + } + + public void activateFigure() { + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/BMSImageFigure.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/BMSImageFigure.java new file mode 100644 index 0000000000000000000000000000000000000000..d5018badfa4354609afeae38f3f5a257b0985b5c --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/BMSImageFigure.java @@ -0,0 +1,54 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.figure; + +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.ImageFigure; +import org.eclipse.draw2d.StackLayout; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.graphics.Image; + +public class BMSImageFigure extends AbstractBMotionFigure { + + private ImageFigure imageFigure; + + public BMSImageFigure() { + setLayoutManager(new StackLayout()); + imageFigure = new ImageFigure() { + public void paintFigure(Graphics g) { + if (getImage() == null) + return; + Rectangle rectangle = getClientArea(); + g.drawImage(getImage(), new Rectangle(getImage().getBounds()), + rectangle); + } + }; + add(imageFigure); + } + + public void setLayout(Rectangle rect) { + getParent().setConstraint(imageFigure, rect); + } + + public void setImage(Image image) { + if (imageFigure.getImage() != null) + imageFigure.getImage().dispose(); + imageFigure.setImage(image); + } + + /* + * (non-Javadoc) + * + * @see de.bmotionstudio.gef.editor.figure.IBMotionFigure#deactivateFigure() + */ + @Override + public void deactivateFigure() { + if (imageFigure.getImage() != null) + imageFigure.getImage().dispose(); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/ButtonFigure.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/ButtonFigure.java new file mode 100644 index 0000000000000000000000000000000000000000..1f7602a791c16a1e62669406ef4f58d82b98615d --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/ButtonFigure.java @@ -0,0 +1,89 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.figure; + +import org.eclipse.draw2d.ButtonBorder; +import org.eclipse.draw2d.ColorConstants; +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.Label; +import org.eclipse.draw2d.StackLayout; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Display; + +public class ButtonFigure extends AbstractBMotionFigure { + + private Label txtLabel; + private Color backgroundColor; + private Color foregroundColor; + + public ButtonFigure() { + setLayoutManager(new StackLayout()); + txtLabel = new Label("Click"); + add(txtLabel); + setOpaque(true); + setBorder(new ButtonBorder()); + } + + public void setText(String text) { + txtLabel.setText(text); + } + + public void setBackgroundColor(RGB rgb) { + if (backgroundColor != null) + backgroundColor.dispose(); + backgroundColor = new Color(Display.getDefault(), rgb); + setBackgroundColor(backgroundColor); + } + + public void setTextColor(RGB rgb) { + if (foregroundColor != null) + foregroundColor.dispose(); + foregroundColor = new Color(Display.getDefault(), rgb); + setForegroundColor(foregroundColor); + } + + public void setBtEnabled(Boolean bool) { + txtLabel.setEnabled(bool); + repaint(); + } + + /* + * (non-Javadoc) + * + * @see de.bmotionstudio.gef.editor.figure.IBMotionFigure#deactivateFigure() + */ + @Override + public void deactivateFigure() { + if (backgroundColor != null) + backgroundColor.dispose(); + if (foregroundColor != null) + foregroundColor.dispose(); + } + + @Override + protected void paintBorder(Graphics graphics) { + super.paintBorder(graphics); + if (hasFocus()) { + graphics.setForegroundColor(ColorConstants.black); + graphics.setBackgroundColor(ColorConstants.white); + Rectangle area = getClientArea(); + graphics.drawFocus(area.x, area.y, area.width, area.height); + } + } + + @Override + protected void paintClientArea(Graphics graphics) { + graphics.translate(1, 1); + graphics.pushState(); + super.paintClientArea(graphics); + graphics.popState(); + graphics.translate(-1, -1); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/CanisterFigure.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/CanisterFigure.java new file mode 100644 index 0000000000000000000000000000000000000000..248ff6825d76105b27f27a8bd1a7f5d0a1fc5819 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/CanisterFigure.java @@ -0,0 +1,190 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.figure; + +import org.eclipse.draw2d.BorderLayout; +import org.eclipse.draw2d.ColorConstants; +import org.eclipse.draw2d.Figure; +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.Label; +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.draw2d.RectangleFigure; +import org.eclipse.draw2d.XYLayout; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.PaletteData; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Display; + +public class CanisterFigure extends AbstractBMotionFigure { + + private RectangleFigure axisRect; + private Figure axisFigure; + private RectangleFigure fillRect; + private Figure fillFigure; + + private Image layerImage; + private ImageData imageData; + + private int fill_height; + private double positions; + private int show_pos; + + private Boolean showMeasure; + + public CanisterFigure() { + + XYLayout layout = new XYLayout(); + setLayoutManager(layout); + + PaletteData palette = new PaletteData( + new RGB[] { ColorConstants.white.getRGB() }); + imageData = new ImageData(1, 1, 8, palette); + imageData.alpha = 255; + imageData.setPixel(0, 0, 0); + layerImage = new Image(null, imageData); + + axisFigure = new Figure(); + axisFigure.setLocation(new Point(0, 0)); + axisFigure.setLayoutManager(new XYLayout()); + add(axisFigure); + + fillFigure = new Figure(); + fillFigure.setLayoutManager(new BorderLayout()); + add(fillFigure); + + fillRect = new RectangleFigure(); + fillRect.setOutline(false); + fillFigure.add(fillRect); + fillFigure.setConstraint(fillRect, BorderLayout.BOTTOM); + + setOpaque(true); + + } + + public void setLayout(Rectangle rect) { + + getParent().setConstraint(this, rect); + + // Set the right size and position of the y-axis + axisFigure.removeAll(); + + int fillPos = 0; + + double one_pos = Double.valueOf(rect.height) / positions; + + if (showMeasure) { + + axisFigure.setSize(100, rect.height); + + axisRect = new RectangleFigure(); + axisFigure.add(axisRect); + axisRect.setBackgroundColor(ColorConstants.black); + axisFigure.setConstraint(axisRect, new Rectangle(14, 0, 1, + rect.height)); + + RectangleFigure line; + Label lb; + + for (int i = 0; i <= positions; i = i + show_pos) { + + lb = new Label(); + axisFigure.add(lb); + lb.setText(String.valueOf((int) (positions - i))); + lb.setBackgroundColor(ColorConstants.red); + lb.setTextAlignment(PositionConstants.LEFT); + + if (i == 0) { + axisFigure.setConstraint(lb, new Rectangle(18, + (int) (i * one_pos), 30, 10)); + } else if (i == positions) { + axisFigure.setConstraint(lb, new Rectangle(18, + (int) (i * one_pos) - 10, 30, 10)); + } else { + axisFigure.setConstraint(lb, new Rectangle(18, + (int) (i * one_pos) - 5, 30, 10)); + } + + line = new RectangleFigure(); + line.setBackgroundColor(ColorConstants.black); + line.setOutline(false); + axisFigure.add(line); + + if (i == positions) { + axisFigure.setConstraint(line, new Rectangle(10, + (int) (i * one_pos) - 1, 10, 1)); + } else { + axisFigure.setConstraint(line, new Rectangle(10, + (int) (i * one_pos), 10, 1)); + } + + } + + fillPos = 60; + + } + + // Set right size of the fill figure + setConstraint(fillFigure, new Rectangle(fillPos, 0, rect.width + - fillPos, rect.height)); + + double tmp = one_pos * (positions - Double.valueOf(fill_height)); + int f_fill_height = (int) tmp; + fillRect.setSize(rect.width - fillPos, rect.height - f_fill_height); + fillFigure.setConstraint(fillRect, BorderLayout.BOTTOM); + fillFigure.repaint(); + + } + + public void setAlpha(int alpha) { + imageData.alpha = alpha; + if (layerImage != null && !layerImage.isDisposed()) { + layerImage.dispose(); + } + layerImage = new Image(null, imageData); + repaint(); + } + + public void paintFigure(Graphics g) { + Rectangle rectangle = getClientArea(); + g.drawImage(layerImage, new Rectangle(layerImage.getBounds()), + rectangle); + } + + public void setFillColor(RGB rgb) { + fillRect.setBackgroundColor(new Color(Display.getDefault(), rgb)); + } + + public void setFillHeight(Integer height) { + this.fill_height = height; + } + + public void setMaxPos(Integer maxPos) { + this.positions = maxPos; + } + + public void setInterval(Integer interval) { + this.show_pos = interval; + } + + public void setMeasure(Boolean bol) { + this.showMeasure = bol; + } + + public void setBackgroundColor(RGB rgb) { + imageData.palette.colors[0] = rgb; + if (layerImage != null && !layerImage.isDisposed()) { + layerImage.dispose(); + } + layerImage = new Image(null, imageData); + repaint(); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/CheckboxFigure.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/CheckboxFigure.java new file mode 100644 index 0000000000000000000000000000000000000000..7cdc32c23df9074f2f6de28ec765eb35004b2bc6 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/CheckboxFigure.java @@ -0,0 +1,45 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.figure; + +import org.eclipse.draw2d.FlowLayout; +import org.eclipse.draw2d.ImageFigure; +import org.eclipse.draw2d.Label; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Image; + +import de.bmotionstudio.gef.editor.BMotionStudioSWTConstants; + +public class CheckboxFigure extends AbstractBMotionFigure { + + private Label textLb; + + private ImageFigure checkBox; + + public CheckboxFigure() { + setLayoutManager(new FlowLayout(true)); + checkBox = new ImageFigure(); + add(checkBox); + textLb = new Label(); + textLb.setFont(BMotionStudioSWTConstants.fontArial10); + add(textLb); + } + + public void setImage(Image img) { + checkBox.setImage(img); + } + + public int setText(String text) { + textLb.setText(text); + return textLb.getPreferredSize().width; + } + + public void setTextColor(Color color) { + textLb.setForegroundColor(color); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/CompositeFigure.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/CompositeFigure.java new file mode 100644 index 0000000000000000000000000000000000000000..6f6414e7bf4ac385d707586ab4e6fb5e3fb31f14 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/CompositeFigure.java @@ -0,0 +1,145 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.figure; + +import org.eclipse.draw2d.ColorConstants; +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.XYLayout; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.PaletteData; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Display; + +public class CompositeFigure extends AbstractBMotionFigure { + + protected Image layerImage; + private ImageData imageData; + private Dimension size = new Dimension(); + private boolean hasImage; + + public CompositeFigure() { + XYLayout layout = new XYLayout(); + setLayoutManager(layout); + PaletteData palette = new PaletteData( + new RGB[] { ColorConstants.white.getRGB() }); + imageData = new ImageData(1, 1, 8, palette); + imageData.alpha = 255; + imageData.setPixel(0, 0, 0); + layerImage = new Image(Display.getDefault(), imageData); + hasImage = false; + setOpaque(true); + } + + // public void setAlpha(int alpha) { + // imageData.alpha = alpha; + // if (!hasImage) { + // if (layerImage != null && !layerImage.isDisposed()) { + // layerImage.dispose(); + // } + // layerImage = new Image(Display.getDefault(), imageData); + // repaint(); + // } + // } + + public void setBackgroundColor(RGB rgb) { + imageData.palette.colors[0] = rgb; + if (!hasImage) { + if (layerImage != null && !layerImage.isDisposed()) { + layerImage.dispose(); + } + layerImage = new Image(Display.getDefault(), imageData); + repaint(); + } + } + + public void paintFigure(Graphics g) { + if (getImage() == null) + return; + Rectangle rectangle = getClientArea(); + if (hasImage) { + int aWidth = rectangle.width; + int aHeight = rectangle.height; + int countX = aWidth / getImage().getBounds().width; + int countY = aHeight / getImage().getBounds().height; + for (int i = 0; i <= countX; i++) { + for (int z = 0; z <= countY; z++) { + g.drawImage(getImage(), getBounds().x + i + * getImage().getBounds().width, getBounds().y + z + * getImage().getBounds().height); + } + } + } else { + g.drawImage(getImage(), 0, 0, 1, 1, rectangle.x, rectangle.y, + rectangle.width, rectangle.height); + } + } + + /** + * Sets the Image that this ImageFigure displays. + * <p> + * IMPORTANT: Note that it is the client's responsibility to dispose the + * given image. + * + * @param image + * The Image to be displayed. It can be <code>null</code>. + */ + public void setImage(Image image) { + if (layerImage != null) + layerImage.dispose(); + layerImage = image; + if (layerImage != null) { + size = new Rectangle(image.getBounds()).getSize(); + hasImage = true; + } else { + layerImage = new Image(null, imageData); + size = new Dimension(); + hasImage = false; + } + revalidate(); + repaint(); + } + + /** + * @return The Image that this Figure displays + */ + public Image getImage() { + return layerImage; + } + + /** + * Calculates the necessary size to display the Image within the figure's + * client area. + * + * @see org.eclipse.draw2d.Figure#getPreferredSize(int, int) + */ + public Dimension getPreferredSize(int wHint, int hHint) { + if (getInsets() == NO_INSETS) + return size; + Insets i = getInsets(); + return size.getExpanded(i.getWidth(), i.getHeight()); + } + + public void setLayout(Rectangle rect) { + getParent().setConstraint(this, rect); + } + + /* + * (non-Javadoc) + * + * @see de.bmotionstudio.gef.editor.figure.IBMotionFigure#deactivateFigure() + */ + @Override + public void deactivateFigure() { + if (layerImage != null) + layerImage.dispose(); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/FixedConnectionAnchor.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/FixedConnectionAnchor.java new file mode 100644 index 0000000000000000000000000000000000000000..7c465787ccada9036fc1e91365c7fd1625e0accd --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/FixedConnectionAnchor.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package de.bmotionstudio.gef.editor.figure; + +import org.eclipse.draw2d.AbstractConnectionAnchor; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.ScalableFigure; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.PrecisionPoint; +import org.eclipse.draw2d.geometry.Rectangle; + +public class FixedConnectionAnchor extends AbstractConnectionAnchor { + + public boolean leftToRight = true; + public int offsetH; + public int offsetV; + public boolean topDown = false; + + public FixedConnectionAnchor(IFigure owner) { + super(owner); + } + + /** + * @see org.eclipse.draw2d.AbstractConnectionAnchor#ancestorMoved(IFigure) + */ + public void ancestorMoved(IFigure figure) { + if (figure instanceof ScalableFigure) + return; + super.ancestorMoved(figure); + } + + public Point getLocation(Point reference) { + + Rectangle r = getOwner().getBounds(); + int x, y; + if (topDown) + y = r.y + offsetV; + else + y = r.bottom() - offsetV; + + if (leftToRight) + x = r.x + offsetH; + else + x = r.right() - offsetH; + + Point p = new PrecisionPoint(x, y); + getOwner().translateToAbsolute(p); + return p; + + } + + public Point getReferencePoint() { + return getLocation(null); + } + + /** + * @param offsetH + * The offsetH to set. + */ + public void setOffsetH(int offsetH) { + this.offsetH = offsetH; + fireAnchorMoved(); + } + + /** + * @param offsetV + * The offsetV to set. + */ + public void setOffsetV(int offsetV) { + this.offsetV = offsetV; + fireAnchorMoved(); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + public boolean equals(Object o) { + if (o instanceof FixedConnectionAnchor) { + FixedConnectionAnchor fa = (FixedConnectionAnchor) o; + + if (fa.leftToRight == this.leftToRight + && fa.topDown == this.topDown && fa.offsetH == this.offsetH + && fa.offsetV == this.offsetV + && fa.getOwner() == this.getOwner()) { + return true; + } + } + + return false; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + return ((this.leftToRight ? 31 : 0) + (this.topDown ? 37 : 0) + + this.offsetH * 43 + this.offsetV * 47) + ^ this.getOwner().hashCode(); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/MouseClickAdapter.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/MouseClickAdapter.java new file mode 100644 index 0000000000000000000000000000000000000000..4a6cef59d6ea4ca65d77e78ebae5ab767210d048 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/MouseClickAdapter.java @@ -0,0 +1,45 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.figure; + +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +import de.bmotionstudio.gef.editor.AttributeConstants; +import de.bmotionstudio.gef.editor.model.BControl; + +public class MouseClickAdapter extends MouseAdapter { + + private BControl control; + + public MouseClickAdapter(BControl control) { + this.control = control; + } + + public void mousePressed(MouseEvent e) { + control.executeEvent(AttributeConstants.EVENT_MOUSECLICK); + } + + // TODO: change mouse cursor! + public void mouseEntered(MouseEvent e) { + if (control.getEvent(AttributeConstants.EVENT_MOUSECLICK) != null) { + if (control.getAttributeValue(AttributeConstants.ATTRIBUTE_ENABLED) != null) { + if (!Boolean.valueOf(control.getAttributeValue( + AttributeConstants.ATTRIBUTE_ENABLED).toString())) { + return; + } + } + } + } + + // TODO: change mouse cursor! + public void mouseExited(MouseEvent e) { + if (control.getEvent(AttributeConstants.EVENT_MOUSECLICK) != null) { + } + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/RadioButtonFigure.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/RadioButtonFigure.java new file mode 100644 index 0000000000000000000000000000000000000000..ebb81912b6139103cb0f3122e0a483af9711bf26 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/RadioButtonFigure.java @@ -0,0 +1,61 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.figure; + +import org.eclipse.draw2d.FlowLayout; +import org.eclipse.draw2d.ImageFigure; +import org.eclipse.draw2d.Label; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Display; + +import de.bmotionstudio.gef.editor.BMotionStudioSWTConstants; + +public class RadioButtonFigure extends AbstractBMotionFigure { + + private Label textLb; + private ImageFigure radioBt; + private Color foregroundColor; + + public RadioButtonFigure() { + setLayoutManager(new FlowLayout(true)); + radioBt = new ImageFigure(); + add(radioBt); + textLb = new Label(); + textLb.setFont(BMotionStudioSWTConstants.fontArial10); + add(textLb); + } + + public void setImage(Image img) { + radioBt.setImage(img); + } + + public int setText(String text) { + textLb.setText(text); + return textLb.getPreferredSize().width; + } + + public void setTextColor(RGB rgb) { + if (foregroundColor != null) + foregroundColor.dispose(); + foregroundColor = new Color(Display.getDefault(), rgb); + textLb.setForegroundColor(foregroundColor); + } + + /* + * (non-Javadoc) + * + * @see de.bmotionstudio.gef.editor.figure.IBMotionFigure#deactivateFigure() + */ + @Override + public void deactivateFigure() { + if (foregroundColor != null) + foregroundColor.dispose(); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/ShapeFigure.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/ShapeFigure.java new file mode 100644 index 0000000000000000000000000000000000000000..9986a37d507bb38569b09240da5809fc5e997c07 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/ShapeFigure.java @@ -0,0 +1,430 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.figure; + +import org.eclipse.draw2d.ColorConstants; +import org.eclipse.draw2d.Figure; +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.Orientable; +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.draw2d.Shape; +import org.eclipse.draw2d.StackLayout; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.PointList; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.PaletteData; +import org.eclipse.swt.graphics.Pattern; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Display; + +import de.bmotionstudio.gef.editor.BMotionEditorPlugin; + +public class ShapeFigure extends AbstractBMotionFigure { + + private int alpha; + private int outlineAlpha; + private int shape; + private Integer fillType; + private Image img; + private Color foregroundColor; + private Color backgroundColor; + + private Image patternImage; + private Image shadedImage; + private Pattern pattern; + private Pattern shadedPattern; + private Pattern gradientPattern; + + private final Color white = Display.getDefault().getSystemColor( + SWT.COLOR_WHITE); + + private static final int FILL_TYPE_FILLED = 0; + private static final int FILL_TYPE_EMPTY = 1; + private static final int FILL_TYPE_SHADED = 2; + private static final int FILL_TYPE_GRADIENT = 3; + + private static final int SHAPE_TYPE_RECTANGLE = 0; + private static final int SHAPE_TYPE_OVAL = 1; + private static final int SHAPE_TYPE_TRIANGLE = 2; + private static final int SHAPE_TYPE_DIAMOND = 3; + + /** + * The direction this triangle will face. Possible values are + * {@link PositionConstants#NORTH}, {@link PositionConstants#SOUTH}, + * {@link PositionConstants#EAST} and {@link PositionConstants#WEST}. + */ + protected int direction = PositionConstants.NORTH; + /** + * The orientation of this triangle. Possible values are + * {@link Orientable#VERTICAL} and {@link Orientable#HORIZONTAL}. + */ + protected int orientation = PositionConstants.VERTICAL; + + /** The points of the triangle. */ + protected PointList triangle = new PointList(3); + + /** The points of the diamond. */ + protected PointList diamond = new PointList(4); + + private Shape shapeFigure; + + public ShapeFigure() { + setLayoutManager(new StackLayout()); + shapeFigure = new Shape() { + + @Override + protected void fillShape(Graphics g) { + + g.setAlpha(alpha); + g.setAntialias(SWT.ON); + + if (fillType == FILL_TYPE_GRADIENT) { // Gradient fill type + + if (gradientPattern != null) + gradientPattern.dispose(); + gradientPattern = new Pattern(Display.getDefault(), + this.getBounds().x, this.getBounds().y, + this.getBounds().x + this.getBounds().width, + this.getBounds().y + this.getBounds().height, + this.getBackgroundColor(), + this.getForegroundColor()); + g.setBackgroundPattern(gradientPattern); + + } else if (fillType == FILL_TYPE_SHADED) { // Shaded fill type + + Color black = this.getForegroundColor(); + PaletteData palette = new PaletteData(new RGB[] { + white.getRGB(), black.getRGB() }); + ImageData sourceData = new ImageData(11, 11, 1, palette); + for (int i = 0; i < 11; i++) { + sourceData.setPixel(6, i, 1); + } + if (shadedImage != null) + shadedImage.dispose(); + shadedImage = new Image(Display.getDefault(), sourceData); + + if (shadedPattern != null) + shadedPattern.dispose(); + shadedPattern = new Pattern(Display.getDefault(), + shadedImage); + g.setBackgroundPattern(shadedPattern); + + } else if (fillType == FILL_TYPE_FILLED && img != null) { + + double zoom = 1; + if (BMotionEditorPlugin.getActiveEditor() != null) + zoom = BMotionEditorPlugin.getActiveEditor() + .getZoomFactor(); + + ImageData d = img.getImageData().scaledTo( + (int) (img.getBounds().width * zoom), + (int) (img.getBounds().height * zoom)); + + if (patternImage != null) + patternImage.dispose(); + + patternImage = new Image(Display.getDefault(), d); + + if (pattern != null) + pattern.dispose(); + + pattern = new Pattern(Display.getDefault(), patternImage); + + g.setBackgroundPattern(pattern); + + } else if (fillType == FILL_TYPE_FILLED) { + g.setBackgroundColor(this.getBackgroundColor()); + } + + switch (shape) { + case SHAPE_TYPE_RECTANGLE: + g.fillRectangle(this.getBounds()); + break; + case SHAPE_TYPE_OVAL: + g.fillOval(this.getBounds()); + break; + case SHAPE_TYPE_TRIANGLE: + g.fillPolygon(triangle); + break; + case SHAPE_TYPE_DIAMOND: + g.fillPolygon(diamond); + break; + default: + break; + } + + } + + @Override + protected void outlineShape(Graphics g) { + + g.setAlpha(outlineAlpha); + g.setAntialias(SWT.ON); + g.setForegroundColor(this.getForegroundColor()); + + float lineInset = Math.max(1.0f, getLineWidthFloat()) / 2.0f; + int inset1 = (int) Math.floor(lineInset); + int inset2 = (int) Math.ceil(lineInset); + + Rectangle r = Rectangle.SINGLETON.setBounds(this.getBounds()); + r.x += inset1; + r.y += inset1; + r.width -= inset1 + inset2; + r.height -= inset1 + inset2; + + switch (shape) { + case SHAPE_TYPE_RECTANGLE: + g.drawRectangle(r); + break; + case SHAPE_TYPE_OVAL: + g.drawOval(r); + break; + case SHAPE_TYPE_TRIANGLE: + g.drawPolygon(triangle); + break; + case SHAPE_TYPE_DIAMOND: + g.drawPolygon(diamond); + break; + default: + break; + } + + } + + }; + shapeFigure.setForegroundColor(ColorConstants.blue); + // setOpaque(true); + add(shapeFigure); + } + + /** + * @see Orientable#setDirection(int) + */ + public void setDirection(int value) { + if ((value & (PositionConstants.NORTH | PositionConstants.SOUTH)) != 0) + orientation = PositionConstants.VERTICAL; + else + orientation = PositionConstants.HORIZONTAL; + direction = value; + revalidate(); + repaint(); + } + + /** + * @see Orientable#setOrientation(int) + */ + public void setOrientation(int value) { + if (orientation == PositionConstants.VERTICAL + && value == PositionConstants.HORIZONTAL) { + if (direction == PositionConstants.NORTH) + setDirection(PositionConstants.WEST); + else + setDirection(PositionConstants.EAST); + } + if (orientation == PositionConstants.HORIZONTAL + && value == PositionConstants.VERTICAL) { + if (direction == PositionConstants.WEST) + setDirection(PositionConstants.NORTH); + else + setDirection(PositionConstants.SOUTH); + } + } + + /** + * @see IFigure#validate() + */ + public void validate() { + + super.validate(); + + Rectangle r = new Rectangle(); + r.setBounds(getBounds()); + r.crop(getInsets()); + r.resize(-1, -1); + + switch (shape) { + + case SHAPE_TYPE_TRIANGLE: + + int size; + switch (direction + & (PositionConstants.NORTH | PositionConstants.SOUTH)) { + case 0: // East or west. + size = Math.min(r.height / 2, r.width); + r.x += (r.width - size) / 2; + break; + default: // North or south + size = Math.min(r.height, r.width / 2); + r.y += (r.height - size) / 2; + break; + } + + size = Math.max(size, 1); // Size cannot be negative + + Point head, + p2, + p3; + + switch (direction) { + case PositionConstants.NORTH: + head = new Point(r.x + r.width / 2, r.y); + p2 = new Point(head.x - size, head.y + size); + p3 = new Point(head.x + size, head.y + size); + break; + case PositionConstants.SOUTH: + head = new Point(r.x + r.width / 2, r.y + size); + p2 = new Point(head.x - size, head.y - size); + p3 = new Point(head.x + size, head.y - size); + break; + case PositionConstants.WEST: + head = new Point(r.x, r.y + r.height / 2); + p2 = new Point(head.x + size, head.y - size); + p3 = new Point(head.x + size, head.y + size); + break; + default: + head = new Point(r.x + size, r.y + r.height / 2); + p2 = new Point(head.x - size, head.y - size); + p3 = new Point(head.x - size, head.y + size); + + } + triangle.removeAllPoints(); + triangle.addPoint(head); + triangle.addPoint(p2); + triangle.addPoint(p3); + + break; + + case SHAPE_TYPE_DIAMOND: + + Point pt1 = new Point(r.x + r.width / 2, r.y); + Point pt2 = new Point(r.x + r.width, r.y + r.height / 2); + Point pt3 = new Point(r.x + r.width / 2, r.y + r.height); + Point pt4 = new Point(r.x, r.y + r.height / 2); + + diamond.removeAllPoints(); + diamond.addPoint(pt1); + diamond.addPoint(pt2); + diamond.addPoint(pt3); + diamond.addPoint(pt4); + + break; + + default: + break; + } + + } + + /** + * @see Figure#primTranslate(int, int) + */ + public void primTranslate(int dx, int dy) { + super.primTranslate(dx, dy); + switch (shape) { + case SHAPE_TYPE_TRIANGLE: + triangle.translate(dx, dy); + break; + case SHAPE_TYPE_DIAMOND: + diamond.translate(dx, dy); + break; + default: + break; + } + } + + public void setBackgroundColor(RGB rgb) { + if (backgroundColor != null) + backgroundColor.dispose(); + backgroundColor = new Color(Display.getDefault(), rgb); + shapeFigure.setBackgroundColor(backgroundColor); + } + + public void setForegroundColor(RGB rgb) { + if (foregroundColor != null) + foregroundColor.dispose(); + foregroundColor = new Color(Display.getDefault(), rgb); + shapeFigure.setForegroundColor(foregroundColor); + shapeFigure.repaint(); + } + + public void setLayout(Rectangle rect) { + getParent().setConstraint(this, rect); + } + + public void setShape(int shape) { + this.shape = shape; + revalidate(); + shapeFigure.repaint(); + } + + public int getShape() { + return shape; + } + + public Integer getAlpha() { + return alpha; + } + + public void setAlpha(Integer alpha) { + this.alpha = alpha; + repaint(); + } + + public Integer getOutlineAlpha() { + return outlineAlpha; + } + + public void setOutlineAlpha(Integer outlineAlpha) { + this.outlineAlpha = outlineAlpha; + repaint(); + } + + public void setFillType(Integer fillType) { + if (fillType == FILL_TYPE_EMPTY) + shapeFigure.setFill(false); + else + shapeFigure.setFill(true); + this.fillType = fillType; + repaint(); + } + + public void setImage(Image img) { + this.img = img; + repaint(); + } + + /* + * (non-Javadoc) + * + * @see de.bmotionstudio.gef.editor.figure.IBMotionFigure#deactivateFigure() + */ + @Override + public void deactivateFigure() { + if (img != null) + img.dispose(); + if (foregroundColor != null) + foregroundColor.dispose(); + if (backgroundColor != null) + backgroundColor.dispose(); + if (patternImage != null) + patternImage.dispose(); + if (shadedImage != null) + shadedImage.dispose(); + if (pattern != null) + pattern.dispose(); + if (shadedPattern != null) + shadedPattern.dispose(); + if (gradientPattern != null) + gradientPattern.dispose(); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/TextFigure.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/TextFigure.java new file mode 100644 index 0000000000000000000000000000000000000000..0c8a51e21e6ab99ff2037ad9bc5b8a33d9466edb --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/TextFigure.java @@ -0,0 +1,101 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.figure; + +import org.eclipse.draw2d.MarginBorder; +import org.eclipse.draw2d.StackLayout; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.draw2d.text.FlowPage; +import org.eclipse.draw2d.text.ParagraphTextLayout; +import org.eclipse.draw2d.text.TextFlow; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Display; + +public class TextFigure extends AbstractBMotionFigure { + + private TextFlow textFlow; + protected Image layerImage; + private Color foregroundColor; + private Font font; + + public TextFigure() { + setBorder(new MarginBorder(1)); + FlowPage flowPage = new FlowPage(); + textFlow = new TextFlow(); + textFlow.setLayoutManager(new ParagraphTextLayout(textFlow, + ParagraphTextLayout.WORD_WRAP_SOFT)); + flowPage.add(textFlow); + setLayoutManager(new StackLayout()); + add(flowPage); + } + + /** + * Returns the text inside the TextFlow. + * + * @return the text flow inside the text. + */ + public String getText() { + return textFlow.getText(); + } + + /** + * Sets the text of the TextFlow to the given value. + * + * @param newText + * the new text value. + */ + public void setText(String newText) { + textFlow.setText(newText); + } + + public void setTextColor(RGB rgb) { + if (foregroundColor != null) + foregroundColor.dispose(); + foregroundColor = new Color(Display.getDefault(), rgb); + textFlow.setForegroundColor(foregroundColor); + } + + public void setBackgroundVisible(Boolean bol) { + setOpaque(bol); + } + + public void setFont(String fontData) { + if (font != null) + font.dispose(); + font = new Font(Display.getDefault(), new FontData(fontData)); + textFlow.setFont(font); + } + + // TODO: CHECK STACK OVERFLOW ERROR!!!! + public Font getFont() { + return textFlow.getFont(); + } + + public void setLayout(Rectangle rect) { + getParent().setConstraint(this, rect); + } + + /* + * (non-Javadoc) + * + * @see de.bmotionstudio.gef.editor.figure.IBMotionFigure#deactivateFigure() + */ + @Override + public void deactivateFigure() { + if (foregroundColor != null) + foregroundColor.dispose(); + if (font != null) + font.dispose(); + if (layerImage != null) + layerImage.dispose(); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/TextfieldFigure.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/TextfieldFigure.java new file mode 100644 index 0000000000000000000000000000000000000000..b2d80ff7ff4bad18fff6fd1e42677d269a79cf7e --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/TextfieldFigure.java @@ -0,0 +1,63 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.figure; + +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.GridLayout; +import org.eclipse.draw2d.Label; +import org.eclipse.draw2d.LineBorder; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.widgets.Display; + +public class TextfieldFigure extends AbstractBMotionFigure { + + private Label lb; + private Color foregroundColor; + + public TextfieldFigure() { + GridLayout fl = new GridLayout(); + fl.marginHeight = 2; + fl.marginWidth = 3; + setLayoutManager(fl); + foregroundColor = new Color(Display.getDefault(), 171, 173, 179); + setBorder(new LineBorder( + new Color(Display.getDefault(), 226, 227, 234), 1)); + this.lb = new Label(); + add(lb); + setOpaque(true); + } + + @Override + public void paint(Graphics g) { + super.paint(g); + Rectangle r = Rectangle.SINGLETON; + r.setBounds(getBounds()); + g.setForegroundColor(foregroundColor); + g.drawLine(r.getTopLeft(), r.getTopRight()); + } + + public void setText(String text) { + lb.setText(text); + } + + public String getText() { + return lb.getText(); + } + + /* + * (non-Javadoc) + * + * @see de.bmotionstudio.gef.editor.figure.IBMotionFigure#deactivateFigure() + */ + @Override + public void deactivateFigure() { + if (foregroundColor != null) + foregroundColor.dispose(); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/UnknownBControl.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/UnknownBControl.java new file mode 100644 index 0000000000000000000000000000000000000000..120245cdb9b4ea6238a642da5cc35abdc2235c70 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/UnknownBControl.java @@ -0,0 +1,47 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.figure; + +import org.eclipse.draw2d.ColorConstants; +import org.eclipse.draw2d.MarginBorder; +import org.eclipse.draw2d.StackLayout; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.draw2d.text.FlowPage; +import org.eclipse.draw2d.text.ParagraphTextLayout; +import org.eclipse.draw2d.text.TextFlow; + +public class UnknownBControl extends AbstractBMotionFigure { + + public static String ID = "de.bmotionstudio.gef.editor.unknown"; + + private final TextFlow textFlow; + + public UnknownBControl() { + setBorder(new MarginBorder(1)); + FlowPage flowPage = new FlowPage(); + textFlow = new TextFlow(); + textFlow.setLayoutManager(new ParagraphTextLayout(textFlow, + ParagraphTextLayout.WORD_WRAP_SOFT)); + flowPage.add(textFlow); + setLayoutManager(new StackLayout()); + add(flowPage); + setBackgroundColor(ColorConstants.red); + setOpaque(true); + } + + public void prepareForEditing() { + } + + public void setMessage(final String type) { + textFlow.setText("Unknown part: " + type); + } + + public void setLayout(final Rectangle rect) { + + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/VisualizationFigure.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/VisualizationFigure.java new file mode 100644 index 0000000000000000000000000000000000000000..1e500bd187ed3d160bc07115b5fb3b22da3724f9 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/figure/VisualizationFigure.java @@ -0,0 +1,33 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.figure; + +import org.eclipse.draw2d.FreeformLayer; +import org.eclipse.draw2d.FreeformLayout; +import org.eclipse.draw2d.LayoutAnimator; +import org.eclipse.draw2d.LayoutListener; +import org.eclipse.draw2d.MarginBorder; +import org.eclipse.draw2d.geometry.Rectangle; + +public class VisualizationFigure extends FreeformLayer { + + private LayoutListener layoutListener = LayoutAnimator.getDefault(); + + public VisualizationFigure() { + setLayoutManager(new FreeformLayout()); + setBorder(new MarginBorder(5)); + addLayoutListener(layoutListener); + } + + public void prepareForEditing() { + removeLayoutListener(layoutListener); + } + + public void setLayout(Rectangle rect) { + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/Animation.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/Animation.java new file mode 100644 index 0000000000000000000000000000000000000000..da2590dc5a6b150f915d52302edc40eb1d54f1d6 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/Animation.java @@ -0,0 +1,160 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.internal; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.swt.widgets.Display; + +import de.bmotionstudio.gef.editor.animation.StaticListenerRegistry; +import de.bmotionstudio.gef.editor.model.Visualization; +import de.prob.core.Animator; +import de.prob.core.IAnimationListener; +import de.prob.core.command.EvaluationGetValuesCommand; +import de.prob.core.command.EvaluationInsertFormulaCommand; +import de.prob.core.command.EvaluationInsertFormulaCommand.FormulaType; +import de.prob.core.domainobjects.EvaluationElement; +import de.prob.core.domainobjects.Operation; +import de.prob.core.domainobjects.State; +import de.prob.exceptions.ProBException; +import de.prob.parserbase.ProBParseException; + +public class Animation implements IAnimationListener { + + private Animator animator; + + private final Map<String, Operation> currentStateOperations; + + private final Map<String, EvaluationElement> cachedEvalElements = new HashMap<String, EvaluationElement>(); + + private State currentState; + + private Visualization visualization; + + private Boolean observerCallBack = true; + + public Animation(Animator anim, Visualization visualization) { + StaticListenerRegistry.registerListener((IAnimationListener) this); + this.currentStateOperations = new HashMap<String, Operation>(); + this.animator = anim; + this.visualization = visualization; + this.visualization.setAnimation(this); + } + + private void setNewState(State state) { + currentState = state; + currentStateOperations.clear(); + for (Operation op : state.getEnabledOperations()) { + this.currentStateOperations.put(op.getName(), op); + } + } + + @Override + public void currentStateChanged(State currentState, Operation operation) { + // set new state and remember old state, if possible + setNewState(currentState); + updateCachedExpressions(currentState); + if (currentState.isInitialized()) { + + if (animator == null) { + animator = Animator.getAnimator(); + } + + checkObserver(); + + } + + } + + /** + * Get values for all used expressions. This should speed up the + * communication between ProB's core and Java. The result is not used, just + * to fill the caches. + * + * @param currentState + */ + private void updateCachedExpressions(State currentState) { + try { + EvaluationGetValuesCommand.getValuesForExpressionsCached( + currentState, cachedEvalElements.values()); + } catch (ProBException e) { + // TODO Log this + } + } + + public void checkObserver() { + if (visualization.isRunning()) { + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + visualization.checkObserver(Animation.this); + visualization.afterCheckObserver(Animation.this); + } + }); + } + } + + // public boolean checkObserverCallBack() { + // return visualization.checkObserverCallBack(); + // } + + public State getState() { + return currentState; + } + + public Animator getAnimator() { + return animator; + } + + public Operation getCurrentStateOperation(String operation) { + return currentStateOperations.get(operation); + } + + public Visualization getVisualization() { + return this.visualization; + } + + public void unregister() { + StaticListenerRegistry.unregisterListener((IAnimationListener) this); + } + + public void setObserverCallBack(Boolean observerCallBack) { + this.observerCallBack = observerCallBack; + } + + public boolean isObserverCallBack() { + return observerCallBack; + } + + public EvaluationElement getCachedEvalElement(String expressionStr, + boolean isPredicate) throws UnsupportedOperationException, + ProBException, ProBParseException { + final EvaluationElement evalElement; + if (cachedEvalElements.containsKey(expressionStr)) { + evalElement = cachedEvalElements.get(expressionStr); + } else { + // TODO: exception handling ... + evalElement = createPredicateExpressionElement(expressionStr, + isPredicate); + cachedEvalElements.put(expressionStr, evalElement); + } + return evalElement; + } + + private EvaluationElement createPredicateExpressionElement( + String expressionStr, boolean isPredicate) + throws UnsupportedOperationException, ProBException, + ProBParseException { + final EvaluationInsertFormulaCommand.FormulaType type = isPredicate ? FormulaType.PREDICATE + : FormulaType.EXPRESSION; + final EvaluationElement evaluationElement = EvaluationInsertFormulaCommand + .insertFormula(animator, type, expressionStr); + return evaluationElement; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/BControlListConverter.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/BControlListConverter.java new file mode 100644 index 0000000000000000000000000000000000000000..44f40543b95a639d01d1e4114524f865dd16773b --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/BControlListConverter.java @@ -0,0 +1,56 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.internal; + +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; + +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.model.BControlList; + +public class BControlListConverter implements Converter { + + @Override + public boolean canConvert(Class clazz) { + if (clazz == BControlList.class) + return true; + return false; + } + + @Override + public void marshal(Object obj, HierarchicalStreamWriter writer, + MarshallingContext context) { + BControlList list = (BControlList) obj; + for (BControl control : list) { + writer.startNode(control.getClass().getName()); + context.convertAnother(control); + writer.endNode(); + } + } + + @Override + public Object unmarshal(HierarchicalStreamReader reader, + UnmarshallingContext context) { + BControlList list = new BControlList(); + while (reader.hasMoreChildren()) { + reader.moveDown(); + try { + BControl c = (BControl) context.convertAnother(list, + Class.forName(reader.getNodeName())); + list.add(c); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + reader.moveUp(); + } + return list; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/BControlPropertySource.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/BControlPropertySource.java new file mode 100644 index 0000000000000000000000000000000000000000..17f1924250af878c695bb46dbe39d443bc28f249 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/BControlPropertySource.java @@ -0,0 +1,70 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.internal; + +import org.eclipse.ui.views.properties.PropertyDescriptor; + +import de.bmotionstudio.gef.editor.attribute.AbstractAttribute; +import de.bmotionstudio.gef.editor.attribute.BAttributeMisc; +import de.bmotionstudio.gef.editor.model.BControl; + +public class BControlPropertySource extends AbstractAttribute { + + private BControl control; + + private BAttributeMisc miscAttribute; + + public BControlPropertySource(BControl control) { + super(null); + this.control = control; + this.miscAttribute = new BAttributeMisc(null); + addChild(this.miscAttribute); + init(); + } + + private void init() { + + for (AbstractAttribute atr : control.getAttributes().values()) { + + atr.setControl(control); + + String group = atr.getGroup(); + + if (group != null) { + + // If group is root node --> add to root + if (group.equals(ROOT)) { + addChild(atr); + } else { + AbstractAttribute groupAtr = control.getAttribute(group); + if (groupAtr != null) { + groupAtr.addChild(atr); + } else { + miscAttribute.addChild(atr); + } + } + + } else { + // No group, add to misc attribute node + miscAttribute.addChild(atr); + } + + } + + } + + @Override + protected PropertyDescriptor preparePropertyDescriptor() { + return null; + } + + @Override + public String getName() { + return "RootProperties"; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/BControlTemplate.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/BControlTemplate.java new file mode 100644 index 0000000000000000000000000000000000000000..5e882b32101d0967748a6862a18f26371e46b002 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/BControlTemplate.java @@ -0,0 +1,21 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.internal; + +public class BControlTemplate { + + private String type; + + public BControlTemplate(String type) { + this.type = type; + } + + public String getType() { + return type; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/BControlTransferDropTargetListener.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/BControlTransferDropTargetListener.java new file mode 100644 index 0000000000000000000000000000000000000000..ef02d27d109ba3895bf37b5c91e2ca737fe50b27 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/BControlTransferDropTargetListener.java @@ -0,0 +1,53 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.internal; + +import org.eclipse.gef.EditPartViewer; +import org.eclipse.gef.dnd.TemplateTransferDropTargetListener; +import org.eclipse.gef.requests.CreationFactory; + +import de.bmotionstudio.gef.editor.BControlCreationFactory; +import de.bmotionstudio.gef.editor.model.Visualization; + +public class BControlTransferDropTargetListener extends + TemplateTransferDropTargetListener { + + private CreationFactory factory = null; + private BControlTemplate currentTempl; + private Visualization visualization; + + public BControlTransferDropTargetListener(EditPartViewer viewer, + Visualization visualization) { + super(viewer); + this.visualization = visualization; + } + + @Override + protected CreationFactory getFactory(Object template) { + + if (template != null) { + + if (template instanceof BControlTemplate) { + + BControlTemplate templ = (BControlTemplate) template; + + if (factory == null + || !templ.getType().equals(currentTempl.getType())) { + factory = new BControlCreationFactory(templ.getType(), + visualization); + currentTempl = templ; + } + + } + + } + + return factory; + + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/BMSConverter512.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/BMSConverter512.java new file mode 100644 index 0000000000000000000000000000000000000000..518b6961c6208988ce9d9258b16eb0ae20301b9c --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/BMSConverter512.java @@ -0,0 +1,322 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.internal; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.util.List; +import java.util.Map; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.TransformerFactoryConfigurationError; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.mapper.MapperWrapper; + +import de.bmotionstudio.gef.editor.BMotionEditorPlugin; +import de.bmotionstudio.gef.editor.IBControlService; +import de.bmotionstudio.gef.editor.attribute.AbstractAttribute; +import de.bmotionstudio.gef.editor.model.BConnection; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.model.BControlList; +import de.bmotionstudio.gef.editor.model.BMotionGuide; +import de.bmotionstudio.gef.editor.model.Visualization; +import de.bmotionstudio.gef.editor.observer.Observer; +import de.bmotionstudio.gef.editor.scheduler.SchedulerEvent; + +public class BMSConverter512 { + + private IFile file; + + public BMSConverter512(IFile file) { + this.file = file; + try { + convert(); + } catch (TransformerConfigurationException e) { + e.printStackTrace(); + } catch (CoreException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (ParserConfigurationException e) { + e.printStackTrace(); + } catch (SAXException e) { + e.printStackTrace(); + } catch (TransformerException e) { + e.printStackTrace(); + } catch (TransformerFactoryConfigurationError e) { + e.printStackTrace(); + } + } + + private void convert() throws CoreException, IOException, + ParserConfigurationException, SAXException, + TransformerConfigurationException, TransformerException, + TransformerFactoryConfigurationError { + + InputStream inputStream = file.getContents(); + + ByteArrayInputStream byteArrayInputStream = null; + + String str = inputStreamToString(inputStream); + + str = str.replace("de.bmotionstudio.gef.basic", + "de.bmotionstudio.gef.editor"); + str = str.replace("de.bmotionstudio.gef.core", + "de.bmotionstudio.gef.editor"); + + str = str.replace("de.bmotionstudio.gef.editor.model.BControl", + "control"); + str = str.replace("de.bmotionstudio.gef.editor.model.BMotionGuide", + "guide"); + str = str.replace("de.bmotionstudio.gef.editor.Visualization", + "visualization"); + str = str.replace("de.bmotionstudio.gef.editor.model.Visualization", + "visualization"); + str = str.replace("de.bmotionstudio.gef.editor.model.BConnection", + "connection"); + + str = str.replace("de.bmotionstudio.gef.editor.rectangle", + "de.bmotionstudio.gef.editor.shape"); + + str = str.replace( + "de.bmotionstudio.gef.editor.observer.ToggleCoordinates", + "de.bmotionstudio.gef.editor.observer.SwitchCoordinates"); + str = str.replace("de.bmotionstudio.gef.editor.observer.ToggleImage", + "de.bmotionstudio.gef.editor.observer.SwitchImage"); + str = str.replace("de.bmotionstudio.gef.editor.observer.ToggleImage", + "de.bmotionstudio.gef.editor.observer.SwitchImage"); + str = str.replace( + "de.bmotionstudio.gef.editor.observer.ToggleChildCoordinates", + "de.bmotionstudio.gef.editor.observer.SwitchChildCoordinates"); + + byteArrayInputStream = new ByteArrayInputStream(str.getBytes()); + + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + Document doc = dBuilder.parse(byteArrayInputStream); + + NodeList nList = doc.getElementsByTagName("type"); + for (int temp = 0; temp < nList.getLength(); temp++) { + + Node nNode = nList.item(temp); + + if (nNode.getParentNode().getNodeName().equals("control")) { + Element parent = (Element) nNode.getParentNode(); + parent.setAttribute("type", nNode.getTextContent()); + } + + } + + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + Source xmlSource = new DOMSource(doc); + Result outputTarget = new StreamResult(outputStream); + TransformerFactory.newInstance().newTransformer() + .transform(xmlSource, outputTarget); + byteArrayInputStream = new ByteArrayInputStream( + outputStream.toByteArray()); + + XStream xstream = new XStream() { + @Override + protected MapperWrapper wrapMapper(final MapperWrapper next) { + return new MapperWrapper(next) { + @Override + public boolean shouldSerializeMember( + @SuppressWarnings("rawtypes") final Class definedIn, + final String fieldName) { + if (definedIn == Object.class) + return false; + return super + .shouldSerializeMember(definedIn, fieldName); + } + }; + } + }; + + xstream.registerConverter(new Converter() { + + @Override + public boolean canConvert(Class clazz) { + if (clazz == BControlList.class) + return true; + return false; + } + + @Override + public void marshal(Object obj, HierarchicalStreamWriter writer, + MarshallingContext context) { + BControlList list = (BControlList) obj; + for (BControl control : list) { + writer.startNode(control.getClass().getName()); + context.convertAnother(control); + writer.endNode(); + } + } + + @Override + public Object unmarshal(HierarchicalStreamReader reader, + UnmarshallingContext context) { + BControlList list = new BControlList(); + while (reader.hasMoreChildren()) { + reader.moveDown(); + list.add((BControl) context.convertAnother(list, + BControl.class)); + reader.moveUp(); + } + return list; + } + }); + xstream.registerConverter(new Converter() { + + @Override + public boolean canConvert(Class clazz) { + if (clazz == BControl.class) + return true; + return false; + } + + @Override + public void marshal(Object obj, HierarchicalStreamWriter writer, + MarshallingContext context) { + BControl c = (BControl) obj; + writer.startNode(c.getClass().getName()); + context.convertAnother(c); + writer.endNode(); + } + + @Override + public Object unmarshal(HierarchicalStreamReader reader, + UnmarshallingContext context) { + + String type = reader.getAttribute("type"); + + BControl c = null; + + IConfigurationElement controlExtension = BMotionEditorPlugin + .getControlExtension(type); + if (controlExtension != null) { + try { + IBControlService service = (IBControlService) controlExtension + .createExecutableExtension("service"); + c = service.createControl(null); + } catch (CoreException e) { + e.printStackTrace(); + } + + } + + if (c != null) { + + while (reader.hasMoreChildren()) { + + reader.moveDown(); + + if ("children".equals(reader.getNodeName())) { + c.setChildrenArray((BControlList) context + .convertAnother(c, BControlList.class)); + } else if ("observers".equals(reader.getNodeName())) { + c.setObserverMap((Map<String, Observer>) context + .convertAnother(c, Map.class)); + } else if ("events".equals(reader.getNodeName())) { + c.setEventMap((Map<String, SchedulerEvent>) (context + .convertAnother(c, Map.class))); + } else if ("attributes".equals(reader.getNodeName())) { + Map<String, AbstractAttribute> attributes = (Map<String, AbstractAttribute>) context + .convertAnother(c, Map.class); + for (AbstractAttribute atr : attributes.values()) { + atr.setEditable(true); + atr.setShow(true); + } + c.setAttributes(attributes); + } else if ("verticalGuide".equals(reader.getNodeName())) { + c.setVerticalGuide((BMotionGuide) context + .convertAnother(c, BMotionGuide.class)); + } else if ("horizontalGuide".equals(reader + .getNodeName())) { + c.setVerticalGuide((BMotionGuide) context + .convertAnother(c, BMotionGuide.class)); + } else if ("sourceConnections".equals(reader + .getNodeName())) { + c.setHorizontalGuide((BMotionGuide) context + .convertAnother(c, BMotionGuide.class)); + } else if ("targetConnections".equals(reader + .getNodeName())) { + c.setTargetConnections((List<BConnection>) context + .convertAnother(c, List.class)); + } + + reader.moveUp(); + + } + + } + + return c; + + } + + }); + xstream.useAttributeFor(BControl.class, "type"); + xstream.alias("control", BControl.class); + xstream.alias("visualization", Visualization.class); + xstream.alias("guide", BMotionGuide.class); + xstream.alias("connection", BConnection.class); + xstream.alias("children", BControlList.class); + + Visualization visualization = (Visualization) xstream + .fromXML(byteArrayInputStream); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + OutputStreamWriter writer = new OutputStreamWriter(out, "UTF8"); + visualization.setVersion("5.2.0"); + xstream.toXML(visualization, writer); + file.setContents(new ByteArrayInputStream(out.toByteArray()), false, + false, null); + + } + + private static String inputStreamToString(InputStream in) + throws IOException { + BufferedReader bufferedReader = new BufferedReader( + new InputStreamReader(in)); + StringBuilder stringBuilder = new StringBuilder(); + String line = null; + while ((line = bufferedReader.readLine()) != null) { + stringBuilder.append(line + "\n"); + } + bufferedReader.close(); + return stringBuilder.toString(); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/BMotionFileInputValidator.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/BMotionFileInputValidator.java new file mode 100644 index 0000000000000000000000000000000000000000..96b89c750ada14851095e6b2f4eeac89276e1a5b --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/BMotionFileInputValidator.java @@ -0,0 +1,31 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.internal; + +import org.eclipse.jface.dialogs.IInputValidator; +import org.rodinp.core.IRodinFile; +import org.rodinp.core.IRodinProject; + +import de.bmotionstudio.gef.editor.BMotionEditorPlugin; + +public class BMotionFileInputValidator implements IInputValidator { + + private IRodinProject prj; + + public BMotionFileInputValidator(IRodinProject prj) { + this.prj = prj; + } + + public String isValid(String newText) { + IRodinFile rodinFile = prj.getRodinFile(newText + "." + + BMotionEditorPlugin.FILEEXT_STUDIO); + if (rodinFile != null && rodinFile.exists()) + return "The BMotion-Project filename must be unique in a project."; + return null; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/NewBMotionProjectAction.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/NewBMotionProjectAction.java new file mode 100644 index 0000000000000000000000000000000000000000..8144c6734f46d6372a9d5bbd4903a65706899450 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/NewBMotionProjectAction.java @@ -0,0 +1,78 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.internal; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.ui.IActionDelegate; +import org.eclipse.ui.IObjectActionDelegate; +import org.eclipse.ui.IWorkbenchPart; +import org.rodinp.core.IRodinProject; + +import de.bmotionstudio.gef.editor.BMotionEditorPlugin; + +@Deprecated +public class NewBMotionProjectAction implements IObjectActionDelegate { + + // private IWorkbenchPart targetPart; + private IStructuredSelection currentSelection; + private IRodinProject rodinProject; + + public NewBMotionProjectAction() { + super(); + } + + /** + * @see IObjectActionDelegate#setActivePart(IAction, IWorkbenchPart) + */ + public void setActivePart(final IAction action, + final IWorkbenchPart targetPart) { + // this.targetPart = targetPart; + } + + /** + * @see IActionDelegate#run(IAction) + */ + public void run(IAction action) { + + if (rodinProject == null) { + return; + } + + NewBMotionProjectWizard wizard = new NewBMotionProjectWizard(); + wizard.init(BMotionEditorPlugin.getDefault().getWorkbench(), + currentSelection); + WizardDialog dialog = new WizardDialog(BMotionEditorPlugin + .getActiveEditor().getSite().getShell(), wizard); + dialog.create(); + dialog.open(); + + } + + /** + * @see IActionDelegate#selectionChanged(IAction, ISelection) + */ + public void selectionChanged(IAction action, ISelection selection) { + + if (selection instanceof IStructuredSelection) { + IStructuredSelection ssel = (IStructuredSelection) selection; + currentSelection = ssel; + if (ssel.size() == 1) { + Object firstElement = ssel.getFirstElement(); + if (firstElement instanceof IRodinProject) { + rodinProject = (IRodinProject) firstElement; + return; + } + } + } + rodinProject = null; + + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/NewBMotionProjectWizard.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/NewBMotionProjectWizard.java new file mode 100644 index 0000000000000000000000000000000000000000..c43736ade824237727c41f35825e477f76d8c0b6 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/NewBMotionProjectWizard.java @@ -0,0 +1,140 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.internal; + +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.lang.reflect.InvocationTargetException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.IWorkspaceRunnable; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.ui.INewWizard; +import org.eclipse.ui.IWorkbench; +import org.rodinp.core.RodinCore; + +import de.bmotionstudio.gef.editor.BMotionEditorPlugin; + +public class NewBMotionProjectWizard extends Wizard implements INewWizard { + + // The wizard page. + private NewBMotionProjectWizardPage page; + + // The selection when the wizard is launched. + private IStructuredSelection selection; + + public NewBMotionProjectWizard() { + super(); + setNeedsProgressMonitor(true); + } + + @Override + public void addPages() { + page = new NewBMotionProjectWizardPage(selection); + addPage(page); + } + + public void init(final IWorkbench workbench, final IStructuredSelection sel) { + this.selection = sel; + } + + @Override + public boolean performFinish() { + + // New project/file name + final String projectName = page.getFileName(); + + // Selected rodin project root + final String projectRoot = page.getProjectRoot(); + + final IRunnableWithProgress op = new IRunnableWithProgress() { + public void run(final IProgressMonitor monitor) + throws InvocationTargetException { + try { + doFinish( + projectRoot, + projectName, + page.getProject(), + page.getInitialContents(BMotionEditorPlugin.FILEEXT_STUDIO), + monitor); + } catch (final CoreException e) { + Logger.getAnonymousLogger().log(Level.SEVERE, + "CoreException", e); + } catch (UnsupportedEncodingException e) { + Logger.getAnonymousLogger().log(Level.SEVERE, + "CoreException", e); + } finally { + monitor.done(); + } + } + + }; + try { + getContainer().run(true, false, op); + } catch (final InterruptedException e) { + return false; + } catch (final InvocationTargetException e) { + final Throwable realException = e.getTargetException(); + MessageDialog.openError(getShell(), "Error", + realException.getMessage()); + return false; + } + + return true; + } + + private void doFinish(String projectRoot, final String projectName, + final IProject project, final InputStream defaultContentStudio, + final IProgressMonitor monitor) throws CoreException { + + monitor.beginTask("Creating " + projectName + + " BMotion Studio Visualization", 2); + + IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); + IResource resource = root.findMember(new Path(projectRoot)); + if (!resource.exists() || !(resource instanceof IContainer)) { + throw new CoreException(new Status(IStatus.ERROR, + "org.eventb.internal.ui", IStatus.OK, "Project \"" + + projectRoot + "\" does not exist.", null)); + } + + RodinCore.run(new IWorkspaceRunnable() { + + public void run(final IProgressMonitor pMonitor) + throws CoreException { + + // Create .bmso file + IFile file = project.getFile(projectName + "." + + BMotionEditorPlugin.FILEEXT_STUDIO); + + file.create(defaultContentStudio, false, monitor); + file.refreshLocal(IResource.DEPTH_ZERO, null); + + } + + }, monitor); + + monitor.worked(1); + + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/NewBMotionProjectWizardPage.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/NewBMotionProjectWizardPage.java new file mode 100644 index 0000000000000000000000000000000000000000..f746da1abb0feb174bc38aee9c89525a94e26c65 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/NewBMotionProjectWizardPage.java @@ -0,0 +1,416 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.internal; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.IExtensionRegistry; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.window.Window; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.dialogs.ContainerSelectionDialog; + +import com.thoughtworks.xstream.XStream; + +import de.bmotionstudio.gef.editor.BMotionEditorPlugin; +import de.bmotionstudio.gef.editor.BMotionStudioImage; +import de.bmotionstudio.gef.editor.ILanguageService; +import de.bmotionstudio.gef.editor.model.Visualization; + +public class NewBMotionProjectWizardPage extends WizardPage { + + private static final String DEFAULT_PROJECT_NAME = "NewBMotionVisualization"; + + private IProject selectedProject; + private final MachineList machineList = new MachineList(); + + private MachineEntry selectedEntry = null; + private Text projectRootText; + private Text projectText; + private TableViewer tableViewer; + + private Map<String, ILanguageService> languages = new HashMap<String, ILanguageService>(); + + protected NewBMotionProjectWizardPage(IStructuredSelection selection) { + super("wizardPage"); + this.selectedProject = getSelectedFromSelection(selection); + setTitle("New BMotion Studio Visualization"); + setDescription("Please select a B-Machine and enter a name for the new BMotion Studio Visualization."); + setImageDescriptor(BMotionStudioImage + .getImageDescriptor("icons/logo_bmotion_64.png")); + initLanguageExtensions(); + } + + private void initLanguageExtensions() { + // Get language loader + IExtensionRegistry registry = Platform.getExtensionRegistry(); + IExtensionPoint extensionPoint = registry + .getExtensionPoint("de.bmotionstudio.gef.editor.language"); + for (IExtension extension : extensionPoint.getExtensions()) { + for (IConfigurationElement configurationElement : extension + .getConfigurationElements()) { + try { + ILanguageService lang = (ILanguageService) configurationElement + .createExecutableExtension("service"); + languages + .put(configurationElement.getAttribute("id"), lang); + } catch (CoreException e) { + e.printStackTrace(); + } + + } + } + } + + private IProject getSelectedFromSelection(IStructuredSelection selection) { + if (selection.size() == 1) { + Object firstElement = selection.getFirstElement(); + if (firstElement instanceof IProject) { + return (IProject) firstElement; + } + } + return null; + } + + public IProject getProject() { + return selectedProject; + } + + public InputStream getInitialContents(String fileExtension) + throws UnsupportedEncodingException { + Visualization visualization = new Visualization(getSelectedEntry() + .getMachineFile().getName(), getSelectedEntry() + .getMachineLanguage(), Platform + .getBundle(BMotionEditorPlugin.PLUGIN_ID).getHeaders() + .get("Bundle-Version")); + XStream xstream = new XStream(); + BMotionEditorPlugin.setAliases(xstream); + String content = xstream.toXML(visualization); + return new ByteArrayInputStream(content.getBytes("UTF-8")); + } + + public String getFileName() { + if (projectText.getText().length() > 0) { + return projectText.getText(); + } + return DEFAULT_PROJECT_NAME; + } + + public MachineEntry getSelectedEntry() { + return this.selectedEntry; + } + + public String getProjectRoot() { + return this.projectRootText.getText(); + } + + public String getBMotionProjectName() { + return this.projectText.getText(); + } + + private void initContent() { + + machineList.clearList(); + + if (selectedProject != null) { + + String basePath = (selectedProject.getLocation().toString()) + .replace("file:", ""); + File dir = new File(basePath); + + for (File f : dir.listFiles()) { + + for (Entry<String, ILanguageService> e : languages.entrySet()) { + + String langID = e.getKey(); + ILanguageService langService = e.getValue(); + + IPath path = new Path(f.getAbsolutePath()); + IFile ifile = ResourcesPlugin.getWorkspace().getRoot() + .getFile(path); + if (langService.isLanguageFile(ifile)) { + machineList.addEntry(new MachineEntry(ifile, langID)); + } + + } + + } + + } + + tableViewer.setInput(machineList.getChildren()); + + } + + private boolean resourceExistsInProject(String resourceName) { + IFile f = selectedProject.getFile(resourceName + "." + + BMotionEditorPlugin.FILEEXT_STUDIO); + return f.exists(); + } + + public void validateInput() { + StringBuffer errorMessages = new StringBuffer(150); + + if (getProjectRoot().length() == 0) { + errorMessages.append("The Project name must not be empty.\n"); + } + + if (getBMotionProjectName().length() == 0) { + errorMessages + .append("The BMotion Studio Visualization filename must not be empty.\n"); + } + + // if (errorMessages.length() == 0) { + // rodinProject = RodinCore.getRodinDB().getRodinProject( + // getProjectRoot().replaceAll("/", "")); + // + // if (!rodinProject.exists()) { + // errorMessages.append("The Project '" + getProjectRoot() + // + "' does not exist.\n"); + // } + // } + + if (getSelectedEntry() == null) { + errorMessages.append("You have to select a Machine.\n"); + } + + if (errorMessages.length() == 0 + && resourceExistsInProject(getBMotionProjectName())) { + errorMessages + .append("The BMotion Studio Visualization filename must be unique in a project.\n"); + } + + if (errorMessages.length() > 0) { + setErrorMessage(errorMessages.toString()); + setPageComplete(false); + } else { + setErrorMessage(null); + setPageComplete(true); + } + } + + public void createControl(final Composite parent) { + final Composite container = new Composite(parent, SWT.NULL); + + final GridLayout layout = new GridLayout(); + container.setLayout(layout); + + layout.numColumns = 3; + layout.verticalSpacing = 20; + + setControl(container); + + final ModifyListener listener = new ModifyListener() { + public void modifyText(final ModifyEvent e) { + validateInput(); + } + }; + + GridData gd = new GridData(); + gd.horizontalAlignment = SWT.FILL; + gd.grabExcessHorizontalSpace = true; + + Label label = new Label(container, SWT.NULL); + label.setText("&Project name:"); + + projectRootText = new Text(container, SWT.BORDER | SWT.SINGLE); + projectRootText.setLayoutData(gd); + if (selectedProject != null) { + projectRootText.setText(selectedProject.getFullPath().toOSString()); + } + projectRootText.addModifyListener(listener); + + final Button button = new Button(container, SWT.NULL); + button.setText("Browse..."); + button.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(final SelectionEvent e) { + final ContainerSelectionDialog dialog = new ContainerSelectionDialog( + getShell(), ResourcesPlugin.getWorkspace().getRoot(), + false, "Select Project"); + if (dialog.open() == Window.OK) { + final Object[] result = dialog.getResult(); + if (result.length == 1) { + Path newPath = (Path) result[0]; + IProject newProject = selectedProject.getWorkspace() + .getRoot().getProject(newPath.toString()); + selectedProject = newProject; + initContent(); + projectRootText.setText(((Path) result[0]).toOSString()); + validateInput(); + } + } + } + }); + + label = new Label(container, SWT.NULL); + label.setText("&BMotion Studio Visualization filename:"); + + projectText = new Text(container, SWT.BORDER | SWT.SINGLE); + projectText.setText(DEFAULT_PROJECT_NAME); + projectText.setLayoutData(gd); + projectText.addModifyListener(listener); + + gd = new GridData(); + gd.verticalAlignment = SWT.BEGINNING; + gd.horizontalSpan = 3; + + label = new Label(container, SWT.NULL); + label.setText("&B-Machine:"); + label.setLayoutData(gd); + + gd = new GridData(GridData.FILL_VERTICAL); + gd.horizontalAlignment = SWT.FILL; + gd.grabExcessHorizontalSpace = true; + gd.horizontalSpan = 3; + + tableViewer = new TableViewer(container, SWT.SINGLE + | SWT.FULL_SELECTION); + final Table table = tableViewer.getTable(); + table.setHeaderVisible(true); + table.setLinesVisible(true); + table.setLayoutData(gd); + + final String[] columnsNames = new String[] { "Machine", "Language" }; + final int[] columnWidths = new int[] { 250, 100 }; + final int[] columnAlignments = new int[] { SWT.LEFT, SWT.LEFT }; + + for (int i = 0; i < columnsNames.length; i++) { + final TableColumn tableColumn = new TableColumn(table, + columnAlignments[i]); + tableColumn.setText(columnsNames[i]); + tableColumn.setWidth(columnWidths[i]); + } + + tableViewer.setLabelProvider(new MachineLabelProvider()); + tableViewer.setContentProvider(new ArrayContentProvider()); + initContent(); + + tableViewer + .addSelectionChangedListener(new ISelectionChangedListener() { + public void selectionChanged(SelectionChangedEvent event) { + IStructuredSelection selection = (IStructuredSelection) event + .getSelection(); + selectedEntry = (MachineEntry) selection + .getFirstElement(); + validateInput(); + } + }); + + validateInput(); + + } + + private static class MachineLabelProvider extends LabelProvider implements + ITableLabelProvider { + + public Image getColumnImage(final Object element, final int columnIndex) { + return null; + } + + public String getColumnText(final Object element, final int columnIndex) { + if (element instanceof MachineEntry) { + + final MachineEntry currentEntry = (MachineEntry) element; + + switch (columnIndex) { + case 0: + return currentEntry.getMachineName(); + case 1: + return currentEntry.getMachineLanguage(); + } + + } + + return null; + } + + } + + private static class MachineList { + private final ArrayList<MachineEntry> entries = new ArrayList<MachineEntry>(); + + public MachineEntry[] getChildren() { + return entries.toArray(new MachineEntry[entries.size()]); + } + + public void addEntry(final MachineEntry entry) { + if (!entries.contains(entry)) { + entries.add(entry); + } + } + + public void clearList() { + this.entries.clear(); + } + + } + + private static class MachineEntry { + + private final String machineName; + private final String machineLanguage; + private final IFile file; + + public MachineEntry(IFile file, String machineLanguage) { + this.file = file; + this.machineName = file.getName(); + this.machineLanguage = machineLanguage; + } + + public String getMachineName() { + return this.machineName; + } + + public String getMachineLanguage() { + return this.machineLanguage; + } + + public IFile getMachineFile() { + return this.file; + } + + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/OpenWebsiteHandler.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/OpenWebsiteHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..500bb85d61ccf97fc90b8f6c132b8544f481fe34 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/OpenWebsiteHandler.java @@ -0,0 +1,39 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.internal; + +import java.net.MalformedURLException; +import java.net.URL; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; + +import de.prob.logging.Logger; + +public class OpenWebsiteHandler extends AbstractHandler { + + private static final String URL = "http://www.stups.uni-duesseldorf.de/BMotionStudio/"; + + public Object execute(ExecutionEvent event) throws ExecutionException { + try { + PlatformUI.getWorkbench().getBrowserSupport().getExternalBrowser() + .openURL(new URL(URL)); + } catch (PartInitException e) { + final String message = "Part init exception occurred\n" + + e.getLocalizedMessage(); + Logger.notifyUser(message, e); + } catch (MalformedURLException e) { + final String message = "This really should never happen unless the http protocol changes"; + Logger.notifyUser(message, e); + } + return null; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/PerspectiveEditFactory.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/PerspectiveEditFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..2603fee362ae80c07df25e5b1caf8e9e4f367193 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/PerspectiveEditFactory.java @@ -0,0 +1,43 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.internal; + +import org.eclipse.ui.IFolderLayout; +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.IPerspectiveFactory; + +import de.bmotionstudio.gef.editor.library.LibraryView; + +public class PerspectiveEditFactory implements IPerspectiveFactory { + + public void createInitialLayout(final IPageLayout layout) { + + final String editorArea = layout.getEditorArea(); + + // Place the project explorer to left of editor area. + final IFolderLayout left = layout.createFolder("left", + IPageLayout.LEFT, 0.15f, editorArea); + left.addView("fr.systerel.explorer.navigator.view"); + + // Place the outline to right of editor area. + final IFolderLayout righttop = layout.createFolder("right", + IPageLayout.RIGHT, 0.8f, editorArea); + righttop.addView(IPageLayout.ID_OUTLINE); + + // Library view + final IFolderLayout rightbot = layout.createFolder("rightb", + IPageLayout.BOTTOM, 0.6f, "right"); + rightbot.addView(LibraryView.ID); + + final IFolderLayout bottom = layout.createFolder("bottom", + IPageLayout.BOTTOM, 0.75f, editorArea); + // Properties view + bottom.addView(IPageLayout.ID_PROP_SHEET); + + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/PerspectiveRunFactory.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/PerspectiveRunFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..cc52fd79fcf9ef27a191d0651191f5c2492f8aaf --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/PerspectiveRunFactory.java @@ -0,0 +1,43 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.internal; + +import org.eclipse.ui.IFolderLayout; +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.IPerspectiveFactory; + +public class PerspectiveRunFactory implements IPerspectiveFactory { + + public void createInitialLayout(IPageLayout layout) { + + String editorArea = layout.getEditorArea(); + + // ProB Event View (Top-Left) + IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT, + 0.15f, editorArea); + left.addView("de.prob.ui.OperationView"); + + // Navigator + Rodin Problem View (Bottom-Left) + IFolderLayout leftb = layout.createFolder("leftb", IPageLayout.BOTTOM, + 0.6f, "left"); + leftb.addView("fr.systerel.explorer.navigator.view"); + // leftb.addView("org.eventb.ui.views.RodinProblemView"); + + // ProB State View (Right) + IFolderLayout right1 = layout.createFolder("right1", IPageLayout.RIGHT, + 0.7f, editorArea); + right1.addView("de.prob.ui.StateView"); + + // ProB History + ProB Event Error View (Right) + IFolderLayout right2 = layout.createFolder("right2", IPageLayout.RIGHT, + 0.6f, "right1"); + right2.addView("de.prob.ui.HistoryView"); + right2.addView("de.prob.ui.EventErrorView"); + + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/ProgressBarDialog.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/ProgressBarDialog.java new file mode 100644 index 0000000000000000000000000000000000000000..693325bff2e39393221139a49131b5f524a2a811 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/ProgressBarDialog.java @@ -0,0 +1,235 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.internal; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CLabel; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.*; +import org.eclipse.swt.widgets.*; + +import de.bmotionstudio.gef.editor.BMotionStudioImage; +import de.bmotionstudio.gef.editor.EditorImageRegistry; + + +public abstract class ProgressBarDialog extends Dialog { + + private Label processMessageLabel; // info of process finish + private Button cancelButton; // cancel button + private Composite cancelComposite; + private Composite progressBarComposite;// + private CLabel message;// + private ProgressBar progressBar = null; // + + private Shell shell; // + + public Shell getShell() { + return shell; + } + + private Display display = null; + + protected volatile boolean isClosed = false;// closed state + + protected int executeTime = 50;// process times + protected String processMessage = "process......";// procress info + protected String shellTitle = "Progress..."; // + protected Image processImage = BMotionStudioImage + .getImage(EditorImageRegistry.IMG_ICON_LOADING);// image + protected boolean mayCancel = true; // cancel + protected int processBarStyle = SWT.SMOOTH; // process bar style + + protected ProcessThread currentThread; + + public void setMayCancel(boolean mayCancel) { + this.mayCancel = mayCancel; + } + + public void setExecuteTime(int executeTime) { + this.executeTime = executeTime; + } + + public void setProcessImage(Image processImage) { + this.processImage = processImage; + } + + public void setProcessMessage(String processInfo) { + this.processMessage = processInfo; + } + + public ProgressBarDialog(Shell parent) { + super(parent); + } + + protected ProcessThread getCurrentThread() { + return this.currentThread; + } + + public abstract void initGuage(); + + public void open() { + createContents(); // create window + shell.open(); + shell.layout(); + + // start work + currentThread = new ProcessThread(executeTime); + currentThread.start(); + + Display display = getParent().getDisplay(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + } + + protected void setClose(boolean b) { + this.isClosed = b; + } + + protected void createContents() { + shell = new Shell(getParent(), SWT.TITLE | SWT.PRIMARY_MODAL + | SWT.NO_TRIM | SWT.ON_TOP); + display = shell.getDisplay(); + FormLayout fl = new FormLayout(); + + shell.setLayout(fl); + shell.setSize(483, 350); + shell.setText(shellTitle); + shell.setBackgroundImage(BMotionStudioImage + .getImage(EditorImageRegistry.IMG_SPLASH)); + + Monitor primary = Display.getCurrent().getPrimaryMonitor(); + Rectangle bounds = primary.getBounds(); + Rectangle rect = shell.getBounds(); + int x = bounds.x + (bounds.width - rect.width) / 2; + int y = bounds.y + (bounds.height - rect.height) / 2; + shell.setLocation(x, y); + + FormData fd = new FormData(); + fd.right = new FormAttachment(100, -5); + fd.bottom = new FormAttachment(100, -10); + + // Cancel button + cancelComposite = new Composite(shell, SWT.NONE); + final GridLayout gridLayout_1 = new GridLayout(); + gridLayout_1.numColumns = 2; + cancelComposite.setLayout(gridLayout_1); + cancelComposite.setLayoutData(fd); + cancelComposite.setBackground(Display.getDefault().getSystemColor( + SWT.COLOR_WHITE)); + + cancelButton = new Button(cancelComposite, SWT.NONE); + cancelButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + isClosed = true; + } + }); + cancelButton.setLayoutData(new GridData(78, SWT.DEFAULT)); + cancelButton.setText("Cancel"); + cancelButton.setEnabled(this.mayCancel); + + fd = new FormData(); + fd.right = new FormAttachment(100, -5); + fd.left = new FormAttachment(0, 10); + fd.bottom = new FormAttachment(cancelComposite, -5); + + processMessageLabel = new Label(shell, SWT.NONE); + processMessageLabel.setBackground(Display.getDefault().getSystemColor( + SWT.COLOR_WHITE)); + processMessageLabel.setLayoutData(fd); + + fd = new FormData(); + fd.right = new FormAttachment(100, -10); + fd.left = new FormAttachment(0, 10); + fd.bottom = new FormAttachment(processMessageLabel, -5); + + progressBarComposite = new Composite(shell, SWT.NONE); + progressBarComposite.setLayout(new FillLayout()); + progressBarComposite.setLayoutData(fd); + progressBar = new ProgressBar(progressBarComposite, processBarStyle); + progressBar.setMaximum(executeTime); + + fd = new FormData(); + fd.right = new FormAttachment(100, -5); + fd.left = new FormAttachment(0, 10); + fd.bottom = new FormAttachment(progressBarComposite, -5); + + // Message label + message = new CLabel(shell, SWT.NONE); + message.setLayoutData(fd); + message.setImage(processImage); + message.setText(processMessage); + message.setBackground(Display.getDefault().getSystemColor( + SWT.COLOR_WHITE)); + } + + protected abstract String process(int times); + + protected void cleanUp() { + } + + protected void doBefore() { + } + + protected void doAfter() { + } + + class ProcessThread extends Thread { + private int max = 0; + private volatile boolean shouldStop = false; + + ProcessThread(int max) { + this.max = max; + } + + public void run() { + doBefore(); + for (final int[] i = new int[] { 1 }; i[0] <= max; i[0]++) { + final String info = process(i[0]); + if (display.isDisposed()) { + return; + } + display.syncExec(new Runnable() { + public void run() { + if (progressBar.isDisposed()) { + return; + } + processMessageLabel.setText(info); + progressBar.setSelection(i[0]); + if (i[0] == max || isClosed) { + if (isClosed) { + shouldStop = true; + cleanUp(); + } + shell.close(); + } + } + }); + if (shouldStop) + break; + } + doAfter(); + } + } + + public void setShellTitle(String shellTitle) { + this.shellTitle = shellTitle; + } + + public void setProcessBarStyle(boolean pStyle) { + if (pStyle) + this.processBarStyle = SWT.SMOOTH; + else + this.processBarStyle = SWT.NONE; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/RenameWizard.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/RenameWizard.java new file mode 100644 index 0000000000000000000000000000000000000000..c9897d93d068dcbd6e9a43d80444ebfca24ae0c7 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/RenameWizard.java @@ -0,0 +1,72 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.internal; + +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; + +public class RenameWizard extends Wizard { + + private class RenamePage extends WizardPage { + + public Text nameText; + + public RenamePage(final String pageName) { + super(pageName); + setTitle("BMotion Studio Rename Wizard"); + setDescription("Rename a control"); + } + + public void createControl(final Composite parent) { + + Composite composite = new Composite(parent, SWT.NONE); + composite.setLayout(new GridLayout(2, false)); + + Label lab = new Label(composite, SWT.NONE); + lab.setText("Rename to: "); + lab.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING)); + + GridData gd = new GridData(GridData.FILL_HORIZONTAL); + gd.heightHint = 90; + + nameText = new Text(composite, SWT.BORDER | SWT.WRAP | SWT.V_SCROLL); + nameText.setText(oldName); + nameText.setLayoutData(gd); + + setControl(composite); + + } + + } + + private final String oldName; + private String newName; + + public RenameWizard(final String oldName) { + this.oldName = oldName; + this.newName = null; + addPage(new RenamePage("MyRenamePage")); + } + + @Override + public boolean performFinish() { + RenamePage page = (RenamePage) getPage("MyRenamePage"); + newName = page.nameText.getText(); + return true; + } + + public String getRenameValue() { + return newName; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/SelectOperationDialog.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/SelectOperationDialog.java new file mode 100644 index 0000000000000000000000000000000000000000..ae9aaf655a6695f08182f17fc4b5e5791aaacc1c --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/SelectOperationDialog.java @@ -0,0 +1,105 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.internal; + +import java.util.List; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ListViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; + +import de.prob.core.domainobjects.Operation; + +public class SelectOperationDialog extends Dialog { + + private List<Operation> ops; + private Operation selectedOperation; + // private ComboViewer cb; + private ListViewer listViewer; + + protected SelectOperationDialog(Shell parentShell, List<Operation> ops) { + super(parentShell); + this.ops = ops; + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite container = (Composite) super.createDialogArea(parent); + + GridLayout gl = new GridLayout(2, false); + gl.marginLeft = 15; + gl.marginTop = 20; + + container.setLayout(gl); + + Label lb = new Label(container, SWT.NONE); + lb.setText("Select an operation:"); + lb.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING)); + + listViewer = new ListViewer(container); + listViewer.setContentProvider(new ArrayContentProvider()); + listViewer.setInput(ops); + listViewer.getList().setLayoutData(new GridData(GridData.FILL_BOTH)); + + // cb = new ComboViewer(container, SWT.NONE); + // cb.setContentProvider(new ArrayContentProvider()); + // cb.setInput(ops); + // cb.getCombo().setLayoutData(new GridData(200, 20)); + // cb.getCombo() + // .setFont( + // JFaceResources.getFontRegistry().get( + // BasicUtils.RODIN_FONT_KEY)); + + return container; + + } + + @Override + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + newShell.setText("Please select an operation ..."); + } + + @Override + protected Point getInitialSize() { + return new Point(600, 250); + } + + @Override + protected void okPressed() { + + IStructuredSelection selection = (IStructuredSelection) listViewer + .getSelection(); + selectedOperation = (Operation) selection.getFirstElement(); + + if (selectedOperation == null) { + MessageDialog.openError(Display.getDefault().getActiveShell(), + "An error occurred", "Please select an operation ..."); + return; + } else { + setReturnCode(OK); + close(); + } + + } + + public Operation getSelectedOperation() { + return this.selectedOperation; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/StartVisualizationEditorHandler.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/StartVisualizationEditorHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..d372e4d5435629678eb967c5a9a0564cde5ff4fc --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/StartVisualizationEditorHandler.java @@ -0,0 +1,73 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.internal; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.IHandler; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.WorkbenchException; + +import de.bmotionstudio.gef.editor.BMotionEditorPlugin; +import de.prob.core.Animator; +import de.prob.logging.Logger; + +public class StartVisualizationEditorHandler extends AbstractHandler implements + IHandler { + + private VisualizationProgressBar dpb; + + public Object execute(final ExecutionEvent event) throws ExecutionException { + + if (BMotionEditorPlugin.getActiveEditor().isDirty()) { + if (MessageDialog + .openConfirm( + Display.getDefault().getActiveShell(), + "Please confirm", + "You made changes in your editor. Do you want to safe before starting visualization?")) { + BMotionEditorPlugin.getActiveEditor().doSave( + new NullProgressMonitor()); + } + } + + IFile projectFile = BMotionEditorPlugin.getActiveEditor() + .getVisualization().getProjectFile(); + + // Get ProB Animator + Animator animator = Animator.getAnimator(); + + // Open Run Perspective + IWorkbench workbench = PlatformUI.getWorkbench(); + try { + workbench.showPerspective("de.bmotionstudio.perspective.run", + workbench.getActiveWorkbenchWindow()); + } catch (WorkbenchException e) { + Logger.notifyUser("Error opening BMotion Studio Run perspective.", + e); + } + + // First, kill old visualization (only if exists) + if (dpb != null) + dpb.kill(); + // Create a new visualization + dpb = new VisualizationProgressBar(Display.getDefault() + .getActiveShell(), animator, + BMotionEditorPlugin.getActiveEditor(), projectFile); + dpb.initGuage(); + dpb.open(); + + return null; + + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/StartVisualizationFileHandler.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/StartVisualizationFileHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..55a3f77554ff818a6757dd1b754b5dde26affb8f --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/StartVisualizationFileHandler.java @@ -0,0 +1,135 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.internal; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.IHandler; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IEditorDescriptor; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.WorkbenchException; +import org.eclipse.ui.handlers.HandlerUtil; +import org.eclipse.ui.part.FileEditorInput; + +import de.bmotionstudio.gef.editor.BMotionEditorPlugin; +import de.bmotionstudio.gef.editor.BMotionStudioEditor; +import de.prob.core.Animator; +import de.prob.logging.Logger; + +public class StartVisualizationFileHandler extends AbstractHandler implements + IHandler { + + private ISelection fSelection; + private VisualizationProgressBar dpb; + private BMotionStudioEditor activeEditor; + + public Object execute(final ExecutionEvent event) throws ExecutionException { + + fSelection = HandlerUtil.getCurrentSelection(event); + + BMotionStudioEditor editor = BMotionEditorPlugin.getActiveEditor(); + if (editor != null) { + if (BMotionEditorPlugin.getActiveEditor().isDirty()) { + if (MessageDialog + .openConfirm( + Display.getDefault().getActiveShell(), + "Please confirm", + "You made changes in your editor. Do you want to safe before starting visualization?")) { + + BMotionEditorPlugin.getActiveEditor().doSave( + new NullProgressMonitor()); + } + } + } + + IFile f = null; + + // Get the Selection + if (fSelection instanceof IStructuredSelection) { + + IStructuredSelection ssel = (IStructuredSelection) fSelection; + + if (ssel.size() == 1) { + + f = getBmsFileFromSelection(ssel); + + IWorkbenchWindow window = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow(); + IWorkbenchPage page = window.getActivePage(); + + IEditorDescriptor desc = PlatformUI.getWorkbench() + .getEditorRegistry().getDefaultEditor(f.getName()); + + try { + IEditorPart part = page.openEditor(new FileEditorInput(f), + desc.getId()); + if (part instanceof BMotionStudioEditor) { + activeEditor = (BMotionStudioEditor) part; + } else { + // TODO: Return some useful error?! + return null; + } + } catch (PartInitException e) { + e.printStackTrace(); + } + + // Get ProB Animator + Animator animator = Animator.getAnimator(); + + // Open Run Perspective + IWorkbench workbench = PlatformUI.getWorkbench(); + try { + workbench.showPerspective( + "de.bmotionstudio.perspective.run", + workbench.getActiveWorkbenchWindow()); + } catch (WorkbenchException e) { + Logger.notifyUser( + "Error opening BMotion Studio Run perspective.", e); + } + + // First, kill old visualization (only if exists) + if (dpb != null) + dpb.kill(); + // Create a new visualization + dpb = new VisualizationProgressBar(Display.getDefault() + .getActiveShell(), animator, activeEditor, f); + dpb.initGuage(); + dpb.open(); + + } + + } + + return null; + + } + + public void selectionChanged(final IAction action, + final ISelection selection) { + fSelection = selection; + } + + protected IFile getBmsFileFromSelection(IStructuredSelection ssel) { + if (ssel.getFirstElement() instanceof IFile) + return (IFile) ssel.getFirstElement(); + return null; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/VisualizationProgressBar.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/VisualizationProgressBar.java new file mode 100644 index 0000000000000000000000000000000000000000..549adbd74d032783c1c88f1a5a16ee82b0482c4b --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/VisualizationProgressBar.java @@ -0,0 +1,288 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.internal; + +import java.io.IOException; +import java.util.List; +import java.util.Locale; + +import javax.xml.parsers.ParserConfigurationException; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.IExtensionRegistry; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.window.Window; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.xml.sax.SAXException; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.io.xml.DomDriver; +import com.thoughtworks.xstream.mapper.MapperWrapper; + +import de.bmotionstudio.gef.editor.BMotionEditorPlugin; +import de.bmotionstudio.gef.editor.BMotionStudioEditor; +import de.bmotionstudio.gef.editor.ILanguageService; +import de.bmotionstudio.gef.editor.model.Visualization; +import de.prob.core.Animator; +import de.prob.core.command.ExecuteOperationCommand; +import de.prob.core.domainobjects.Operation; +import de.prob.exceptions.ProBException; + +public class VisualizationProgressBar extends ProgressBarDialog { + + private Animator animator; + private IFile f; + private Visualization visualization; + private Animation animation; + private int confirm = -1; + private SelectOperationDialog dialog; + private BMotionStudioEditor activeEditor; + + public VisualizationProgressBar(Shell parent, Animator animator, + BMotionStudioEditor activeEditor, IFile f) { + super(parent); + this.animator = animator; + this.activeEditor = activeEditor; + this.f = f; + } + + @Override + public void initGuage() { + this.setExecuteTime(6); + this.setMayCancel(true); + this.setProcessMessage("Starting Visualization ..."); + this.setShellTitle("Starting Visualization"); + } + + @Override + protected String process(int i) { + + switch (i) { + case 1: + try { + createVisualizationRoot(); + } catch (CoreException e) { + openErrorDialog(e.getMessage()); + setClose(true); + } catch (IOException e) { + openErrorDialog(e.getMessage()); + setClose(true); + } catch (ParserConfigurationException e) { + openErrorDialog(e.getMessage()); + setClose(true); + } catch (SAXException e) { + openErrorDialog(e.getMessage()); + setClose(true); + } + return "Starting ProB Animator"; + case 2: + startProbAnimator(); + return "Setup Constants"; + case 3: + try { + setupOperation("SETUP_CONTEXT"); + } catch (InterruptedException e) { + openErrorDialog(e.getMessage()); + setClose(true); + } + return "Create Visualization"; + case 4: + Display.getDefault().asyncExec(new Runnable() { + public void run() { + createShell(); + } + }); + return "Initialize machine"; + case 5: + try { + setupOperation("INITIALISATION"); + } catch (InterruptedException e) { + openErrorDialog(e.getMessage()); + setClose(true); + } + return "Starting Operation Scheduler"; + case 6: + startOperationScheduler(); + return "Starting Visualization"; + } + + return "Starting BMotion Studio Visualization"; + + } + + private void startOperationScheduler() { + visualization.startOperationScheduler(); + } + + private void createVisualizationRoot() throws CoreException, IOException, + ParserConfigurationException, SAXException { + XStream xstream = new XStream(new DomDriver()) { + @Override + protected MapperWrapper wrapMapper(MapperWrapper next) { + return new MapperWrapper(next) { + @Override + public boolean shouldSerializeMember( + @SuppressWarnings("rawtypes") Class definedIn, + String fieldName) { + if (definedIn == Object.class) { + return false; + } + return super + .shouldSerializeMember(definedIn, fieldName); + } + }; + } + }; + BMotionEditorPlugin.setAliases(xstream); + visualization = (Visualization) xstream.fromXML(f.getContents()); + visualization.setProjectFile(f); + } + + @Override + protected void cleanUp() { + if (animation != null) + animation.unregister(); + } + + private void startProbAnimator() { + animation = new Animation(animator, visualization); + ILanguageService langService = getGenericLoadMachine(visualization + .getLanguage()); + if (langService != null) { + try { + langService.startProBAnimator(visualization); + } catch (ProBException e) { + openErrorDialog(e.getMessage()); + setClose(true); + } + } else { + openErrorDialog("Unknown formal language: " + + visualization.getLanguage()); + setClose(true); + } + } + + private void setupOperation(String opName) throws InterruptedException { + + final List<Operation> ops = animation.getState().getEnabledOperations(); + + if (ops.size() > 1) { + + Display.getDefault().asyncExec(new Runnable() { + public void run() { + dialog = new SelectOperationDialog(getShell(), ops); + confirm = dialog.open(); + } + }); + + while (true) { + try { + Thread.sleep(500); + } catch (InterruptedException e) { + openErrorDialog(e.getMessage()); + setClose(true); + } + + if (confirm == Window.OK) { + Operation op = dialog.getSelectedOperation(); + if (op != null) + try { + ExecuteOperationCommand.executeOperation(animator, + op); + } catch (ProBException e) { + openErrorDialog(e.getMessage()); + setClose(true); + } + confirm = -1; + break; + } else if (confirm == Window.CANCEL) { + setClose(true); + confirm = -1; + break; + } + + } + + } else { + Operation op = animation.getCurrentStateOperation(opName); + if (op != null) + try { + ExecuteOperationCommand.executeOperation(animator, op); + } catch (ProBException e) { + openErrorDialog(e.getMessage()); + setClose(true); + } + } + + visualization.setIsRunning(true); + + } + + private void createShell() { + activeEditor.createRunPage(visualization, animation); + } + + private ILanguageService getGenericLoadMachine(String language) { + IExtensionRegistry registry = Platform.getExtensionRegistry(); + IExtensionPoint extensionPoint = registry + .getExtensionPoint("de.bmotionstudio.gef.editor.language"); + ILanguageService langService = null; + + // Get GenericLoadMachine command for language + for (IExtension extension : extensionPoint.getExtensions()) { + for (IConfigurationElement configurationElement : extension + .getConfigurationElements()) { + + if ("language".equals(configurationElement.getName())) { + + String languageEx = configurationElement.getAttribute("id"); + if (language.toLowerCase(Locale.ENGLISH).equals( + languageEx.toLowerCase(Locale.ENGLISH))) { + + try { + langService = (ILanguageService) configurationElement + .createExecutableExtension("service"); + } catch (final CoreException e) { + openErrorDialog(e.getMessage()); + setClose(true); + } + + } + + } + + } + } + return langService; + } + + public void kill() { + // if (shell != null) + // if (shell.getShell() != null) + // shell.getShell().dispose(); + } + + public void openErrorDialog(final String msg) { + Display.getDefault().asyncExec(new Runnable() { + public void run() { + ErrorDialog.openError(getParent(), "Error", + "Error creating visualization", new Status( + IStatus.ERROR, BMotionEditorPlugin.PLUGIN_ID, + msg)); + } + }); + } + +} \ No newline at end of file diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/AbstractLibraryAction.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/AbstractLibraryAction.java new file mode 100644 index 0000000000000000000000000000000000000000..9ba118c5c77502911854349ce0aa1c17b743516e --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/AbstractLibraryAction.java @@ -0,0 +1,28 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.library; + +import org.eclipse.jface.action.Action; + + +public class AbstractLibraryAction extends Action { + + private LibraryPage page; + + public AbstractLibraryAction(LibraryPage page) { + this.page = page; + } + + public void setPage(LibraryPage page) { + this.page = page; + } + + public LibraryPage getPage() { + return page; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/AbstractLibraryCommand.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/AbstractLibraryCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..3e6f5cb1a0c6871708f170aed81eb402e15a56e8 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/AbstractLibraryCommand.java @@ -0,0 +1,66 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ +package de.bmotionstudio.gef.editor.library; + +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.gef.EditPart; +import org.eclipse.gef.commands.Command; + +import de.bmotionstudio.gef.editor.model.BControl; + +/** + * @author Lukas Ladenberger + * + */ +public abstract class AbstractLibraryCommand extends Command { + + protected EditPart editPart; + protected AttributeTransferObject transferObject; + protected String attributeName; + protected Object attributeValue; + protected Object oldAttributeValue; + protected Point dropLocation; + + public boolean canExecute() { + return true; + } + + public void setEditPart(EditPart editPart) { + this.editPart = editPart; + } + + public EditPart getEditPart() { + return this.editPart; + } + + public void undo() { + if (attributeName != null) + getCastedModel() + .setAttributeValue(attributeName, oldAttributeValue); + } + + public void setAttributeTransferObject( + AttributeTransferObject transferObject) { + this.transferObject = transferObject; + } + + public AttributeTransferObject getAttributeTransferObject() { + return this.transferObject; + } + + public Point getDropLocation() { + return dropLocation; + } + + public void setDropLocation(Point dropLocation) { + this.dropLocation = dropLocation; + } + + protected BControl getCastedModel() { + return (BControl) editPart.getModel(); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/AttributeRequest.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/AttributeRequest.java new file mode 100644 index 0000000000000000000000000000000000000000..11837177d96a10a13bad7225f975c1e05ae9564b --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/AttributeRequest.java @@ -0,0 +1,39 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.library; + +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.gef.Request; + + +public class AttributeRequest extends Request { + + private AttributeTransferObject attributeTransferObject; + private Point dropLocation; + + public Point getDropLocation() { + return this.dropLocation; + } + + public void setDropLocation(Point dropLocation) { + this.dropLocation = dropLocation; + } + + public AttributeRequest() { + super("change attribute"); + } + + public void setAttributeTransferObject( + AttributeTransferObject attributeTransferObject) { + this.attributeTransferObject = attributeTransferObject; + } + + public AttributeTransferObject getAttributeTransferObject() { + return attributeTransferObject; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/AttributeTransfer.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/AttributeTransfer.java new file mode 100644 index 0000000000000000000000000000000000000000..9c309696ea0e03f74c2c040f60a3441216ef1c83 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/AttributeTransfer.java @@ -0,0 +1,41 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.library; + +import org.eclipse.gef.dnd.SimpleObjectTransfer; + +public class AttributeTransfer extends SimpleObjectTransfer { + + private static final AttributeTransfer INSTANCE = new AttributeTransfer(); + private static final String TYPE_NAME = "Attribute transfer"//$NON-NLS-1$ + + System.currentTimeMillis() + ":" + INSTANCE.hashCode();//$NON-NLS-1$ + private static final int TYPEID = registerType(TYPE_NAME); + + /** + * @see org.eclipse.swt.dnd.Transfer#getTypeIds() + */ + protected int[] getTypeIds() { + return new int[] { TYPEID }; + } + + /** + * @see org.eclipse.swt.dnd.Transfer#getTypeNames() + */ + protected String[] getTypeNames() { + return new String[] { TYPE_NAME }; + } + + /** + * Returns the singleton instance + * + * @return the singleton + */ + public static AttributeTransfer getInstance() { + return INSTANCE; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/AttributeTransferDropTargetListener.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/AttributeTransferDropTargetListener.java new file mode 100644 index 0000000000000000000000000000000000000000..d65d146ed234a8de6a64a997341b8b19953b3030 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/AttributeTransferDropTargetListener.java @@ -0,0 +1,60 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.library; + +import org.eclipse.gef.EditPartViewer; +import org.eclipse.gef.Request; +import org.eclipse.gef.dnd.AbstractTransferDropTargetListener; +import org.eclipse.swt.dnd.DND; +import org.eclipse.ui.IWorkbenchPart; + + +public class AttributeTransferDropTargetListener extends + AbstractTransferDropTargetListener { + + private IWorkbenchPart workbenchPart; + + public AttributeTransferDropTargetListener(EditPartViewer viewer, + IWorkbenchPart workbenchPart) { + super(viewer, AttributeTransfer.getInstance()); + this.workbenchPart = workbenchPart; + } + + @Override + protected void updateTargetRequest() { + } + + @Override + protected Request createTargetRequest() { + AttributeRequest req = new AttributeRequest(); + req.setDropLocation(getDropLocation()); + Object transferObject = AttributeTransfer.getInstance().getObject(); + if (transferObject instanceof AttributeTransferObject) + req + .setAttributeTransferObject((AttributeTransferObject) transferObject); + return req; + } + + @Override + protected void handleDragOperationChanged() { + getCurrentEvent().detail = DND.DROP_COPY; + super.handleDragOperationChanged(); + } + + @Override + protected void handleDragOver() { + getCurrentEvent().detail = DND.DROP_COPY; + super.handleDragOver(); + } + + @Override + protected void handleDrop() { + super.handleDrop(); + workbenchPart.setFocus(); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/AttributeTransferObject.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/AttributeTransferObject.java new file mode 100644 index 0000000000000000000000000000000000000000..cb714f3435fa96006796e16fd8fa962985512927 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/AttributeTransferObject.java @@ -0,0 +1,26 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.library; + + +public class AttributeTransferObject { + + private LibraryObject libraryObject; + + public AttributeTransferObject(LibraryObject attributeValue) { + this.libraryObject = attributeValue; + } + + public void setLibraryObject(LibraryObject libraryObject) { + this.libraryObject = libraryObject; + } + + public LibraryObject getLibraryObject() { + return libraryObject; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/DeleteItemsAction.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/DeleteItemsAction.java new file mode 100644 index 0000000000000000000000000000000000000000..5ccb2146d2e911dacd7399f13678de30e6601df7 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/DeleteItemsAction.java @@ -0,0 +1,55 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.library; + +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.widgets.Display; + +import de.bmotionstudio.gef.editor.BMotionStudioImage; + +public class DeleteItemsAction extends AbstractLibraryAction { + + public DeleteItemsAction(LibraryPage page) { + super(page); + setText("Delete selected items"); + setImageDescriptor(BMotionStudioImage.getImageDescriptor( + "org.eclipse.ui", "$nl$/icons/full/etool16/delete_edit.gif")); + } + + @Override + public void run() { + + IStructuredSelection sel = (IStructuredSelection) getPage() + .getTableViewer().getSelection(); + Object[] lobjects = sel.toArray(); + + if (MessageDialog.openConfirm(Display.getDefault().getActiveShell(), + "Please confirm", "Do you realy want to delete these objects?")) { + + for (Object lobj : lobjects) { + ((LibraryObject) lobj).delete(getPage()); + } + + getPage().refresh(); + + try { + getPage().getEditor().getVisualization().getProjectFile() + .getProject().getProject().refreshLocal( + IResource.DEPTH_ONE, new NullProgressMonitor()); + } catch (CoreException e) { + e.printStackTrace(); + } + + } + + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/ImportImagesAction.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/ImportImagesAction.java new file mode 100644 index 0000000000000000000000000000000000000000..9dd9d28c4289e7f411611df7b07dce6b163be33c --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/ImportImagesAction.java @@ -0,0 +1,104 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.library; + +import java.io.File; +import java.io.IOException; + +import org.eclipse.core.resources.IFile; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.MessageBox; + +import de.bmotionstudio.gef.editor.BMotionStudioImage; +import de.bmotionstudio.gef.editor.util.FileUtil; + +public class ImportImagesAction extends AbstractLibraryAction { + + public ImportImagesAction(LibraryPage page) { + super(page); + setText("Import images..."); + setImageDescriptor(BMotionStudioImage.getImageDescriptor( + "org.eclipse.ui", "$nl$/icons/full/etool16/import_wiz.gif")); + } + + @Override + public void run() { + + // The file dialog + FileDialog fd = new FileDialog(Display.getDefault().getActiveShell(), + SWT.OPEN | SWT.MULTI); + fd.setText("Open"); + fd.setFilterPath("C:/"); + String[] filterExt = { "*.jpg", "*.gif", "*.png", "*.*" }; + fd.setFilterExtensions(filterExt); + + fd.open(); + + // File path + String folderPath = fd.getFilterPath(); + + // Selected items + String[] selectedFiles = fd.getFileNames(); + + // The project file + IFile pFile = getPage().getEditor().getVisualization().getProjectFile(); + + String imagePath = (pFile.getProject().getLocationURI() + "/images") + .replace("file:", ""); + File imageFilePath = new File(imagePath); + + // Check if images folder exists! + // If no such folder exists -> create + if (!imageFilePath.exists()) { + Boolean check = imageFilePath.mkdir(); + if (check) { + // TODO: Do something with return value + } + } + + // Iterate the selected files + for (String fileName : selectedFiles) { + + String filePath = (pFile.getProject().getLocation() + "/images/" + fileName) + .replace("file:", ""); + + // Copy files into project sub folder project/images + File inputFile = new File(folderPath + File.separator + fileName); + File outputFile = new File(filePath); + + boolean ok = false; + + if (outputFile.exists()) { + // The file already exists; asks for confirmation + MessageBox mb = new MessageBox(fd.getParent(), SWT.ICON_WARNING + | SWT.YES | SWT.NO); + mb.setMessage(fileName + + " already exists. Do you want to replace it?"); + // If they click Yes, we're done and we drop out. If + // they click No, we redisplay the File Dialog + ok = mb.open() == SWT.YES; + } else { + ok = true; + } + + if (ok) { + try { + FileUtil.copyFile(inputFile, outputFile); + } catch (IOException e) { + e.printStackTrace(); + } + } + + } + + getPage().refresh(); + + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/LibraryImageCommand.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/LibraryImageCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..2ff5c604982f9d11040a07c6aa138b5e98fe46b8 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/LibraryImageCommand.java @@ -0,0 +1,83 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.library; + +import java.io.File; + +import org.eclipse.core.resources.IFile; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; + +import de.bmotionstudio.gef.editor.AttributeConstants; +import de.bmotionstudio.gef.editor.command.CreateCommand; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.model.BImage; + +public class LibraryImageCommand extends AbstractLibraryCommand { + + private BControl newImageControl; + + public void execute() { + + attributeName = AttributeConstants.ATTRIBUTE_IMAGE; + attributeValue = transferObject.getLibraryObject().getName(); + oldAttributeValue = getCastedModel().getAttributeValue(attributeName); + + if (getCastedModel().canHaveChildren()) { + + newImageControl = new BImage(getCastedModel().getVisualization()); + newImageControl.setAttributeValue(attributeName, attributeValue); + + CreateCommand createCommand = new CreateCommand( + newImageControl, getCastedModel()); + + String imagePath = attributeValue.toString(); + + org.eclipse.swt.graphics.Rectangle imageBounds = null; + Image img = null; + + IFile pFile = getCastedModel().getVisualization().getProjectFile(); + + Rectangle fRect = new Rectangle(getDropLocation().x + - getCastedModel().getLocation().x, getDropLocation().y + - getCastedModel().getLocation().y, 100, 100); + + if (pFile != null) { + final String myPath = (pFile.getProject().getLocation() + + "/images/" + imagePath).replace("file:", ""); + if (new File(myPath).exists() && imagePath.length() > 0) { + img = new Image(Display.getCurrent(), myPath); + imageBounds = img.getBounds(); + } + } + + if (imageBounds != null) { + fRect.width = imageBounds.width; + fRect.height = imageBounds.height; + } + + createCommand.setLayout(fRect); + createCommand.execute(); + + } else { + + if (getCastedModel().hasAttribute( + AttributeConstants.ATTRIBUTE_IMAGE)) + getCastedModel().setAttributeValue(attributeName, + attributeValue); + + } + + } + + public void undo() { + super.undo(); + getCastedModel().removeChild(newImageControl); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/LibraryImageObject.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/LibraryImageObject.java new file mode 100644 index 0000000000000000000000000000000000000000..eed6dc2930f259b9b10c54af1d912bc7257371f0 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/LibraryImageObject.java @@ -0,0 +1,43 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.library; + +import java.io.File; + +import org.eclipse.core.resources.IFile; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; + +import de.bmotionstudio.gef.editor.util.FileUtil; + +public class LibraryImageObject extends LibraryObject { + + public LibraryImageObject(String name, String type, Image typeImage) { + super(name, type, typeImage); + } + + @Override + public void delete(LibraryPage page) { + String myPath = (page.getEditor().getVisualization().getProjectFile() + .getProject().getLocation() + + "/images/" + getName()).replace("file:", ""); + FileUtil.deleteFile(new File(myPath)); + } + + @Override + public Image getPreview(LibraryPage page) { + IFile pFile = page.getEditor().getVisualization().getProjectFile(); + if (pFile != null) { + String myPath = (pFile.getProject().getLocation() + "/images/" + getName()) + .replace("file:", ""); + return new Image(Display.getDefault(), myPath); + } else { + return null; + } + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/LibraryObject.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/LibraryObject.java new file mode 100644 index 0000000000000000000000000000000000000000..25ae33b0adc6efd18ccd05eb6e2c260401c7b590 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/LibraryObject.java @@ -0,0 +1,54 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.library; + +import org.eclipse.swt.graphics.Image; + +public class LibraryObject { + + private String name; + private String type; + private Image typeImage; + + public LibraryObject(String name, String type, Image typeImage) { + this.name = name; + this.type = type; + this.typeImage = typeImage; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public void setImage(Image image) { + this.typeImage = image; + } + + public Image getImage() { + return typeImage; + } + + public void delete(LibraryPage page) { + } + + public Image getPreview(LibraryPage page) { + return null; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/LibraryPage.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/LibraryPage.java new file mode 100644 index 0000000000000000000000000000000000000000..77752772e9e93264e19ccaac2069ff44b12d2890 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/LibraryPage.java @@ -0,0 +1,310 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.library; + +import java.io.File; +import java.io.FilenameFilter; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.databinding.observable.list.WritableList; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.databinding.viewers.ObservableListContentProvider; +import org.eclipse.jface.viewers.CellLabelProvider; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.viewers.ViewerCell; +import org.eclipse.swt.SWT; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.DragSourceAdapter; +import org.eclipse.swt.dnd.DragSourceEvent; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.ui.part.IPageSite; +import org.eclipse.ui.part.Page; + +import de.bmotionstudio.gef.editor.BMotionStudioEditor; +import de.bmotionstudio.gef.editor.BMotionStudioImage; +import de.bmotionstudio.gef.editor.EditorImageRegistry; + +public class LibraryPage extends Page { + + private Image previewImage; + + private TableViewer tvLibrary; + + private Canvas previewCanvas; + + private Composite libMainContainer; + + private Action importImagesAction, deleteItemAction; + + private BMotionStudioEditor editor; + + public LibraryPage(final BMotionStudioEditor editor) { + this.editor = editor; + } + + @Override + public void createControl(final Composite parent) { + + libMainContainer = new Composite(parent, SWT.NONE); + + GridLayout gl = new GridLayout(1, true); + gl.horizontalSpacing = 0; + + libMainContainer.setLayout(gl); + + GridData gd = new GridData(GridData.FILL_BOTH); + gd.horizontalIndent = 0; + + previewCanvas = new Canvas(libMainContainer, SWT.BORDER); + previewCanvas.addPaintListener(new PaintListener() { + public void paintControl(final PaintEvent e) { + if (previewImage == null) { + e.gc.drawString("No preview...", 0, 0); + } else { + e.gc.drawImage(previewImage, 0, 0); + } + } + }); + previewCanvas.setLayoutData(gd); + + Composite libContainer = new Composite(libMainContainer, SWT.NONE); + libContainer.setLayoutData(gd); + libContainer.setLayout(new FillLayout()); + + tvLibrary = new TableViewer(libContainer, SWT.FULL_SELECTION + | SWT.V_SCROLL | SWT.MULTI); + tvLibrary.getTable().setLayoutData(gd); + tvLibrary.addSelectionChangedListener(new ISelectionChangedListener() { + + public void selectionChanged(final SelectionChangedEvent event) { + + IStructuredSelection selection = (IStructuredSelection) event + .getSelection(); + + LibraryObject obj = (LibraryObject) selection.getFirstElement(); + + if (previewImage != null) { + previewImage.dispose(); + } + + if (obj != null) { + previewImage = obj.getPreview(LibraryPage.this); + } else { + previewImage = null; + } + + previewCanvas.redraw(); + + updateActionEnablement(); + + } + + }); + + tvLibrary.getControl().addKeyListener(new KeyAdapter() { + public void keyPressed(final KeyEvent event) { + if (event.character == SWT.DEL && event.stateMask == 0 + && deleteItemAction.isEnabled()) { + deleteItemAction.run(); + } + } + }); + + ObservableListContentProvider contentProvider = new ObservableListContentProvider(); + tvLibrary.setContentProvider(contentProvider); + + tvLibrary.getTable().setLinesVisible(true); + tvLibrary.getTable().setHeaderVisible(true); + + TableViewerColumn column1 = new TableViewerColumn(tvLibrary, SWT.NONE); + column1.getColumn().setText("Name"); + column1.getColumn().setWidth(190); + column1.setLabelProvider(new CellLabelProvider() { + @Override + public void update(final ViewerCell cell) { + cell.setText(((LibraryObject) cell.getElement()).getName()); + cell.setImage(((LibraryObject) cell.getElement()).getImage()); + } + }); + + TableViewerColumn column2 = new TableViewerColumn(tvLibrary, SWT.NONE); + column2.getColumn().setText("Type"); + column2.getColumn().setWidth(60); + column2.setLabelProvider(new CellLabelProvider() { + @Override + public void update(final ViewerCell cell) { + cell.setText(((LibraryObject) cell.getElement()).getType()); + } + }); + + createDragAndDropSupport(); + createActions(); + createContextMenu(); + createMenu(getSite()); + refresh(); + + } + + private void createDragAndDropSupport() { + + tvLibrary.addDragSupport(DND.DROP_COPY, + new Transfer[] { AttributeTransfer.getInstance() }, + new DragSourceAdapter() { + + public void dragSetData(final DragSourceEvent event) { + LibraryObject object = (LibraryObject) ((StructuredSelection) tvLibrary + .getSelection()).getFirstElement(); + + // TODO: Abstract this method!!! + // String attributeID = + // AttributeConstants.ATTRIBUTE_IMAGE; + // if (object.getType().equals("variable")) { + // attributeID = AttributeConstants.ATTRIBUTE_TEXT; + // } + event.data = new AttributeTransferObject(object); + } + + public void dragStart(final DragSourceEvent event) { + } + + }); + + } + + @Override + public Control getControl() { + return libMainContainer; + } + + @Override + public void setFocus() { + libMainContainer.setFocus(); + } + + private void createContextMenu() { + MenuManager manager = new MenuManager(); + tvLibrary.getControl().setMenu( + manager.createContextMenu(tvLibrary.getControl())); + manager.add(deleteItemAction); + } + + public void refresh() { + tvLibrary.setInput(new WritableList(getLibraryObjects(), + LibraryObject.class)); + updateActionEnablement(); + } + + private List<LibraryObject> getLibraryObjects() { + + List<LibraryObject> tmpList = new ArrayList<LibraryObject>(); + + if (editor != null) { + + String basePath = (editor.getVisualization().getProjectFile() + .getProject().getLocation().toString()) + .replace("file:", ""); + File dir = new File(basePath + "/images"); + File[] fileList = dir.listFiles(new FilenameFilter() { + public boolean accept(final File dir, final String name) { + if (name.toLowerCase().endsWith(".jpg") + || name.toLowerCase().endsWith(".gif") + || name.toLowerCase().endsWith(".png")) { + return true; + } + return false; + } + }); + if (fileList != null) { + for (File f : fileList) { + Image img = null; + if (f.getName().toLowerCase().endsWith(".jpg")) { + img = BMotionStudioImage + .getImage(EditorImageRegistry.IMG_ICON_JPG); + } else { + img = BMotionStudioImage + .getImage(EditorImageRegistry.IMG_ICON_GIF); + } + tmpList.add(new LibraryImageObject(f.getName(), "image", + img)); + } + } + + // TODO: Reimplement me!!! + // Visualization vis = this.editor.getVisualization(); + // if (vis != null) { + // for (MachineContentObject obj : vis.getVariableList() + // .getCollection()) { + // tmpList.add(new LibraryVariableObject(obj.getLabel(), + // "variable", BMotionStudioImage + // .getImage(BMotionStudioImage.IMG_LOGO_B))); + // } + // } + + } + + return tmpList; + + } + + private void createMenu(final IPageSite pageSite) { + pageSite.getActionBars().getToolBarManager().add(importImagesAction); + pageSite.getActionBars().getToolBarManager().add(deleteItemAction); + } + + private void createActions() { + importImagesAction = new ImportImagesAction(this); + deleteItemAction = new DeleteItemsAction(this); + } + + private void updateActionEnablement() { + IStructuredSelection sel = (IStructuredSelection) tvLibrary + .getSelection(); + deleteItemAction.setEnabled(sel.size() > 0); + } + + @Override + public void dispose() { + if (previewImage != null) + previewImage.dispose(); + super.dispose(); + } + + public BMotionStudioEditor getEditor() { + return editor; + } + + public void setEditor(final BMotionStudioEditor editor) { + this.editor = editor; + } + + public TableViewer getTableViewer() { + return tvLibrary; + } + + public void setTableViewer(final TableViewer viewer) { + this.tvLibrary = viewer; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/LibraryVariableCommand.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/LibraryVariableCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..39c76dcaf6bffe25e999f136c7b165445483bc11 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/LibraryVariableCommand.java @@ -0,0 +1,64 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.library; + +import org.eclipse.draw2d.geometry.Rectangle; + +import de.bmotionstudio.gef.editor.AttributeConstants; +import de.bmotionstudio.gef.editor.command.CreateCommand; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.model.BText; +import de.bmotionstudio.gef.editor.observer.SimpleValueDisplay; + +public class LibraryVariableCommand extends AbstractLibraryCommand { + + private BControl newControl; + + public void execute() { + + attributeName = AttributeConstants.ATTRIBUTE_TEXT; + attributeValue = transferObject.getLibraryObject().getName(); + oldAttributeValue = getCastedModel().getAttributeValue(attributeName); + + SimpleValueDisplay observer = new SimpleValueDisplay(); + observer.setEval(attributeValue.toString()); + observer.setReplacementString("%%VALUE%%"); + + if (getCastedModel().canHaveChildren()) { + + newControl = new BText(getCastedModel().getVisualization()); + newControl.setAttributeValue(attributeName, attributeValue + + " = %%VALUE%%"); + newControl.addObserver(observer); + + CreateCommand createCommand = new CreateCommand( + newControl, getCastedModel()); + + Rectangle fRect = new Rectangle(getDropLocation().x + - getCastedModel().getLocation().x, getDropLocation().y + - getCastedModel().getLocation().y, 100, 100); + + createCommand.setLayout(fRect); + createCommand.execute(); + + } else { + if (getCastedModel() + .hasAttribute(AttributeConstants.ATTRIBUTE_TEXT)) { + getCastedModel().setAttributeValue(attributeName, + attributeValue + " = %%VALUE%%"); + getCastedModel().addObserver(observer); + } + } + + } + + public void undo() { + super.undo(); + getCastedModel().removeChild(newControl); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/LibraryVariableObject.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/LibraryVariableObject.java new file mode 100644 index 0000000000000000000000000000000000000000..26ac39aedd2586b8518d8d42eef1b9885b64b2c1 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/LibraryVariableObject.java @@ -0,0 +1,20 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ +package de.bmotionstudio.gef.editor.library; + +import org.eclipse.swt.graphics.Image; + +/** + * @author Lukas Ladenberger + * + */ +public class LibraryVariableObject extends LibraryObject { + + public LibraryVariableObject(String name, String type, Image typeImage) { + super(name, type, typeImage); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/LibraryView.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/LibraryView.java new file mode 100644 index 0000000000000000000000000000000000000000..08240a63b7a45fd3e70872f75bd61fbefeb93742 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/library/LibraryView.java @@ -0,0 +1,76 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.library; + +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.part.IPage; +import org.eclipse.ui.part.MessagePage; +import org.eclipse.ui.part.PageBook; +import org.eclipse.ui.part.PageBookView; + +import de.bmotionstudio.gef.editor.BMotionStudioEditor; + +public class LibraryView extends PageBookView { + + public static String ID = "de.bmotionstudio.gef.editor.LibraryView"; + + private String defaultText = "A library is not available."; + + private LibraryPage page; + + public LibraryView() { + super(); + } + + @Override + protected IPage createDefaultPage(PageBook book) { + MessagePage page = new MessagePage(); + initPage(page); + page.createControl(book); + page.setMessage(defaultText); + return page; + } + + @Override + protected PageRec doCreatePage(IWorkbenchPart part) { + if (part instanceof BMotionStudioEditor) { + page = new LibraryPage((BMotionStudioEditor) part); + initPage(page); + page.createControl(getPageBook()); + return new PageRec(part, page); + } + return null; + } + + @Override + protected void doDestroyPage(IWorkbenchPart part, PageRec rec) { + LibraryPage page = (LibraryPage) rec.page; + page.dispose(); + rec.dispose(); + } + + @Override + protected IWorkbenchPart getBootstrapPart() { + IWorkbenchPage page = getSite().getPage(); + if (page != null) { + return page.getActiveEditor(); + } + return null; + } + + public void partBroughtToTop(IWorkbenchPart part) { + partActivated(part); + } + + @Override + protected boolean isImportant(IWorkbenchPart part) { + return (part instanceof IEditorPart); + } + +} \ No newline at end of file diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BButton.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BButton.java new file mode 100644 index 0000000000000000000000000000000000000000..1d7958ee2bb041eeaef9bfac480b569d976851d4 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BButton.java @@ -0,0 +1,43 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.model; + +import org.eclipse.swt.graphics.RGB; + +import de.bmotionstudio.gef.editor.attribute.BAttributeBackgroundColor; +import de.bmotionstudio.gef.editor.attribute.BAttributeEnabled; +import de.bmotionstudio.gef.editor.attribute.BAttributeText; +import de.bmotionstudio.gef.editor.attribute.BAttributeTextColor; + +/** + * @author Lukas Ladenberger + * + */ +public class BButton extends BControl { + + public static transient String TYPE = "de.bmotionstudio.gef.editor.button"; + + public static transient String DEFAULT_TEXT = "Click!"; + + public BButton(Visualization visualization) { + super(visualization); + } + + @Override + public String getType() { + return TYPE; + } + + @Override + protected void initAttributes() { + initAttribute(new BAttributeText(DEFAULT_TEXT)); + initAttribute(new BAttributeBackgroundColor(new RGB(192, 192, 192))); + initAttribute(new BAttributeTextColor(new RGB(0, 0, 0))); + initAttribute(new BAttributeEnabled(true)); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BCheckbox.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BCheckbox.java new file mode 100644 index 0000000000000000000000000000000000000000..95b46552e1c5d6250f6b7ac9722b8970d1e31558 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BCheckbox.java @@ -0,0 +1,64 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.model; + +import org.eclipse.swt.graphics.RGB; + +import de.bmotionstudio.gef.editor.AttributeConstants; +import de.bmotionstudio.gef.editor.attribute.BAttributeButtonGroup; +import de.bmotionstudio.gef.editor.attribute.BAttributeChecked; +import de.bmotionstudio.gef.editor.attribute.BAttributeFalseValue; +import de.bmotionstudio.gef.editor.attribute.BAttributeText; +import de.bmotionstudio.gef.editor.attribute.BAttributeTextColor; +import de.bmotionstudio.gef.editor.attribute.BAttributeTrueValue; +import de.bmotionstudio.gef.editor.attribute.BAttributeValue; + +/** + * @author Lukas Ladenberger + * + */ +public class BCheckbox extends BControl { + + public static transient String TYPE = "de.bmotionstudio.gef.editor.checkbox"; + + public static transient String DEFAULT_TEXT = "Text..."; + + public BCheckbox(Visualization visualization) { + super(visualization); + } + + @Override + public String getType() { + return TYPE; + } + + @Override + protected void initAttributes() { + initAttribute(new BAttributeText(DEFAULT_TEXT)); + initAttribute(new BAttributeTextColor(new RGB(0, 0, 0))); + initAttribute(new BAttributeChecked(true)); + initAttribute(new BAttributeValue("")); + initAttribute(new BAttributeButtonGroup("")); + initAttribute(new BAttributeTrueValue("")); + initAttribute(new BAttributeFalseValue("")); + getAttribute(AttributeConstants.ATTRIBUTE_HEIGHT).setValue(21); + getAttribute(AttributeConstants.ATTRIBUTE_HEIGHT).setEditable(false); + } + + @Override + public String getValueOfData() { + if (Boolean.valueOf(getAttributeValue( + AttributeConstants.ATTRIBUTE_CHECKED).toString())) { + return getAttributeValue(AttributeConstants.ATTRIBUTE_TRUEVALUE) + .toString(); + } else { + return getAttributeValue(AttributeConstants.ATTRIBUTE_FALSEVALUE) + .toString(); + } + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BComposite.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BComposite.java new file mode 100644 index 0000000000000000000000000000000000000000..bd27178b389ce230c92a0be75cc1d86651f0d9fd --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BComposite.java @@ -0,0 +1,42 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.model; + +import org.eclipse.swt.graphics.RGB; + +import de.bmotionstudio.gef.editor.attribute.BAttributeBackgroundColor; +import de.bmotionstudio.gef.editor.attribute.BAttributeImage; + +/** + * @author Lukas Ladenberger + * + */ +public class BComposite extends BControl { + + public static transient String TYPE = "de.bmotionstudio.gef.editor.composite"; + + public BComposite(Visualization visualization) { + super(visualization); + } + + @Override + public String getType() { + return TYPE; + } + + @Override + protected void initAttributes() { + initAttribute(new BAttributeBackgroundColor(new RGB(192, 192, 192))); + initAttribute(new BAttributeImage(null)); + } + + @Override + public boolean canHaveChildren() { + return true; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BConnection.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BConnection.java new file mode 100644 index 0000000000000000000000000000000000000000..7bc29f41187bf6c9727fdae329b3c39956eebf2a --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BConnection.java @@ -0,0 +1,141 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.model; + +import org.eclipse.swt.graphics.RGB; + +import de.bmotionstudio.gef.editor.attribute.BAttributeConnection; +import de.bmotionstudio.gef.editor.attribute.BAttributeConnectionSourceDecoration; +import de.bmotionstudio.gef.editor.attribute.BAttributeConnectionTargetDecoration; +import de.bmotionstudio.gef.editor.attribute.BAttributeForegroundColor; +import de.bmotionstudio.gef.editor.attribute.BAttributeLabel; +import de.bmotionstudio.gef.editor.attribute.BAttributeLineStyle; +import de.bmotionstudio.gef.editor.attribute.BAttributeLineWidth; +import de.bmotionstudio.gef.editor.internal.BControlPropertySource; + +public class BConnection extends BControl { + + public static String TYPE = "de.bmotionstudio.gef.editor.connection"; + + /** True, if the connection is attached to its endpoints. */ + private boolean isConnected; + /** Connection's source endpoint. */ + private BControl source; + /** Connection's target endpoint. */ + private BControl target; + + /** + * Create a (solid) connection between two distinct shapes. + * + * @param source + * a source endpoint for this connection (non null) + * @param target + * a target endpoint for this connection (non null) + * @throws IllegalArgumentException + * if any of the parameters are null or source == target + * @see #setLineStyle(int) + */ + public BConnection(Visualization visualization) { + super(visualization); + } + + /** + * Disconnect this connection from the shapes it is attached to. + */ + public void disconnect() { + if (isConnected) { + source.removeConnection(this); + target.removeConnection(this); + isConnected = false; + } + } + + /** + * Returns the source endpoint of this connection. + * + * @return a non-null Shape instance + */ + public BControl getSource() { + return source; + } + + /** + * Returns the target endpoint of this connection. + * + * @return a non-null Shape instance + */ + public BControl getTarget() { + return target; + } + + public void setTarget(BControl c) { + this.target = c; + } + + public void setSource(BControl c) { + this.source = c; + } + + /** + * Reconnect this connection. The connection will reconnect with the shapes + * it was previously attached to. + */ + public void reconnect() { + if (!isConnected) { + source.addConnection(this); + target.addConnection(this); + isConnected = true; + } + } + + /** + * Reconnect to a different source and/or target shape. The connection will + * disconnect from its current attachments and reconnect to the new source + * and target. + * + * @param newSource + * a new source endpoint for this connection (non null) + * @param newTarget + * a new target endpoint for this connection (non null) + * @throws IllegalArgumentException + * if any of the paramers are null or newSource == newTarget + */ + public void reconnect(BControl newSource, BControl newTarget) { + if (newSource == null || newTarget == null || newSource == newTarget) { + throw new IllegalArgumentException(); + } + disconnect(); + this.source = newSource; + this.target = newTarget; + reconnect(); + } + + @Override + public String getType() { + return TYPE; + } + + @Override + protected void initAttributes() { + BAttributeConnection bAttributeConnection = new BAttributeConnection( + null); + initAttribute(bAttributeConnection, BControlPropertySource.ROOT); + initAttribute(new BAttributeLineWidth(1), bAttributeConnection); + initAttribute(new BAttributeLineStyle( + BAttributeLineStyle.SOLID_CONNECTION), bAttributeConnection); + initAttribute(new BAttributeForegroundColor(new RGB(0, 0, 0)), + bAttributeConnection); + initAttribute(new BAttributeConnectionSourceDecoration( + BAttributeConnectionSourceDecoration.DECORATION_NONE), + bAttributeConnection); + initAttribute(new BAttributeConnectionTargetDecoration( + BAttributeConnectionTargetDecoration.DECORATION_NONE), + bAttributeConnection); + initAttribute(new BAttributeLabel("Label..."), bAttributeConnection); + } + +} \ No newline at end of file diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BControl.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BControl.java new file mode 100644 index 0000000000000000000000000000000000000000..37df8512aa391cdd03e502b9091e0624e71c6786 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BControl.java @@ -0,0 +1,760 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.model; + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.UUID; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.ui.views.properties.IPropertySource; + +import de.bmotionstudio.gef.editor.AttributeConstants; +import de.bmotionstudio.gef.editor.BMotionEditorPlugin; +import de.bmotionstudio.gef.editor.IBControlService; +import de.bmotionstudio.gef.editor.attribute.AbstractAttribute; +import de.bmotionstudio.gef.editor.attribute.BAttributeCoordinates; +import de.bmotionstudio.gef.editor.attribute.BAttributeCustom; +import de.bmotionstudio.gef.editor.attribute.BAttributeHeight; +import de.bmotionstudio.gef.editor.attribute.BAttributeID; +import de.bmotionstudio.gef.editor.attribute.BAttributeSize; +import de.bmotionstudio.gef.editor.attribute.BAttributeVisible; +import de.bmotionstudio.gef.editor.attribute.BAttributeWidth; +import de.bmotionstudio.gef.editor.attribute.BAttributeX; +import de.bmotionstudio.gef.editor.attribute.BAttributeY; +import de.bmotionstudio.gef.editor.internal.Animation; +import de.bmotionstudio.gef.editor.internal.BControlPropertySource; +import de.bmotionstudio.gef.editor.observer.IObserverListener; +import de.bmotionstudio.gef.editor.observer.Observer; +import de.bmotionstudio.gef.editor.scheduler.SchedulerEvent; + +/** + * + * A Control is a graphical representation of some aspects of the model. + * Typically we use labels, images or buttons to represent informations. For + * instance, if we model a system that has a temperature and a threshold + * temperature that triggers a cool down, we might simply use two labels + * displaying both values, or maybe we can incorporate both information into a + * gauge display. It is also possible to define new controls for domain specific + * visualizations. + * + * @author Lukas Ladenberger + * + */ +public abstract class BControl implements IAdaptable, Cloneable { + + /** The type of the control (e.g. label, button ...) */ + protected String type; + + private transient Rectangle layout = null; + + private transient Point location = null; + + private BControlList children; + + private Map<String, Observer> observers; + + private Map<String, SchedulerEvent> events; + + private Map<String, AbstractAttribute> attributes; + + /** + * Since the parent is set via the method readResolve(), we mark the + * variable as transient + */ + private transient BControl parent; + + private transient Visualization visualization; + + private transient PropertyChangeSupport listeners; + + private transient ArrayList<IObserverListener> observerListener; + + private BMotionGuide verticalGuide, horizontalGuide; + + /** List of outgoing Connections. */ + private List<BConnection> sourceConnections; + /** List of incoming Connections. */ + private List<BConnection> targetConnections; + + public static final transient String PROPERTY_LAYOUT = "NodeLayout"; + public static final transient String PROPERTY_LOCATION = "NodeLocation"; + public static final transient String PROPERTY_ADD = "NodeAddChild"; + public static final transient String PROPERTY_REMOVE = "NodeRemoveChild"; + public static final transient String PROPERTY_RENAME = "NodeRename"; + /** Property ID to use when the list of outgoing connections is modified. */ + public static final String SOURCE_CONNECTIONS_PROP = "BMS.SourceConn"; + /** Property ID to use when the list of incoming connections is modified. */ + public static final String TARGET_CONNECTIONS_PROP = "BMS.TargetConn"; + + public BControl(Visualization visualization) { + this.visualization = visualization; + this.children = new BControlList(); + this.observers = new HashMap<String, Observer>(); + this.events = new HashMap<String, SchedulerEvent>(); + this.attributes = new HashMap<String, AbstractAttribute>(); + this.listeners = new PropertyChangeSupport(this); + this.observerListener = new ArrayList<IObserverListener>(); + this.sourceConnections = new ArrayList<BConnection>(); + this.targetConnections = new ArrayList<BConnection>(); + init(); + } + + protected Object readResolve() { + // Populate parent + for (BControl child : getChildrenArray()) + child.setParent(this); + return this; + } + + /** + * Remove an incoming or outgoing connection from this shape. + * + * @param conn + * a non-null connection instance + * @throws IllegalArgumentException + * if the parameter is null + */ + public void removeConnection(BConnection conn) { + if (conn == null) { + throw new IllegalArgumentException(); + } + if (conn.getSource() == this) { + getSourceConnections().remove(conn); + getListeners().firePropertyChange(SOURCE_CONNECTIONS_PROP, null, + conn); + } else if (conn.getTarget() == this) { + getTargetConnections().remove(conn); + getListeners().firePropertyChange(TARGET_CONNECTIONS_PROP, null, + conn); + } + } + + /** + * Add an incoming or outgoing connection to this shape. + * + * @param conn + * a non-null connection instance + * @throws IllegalArgumentException + * if the connection is null or has not distinct endpoints + */ + public void addConnection(BConnection conn) { + if (conn == null || conn.getSource() == conn.getTarget()) { + throw new IllegalArgumentException(); + } + conn.setVisualization(getVisualization()); + if (conn.getSource() == this) { + getSourceConnections().add(conn); + getListeners().firePropertyChange(SOURCE_CONNECTIONS_PROP, null, + conn); + } else if (conn.getTarget() == this) { + getTargetConnections().add(conn); + getListeners().firePropertyChange(TARGET_CONNECTIONS_PROP, null, + conn); + } + } + + private void init() { + + // Init ID + String ID; + if (this instanceof Visualization) + ID = "visualization"; + else if (visualization == null) + ID = UUID.randomUUID().toString(); + else + ID = (visualization.getMaxIDString(type)); + initAttribute(new BAttributeID(ID), AbstractAttribute.ROOT); + + // Init location and dimension attributes + BAttributeCoordinates coordinatesAtr = new BAttributeCoordinates(null); + initAttribute(coordinatesAtr, AbstractAttribute.ROOT); + initAttribute(new BAttributeX(100), coordinatesAtr); + initAttribute(new BAttributeY(100), coordinatesAtr); + + BAttributeSize sizeAtr = new BAttributeSize(null); + initAttribute(sizeAtr, AbstractAttribute.ROOT); + initAttribute(new BAttributeWidth(100), sizeAtr); + initAttribute(new BAttributeHeight(100), sizeAtr); + + // Init visible and this attribute + initAttribute(new BAttributeVisible(true), AbstractAttribute.ROOT); + initAttribute(new BAttributeCustom(""), AbstractAttribute.ROOT); + + // Init custom control attributes + initAttributes(); + + } + + protected abstract void initAttributes(); + + public String getID() { + return getAttributeValue(AttributeConstants.ATTRIBUTE_ID).toString(); + } + + public AbstractAttribute getAttribute(String attributeID) { + return getAttributes().get(attributeID); + } + + public Object getAttributeValue(String attributeID) { + + AbstractAttribute atr = attributes.get(attributeID); + + if (atr != null) { + return atr.getValue(); + } else { + // TODO: handle error/exception (no such attribute) + return null; + } + + } + + public boolean setAttributeValue(String attributeID, Object value) { + return setAttributeValue(attributeID, value, true); + } + + public boolean setAttributeValue(String attributeID, Object value, + Boolean firePropertyChange) { + + AbstractAttribute atr = attributes.get(attributeID); + + if (atr == null) { + return false; + // TODO: Throw some error!?! + } + + atr.setControl(this); + + if ((atr.getValue() != null && atr.getValue().equals(value)) + || !atr.isEditable()) + return true; + + atr.setValue(value, firePropertyChange); + + return true; + + } + + public void restoreDefaultValue(String attributeID) { + AbstractAttribute atr = attributes.get(attributeID); + if (atr != null) { + atr.restoreValue(); + Object oldVal = atr.getValue(); + Object initValue = atr.getInitValue(); + getListeners().firePropertyChange(attributeID, oldVal, initValue); + } + } + + public boolean hasAttribute(String attributeID) { + return attributes.containsKey(attributeID); + } + + public void setLayout(Rectangle newLayout) { + Rectangle oldLayout = getLayout(); + layout = newLayout; + setAttributeValue(AttributeConstants.ATTRIBUTE_X, newLayout.x, false); + setAttributeValue(AttributeConstants.ATTRIBUTE_Y, newLayout.y, false); + setAttributeValue(AttributeConstants.ATTRIBUTE_WIDTH, newLayout.width, + false); + setAttributeValue(AttributeConstants.ATTRIBUTE_HEIGHT, + newLayout.height, false); + getListeners() + .firePropertyChange(PROPERTY_LAYOUT, oldLayout, newLayout); + } + + public Rectangle getLayout() { + int width = Integer.valueOf(getAttributeValue( + AttributeConstants.ATTRIBUTE_WIDTH).toString()); + int height = Integer.valueOf(getAttributeValue( + AttributeConstants.ATTRIBUTE_HEIGHT).toString()); + int x = Integer.valueOf(getAttributeValue( + AttributeConstants.ATTRIBUTE_X).toString()); + int y = Integer.valueOf(getAttributeValue( + AttributeConstants.ATTRIBUTE_Y).toString()); + if (layout == null) { + layout = new Rectangle(x, y, width, height); + } else { + layout.x = x; + layout.y = y; + layout.width = width; + layout.height = height; + } + return layout; + } + + public void setLocation(Point newLocation) { + Point oldLocation = getLocation(); + location = newLocation; + setAttributeValue(AttributeConstants.ATTRIBUTE_X, newLocation.x, false); + setAttributeValue(AttributeConstants.ATTRIBUTE_Y, newLocation.y, false); + getListeners().firePropertyChange(PROPERTY_LOCATION, oldLocation, + newLocation); + } + + public Point getLocation() { + int x = Integer.valueOf(getAttributeValue( + AttributeConstants.ATTRIBUTE_X).toString()); + int y = Integer.valueOf(getAttributeValue( + AttributeConstants.ATTRIBUTE_Y).toString()); + if (location == null) { + location = new Point(x, y); + } else { + location.x = x; + location.y = y; + } + return location; + } + + public Dimension getDimension() { + int width = Integer.valueOf(getAttributeValue( + AttributeConstants.ATTRIBUTE_WIDTH).toString()); + int height = Integer.valueOf(getAttributeValue( + AttributeConstants.ATTRIBUTE_HEIGHT).toString()); + return new Dimension(width, height); + } + + public void addChild(BControl child) { + addChild(child, -1); + } + + public void addChild(BControl child, int index) { + child.setParent(this); + if (index >= 0) { + children.add(index, child); + } else { + children.add(child); + } + getListeners().firePropertyChange(PROPERTY_ADD, index, child); + } + + public boolean removeChild(BControl child) { + boolean b = children.remove(child); + if (b) + getListeners().firePropertyChange(PROPERTY_REMOVE, child, null); + return b; + } + + public List<BControl> getChildrenArray() { + if (children == null) + children = new BControlList(); + return children; + } + + public void setChildrenArray(BControlList children) { + this.children = children; + } + + public boolean hasChildren() { + return children.size() > 0; + } + + public BControl getChild(String ID) { + for (BControl bcontrol : children) { + String bcontrolID = bcontrol.getAttributeValue( + AttributeConstants.ATTRIBUTE_ID).toString(); + if (bcontrolID != null) { + if (bcontrolID.equals(ID)) + return bcontrol; + } + } + return null; + } + + public Map<String, Observer> getObservers() { + if (observers == null) + observers = new HashMap<String, Observer>(); + return observers; + } + + public Observer getObserver(String observerID) { + return this.observers.get(observerID); + } + + public Boolean hasObserver(String ID) { + if (getObservers().containsKey(ID)) + return true; + return false; + } + + public void addObserver(Observer observer) { + observers.put(observer.getID(), (Observer) observer); + for (IObserverListener listener : getObserverListener()) { + listener.addedObserver(this, observer); + } + } + + public void removeObserver(String observerID) { + if (hasObserver(observerID)) + observers.get(observerID).beforeDelete(this); + observers.remove(observerID); + for (IObserverListener listener : getObserverListener()) { + listener.removedObserver(this); + } + } + + public Map<String, SchedulerEvent> getEvents() { + if (events == null) + events = new HashMap<String, SchedulerEvent>(); + return events; + } + + public SchedulerEvent getEvent(String ID) { + return events.get(ID); + } + + public Boolean hasEvent(String ID) { + if (getEvents().containsKey(ID)) + return true; + return false; + } + + public void addEvent(String eventID, SchedulerEvent schedulerEvent) { + events.put(eventID, schedulerEvent); + } + + public void removeEvent(String eventID) { + if (hasEvent(eventID)) + events.get(eventID).beforeDelete(this); + events.remove(eventID); + } + + public Map<String, AbstractAttribute> getAttributes() { + return attributes; + } + + public void setAttributes(Map<String, AbstractAttribute> attributes) { + this.attributes = attributes; + } + + public void setParent(BControl parent) { + this.parent = parent; + } + + public BControl getParent() { + return this.parent; + } + + public void addPropertyChangeListener(PropertyChangeListener listener) { + getListeners().addPropertyChangeListener(listener); + } + + public PropertyChangeSupport getListeners() { + if (listeners == null) + listeners = new PropertyChangeSupport(this); + return listeners; + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + getListeners().removePropertyChangeListener(listener); + } + + public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) { + if (adapter == IPropertySource.class) { + return new BControlPropertySource(this); + } + return null; + } + + public boolean contains(BControl child) { + return children.contains(child); + } + + public String getDefaultValue(String attributeID) { + + IConfigurationElement configurationElement = BMotionEditorPlugin + .getControlExtension(getType()); + + if (configurationElement != null) { + + for (final IConfigurationElement configBAttributes : configurationElement + .getChildren("attributes")) { + + for (final IConfigurationElement configBAttribute : configBAttributes + .getChildren("attribute-string")) { + + String aID = configBAttribute.getAttribute("id"); + + if (aID.equals(attributeID)) { + String attributeDefaultValue = configBAttribute + .getAttribute("default-value"); + + return attributeDefaultValue; + } + + } + + } + + } + + return null; + + } + + public Boolean isAttributeEditable(String attributeID) { + + IConfigurationElement configurationElement = BMotionEditorPlugin + .getControlExtension(getType()); + + if (configurationElement != null) { + + for (final IConfigurationElement configBAttributes : configurationElement + .getChildren("attributes")) { + + for (final IConfigurationElement configBAttribute : configBAttributes + .getChildren("attribute-string")) { + + String aID = configBAttribute.getAttribute("id"); + + if (aID.equals(attributeID)) { + String val = configBAttribute.getAttribute("editable"); + return Boolean.valueOf(val); + } + + } + + } + + } + + return false; + + } + + public Visualization getVisualization() { + return visualization; + } + + public void setVisualization(Visualization visualization) { + this.visualization = visualization; + } + + protected void populateVisualization(Visualization visualization) { + // Populate visualization node + setVisualization(visualization); + for (BControl child : getChildrenArray()) + child.populateVisualization(visualization); + for (BConnection con : getTargetConnections()) + con.populateVisualization(visualization); + for (BConnection con : getSourceConnections()) + con.populateVisualization(visualization); + } + + @Override + public BControl clone() throws CloneNotSupportedException { + + BControl clonedControl = (BControl) super.clone(); + + IConfigurationElement configElement = BMotionEditorPlugin + .getControlServices().get(getType()); + if (configElement != null) { + + try { + + IBControlService service = (IBControlService) configElement + .createExecutableExtension("service"); + clonedControl = service.createControl(visualization); + + clonedControl.setParent(getParent()); + + String newID = clonedControl.getID(); + + Map<String, AbstractAttribute> newProperties = new HashMap<String, AbstractAttribute>(); + for (Entry<String, AbstractAttribute> e : getAttributes() + .entrySet()) { + AbstractAttribute idAtr = e.getValue().clone(); + newProperties.put(e.getKey(), idAtr); + } + + clonedControl.setAttributes(newProperties); + clonedControl.setAttributeValue( + AttributeConstants.ATTRIBUTE_ID, newID); + + Iterator<BControl> it = getChildrenArray().iterator(); + while (it.hasNext()) { + clonedControl.addChild(((BControl) it.next()).clone()); + } + + for (Observer observer : observers.values()) { + clonedControl.addObserver(observer.clone()); + } + + for (Map.Entry<String, SchedulerEvent> e : events.entrySet()) { + clonedControl.addEvent(e.getKey(), e.getValue().clone()); + } + + } catch (CoreException e) { + e.printStackTrace(); + } + + } + + return clonedControl; + + } + + public void checkObserver(final Animation animation) { + + // Check all Observers + for (Observer observer : getObservers().values()) { + observer.check(animation, BControl.this); + } + + // TODO: Currently connection observer are checked twice (source + + // target) => change this, so that observer are checked only on time per + // state!!! + for (BConnection con : getSourceConnections()) { + con.checkObserver(animation); + } + for (BConnection con : getTargetConnections()) { + con.checkObserver(animation); + } + + // Check Observers of children + if (getChildrenArray().size() > 0) { + for (BControl bcontrol : getChildrenArray()) { + bcontrol.checkObserver(animation); + } + } + + } + + public void afterCheckObserver(Animation animation) { + // Check all Observers + for (Observer observer : getObservers().values()) { + observer.afterCheck(animation, this); + } + // Check Observers of children + if (getChildrenArray().size() > 0) { + for (BControl bcontrol : getChildrenArray()) { + bcontrol.afterCheckObserver(animation); + } + } + } + + public void executeEvent(String eventID) { + if (hasAttribute(AttributeConstants.ATTRIBUTE_ENABLED)) { + if (!(Boolean) getAttributeValue(AttributeConstants.ATTRIBUTE_ENABLED)) + return; + } + SchedulerEvent e = getEvents().get(eventID); + if (e != null) + e.execute(getVisualization().getAnimation(), this); + } + + public void setVerticalGuide(BMotionGuide verticalGuide) { + this.verticalGuide = verticalGuide; + } + + public BMotionGuide getVerticalGuide() { + return verticalGuide; + } + + public void setHorizontalGuide(BMotionGuide horizontalGuide) { + this.horizontalGuide = horizontalGuide; + } + + public BMotionGuide getHorizontalGuide() { + return horizontalGuide; + } + + /** + * @return the observerListener + */ + public ArrayList<IObserverListener> getObserverListener() { + if (observerListener == null) + observerListener = new ArrayList<IObserverListener>(); + return observerListener; + } + + public void addObserverListener(IObserverListener listener) { + getObserverListener().add(listener); + } + + public void removeObserverListener(IObserverListener listener) { + getObserverListener().remove(listener); + } + + /** + * Return a List of outgoing Connections. + */ + public List<BConnection> getSourceConnections() { + if (this.sourceConnections == null) + this.sourceConnections = new ArrayList<BConnection>(); + return this.sourceConnections; + } + + public void setSourceConnections(List<BConnection> connections) { + this.sourceConnections = connections; + } + + public void setTargetConnections(List<BConnection> connections) { + this.targetConnections = connections; + } + + /** + * Return a List of incoming Connections. + */ + public List<BConnection> getTargetConnections() { + if (this.targetConnections == null) + this.targetConnections = new ArrayList<BConnection>(); + return this.targetConnections; + } + + public boolean hasConnections() { + return !getTargetConnections().isEmpty() + || !getSourceConnections().isEmpty(); + } + + public boolean showInOutlineView() { + return true; + } + + public void setObserverMap(Map<String, Observer> observerMap) { + observers = observerMap; + } + + public void setEventMap(Map<String, SchedulerEvent> eventMap) { + events = eventMap; + } + + public abstract String getType(); + + protected void initAttribute(AbstractAttribute atr) { + getAttributes().put(atr.getID(), atr); + } + + protected void initAttribute(AbstractAttribute atr, AbstractAttribute group) { + initAttribute(atr, group.getClass().getName()); + } + + protected void initAttribute(AbstractAttribute atr, String group) { + atr.setGroup(group); + initAttribute(atr); + } + + public boolean canHaveChildren() { + return false; + } + + public String getValueOfData() { + return getAttributeValue(AttributeConstants.ATTRIBUTE_CUSTOM) + .toString(); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BControlList.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BControlList.java new file mode 100644 index 0000000000000000000000000000000000000000..8b156629c91fed2acbc5da0e93d048713c413a25 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BControlList.java @@ -0,0 +1,19 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.model; + +import java.util.ArrayList; + +/** + * @author Lukas Ladenberger + * + */ +public class BControlList extends ArrayList<BControl> { + + private static final long serialVersionUID = 1L; + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BImage.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BImage.java new file mode 100644 index 0000000000000000000000000000000000000000..56bfeb04b8aaed27b1f8b8973aebc1d2a99e4468 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BImage.java @@ -0,0 +1,33 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.model; + +import de.bmotionstudio.gef.editor.attribute.BAttributeImage; + +/** + * @author Lukas Ladenberger + * + */ +public class BImage extends BControl { + + public static transient String TYPE = "de.bmotionstudio.gef.editor.image"; + + public BImage(Visualization visualization) { + super(visualization); + } + + @Override + public String getType() { + return TYPE; + } + + @Override + protected void initAttributes() { + initAttribute(new BAttributeImage(null)); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BMotionGuide.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BMotionGuide.java new file mode 100644 index 0000000000000000000000000000000000000000..37bd419e09e0ecc8ff3bc9ec7940e58d8528c00b --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BMotionGuide.java @@ -0,0 +1,218 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.model; + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.io.Serializable; +import java.util.HashMap; +import java.util.Set; + +import org.eclipse.gef.EditPart; +import org.eclipse.gef.requests.ChangeBoundsRequest; + +/** + * Model object representing a guide. + * <p> + * In addition to maintaining information about which parts are attached to the + * guide, LogicGuide also maintains information about the edge along which those + * parts are attached. This information is useful during resize operations to + * determine the attachment status of a part. + * </p> + */ +public class BMotionGuide implements Serializable { + + /** + * Property used to notify listeners when the parts attached to a guide are + * changed + */ + public transient static final String PROPERTY_CHILDREN = "subparts changed"; //$NON-NLS-1$ + /** + * Property used to notify listeners when the guide is re-positioned + */ + public transient static final String PROPERTY_POSITION = "position changed"; //$NON-NLS-1$ + + static transient final long serialVersionUID = 1; + + protected transient PropertyChangeSupport listeners = new PropertyChangeSupport( + this); + private HashMap<BControl, Integer> map; + private int position; + private boolean horizontal; + + /** + * Empty default constructor + */ + public BMotionGuide() { + // empty constructor + } + + /** + * Constructor + * + * @param isHorizontal + * <code>true</code> if the guide is horizontal (i.e., placed on + * a vertical ruler) + */ + public BMotionGuide(boolean isHorizontal) { + setHorizontal(isHorizontal); + } + + protected Object readResolve() { + this.listeners = new PropertyChangeSupport(this); + return this; + } + + /** + * @see PropertyChangeSupport#addPropertyChangeListener(java.beans.PropertyChangeListener) + */ + public void addPropertyChangeListener(PropertyChangeListener listener) { + listeners.addPropertyChangeListener(listener); + } + + /* + * @TODO:Pratik use PositionConstants here + */ + /** + * Attaches the given part along the given edge to this guide. The + * LogicSubpart is also updated to reflect this attachment. + * + * @param part + * The part that is to be attached to this guide; if the part is + * already attached, its alignment is updated + * @param alignment + * -1 is left or top; 0, center; 1, right or bottom + */ + public void attachPart(BControl control, int alignment) { + + if (getMap().containsKey(control) && getAlignment(control) == alignment) + return; + + getMap().put(control, Integer.valueOf(alignment)); + + BMotionGuide parent = isHorizontal() ? control.getHorizontalGuide() + : control.getVerticalGuide(); + if (parent != null && parent != this) { + parent.detachPart(control); + } + if (isHorizontal()) { + control.setHorizontalGuide(this); + } else { + control.setVerticalGuide(this); + } + listeners.firePropertyChange(PROPERTY_CHILDREN, null, control); + + } + + /** + * Detaches the given part from this guide. The LogicSubpart is also updated + * to reflect this change. + * + * @param part + * the part that is to be detached from this guide + */ + public void detachPart(BControl control) { + if (getMap().containsKey(control)) { + getMap().remove(control); + if (isHorizontal()) { + control.setHorizontalGuide(null); + } else { + control.setVerticalGuide(null); + } + listeners.firePropertyChange(PROPERTY_CHILDREN, null, control); + } + } + + /** + * This methods returns the edge along which the given part is attached to + * this guide. This information is used by + * {@link org.eclipse.gef.examples.logicdesigner.edit.LogicXYLayoutEditPolicy + * LogicXYLayoutEditPolicy} to determine whether to attach or detach a part + * from a guide during resize operations. + * + * @param part + * The part whose alignment has to be found + * @return an int representing the edge along which the given part is + * attached to this guide; 1 is bottom or right; 0, center; -1, top + * or left; -2 if the part is not attached to this guide + * @see org.eclipse.gef.examples.logicdesigner.edit.LogicXYLayoutEditPolicy#createChangeConstraintCommand(ChangeBoundsRequest, + * EditPart, Object) + */ + public int getAlignment(BControl part) { + if (getMap().get(part) != null) + return ((Integer) getMap().get(part)).intValue(); + return -2; + } + + /** + * @return The Map containing all the parts attached to this guide, and + * their alignments; the keys are LogicSubparts and values are + * Integers + */ + public HashMap<BControl, Integer> getMap() { + if (map == null) { + map = new HashMap<BControl, Integer>(); + } + return map; + } + + /** + * @return the set of all the parts attached to this guide; a set is used + * because a part can only be attached to a guide along one edge. + */ + public Set<BControl> getParts() { + return getMap().keySet(); + } + + /** + * @return the position/location of the guide (in pixels) + */ + public int getPosition() { + return position; + } + + /** + * @return <code>true</code> if the guide is horizontal (i.e., placed on a + * vertical ruler) + */ + public boolean isHorizontal() { + return horizontal; + } + + /** + * @see PropertyChangeSupport#removePropertyChangeListener(java.beans.PropertyChangeListener) + */ + public void removePropertyChangeListener(PropertyChangeListener listener) { + listeners.removePropertyChangeListener(listener); + } + + /** + * Sets the orientation of the guide + * + * @param isHorizontal + * <code>true</code> if this guide is to be placed on a vertical + * ruler + */ + public void setHorizontal(boolean isHorizontal) { + horizontal = isHorizontal; + } + + /** + * Sets the location of the guide + * + * @param offset + * The location of the guide (in pixels) + */ + public void setPosition(int offset) { + if (position != offset) { + int oldValue = position; + position = offset; + listeners.firePropertyChange(PROPERTY_POSITION, + Integer.valueOf(oldValue), Integer.valueOf(position)); + } + } +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BMotionRuler.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BMotionRuler.java new file mode 100644 index 0000000000000000000000000000000000000000..cb3d4333d1d2fd09199c19f7773ecb42baae071b --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BMotionRuler.java @@ -0,0 +1,95 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.model; + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.gef.rulers.RulerProvider; + + +public class BMotionRuler implements Serializable { + + public transient static final String PROPERTY_CHILDREN = "children changed"; //$NON-NLS-1$ + public transient static final String PROPERTY_UNIT = "units changed"; //$NON-NLS-1$ + + static transient final long serialVersionUID = 1; + + protected transient PropertyChangeSupport listeners = new PropertyChangeSupport( + this); + private int unit; + private boolean horizontal; + private List<BMotionGuide> guides = new ArrayList<BMotionGuide>(); + + public BMotionRuler(boolean isHorizontal) { + this(isHorizontal, RulerProvider.UNIT_PIXELS); + } + + public BMotionRuler(boolean isHorizontal, int unit) { + horizontal = isHorizontal; + setUnit(unit); + } + + protected Object readResolve() { + this.listeners = new PropertyChangeSupport(this); + return this; + } + + public void addGuide(BMotionGuide guide) { + if (!guides.contains(guide)) { + guide.setHorizontal(!isHorizontal()); + guides.add(guide); + listeners.firePropertyChange(PROPERTY_CHILDREN, null, guide); + } + } + + public void addPropertyChangeListener(PropertyChangeListener listener) { + listeners.addPropertyChangeListener(listener); + } + + // the returned list should not be modified + public List<BMotionGuide> getGuides() { + return guides; + } + + public int getUnit() { + return unit; + } + + public boolean isHidden() { + return false; + } + + public boolean isHorizontal() { + return horizontal; + } + + public void removeGuide(BMotionGuide guide) { + if (guides.remove(guide)) { + listeners.firePropertyChange(PROPERTY_CHILDREN, null, guide); + } + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + listeners.removePropertyChangeListener(listener); + } + + public void setHidden(boolean isHidden) { + } + + public void setUnit(int newUnit) { + if (unit != newUnit) { + int oldUnit = unit; + unit = newUnit; + listeners.firePropertyChange(PROPERTY_UNIT, oldUnit, newUnit); + } + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BMotionRulerProvider.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BMotionRulerProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..a124bbededfbed0e8917e02ad3d45b4c8d910f9c --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BMotionRulerProvider.java @@ -0,0 +1,118 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.model; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.gef.commands.Command; +import org.eclipse.gef.rulers.RulerChangeListener; +import org.eclipse.gef.rulers.RulerProvider; + +import de.bmotionstudio.gef.editor.command.CreateGuideCommand; +import de.bmotionstudio.gef.editor.command.DeleteGuideCommand; +import de.bmotionstudio.gef.editor.command.MoveGuideCommand; + +public class BMotionRulerProvider extends RulerProvider { + + private BMotionRuler ruler; + private PropertyChangeListener rulerListener = new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals(BMotionRuler.PROPERTY_CHILDREN)) { + BMotionGuide guide = (BMotionGuide) evt.getNewValue(); + if (getGuides().contains(guide)) { + guide.addPropertyChangeListener(guideListener); + } else { + guide.removePropertyChangeListener(guideListener); + } + for (int i = 0; i < listeners.size(); i++) { + ((RulerChangeListener) listeners.get(i)) + .notifyGuideReparented(guide); + } + } else { + for (int i = 0; i < listeners.size(); i++) { + ((RulerChangeListener) listeners.get(i)) + .notifyUnitsChanged(ruler.getUnit()); + } + } + } + }; + private PropertyChangeListener guideListener = new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals(BMotionGuide.PROPERTY_CHILDREN)) { + for (int i = 0; i < listeners.size(); i++) { + ((RulerChangeListener) listeners.get(i)) + .notifyPartAttachmentChanged(evt.getNewValue(), evt + .getSource()); + } + } else { + for (int i = 0; i < listeners.size(); i++) { + ((RulerChangeListener) listeners.get(i)) + .notifyGuideMoved(evt.getSource()); + } + } + } + }; + + public BMotionRulerProvider(BMotionRuler ruler) { + this.ruler = ruler; + this.ruler.addPropertyChangeListener(rulerListener); + List<BMotionGuide> guides = getGuides(); + for (int i = 0; i < guides.size(); i++) { + ((BMotionGuide) guides.get(i)) + .addPropertyChangeListener(guideListener); + } + } + + public List<BControl> getAttachedModelObjects(Object guide) { + return new ArrayList<BControl>(((BMotionGuide) guide).getParts()); + } + + public Command getCreateGuideCommand(int position) { + return new CreateGuideCommand(ruler, position); + } + + public Command getDeleteGuideCommand(Object guide) { + return new DeleteGuideCommand((BMotionGuide) guide, ruler); + } + + public Command getMoveGuideCommand(Object guide, int pDelta) { + return new MoveGuideCommand((BMotionGuide) guide, pDelta); + } + + public int[] getGuidePositions() { + List<BMotionGuide> guides = getGuides(); + int[] result = new int[guides.size()]; + for (int i = 0; i < guides.size(); i++) { + result[i] = ((BMotionGuide) guides.get(i)).getPosition(); + } + return result; + } + + public Object getRuler() { + return ruler; + } + + public int getUnit() { + return ruler.getUnit(); + } + + public void setUnit(int newUnit) { + ruler.setUnit(newUnit); + } + + public int getGuidePosition(Object guide) { + return ((BMotionGuide) guide).getPosition(); + } + + public List<BMotionGuide> getGuides() { + return ruler.getGuides(); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BRadioButton.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BRadioButton.java new file mode 100644 index 0000000000000000000000000000000000000000..4afdda7f530120b9880822696432cd6f104da418 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BRadioButton.java @@ -0,0 +1,83 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.model; + +import java.util.Collection; + +import org.eclipse.swt.graphics.RGB; + +import de.bmotionstudio.gef.editor.AttributeConstants; +import de.bmotionstudio.gef.editor.ButtonGroupHelper; +import de.bmotionstudio.gef.editor.attribute.BAttributeBackgroundColor; +import de.bmotionstudio.gef.editor.attribute.BAttributeButtonGroup; +import de.bmotionstudio.gef.editor.attribute.BAttributeChecked; +import de.bmotionstudio.gef.editor.attribute.BAttributeText; +import de.bmotionstudio.gef.editor.attribute.BAttributeTextColor; +import de.bmotionstudio.gef.editor.attribute.BAttributeValue; + +/** + * @author Lukas Ladenberger + * + */ +public class BRadioButton extends BControl { + + public static transient String TYPE = "de.bmotionstudio.gef.editor.radiobutton"; + + public static transient String DEFAULT_TEXT = "Text..."; + + public BRadioButton(Visualization visualization) { + super(visualization); + } + + /* + * (non-Javadoc) + * + * @see de.bmotionstudio.gef.editor.model.BControl#getType() + */ + @Override + public String getType() { + return TYPE; + } + + @Override + protected void initAttributes() { + initAttribute(new BAttributeText(DEFAULT_TEXT)); + initAttribute(new BAttributeBackgroundColor(new RGB(192, 192, 192))); + initAttribute(new BAttributeTextColor(new RGB(0, 0, 0))); + initAttribute(new BAttributeChecked(true)); + initAttribute(new BAttributeValue("")); + initAttribute(new BAttributeButtonGroup("")); + getAttribute(AttributeConstants.ATTRIBUTE_HEIGHT).setValue(21); + getAttribute(AttributeConstants.ATTRIBUTE_HEIGHT).setEditable(false); + } + + @Override + public String getValueOfData() { + String btgroupid = getAttributeValue( + AttributeConstants.ATTRIBUTE_BUTTONGROUP).toString(); + if (!btgroupid.trim().equals("")) { + Collection<BControl> btGroup = ButtonGroupHelper + .getButtonGroup(btgroupid); + return getValueFromButtonGroup(btGroup); + } else { + return getAttributeValue(AttributeConstants.ATTRIBUTE_VALUE) + .toString(); + } + } + + private String getValueFromButtonGroup(Collection<BControl> group) { + for (BControl control : group) { + if (Boolean.valueOf(control.getAttributeValue( + AttributeConstants.ATTRIBUTE_CHECKED).toString())) { + return control.getAttributeValue( + AttributeConstants.ATTRIBUTE_VALUE).toString(); + } + } + return null; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BShape.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BShape.java new file mode 100644 index 0000000000000000000000000000000000000000..66ac95f8112f3c36d1cd99bf05c8f2df5f760b7c --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BShape.java @@ -0,0 +1,52 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.model; + +import org.eclipse.swt.graphics.RGB; + +import de.bmotionstudio.gef.editor.attribute.BAttributeAlpha; +import de.bmotionstudio.gef.editor.attribute.BAttributeBackgroundColor; +import de.bmotionstudio.gef.editor.attribute.BAttributeDirection; +import de.bmotionstudio.gef.editor.attribute.BAttributeFillType; +import de.bmotionstudio.gef.editor.attribute.BAttributeForegroundColor; +import de.bmotionstudio.gef.editor.attribute.BAttributeImage; +import de.bmotionstudio.gef.editor.attribute.BAttributeOrientation; +import de.bmotionstudio.gef.editor.attribute.BAttributeOutlineAlpha; +import de.bmotionstudio.gef.editor.attribute.BAttributeShape; + +/** + * @author Lukas Ladenberger + * + */ +public class BShape extends BControl { + + public static transient String TYPE = "de.bmotionstudio.gef.editor.shape"; + + public BShape(Visualization visualization) { + super(visualization); + } + + @Override + public String getType() { + return TYPE; + } + + @Override + protected void initAttributes() { + initAttribute(new BAttributeBackgroundColor(new RGB(255, 0, 0))); + initAttribute(new BAttributeForegroundColor(new RGB(0, 0, 0))); + initAttribute(new BAttributeImage(null)); + initAttribute(new BAttributeAlpha(255)); + initAttribute(new BAttributeOutlineAlpha(255)); + initAttribute(new BAttributeShape(BAttributeShape.SHAPE_RECTANGLE)); + initAttribute(new BAttributeOrientation( + BAttributeOrientation.HORIZONTAL)); + initAttribute(new BAttributeDirection(BAttributeDirection.NORTH)); + initAttribute(new BAttributeFillType(BAttributeFillType.FILLED)); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BText.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BText.java new file mode 100644 index 0000000000000000000000000000000000000000..0e713693b0ddcd75bf44869b9842317d47a6eeba --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BText.java @@ -0,0 +1,46 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.model; + +import org.eclipse.swt.graphics.RGB; + +import de.bmotionstudio.gef.editor.attribute.BAttributeBackgroundColor; +import de.bmotionstudio.gef.editor.attribute.BAttributeBackgroundVisible; +import de.bmotionstudio.gef.editor.attribute.BAttributeFont; +import de.bmotionstudio.gef.editor.attribute.BAttributeText; +import de.bmotionstudio.gef.editor.attribute.BAttributeTextColor; + +/** + * @author Lukas Ladenberger + * + */ +public class BText extends BControl { + + public static transient String TYPE = "de.bmotionstudio.gef.editor.text"; + + public static transient String DEFAULT_TEXT = "Text..."; + + public BText(Visualization visualization) { + super(visualization); + } + + @Override + public String getType() { + return TYPE; + } + + @Override + protected void initAttributes() { + initAttribute(new BAttributeText(DEFAULT_TEXT)); + initAttribute(new BAttributeBackgroundColor(new RGB(255, 255, 255))); + initAttribute(new BAttributeTextColor(new RGB(0, 0, 0))); + initAttribute(new BAttributeBackgroundVisible(true)); + initAttribute(new BAttributeFont( + "1||9.75|0|WINDOWS|1|-13|0|0|0|400|0|0|0|0|0|0|0|0|")); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BTextfield.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BTextfield.java new file mode 100644 index 0000000000000000000000000000000000000000..e0d323c5ce2005008306e42cbca002899cd7bf8b --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BTextfield.java @@ -0,0 +1,42 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.model; + +import de.bmotionstudio.gef.editor.AttributeConstants; +import de.bmotionstudio.gef.editor.attribute.BAttributeText; + +/** + * @author Lukas Ladenberger + * + */ +public class BTextfield extends BControl { + + public static transient String TYPE = "de.bmotionstudio.gef.editor.textfield"; + + public static transient String DEFAULT_TEXT = "Text..."; + + public BTextfield(Visualization visualization) { + super(visualization); + } + + @Override + public String getType() { + return TYPE; + } + + @Override + protected void initAttributes() { + initAttribute(new BAttributeText(DEFAULT_TEXT)); + getAttribute(AttributeConstants.ATTRIBUTE_HEIGHT).setValue(21); + } + + @Override + public String getValueOfData() { + return getAttributeValue(AttributeConstants.ATTRIBUTE_TEXT).toString(); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/Visualization.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/Visualization.java new file mode 100644 index 0000000000000000000000000000000000000000..bc5e5523997539f20c68b4d0272d0a42c492eb53 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/Visualization.java @@ -0,0 +1,345 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.model; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.resources.IFile; +import org.eclipse.draw2d.PositionConstants; + +import de.be4.classicalb.core.parser.exceptions.BException; +import de.bmotionstudio.gef.editor.AttributeConstants; +import de.bmotionstudio.gef.editor.IAddErrorListener; +import de.bmotionstudio.gef.editor.internal.Animation; +import de.bmotionstudio.gef.editor.scheduler.PredicateOperation; +import de.prob.core.command.ExecuteOperationCommand; +import de.prob.core.command.GetOperationByPredicateCommand; +import de.prob.core.domainobjects.Operation; +import de.prob.exceptions.ProBException; + +public class Visualization extends BControl { + + public static transient String TYPE = "de.bmotionstudio.gef.editor.text"; + + protected String bmachine, language, version; + + protected BMotionRuler leftRuler, topRuler; + + private boolean rulersVisibility, snapToGeometry, gridEnabled; + + private transient List<String> allBControlIDs; + + public List<String> getAllBControlIDs() { + if (allBControlIDs == null) + allBControlIDs = getAllBControlNames(); + return allBControlIDs; + } + + private transient Boolean isRunning; + + private transient Animation animation; + + private transient IFile projectFile; + + private transient ArrayList<IAddErrorListener> errorListener; + + private transient Thread operationSchedulerThread; + + private ArrayList<PredicateOperation> schedulerOperations; + + public Visualization(String bmachine, String language, String version) { + super(null); + setVisualization(this); + this.rulersVisibility = true; + this.bmachine = bmachine; + this.language = language; + this.version = version; + this.errorListener = new ArrayList<IAddErrorListener>(); + this.isRunning = false; + createRulers(); + } + + @Override + protected Object readResolve() { + super.readResolve(); + this.isRunning = false; + populateVisualization(this); + createRulers(); + this.errorListener = new ArrayList<IAddErrorListener>(); + // this.errorMessages = new ArrayList<ErrorMessage>(); + // setAttributeValue(AttributeConstants.ATTRIBUTE_ID, "surface", false); + return this; + } + + public void startOperationScheduler() { + + if (!getSchedulerOperations().isEmpty()) { + + operationSchedulerThread = new Thread(new Runnable() { + public void run() { + while (true) { + + for (PredicateOperation p : getSchedulerOperations()) { + + if (animation.getCurrentStateOperation(p + .getOperationName()) != null) { + + try { + + String fpredicate = "1=1"; + + if (p.getPredicate().length() > 0) { + fpredicate = p.getPredicate(); + } + + Operation op = GetOperationByPredicateCommand + .getOperation(animation + .getAnimator(), animation + .getState().getId(), p + .getOperationName(), + fpredicate); + ExecuteOperationCommand.executeOperation( + animation.getAnimator(), op); + + } catch (ProBException e) { + break; + } catch (BException e) { + break; + } + + } + + } + + try { + Thread.sleep(500); + } catch (InterruptedException e) { + break; + } + + } + } + }); + operationSchedulerThread.start(); + + } + + } + + public void stopOperationScheduler() { + if (operationSchedulerThread != null) + operationSchedulerThread.interrupt(); + } + + public void setIsRunning(Boolean bol) { + this.isRunning = bol; + } + + public Boolean isRunning() { + return isRunning; + } + + public IFile getProjectFile() { + return projectFile; + } + + public void setProjectFile(IFile pf) { + projectFile = pf; + } + + public String getMachineName() { + return this.bmachine; + } + + public void setMachineName(String machineName) { + this.bmachine = machineName; + } + + public String getLanguage() { + return this.language; + } + + public void setLanguage(String language) { + this.language = language; + } + + public void setAnimation(Animation animation) { + this.animation = animation; + } + + public Animation getAnimation() { + return this.animation; + } + + public List<String> getAllBControlNames() { + return getAllBControlNames(getChildrenArray()); + } + + private List<String> getAllBControlNames(List<BControl> children) { + List<String> list = new ArrayList<String>(); + for (BControl bcontrol : children) { + list.add(bcontrol + .getAttributeValue(AttributeConstants.ATTRIBUTE_ID) + .toString()); + if (bcontrol.getChildrenArray().size() > 0) { + list.addAll(getAllBControlNames(bcontrol.getChildrenArray())); + } + } + return list; + } + + public String getMaxIDString(String type) { + String newID = getMaxID(type, 0, getAllBControlIDs()); + getAllBControlIDs().add(newID); + return newID; + } + + // old method + private String getMaxID(String type, int count, List<String> allIDs) { + String newID = "control_" + count; + if (allIDs.contains(newID)) { + return getMaxID(type, (count + 1), allIDs); + } else { + return newID; + } + } + + // TODO: Reimplement me!!! + public boolean checkIfIdExists(String ID) { + // if (getVariableList().hasEntry(ID) == true) + // return true; + // if (getConstantList().hasEntry(ID) == true) + // return true; + return getAllBControlNames().contains(ID); + } + + public BControl getBControl(String ID) { + return getBControl(ID, getChildrenArray()); + } + + private BControl getBControl(String ID, List<BControl> children) { + for (BControl bcontrol : children) { + if (bcontrol.getID().equals(ID)) { + return bcontrol; + } + if (bcontrol.getChildrenArray().size() > 0) { + BControl childControl = getBControl(ID, + bcontrol.getChildrenArray()); + if (childControl != null) + return childControl; + } + } + return null; + } + + public BMotionRuler getRuler(int orientation) { + BMotionRuler result = null; + switch (orientation) { + case PositionConstants.NORTH: + result = topRuler; + break; + case PositionConstants.WEST: + result = leftRuler; + break; + } + return result; + } + + public BMotionRuler getTopRuler() { + return topRuler; + } + + public void setTopRuler(BMotionRuler topRuler) { + this.topRuler = topRuler; + } + + public BMotionRuler getLeftRuler() { + return leftRuler; + } + + public void setLeftRuler(BMotionRuler leftRuler) { + this.leftRuler = leftRuler; + } + + protected void createRulers() { + if (leftRuler == null) + leftRuler = new BMotionRuler(false); + if (topRuler == null) + topRuler = new BMotionRuler(true); + } + + public void setRulerVisibility(boolean newValue) { + rulersVisibility = newValue; + } + + public void setGridEnabled(boolean isEnabled) { + gridEnabled = isEnabled; + } + + public void setSnapToGeometry(boolean isEnabled) { + snapToGeometry = isEnabled; + } + + public boolean getRulerVisibility() { + return rulersVisibility; + } + + public boolean isGridEnabled() { + return gridEnabled; + } + + public boolean isSnapToGeometryEnabled() { + return snapToGeometry; + } + + public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) { + return null; + } + + public void addErrorListener(IAddErrorListener listener) { + this.errorListener.add(listener); + } + + public void removeErrorListener(IAddErrorListener listener) { + this.errorListener.remove(listener); + } + + public void setSchedulerOperations( + ArrayList<PredicateOperation> schedulerOperations) { + this.schedulerOperations = schedulerOperations; + } + + public ArrayList<PredicateOperation> getSchedulerOperations() { + if (this.schedulerOperations == null) + this.schedulerOperations = new ArrayList<PredicateOperation>(); + return this.schedulerOperations; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + @Override + public String getType() { + return TYPE; + } + + @Override + protected void initAttributes() { + } + + @Override + public boolean canHaveChildren() { + return true; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/CloneObserver.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/CloneObserver.java new file mode 100644 index 0000000000000000000000000000000000000000..ff38608cc1f88782cc1b6149a09677a6496eca8e --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/CloneObserver.java @@ -0,0 +1,130 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.observer; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import de.bmotionstudio.gef.editor.AttributeConstants; +import de.bmotionstudio.gef.editor.internal.Animation; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.observer.wizard.WizardObserverClone; + +public class CloneObserver extends Observer { + + private transient Collection<BControl> clonedControls; + private List<ObserverCloneObject> observerCloneObjects; + private boolean newControls = false; + private int oldInt = 0; + + public CloneObserver() { + observerCloneObjects = new ArrayList<ObserverCloneObject>(); + } + + @Override + public void check(Animation animation, final BControl control) { + + for (ObserverCloneObject obj : observerCloneObjects) { + + final BControl toCloneControl = animation.getVisualization() + .getBControl(obj.getControlId()); + String evalString = obj.getEval(); + + String fEval = parseExpression(evalString, control, animation, obj); + + if (toCloneControl == null) { + addError(control, animation, + "No control found with id: " + obj.getControlId()); + } else { + + int clones = 0; + + try { + clones = Integer.parseInt(fEval); + } catch (NumberFormatException e) { + addError(control, animation, "The expression: " + fEval + + " should return an integer value!"); + } + + if (oldInt == clones) { + + newControls = false; + + } else { + + for (BControl c : getClonedControls()) { + control.removeChild(c); + } + + getClonedControls().clear(); + + for (int i = obj.getCounter(); i < clones + + obj.getCounter(); i++) { + try { + BControl clonedControl = toCloneControl.clone(); + clonedControl.setAttributeValue( + AttributeConstants.ATTRIBUTE_CUSTOM, i); + getClonedControls().add(clonedControl); + } catch (CloneNotSupportedException e) { + } + } + + oldInt = clones; + newControls = true; + + } + + } + + } + + } + + @Override + public ObserverWizard getWizard(BControl control) { + return new WizardObserverClone(control, this); + } + + public List<ObserverCloneObject> getObserverCloneObjects() { + return observerCloneObjects; + } + + public void setObserverCloneObjects( + List<ObserverCloneObject> observerCloneObjects) { + this.observerCloneObjects = observerCloneObjects; + } + + public Observer clone() throws CloneNotSupportedException { + CloneObserver clonedObserver = (CloneObserver) super.clone(); + List<ObserverCloneObject> list = new ArrayList<ObserverCloneObject>(); + for (ObserverCloneObject obj : getObserverCloneObjects()) { + list.add(obj.clone()); + } + clonedObserver.setObserverCloneObjects(list); + return clonedObserver; + } + + @Override + public void afterCheck(final Animation animation, final BControl control) { + if (newControls) { + synchronized (control) { + for (BControl c : clonedControls) { + control.addChild(c); + c.checkObserver(animation); + } + } + } + } + + public Collection<BControl> getClonedControls() { + if (clonedControls == null) + clonedControls = new ArrayList<BControl>(); + return clonedControls; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/IObserverListener.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/IObserverListener.java new file mode 100644 index 0000000000000000000000000000000000000000..b1189aac3fd5f7f7cd8ae8bf21dc148d73528fc4 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/IObserverListener.java @@ -0,0 +1,21 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.observer; + +import de.bmotionstudio.gef.editor.model.BControl; + +/** + * @author Lukas Ladenberger + * + */ +public interface IObserverListener { + + public void addedObserver(BControl control, Observer observer); + + public void removedObserver(BControl control); + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/ListenOperationByPredicate.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/ListenOperationByPredicate.java new file mode 100644 index 0000000000000000000000000000000000000000..aa846ff3c6c6f279ad489d77fc47addb1f63fe67 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/ListenOperationByPredicate.java @@ -0,0 +1,197 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.observer; + +import java.util.ArrayList; +import java.util.List; + +import de.be4.classicalb.core.parser.exceptions.BException; +import de.bmotionstudio.gef.editor.AttributeConstants; +import de.bmotionstudio.gef.editor.attribute.AbstractAttribute; +import de.bmotionstudio.gef.editor.internal.Animation; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.observer.wizard.WizardObserverListenOperationByPredicate; +import de.bmotionstudio.gef.editor.scheduler.PredicateOperation; +import de.prob.core.Animator; +import de.prob.core.command.GetOperationByPredicateCommand; +import de.prob.core.domainobjects.Operation; +import de.prob.core.domainobjects.State; +import de.prob.exceptions.ProBException; + +public class ListenOperationByPredicate extends Observer { + + public static String ID = "de.bmotionstudio.gef.editor.observer.ListenOperationByPredicate"; + + private ArrayList<PredicateOperation> list = new ArrayList<PredicateOperation>(); + private transient List<String> setAttributes; + + public ListenOperationByPredicate() { + this(new ArrayList<PredicateOperation>()); + } + + public ListenOperationByPredicate(ArrayList<PredicateOperation> list) { + super(); + this.setAttributes = new ArrayList<String>(); + this.list = list; + } + + protected Object readResolve() { + this.setAttributes = new ArrayList<String>(); + return super.readResolve(); + } + + @Override + public void check(Animation animation, BControl control) { + + this.setAttributes.clear(); + + State state = animation.getState(); + Animator animator = animation.getAnimator(); + + for (PredicateOperation pop : getList()) { + + if (pop.getAttribute() == null) { + pop.setAttribute(AttributeConstants.ATTRIBUTE_ENABLED); + } + + if (pop.getValue() == null) { + pop.setValue(true); + } + + String fPredicate = pop.getPredicate(); + + if (fPredicate.length() > 0) { + fPredicate = parseControls(fPredicate, control); + } + + String fOpName = pop.getOperationName(); + if (fOpName != null && fPredicate != null) { + try { + if (fPredicate.equals("")) + fPredicate = "1=1"; + Operation operation = GetOperationByPredicateCommand + .getOperation(animator, state.getId(), fOpName, + fPredicate); + if (operation != null) { // Operation enabled + + String attributeID = pop.getAttribute(); + + AbstractAttribute attributeObj = control + .getAttribute(attributeID); + + Object attributeVal = pop.getValue(); + + if (pop.isExpressionMode()) { + String strAtrVal = parseExpression( + attributeVal.toString(), control, + animation, pop); + String er = attributeObj.validateValue(strAtrVal, null); + if (er != null) { + addError( + control, + animation, + "You selected " + + attributeObj.getName() + + " as attribute. There is a problem with your value: " + + strAtrVal + " - Reason: " + + er); + pop.setHasError(true); + } else { + attributeVal = attributeObj + .unmarshal(strAtrVal); + } + } + + if (!pop.hasError()) { + Object oldAttrVal = control + .getAttributeValue(attributeID); + if (!oldAttrVal.equals(attributeVal)) { + control.setAttributeValue(attributeID, + attributeVal); + } + } + + setAttributes.add(attributeID); + + } + } catch (ProBException e) { + addError( + control, + animation, + "An error occurred while evaluating. Reason: " + + e.getMessage()); + } catch (BException e) { + addError(control, animation, "Parsing error in: " + + fPredicate + " Reason: " + e.getMessage()); + } + } + + } + + // Restore attribute values + for (PredicateOperation obj : list) { + if (!setAttributes.contains(obj.getAttribute())) { + AbstractAttribute attributeObj = control.getAttribute(obj + .getAttribute()); + Object oldAttrVal = control.getAttributeValue(obj + .getAttribute()); + if (!oldAttrVal.equals(attributeObj.getInitValue())) { + control.restoreDefaultValue(attributeObj.getID()); + } + } + } + + } + + @Override + public ObserverWizard getWizard(BControl control) { + return new WizardObserverListenOperationByPredicate(control, this); + } + + public void setList(ArrayList<PredicateOperation> list) { + this.list = list; + } + + public ArrayList<PredicateOperation> getList() { + if (this.list == null) + this.list = new ArrayList<PredicateOperation>(); + return this.list; + } + + public void addPredicateOperation(PredicateOperation predicateOperation) { + getList().add(predicateOperation); + } + + public void removePredicateOperation(PredicateOperation predicateOperation) { + getList().remove(predicateOperation); + } + + // public Boolean removePredicateOperationByUniqueID(String uniqueID) { + // for (PredicateOperation po : this.list) { + // String cuID = po.getUniqueID(); + // if (cuID != null) { + // if (cuID.equals(uniqueID)) { + // this.list.remove(po); + // return true; + // } + // } + // } + // return false; + // } + + public Observer clone() throws CloneNotSupportedException { + ListenOperationByPredicate clone = (ListenOperationByPredicate) super + .clone(); + ArrayList<PredicateOperation> clonedList = new ArrayList<PredicateOperation>(); + for (PredicateOperation pop : this.getList()) { + clonedList.add(pop.clone()); + } + clone.setList(clonedList); + return clone; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/ListenOperationObject.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/ListenOperationObject.java new file mode 100644 index 0000000000000000000000000000000000000000..2fb6a74518d6b0b7467943824e6fd7e0bbae7772 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/ListenOperationObject.java @@ -0,0 +1,40 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.observer; + +import de.bmotionstudio.gef.editor.BindingObject; + +public class ListenOperationObject extends BindingObject implements Cloneable { + + private String operationName; + private String predicate; + + public ListenOperationObject clone() throws CloneNotSupportedException { + return (ListenOperationObject) super.clone(); + } + + public void setOperationName(String operationName) { + Object oldValue = this.operationName; + this.operationName = operationName; + firePropertyChange("operationName", oldValue, this.operationName); + } + + public String getOperationName() { + return operationName; + } + + public void setPredicate(String predicate) { + Object oldValue = this.predicate; + this.predicate = predicate; + firePropertyChange("predicate", oldValue, this.predicate); + } + + public String getPredicate() { + return predicate; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/Observer.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/Observer.java new file mode 100644 index 0000000000000000000000000000000000000000..fde46fcd929494efa157fccee57e322db1e7cafb --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/Observer.java @@ -0,0 +1,103 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.observer; + +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.draw2d.IFigure; + +import de.bmotionstudio.gef.editor.AbstractExpressionControl; +import de.bmotionstudio.gef.editor.BMotionEditorPlugin; +import de.bmotionstudio.gef.editor.internal.Animation; +import de.bmotionstudio.gef.editor.model.BControl; + +/** + * + * Observers are used to link controls to the model's state, i.e., they do the + * same as the animation function in ProB. The main difference is, that we allow + * to decompose the animation function into different aspects, i.e., if our + * model contains information about the speed of a motor, we can separate all + * information regarding the speed from the information regarding the + * temperature. This allows us to write small functions and combine them rather + * than writing a single function covering all aspects of the model. + * + * @author Lukas Ladenberger + * + */ +public abstract class Observer extends AbstractExpressionControl { + + // private transient Boolean callBack = false; + + public Observer() { + init(); + } + + protected Object readResolve() { + init(); + // callBack = false; + return this; + } + + /** + * Method to initialize the observer. Gets the ID, name and description from + * the corresponding extension point + */ + private void init() { + IConfigurationElement configElement = BMotionEditorPlugin + .getObserverExtension(getClass().getName()); + if (configElement != null) { + this.ID = configElement.getAttribute("class"); + this.name = configElement.getAttribute("name"); + this.description = configElement.getAttribute("description"); + } + } + + /** + * Makes a copy of the observer + * + * @return the cloned observer + */ + public Observer clone() throws CloneNotSupportedException { + return (Observer) super.clone(); + } + + // public void setCallBack(Boolean callBack) { + // this.callBack = callBack; + // } + // + // public Boolean isCallBack() { + // return callBack; + // } + + /** + * This method is called after every state change. The method tells the + * control how it has to look like and how to behave. + * + * @param animation + * The running animation + * @param bcontrol + * The corresponding control + * @throws BMotionObserverException + */ + public abstract void check(Animation animation, BControl control); + + /** + * Returns a corresponding wizard for the observer. + * + * @param bcontrol + * The corresponding control + * @return the corresponding wizard + */ + public abstract ObserverWizard getWizard(BControl control); + + public IFigure getToolTip(BControl control) { + return null; + } + + public void afterCheck(Animation animation, BControl control) { + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/ObserverCloneObject.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/ObserverCloneObject.java new file mode 100644 index 0000000000000000000000000000000000000000..480e1686b521fdba41307d7d1b1fcc5b7cad7802 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/ObserverCloneObject.java @@ -0,0 +1,47 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ +package de.bmotionstudio.gef.editor.observer; + +/** + * @author Lukas Ladenberger + * + */ +public class ObserverCloneObject extends ObserverEvalObject implements + Cloneable { + + private String controlId; + + private int counter; + + public ObserverCloneObject() { + super(); + } + + public void setControlId(String controlId) { + Object oldValue = this.controlId; + this.controlId = controlId; + firePropertyChange("controlId", oldValue, this.controlId); + } + + public String getControlId() { + return controlId; + } + + public void setCounter(int counter) { + Object oldValue = this.counter; + this.counter = counter; + firePropertyChange("counter", oldValue, this.counter); + } + + public int getCounter() { + return counter; + } + + public ObserverCloneObject clone() throws CloneNotSupportedException { + return (ObserverCloneObject) super.clone(); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/ObserverEvalObject.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/ObserverEvalObject.java new file mode 100644 index 0000000000000000000000000000000000000000..22a1ed781d989efc359f214ddbd56f8afcf86b57 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/ObserverEvalObject.java @@ -0,0 +1,114 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.observer; + +import de.bmotionstudio.gef.editor.BindingObject; + +public class ObserverEvalObject extends BindingObject implements Cloneable { + + private String type; // unused + + private String eval; // Predicate + + private Object value; + + private String attribute; + + /** + * If true, value attribute is an ExpressionValueElement otherwise value + * attribute is an simple value object (e.g. background image) + * + * @see ExpressionValueElement + */ + private Boolean isExpressionMode; + + private transient Boolean hasError; + + public ObserverEvalObject() { + } + + public ObserverEvalObject(String type, String eval, Boolean isExpressionMode) { + this.type = type; + this.eval = eval; + this.isExpressionMode = isExpressionMode; + } + + public ObserverEvalObject(String type, String eval) { + this(type, eval, false); + } + + public void setType(String type) { + Object oldValue = this.type; + this.type = type; + firePropertyChange("type", oldValue, this.type); + } + + public String getType() { + return type; + } + + public void setEval(String eval) { + Object oldValue = this.eval; + this.eval = eval; + firePropertyChange("eval", oldValue, this.eval); + } + + public String getEval() { + return eval; + } + + public ObserverEvalObject clone() throws CloneNotSupportedException { + return (ObserverEvalObject) super.clone(); + } + + public void setHasError(Boolean hasError) { + this.hasError = hasError; + } + + public Boolean hasError() { + if (hasError == null) + hasError = false; + return hasError; + } + + public void setValue(Object value) { + Object oldValue = this.value; + this.value = value; + firePropertyChange("value", oldValue, this.value); + } + + public Object getValue() { + return this.value; + } + + public void setIsExpressionMode(Boolean isExpressionMode) { + Object oldValue = this.isExpressionMode; + this.isExpressionMode = isExpressionMode; + firePropertyChange("isExpressionMode", oldValue, this.isExpressionMode); + } + + public Boolean getIsExpressionMode() { + return isExpressionMode(); + } + + public Boolean isExpressionMode() { + if (isExpressionMode == null) + isExpressionMode = false; + return isExpressionMode; + } + + public void setAttribute(String attribute) { + Object oldValue = this.attribute; + this.attribute = attribute; + firePropertyChange("attribute", oldValue, this.attribute); + } + + public String getAttribute() { + return attribute; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/ObserverWizard.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/ObserverWizard.java new file mode 100644 index 0000000000000000000000000000000000000000..ddddd919b5fc189a350fc4fc783d7a19d1479717 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/ObserverWizard.java @@ -0,0 +1,60 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.observer; + +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.swt.graphics.Point; + +import de.bmotionstudio.gef.editor.model.BControl; + +/** + * + * The BMotion Studio provides an easy way to handle Observers. For this, + * Observers can have a corresponding wizard. The user can open it by calling + * the context menu of a Control. + * + * @author Lukas Ladenberger + * + */ +public abstract class ObserverWizard extends Wizard { + + private BControl control; + private Observer observer; + + protected Boolean observerDelete = false; + + public ObserverWizard(BControl control, Observer observer) { + this.control = control; + this.observer = observer; + } + + public BControl getBControl() { + return this.control; + } + + public Observer getObserver() { + return this.observer; + } + + protected void setObserverDelete(Boolean b) { + this.observerDelete = b; + } + + protected abstract Boolean prepareToFinish(); + + @Override + public boolean performFinish() { + return prepareToFinish(); + } + + public Boolean isObserverDelete() { + return this.observerDelete; + } + + public abstract Point getSize(); + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/SetAttribute.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/SetAttribute.java new file mode 100644 index 0000000000000000000000000000000000000000..d4e801a2491df21e32f4d8f53c9b82d87ea69deb --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/SetAttribute.java @@ -0,0 +1,153 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.observer; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.draw2d.IFigure; + +import de.bmotionstudio.gef.editor.attribute.AbstractAttribute; +import de.bmotionstudio.gef.editor.internal.Animation; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.observer.wizard.WizardObserverSetAttribute; + +public class SetAttribute extends Observer { + + private List<SetAttributeObject> setAttributeObjects; + private transient List<String> setAttributes; + + public SetAttribute() { + super(); + setAttributeObjects = new ArrayList<SetAttributeObject>(); + setAttributes = new ArrayList<String>(); + } + + protected Object readResolve() { + setAttributes = new ArrayList<String>(); + return super.readResolve(); + } + + @Override + public void check(Animation animation, BControl control) { + + this.setAttributes.clear(); + + // Collect evaluate predicate objects in list + for (SetAttributeObject obj : setAttributeObjects) { + + obj.setHasError(false); + + // First evaluate predicate (predicate field) + String bolValue = "true"; + if (obj.getEval().length() > 0) { + bolValue = parsePredicate(obj.getEval(), control, animation, + obj); + } + + if (!obj.hasError() && Boolean.valueOf(bolValue)) { + + String attributeID = obj.getAttribute(); + + AbstractAttribute attributeObj = control + .getAttribute(attributeID); + + Object attributeVal = obj.getValue(); + + if (obj.isExpressionMode()) { + String strAtrVal = parseExpression(attributeVal.toString(), + control, animation, obj); + String er = attributeObj.validateValue(strAtrVal, null); + if (er != null) { + addError( + control, + animation, + "You selected " + + attributeObj.getName() + + " as attribute. There is a problem with your value: " + + strAtrVal + " - Reason: " + er); + obj.setHasError(true); + } else { + attributeVal = attributeObj.unmarshal(strAtrVal); + } + } + + if (!obj.hasError()) { + Object oldAttrVal = control.getAttributeValue(attributeID); + if (!oldAttrVal.equals(attributeVal)) { + control.setAttributeValue(attributeID, attributeVal); + } + } + + setAttributes.add(attributeID); + + } + + } + + // Restore attribute values + for (SetAttributeObject obj : setAttributeObjects) { + if (!setAttributes.contains(obj.getAttribute())) { + AbstractAttribute attributeObj = control.getAttribute(obj + .getAttribute()); + Object oldAttrVal = control.getAttributeValue(obj + .getAttribute()); + if (!oldAttrVal.equals(attributeObj.getInitValue())) { + control.restoreDefaultValue(attributeObj.getID()); + } + } + } + + } + + @Override + public ObserverWizard getWizard(BControl control) { + return new WizardObserverSetAttribute(control, this); + } + + public void setSetAttributeObjects( + List<SetAttributeObject> setAttributeObjects) { + this.setAttributeObjects = setAttributeObjects; + } + + public List<SetAttributeObject> getSetAttributeObjects() { + return setAttributeObjects; + } + + public Observer clone() throws CloneNotSupportedException { + SetAttribute clonedObserver = (SetAttribute) super.clone(); + List<SetAttributeObject> list = new ArrayList<SetAttributeObject>(); + for (SetAttributeObject obj : getSetAttributeObjects()) { + list.add(obj.clone()); + } + clonedObserver.setSetAttributeObjects(list); + return clonedObserver; + } + + @Override + public IFigure getToolTip(BControl control) { + // // TODO: This method need rework!!! + // StringBuilder builder = new StringBuilder(); + // builder.append("Set Attribute Observer:\n\n"); + // for (SetAttributeObject obj : getSetAttributeObjects()) { + // if (obj.getEval() != null) { + // builder.append("[Predicate: " + obj.getEval()); + // } + // if (obj.getAttribute() != null) { + // builder.append(" | Attribute: " + // + control.getAttribute(obj.getAttribute()).getName()); + // } + // if (obj.getValue() != null) { + // builder.append(" | Value: " + obj.getValue() + "]"); + // } + // builder.append("\n"); + // } + // Label lb = new Label(builder.toString()); + return null; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/SetAttributeObject.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/SetAttributeObject.java new file mode 100644 index 0000000000000000000000000000000000000000..d73f0c5abadd0e021fdff1f2932ab3346e79004f --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/SetAttributeObject.java @@ -0,0 +1,24 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.observer; + + +public class SetAttributeObject extends ObserverEvalObject implements Cloneable { + + public SetAttributeObject() { + super(); + } + + public SetAttributeObject(String type, String eval) { + super(type, eval); + } + + public SetAttributeObject clone() throws CloneNotSupportedException { + return (SetAttributeObject) super.clone(); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/SimpleValueDisplay.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/SimpleValueDisplay.java new file mode 100644 index 0000000000000000000000000000000000000000..a6934ec7539ce6f1fc3c4063dcb0d3bc8804a60e --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/SimpleValueDisplay.java @@ -0,0 +1,100 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.observer; + +import de.bmotionstudio.gef.editor.AttributeConstants; +import de.bmotionstudio.gef.editor.internal.Animation; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.observer.wizard.WizardObserverSimpleValueDisplay; + +public class SimpleValueDisplay extends Observer { + + private String type; + private String eval; + private String predicate; + private String replacementString; + private transient String orgString; + private transient boolean isOrgStringSet = false; + + public void check(final Animation animation, final BControl bcontrol) { + + // First evaluate predicate (predicate field) + String bolValue = "true"; + if (predicate != null && predicate.length() > 0) { + bolValue = parsePredicate(predicate, bcontrol, animation, null); + } + + if (Boolean.valueOf(bolValue)) { + + String fEval = parseExpression(eval, bcontrol, animation, null); + + if (!isOrgStringSet) { + orgString = bcontrol.getAttributeValue( + AttributeConstants.ATTRIBUTE_TEXT).toString(); + isOrgStringSet = true; + } + + String parseString = orgString; + + if (replacementString != null) { + if (replacementString.length() > 0) { + parseString = orgString.replace(replacementString, fEval); + } + } else { + parseString = fEval; + } + + bcontrol.setAttributeValue(AttributeConstants.ATTRIBUTE_TEXT, + parseString); + + } + + } + + public ObserverWizard getWizard(final BControl bcontrol) { + return new WizardObserverSimpleValueDisplay(bcontrol, this); + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public void setEval(String eval) { + this.eval = eval; + } + + public String getEval() { + return eval; + } + + public String getPredicate() { + return predicate; + } + + public void setPredicate(String predicate) { + this.predicate = predicate; + } + + public void setReplacementString(String replacementString) { + this.replacementString = replacementString; + } + + public String getReplacementString() { + return replacementString; + } + + public Observer clone() throws CloneNotSupportedException { + SimpleValueDisplay clonedObserver = (SimpleValueDisplay) super.clone(); + clonedObserver.isOrgStringSet = false; + return clonedObserver; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/SwitchChildCoordinates.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/SwitchChildCoordinates.java new file mode 100644 index 0000000000000000000000000000000000000000..273f37ab987e3dc546df27579f31aaef5c16e8c9 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/SwitchChildCoordinates.java @@ -0,0 +1,147 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.observer; + +import java.util.ArrayList; +import java.util.List; + +import de.bmotionstudio.gef.editor.AttributeConstants; +import de.bmotionstudio.gef.editor.animation.AnimationMove; +import de.bmotionstudio.gef.editor.internal.Animation; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.observer.wizard.WizardObserverCSwitchCoordinates; + +public class SwitchChildCoordinates extends Observer { + + private List<ToggleObjectCoordinates> toggleObjects; + + // private transient AnimationListener animationListener; + + // private transient Boolean checked; + + public SwitchChildCoordinates() { + toggleObjects = new ArrayList<ToggleObjectCoordinates>(); + } + + public void check(final Animation animation, final BControl control) { + + // if (checked == null) + // checked = true; + // + // if (!checked) + // return; + // + // if (animationListener == null) { + // animationListener = new AnimationListener() { + // public void animationStopped(AnimationEvent evt) { + // setCallBack(true); + // // checked = true; + // } + // + // public void animationStarted(AnimationEvent evt) { + // setCallBack(false); + // checked = false; + // } + // }; + // } + + // Collect evaluate predicate objects in list + for (ToggleObjectCoordinates obj : toggleObjects) { + + obj.setHasError(false); + + // First evaluate predicate (predicate field) + String bolValue = "true"; + if (obj.getEval().length() > 0) { + bolValue = parsePredicate(obj.getEval(), control, animation, + obj); + } + + if (!obj.hasError() && Boolean.valueOf(bolValue)) { + + // Handle control field + BControl toggleControl = null; + String parsedControl = parseExpression(obj.getBcontrol(), + false, control, animation, obj, false); + toggleControl = control.getChild(parsedControl); + if (toggleControl == null) { + obj.setHasError(true); + addError(control, animation, "No such control: " + + parsedControl); + } + + Integer parsedX = 0; + Integer parsedY = 0; + // Handle X field + try { + parsedX = Integer.valueOf(parseExpression(obj.getX(), + false, control, animation, obj, false)); + } catch (NumberFormatException n) { + obj.setHasError(true); + addError(control, animation, "x is not a valid integer: " + + n.getMessage()); + } + // Handle Y field + try { + parsedY = Integer.valueOf(parseExpression(obj.getY(), + false, control, animation, obj, false)); + } catch (NumberFormatException n) { + obj.setHasError(true); + addError(control, animation, "y is not a valid integer: " + + n.getMessage()); + } + + if (!obj.hasError()) { + if (Boolean.valueOf(bolValue)) { // If true + if (obj.getAnimate()) { + + AnimationMove aMove = new AnimationMove(500, true, + toggleControl, parsedX, parsedY); + // aMove.addAnimationListener(animationListener); + aMove.start(); + + } else { + + toggleControl.setAttributeValue( + AttributeConstants.ATTRIBUTE_X, parsedX); + toggleControl.setAttributeValue( + AttributeConstants.ATTRIBUTE_Y, parsedY); + + } + } + } + + } + + } + + } + + public ObserverWizard getWizard(final BControl bcontrol) { + return new WizardObserverCSwitchCoordinates(bcontrol, this); + } + + public List<ToggleObjectCoordinates> getToggleObjects() { + return this.toggleObjects; + } + + public void setToggleObjects(final List<ToggleObjectCoordinates> list) { + this.toggleObjects = list; + } + + public Observer clone() throws CloneNotSupportedException { + SwitchChildCoordinates clonedObserver = (SwitchChildCoordinates) super + .clone(); + List<ToggleObjectCoordinates> list = new ArrayList<ToggleObjectCoordinates>(); + for (ToggleObjectCoordinates obj : getToggleObjects()) { + list.add(obj.clone()); + } + clonedObserver.setToggleObjects(list); + return clonedObserver; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/SwitchCoordinates.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/SwitchCoordinates.java new file mode 100644 index 0000000000000000000000000000000000000000..10ec1ecce5a9f5337d31be76d23084352fd8b0dc --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/SwitchCoordinates.java @@ -0,0 +1,159 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.observer; + +import java.util.ArrayList; +import java.util.List; + +import de.bmotionstudio.gef.editor.AttributeConstants; +import de.bmotionstudio.gef.editor.animation.AnimationMove; +import de.bmotionstudio.gef.editor.internal.Animation; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.observer.wizard.WizardObserverSwitchCoordinates; + +public class SwitchCoordinates extends Observer { + + private List<ToggleObjectCoordinates> toggleObjects; + + // private transient AnimationListener animationListener; + + // private transient Boolean checked; + + public SwitchCoordinates() { + toggleObjects = new ArrayList<ToggleObjectCoordinates>(); + } + + public void check(final Animation animation, final BControl control) { + + boolean set = false; + + // if (checked == null) + // checked = true; + + // if (animationListener == null) { + // animationListener = new AnimationListener() { + // public void animationStopped(AnimationEvent evt) { + // setCallBack(true); + // checked = true; + // // System.out + // // .println("Animation stopped ---> Set callback to TRUE!"); + // } + // + // public void animationStarted(AnimationEvent evt) { + // setCallBack(false); + // checked = false; + // // System.out + // // .println("Animation started ---> Set callback to FALSE!"); + // } + // }; + // } + + // Collect evaluate predicate objects in list + for (ToggleObjectCoordinates obj : toggleObjects) { + + obj.setHasError(false); + + // First evaluate predicate (predicate field) + String bolValue = "true"; + if (obj.getEval().length() > 0) { + bolValue = parsePredicate(obj.getEval(), control, animation, + obj); + } + + if (!obj.hasError() && Boolean.valueOf(bolValue)) { + + int parsedX = 0; + int parsedY = 0; + // Handle X field + try { + parsedX = Integer.valueOf(parseExpression(obj.getX(), + false, control, animation, obj, false)); + } catch (NumberFormatException n) { + obj.setHasError(true); + addError(control, animation, "x is not a valid integer: " + + n.getMessage()); + } + // Handle Y field + try { + parsedY = Integer.valueOf(parseExpression(obj.getY(), + false, control, animation, obj, false)); + } catch (NumberFormatException n) { + obj.setHasError(true); + addError(control, animation, "y is not a valid integer: " + + n.getMessage()); + } + + int currentX = Integer.valueOf(control.getAttributeValue( + AttributeConstants.ATTRIBUTE_X).toString()); + int currentY = Integer.valueOf(control.getAttributeValue( + AttributeConstants.ATTRIBUTE_Y).toString()); + + if (currentX != parsedX || currentY != parsedY) { + + // setCallBack(false); + + // If true + if (obj.getAnimate()) { + + // if (!checked) + // return; + + AnimationMove aMove = new AnimationMove(5000, true, + control, parsedX, parsedY); + // aMove.addAnimationListener(animationListener); + aMove.start(); + + } else { + control.setAttributeValue( + AttributeConstants.ATTRIBUTE_X, parsedX); + control.setAttributeValue( + AttributeConstants.ATTRIBUTE_Y, parsedY); + // setCallBack(true); + // checked = false; + } + + } + // else { + // setCallBack(true); + // } + + set = true; + + } + + } + + if (!set) { + control.restoreDefaultValue(AttributeConstants.ATTRIBUTE_X); + control.restoreDefaultValue(AttributeConstants.ATTRIBUTE_Y); + } + + } + + public ObserverWizard getWizard(final BControl bcontrol) { + return new WizardObserverSwitchCoordinates(bcontrol, this); + } + + public List<ToggleObjectCoordinates> getToggleObjects() { + return this.toggleObjects; + } + + public void setToggleObjects(final List<ToggleObjectCoordinates> list) { + this.toggleObjects = list; + } + + public Observer clone() throws CloneNotSupportedException { + SwitchCoordinates clonedObserver = (SwitchCoordinates) super.clone(); + List<ToggleObjectCoordinates> list = new ArrayList<ToggleObjectCoordinates>(); + for (ToggleObjectCoordinates obj : getToggleObjects()) { + list.add(obj.clone()); + } + clonedObserver.setToggleObjects(list); + return clonedObserver; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/SwitchImage.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/SwitchImage.java new file mode 100644 index 0000000000000000000000000000000000000000..38bd1896e469f31c4b147662358ce619c0c799fe --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/SwitchImage.java @@ -0,0 +1,102 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.observer; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.resources.IFile; + +import de.bmotionstudio.gef.editor.AttributeConstants; +import de.bmotionstudio.gef.editor.internal.Animation; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.observer.wizard.WizardObserverSwitchImage; + +public class SwitchImage extends Observer { + + private List<ToggleObjectImage> toggleObjects; + + public SwitchImage() { + toggleObjects = new ArrayList<ToggleObjectImage>(); + } + + public void check(final Animation animation, final BControl control) { + + boolean set = false; + + // Collect evaluate predicate objects in list + for (ToggleObjectImage obj : toggleObjects) { + + obj.setHasError(false); + + // First evaluate predicate (predicate field) + String bolValue = "true"; + if (obj.getEval().length() > 0) { + bolValue = parsePredicate(obj.getEval(), control, animation, + obj); + } + + if (!obj.hasError() && Boolean.valueOf(bolValue)) { + + String fImage = obj.getImage(); + + if (obj.isExpressionMode()) { // Expression mode + fImage = parseExpression(obj.getImage(), control, + animation, obj); + } + + IFile pFile = control.getVisualization().getProjectFile(); + String myPath = (pFile.getProject().getLocation() + "/images/" + fImage) + .replace("file:", ""); + if (!new File(myPath).exists()) { + addError(control, animation, + "No such image in your library: " + fImage); + } + + if (!obj.hasError()) { + if (!control.getAttributeValue( + AttributeConstants.ATTRIBUTE_IMAGE).equals(fImage)) { + control.setAttributeValue( + AttributeConstants.ATTRIBUTE_IMAGE, fImage); + } + } + + set = true; + + } + + } + + if (!set) + control.restoreDefaultValue(AttributeConstants.ATTRIBUTE_IMAGE); + + } + + public ObserverWizard getWizard(final BControl bcontrol) { + return new WizardObserverSwitchImage(bcontrol, this); + } + + public List<ToggleObjectImage> getToggleObjects() { + return this.toggleObjects; + } + + public void setToggleObjects(final List<ToggleObjectImage> list) { + this.toggleObjects = list; + } + + public Observer clone() throws CloneNotSupportedException { + SwitchImage clonedObserver = (SwitchImage) super.clone(); + List<ToggleObjectImage> list = new ArrayList<ToggleObjectImage>(); + for (ToggleObjectImage obj : getToggleObjects()) { + list.add(obj.clone()); + } + clonedObserver.setToggleObjects(list); + return clonedObserver; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/ToggleObjectCoordinates.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/ToggleObjectCoordinates.java new file mode 100644 index 0000000000000000000000000000000000000000..0fedb912e160ae0cb01d67572b2ee4ed8e644728 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/ToggleObjectCoordinates.java @@ -0,0 +1,79 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.observer; + + +public class ToggleObjectCoordinates extends ObserverEvalObject implements + Cloneable { + + private String bcontrol; + private String x; + private String y; + private Boolean animate = false; + + public ToggleObjectCoordinates() { + } + + public ToggleObjectCoordinates(String type, String bcontrol, String x, + String y, String eval, Boolean animate) { + super(type, eval); + this.bcontrol = bcontrol; + this.x = x; + this.y = y; + this.animate = animate; + } + + public ToggleObjectCoordinates(String type, String x, String y, + String eval, Boolean animate) { + this(type, null, x, y, eval, animate); + } + + public String getBcontrol() { + return bcontrol; + } + + public String getX() { + return x; + } + + public String getY() { + return y; + } + + public Boolean getAnimate() { + return animate; + } + + public void setBcontrol(String bcontrol) { + Object oldValue = this.bcontrol; + this.bcontrol = bcontrol; + firePropertyChange("bcontrol", oldValue, this.bcontrol); + } + + public void setX(String x) { + Object oldValue = this.x; + this.x = x; + firePropertyChange("x", oldValue, this.x); + } + + public void setY(String y) { + Object oldValue = this.y; + this.y = y; + firePropertyChange("y", oldValue, this.y); + } + + public void setAnimate(Boolean animate) { + Object oldValue = this.animate; + this.animate = animate; + firePropertyChange("animate", oldValue, this.animate); + } + + public ToggleObjectCoordinates clone() throws CloneNotSupportedException { + return (ToggleObjectCoordinates) super.clone(); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/ToggleObjectImage.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/ToggleObjectImage.java new file mode 100644 index 0000000000000000000000000000000000000000..5169e967a6ec6bf3c06612d5219e952bba40aff2 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/ToggleObjectImage.java @@ -0,0 +1,36 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.observer; + + +public class ToggleObjectImage extends ObserverEvalObject implements Cloneable { + + private String image; + + public ToggleObjectImage() { + } + + public ToggleObjectImage(String type, String image, String eval) { + super(type, eval); + this.image = image; + } + + public String getImage() { + return image; + } + + public void setImage(String image) { + Object oldValue = this.image; + this.image = image; + firePropertyChange("image", oldValue, this.image); + } + + public ToggleObjectImage clone() throws CloneNotSupportedException { + return (ToggleObjectImage) super.clone(); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/wizard/WizardObserverCSwitchCoordinates.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/wizard/WizardObserverCSwitchCoordinates.java new file mode 100644 index 0000000000000000000000000000000000000000..f0a7b93f08608cfe242ed95bba53b6bbb33c13e8 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/wizard/WizardObserverCSwitchCoordinates.java @@ -0,0 +1,272 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.observer.wizard; + +import org.eclipse.core.databinding.DataBindingContext; +import org.eclipse.core.databinding.beans.BeansObservables; +import org.eclipse.core.databinding.observable.list.WritableList; +import org.eclipse.core.databinding.observable.map.IObservableMap; +import org.eclipse.jface.databinding.viewers.ObservableListContentProvider; +import org.eclipse.jface.databinding.viewers.ObservableMapLabelProvider; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.CheckboxCellEditor; +import org.eclipse.jface.viewers.EditingSupport; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITableColorProvider; +import org.eclipse.jface.viewers.ITableFontProvider; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; + +import de.be4.classicalb.core.parser.BParser; +import de.bmotionstudio.gef.editor.BMotionStudioImage; +import de.bmotionstudio.gef.editor.EditorImageRegistry; +import de.bmotionstudio.gef.editor.edit.PredicateEditingSupport; +import de.bmotionstudio.gef.editor.edit.TextEditingSupport; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.observer.Observer; +import de.bmotionstudio.gef.editor.observer.ObserverWizard; +import de.bmotionstudio.gef.editor.observer.SwitchChildCoordinates; +import de.bmotionstudio.gef.editor.observer.ToggleObjectCoordinates; +import de.bmotionstudio.gef.editor.property.CheckboxCellEditorHelper; + +public class WizardObserverCSwitchCoordinates extends ObserverWizard { + + private class ObserverCSwitchCoordinatesPage extends WizardPage { + + private TableViewer tableViewer; + + protected ObserverCSwitchCoordinatesPage(final String pageName) { + super(pageName); + } + + public void createControl(Composite parent) { + + DataBindingContext dbc = new DataBindingContext(); + + Composite container = new Composite(parent, SWT.NONE); + container.setLayout(new GridLayout(1, true)); + + tableViewer = new TableViewer(container, SWT.BORDER + | SWT.FULL_SELECTION); + tableViewer.getTable().setLinesVisible(true); + tableViewer.getTable().setHeaderVisible(true); + tableViewer.getTable().setLayoutData( + new GridData(GridData.FILL_BOTH)); + tableViewer.getTable().setFont( + new Font(Display.getDefault(), new FontData("Arial", 10, + SWT.NONE))); + + TableViewerColumn column = new TableViewerColumn(tableViewer, + SWT.NONE); + column.getColumn().setText("Predicate"); + column.getColumn().setWidth(100); + column.setEditingSupport(new PredicateEditingSupport(tableViewer, + dbc, "eval", getBControl().getVisualization(), getShell())); + + column = new TableViewerColumn(tableViewer, SWT.NONE); + column.getColumn().setText("Control"); + column.getColumn().setWidth(175); + column.setEditingSupport(new TextEditingSupport(tableViewer, dbc, + "bcontrol")); + + column = new TableViewerColumn(tableViewer, SWT.NONE); + column.getColumn().setText("X"); + column.getColumn().setWidth(125); + column.setEditingSupport(new TextEditingSupport(tableViewer, dbc, + "x")); + + column = new TableViewerColumn(tableViewer, SWT.NONE); + column.getColumn().setText("Y"); + column.getColumn().setWidth(125); + column.setEditingSupport(new TextEditingSupport(tableViewer, dbc, + "y")); + + column = new TableViewerColumn(tableViewer, SWT.NONE); + column.getColumn().setText("Animate?"); + column.getColumn().setWidth(75); + column.setEditingSupport(new EditingSupport(tableViewer) { + + private CellEditor cellEditor = new CheckboxCellEditor( + (Composite) tableViewer.getControl()); + + @Override + protected void setValue(Object element, Object value) { + ((ToggleObjectCoordinates) element).setAnimate(Boolean + .valueOf(String.valueOf(value))); + } + + @Override + protected Object getValue(Object element) { + Boolean b = ((ToggleObjectCoordinates) element) + .getAnimate(); + return b != null ? b : false; + } + + @Override + protected CellEditor getCellEditor(Object element) { + return cellEditor; + } + + @Override + protected boolean canEdit(Object element) { + return true; + } + + }); + + ObservableListContentProvider contentProvider = new ObservableListContentProvider(); + tableViewer.setContentProvider(contentProvider); + tableViewer + .setLabelProvider(new ObserverLabelProvider( + BeansObservables.observeMaps( + contentProvider.getKnownElements(), + new String[] { "eval", "bcontrol", "x", + "y", "animate" }))); + + final WritableList input = new WritableList( + ((SwitchChildCoordinates) getObserver()).getToggleObjects(), + ToggleObjectCoordinates.class); + tableViewer.setInput(input); + + Composite comp = new Composite(container, SWT.NONE); + comp.setLayout(new RowLayout()); + comp.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END)); + + Button btRemove = new Button(comp, SWT.PUSH); + btRemove.setText("Remove"); + btRemove.setImage(BMotionStudioImage + .getImage(EditorImageRegistry.IMG_ICON_DELETE)); + btRemove.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (tableViewer.getSelection().isEmpty()) { + return; + } + ToggleObjectCoordinates toggleObj = (ToggleObjectCoordinates) ((IStructuredSelection) tableViewer + .getSelection()).getFirstElement(); + input.remove(toggleObj); + } + }); + + Button btAdd = new Button(comp, SWT.PUSH); + btAdd.setText("Add"); + btAdd.setImage(BMotionStudioImage + .getImage(EditorImageRegistry.IMG_ICON_ADD)); + btAdd.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + ToggleObjectCoordinates toggleObj = new ToggleObjectCoordinates( + BParser.PREDICATE_PREFIX, "", "", "", "", false); + input.add(toggleObj); + } + }); + + setControl(container); + + } + } + + public WizardObserverCSwitchCoordinates(final BControl bcontrol, + final Observer bobserver) { + super(bcontrol, bobserver); + addPage(new ObserverCSwitchCoordinatesPage( + "ObserverCToggleCoordinatesPage")); + } + + @Override + protected Boolean prepareToFinish() { + if (((SwitchChildCoordinates) getObserver()).getToggleObjects().size() == 0) { + setObserverDelete(true); + } else { + for (ToggleObjectCoordinates obj : ((SwitchChildCoordinates) getObserver()) + .getToggleObjects()) { + if (obj.getX().isEmpty() || obj.getY().isEmpty() + || obj.getBcontrol().isEmpty()) { + MessageDialog + .openError(getShell(), "Please check your entries", + "Please check your entries. The x , y and control fields must not be empty."); + return false; + } + } + } + return true; + } + + @Override + public Point getSize() { + return new Point(650, 500); + } + + private static class ObserverLabelProvider extends + ObservableMapLabelProvider implements ITableLabelProvider, + ITableColorProvider, ITableFontProvider { + + public ObserverLabelProvider(IObservableMap[] attributeMaps) { + super(attributeMaps); + } + + private final Color errorColor = Display.getDefault().getSystemColor( + SWT.COLOR_INFO_BACKGROUND); + + // final Font bold = JFaceResources.getFontRegistry().getBold( + // JFaceResources.BANNER_FONT); + + @Override + public String getColumnText(Object element, int columnIndex) { + if (columnIndex == 4) { + return ""; + } + return super.getColumnText(element, columnIndex); + } + + @Override + public Image getColumnImage(Object element, int columnIndex) { + if (columnIndex == 4) { + return CheckboxCellEditorHelper + .getCellEditorImage(((ToggleObjectCoordinates) element) + .getAnimate()); + } + return null; + } + + public Color getBackground(final Object element, final int column) { + ToggleObjectCoordinates attributeObject = (ToggleObjectCoordinates) element; + if (attributeObject.hasError()) + return errorColor; + return null; + } + + public Color getForeground(final Object element, final int column) { + return null; + } + + public Font getFont(final Object element, final int column) { + // return JFaceResources.getFontRegistry().get( + // BMotionStudioConstants.RODIN_FONT_KEY); + return null; + } + + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/wizard/WizardObserverClone.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/wizard/WizardObserverClone.java new file mode 100644 index 0000000000000000000000000000000000000000..9c17c7d43ac6589d3e3d727be449814df8b60b62 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/wizard/WizardObserverClone.java @@ -0,0 +1,242 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.observer.wizard; + +import org.eclipse.core.databinding.DataBindingContext; +import org.eclipse.core.databinding.beans.BeansObservables; +import org.eclipse.core.databinding.observable.list.WritableList; +import org.eclipse.core.databinding.observable.map.IObservableMap; +import org.eclipse.jface.databinding.viewers.ObservableListContentProvider; +import org.eclipse.jface.databinding.viewers.ObservableMapLabelProvider; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITableColorProvider; +import org.eclipse.jface.viewers.ITableFontProvider; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; + +import de.bmotionstudio.gef.editor.BMotionStudioImage; +import de.bmotionstudio.gef.editor.EditorImageRegistry; +import de.bmotionstudio.gef.editor.edit.PredicateEditingSupport; +import de.bmotionstudio.gef.editor.edit.TextEditingSupport; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.observer.CloneObserver; +import de.bmotionstudio.gef.editor.observer.Observer; +import de.bmotionstudio.gef.editor.observer.ObserverCloneObject; +import de.bmotionstudio.gef.editor.observer.ObserverWizard; + +/** + * @author Lukas Ladenberger + * + */ +public class WizardObserverClone extends ObserverWizard { + + public WizardObserverClone(BControl control, Observer observer) { + super(control, observer); + addPage(new WizardObserverClonePage("WizardObserverClonePage")); + } + + private class WizardObserverClonePage extends WizardPage { + + private TableViewer tableViewer; + + protected WizardObserverClonePage(String pageName) { + super(pageName); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt + * .widgets.Composite) + */ + @Override + public void createControl(Composite parent) { + + DataBindingContext dbc = new DataBindingContext(); + + Composite container = new Composite(parent, SWT.NONE); + container.setLayout(new GridLayout(1, true)); + + setControl(container); + + tableViewer = new TableViewer(container, SWT.BORDER + | SWT.FULL_SELECTION); + tableViewer.getTable().setLinesVisible(true); + tableViewer.getTable().setHeaderVisible(true); + tableViewer.getTable().setLayoutData( + new GridData(GridData.FILL_BOTH)); + tableViewer.getTable().setFont( + new Font(Display.getDefault(), new FontData("Arial", 10, + SWT.NONE))); + + TableViewerColumn column = new TableViewerColumn(tableViewer, + SWT.NONE); + column.getColumn().setText("Expression"); + column.getColumn().setWidth(200); + column.setEditingSupport(new PredicateEditingSupport(tableViewer, + dbc, "eval", getBControl().getVisualization(), getShell())); + + column = new TableViewerColumn(tableViewer, SWT.NONE); + column.getColumn().setText("Control"); + column.getColumn().setWidth(175); + column.setEditingSupport(new TextEditingSupport(tableViewer, dbc, + "controlId")); + + column = new TableViewerColumn(tableViewer, SWT.NONE); + column.getColumn().setText("Count from"); + column.getColumn().setWidth(125); + column.setEditingSupport(new TextEditingSupport(tableViewer, dbc, + "counter")); + + ObservableListContentProvider contentProvider = new ObservableListContentProvider(); + tableViewer.setContentProvider(contentProvider); + tableViewer.setLabelProvider(new ObserverLabelProvider( + BeansObservables.observeMaps( + contentProvider.getKnownElements(), new String[] { + "eval", "controlId", "counter" }))); + + final WritableList input = new WritableList( + ((CloneObserver) getObserver()).getObserverCloneObjects(), + ObserverCloneObject.class); + tableViewer.setInput(input); + + Composite comp = new Composite(container, SWT.NONE); + comp.setLayout(new RowLayout()); + comp.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END)); + + Button btRemove = new Button(comp, SWT.PUSH); + btRemove.setText("Remove"); + btRemove.setImage(BMotionStudioImage + .getImage(EditorImageRegistry.IMG_ICON_DELETE)); + btRemove.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (tableViewer.getSelection().isEmpty()) { + return; + } + ObserverCloneObject obj = (ObserverCloneObject) ((IStructuredSelection) tableViewer + .getSelection()).getFirstElement(); + input.remove(obj); + } + }); + + Button btAdd = new Button(comp, SWT.PUSH); + btAdd.setText("Add"); + btAdd.setImage(BMotionStudioImage + .getImage(EditorImageRegistry.IMG_ICON_ADD)); + btAdd.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + ObserverCloneObject obj = new ObserverCloneObject(); + input.add(obj); + } + }); + + } + + } + + /* + * (non-Javadoc) + * + * @see + * de.bmotionstudio.gef.editor.observer.ObserverWizard#prepareToFinish() + */ + @Override + protected Boolean prepareToFinish() { + if (((CloneObserver) getObserver()).getObserverCloneObjects().size() == 0) { + setObserverDelete(true); + } else { + for (ObserverCloneObject obj : ((CloneObserver) getObserver()) + .getObserverCloneObjects()) { + if (obj.getEval() == null || obj.getControlId() == null) { + MessageDialog + .openError(getShell(), "Please check your entries", + "Please check your entries. The eval and control field must not be empty."); + return false; + } + } + } + return true; + } + + /* + * (non-Javadoc) + * + * @see de.bmotionstudio.gef.editor.observer.ObserverWizard#getSize() + */ + @Override + public Point getSize() { + return new Point(700, 500); + } + + private static class ObserverLabelProvider extends + ObservableMapLabelProvider implements ITableLabelProvider, + ITableColorProvider, ITableFontProvider { + + public ObserverLabelProvider(IObservableMap[] attributeMaps) { + super(attributeMaps); + } + + private final Color errorColor = Display.getDefault().getSystemColor( + SWT.COLOR_INFO_BACKGROUND); + + @Override + public Image getColumnImage(Object element, int columnIndex) { + return null; + } + + @Override + public String getColumnText(Object element, int columnIndex) { + ObserverCloneObject obj = (ObserverCloneObject) element; + if (columnIndex == 0) { + return obj.getEval(); + } + if (columnIndex == 1) { + return obj.getControlId(); + } + return super.getColumnText(element, columnIndex); + } + + public Color getBackground(final Object element, final int column) { + ObserverCloneObject obj = (ObserverCloneObject) element; + if (obj.hasError()) + return errorColor; + return null; + } + + public Color getForeground(final Object element, final int column) { + return null; + } + + public Font getFont(final Object element, final int column) { + // return JFaceResources.getFontRegistry().get( + // BMotionStudioConstants.RODIN_FONT_KEY); + return null; + } + + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/wizard/WizardObserverListenOperationByPredicate.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/wizard/WizardObserverListenOperationByPredicate.java new file mode 100644 index 0000000000000000000000000000000000000000..d8f7ee53c14fa4421d8abff4c02c168d964d7c9f --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/wizard/WizardObserverListenOperationByPredicate.java @@ -0,0 +1,405 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.observer.wizard; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.databinding.DataBindingContext; +import org.eclipse.core.databinding.beans.BeansObservables; +import org.eclipse.core.databinding.observable.list.ComputedList; +import org.eclipse.core.databinding.observable.list.WritableList; +import org.eclipse.core.databinding.observable.map.IObservableMap; +import org.eclipse.jface.databinding.viewers.ObservableListContentProvider; +import org.eclipse.jface.databinding.viewers.ObservableMapLabelProvider; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ComboBoxViewerCellEditor; +import org.eclipse.jface.viewers.EditingSupport; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITableColorProvider; +import org.eclipse.jface.viewers.ITableFontProvider; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CCombo; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; + +import de.bmotionstudio.gef.editor.BMotionStudioImage; +import de.bmotionstudio.gef.editor.EditorImageRegistry; +import de.bmotionstudio.gef.editor.attribute.AbstractAttribute; +import de.bmotionstudio.gef.editor.edit.AttributeExpressionEdittingSupport; +import de.bmotionstudio.gef.editor.edit.IsExpressionModeEditingSupport; +import de.bmotionstudio.gef.editor.edit.OperationValueEditingSupport; +import de.bmotionstudio.gef.editor.edit.PredicateEditingSupport; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.observer.ListenOperationByPredicate; +import de.bmotionstudio.gef.editor.observer.Observer; +import de.bmotionstudio.gef.editor.observer.ObserverWizard; +import de.bmotionstudio.gef.editor.property.CheckboxCellEditorHelper; +import de.bmotionstudio.gef.editor.scheduler.PredicateOperation; + +public class WizardObserverListenOperationByPredicate extends ObserverWizard { + + private class ObserverListenOperationByPredicatePage extends WizardPage { + + private TableViewer tableViewer; + + protected ObserverListenOperationByPredicatePage(final String pageName) { + super(pageName); + } + + public void createControl(final Composite parent) { + + DataBindingContext dbc = new DataBindingContext(); + + Composite container = new Composite(parent, SWT.NONE); + container.setLayout(new GridLayout(1, true)); + + setControl(container); + + tableViewer = new TableViewer(container, SWT.BORDER + | SWT.FULL_SELECTION); + tableViewer.getTable().setLinesVisible(true); + tableViewer.getTable().setHeaderVisible(true); + tableViewer.getTable().setLayoutData( + new GridData(GridData.FILL_BOTH)); + tableViewer.getTable().setFont( + new Font(Display.getDefault(), new FontData("Arial", 10, + SWT.NONE))); + + TableViewerColumn column = new TableViewerColumn(tableViewer, + SWT.NONE); + column.getColumn().setText("Operation"); + column.getColumn().setWidth(150); + column.setEditingSupport(new OperationValueEditingSupport( + tableViewer, getBControl())); + + column = new TableViewerColumn(tableViewer, SWT.NONE); + column.getColumn().setText("Predicate"); + column.getColumn().setWidth(150); + column.setEditingSupport(new PredicateEditingSupport(tableViewer, + dbc, "predicate", getBControl().getVisualization(), + getShell())); + + column = new TableViewerColumn(tableViewer, SWT.NONE); + column.getColumn().setText("Attribute"); + column.getColumn().setWidth(150); + column.setEditingSupport(new AttributeObserverValueEditing( + tableViewer)); + + column = new TableViewerColumn(tableViewer, SWT.NONE); + column.getColumn().setText("Value"); + column.getColumn().setWidth(175); + column.setEditingSupport(new AttributeExpressionEdittingSupport( + tableViewer, getBControl())); + + column = new TableViewerColumn(tableViewer, SWT.NONE); + column.getColumn().setText("Expression?"); + column.getColumn().setWidth(100); + column.setEditingSupport(new IsExpressionModeEditingSupport( + tableViewer, getBControl())); + + // MathTableViewerColumn columnEval = new MathTableViewerColumn( + // tableViewer, column, dbc, "predicate"); + // columnEval.addErrorMessageListener(new IMessageListener() { + // public void setMsg(final String errorMsg) { + // if (errorMsg != null) { + // setErrorMessage(errorMsg); + // } else { + // setErrorMessage(null); + // setMessage(getObserver().getDescription()); + // } + // } + // }); + + ObservableListContentProvider contentProvider = new ObservableListContentProvider(); + tableViewer.setContentProvider(contentProvider); + tableViewer.setLabelProvider(new ObserverLabelProvider( + BeansObservables.observeMaps( + contentProvider.getKnownElements(), new String[] { + "operationName", "predicate", "attribute", + "value", "isExpressionMode" }))); + final WritableList input = new WritableList( + ((ListenOperationByPredicate) getObserver()).getList(), + PredicateOperation.class); + tableViewer.setInput(input); + + // ColumnViewerEditorActivationStrategy activationSupport = new + // ColumnViewerEditorActivationStrategy( + // tableViewer) { + // protected boolean isEditorActivationEvent( + // ColumnViewerEditorActivationEvent event) { + // return event.eventType == + // ColumnViewerEditorActivationEvent.TRAVERSAL + // || event.eventType == + // ColumnViewerEditorActivationEvent.MOUSE_DOUBLE_CLICK_SELECTION + // || event.eventType == + // ColumnViewerEditorActivationEvent.PROGRAMMATIC + // || (event.eventType == + // ColumnViewerEditorActivationEvent.KEY_PRESSED && event.keyCode == + // KeyLookupFactory + // .getDefault().formalKeyLookup( + // IKeyLookup.ENTER_NAME)); + // } + // }; + // activationSupport.setEnableEditorActivationWithKeyboard(true); + + /* + * Without focus highlighter, keyboard events will not be delivered + * to + * ColumnViewerEditorActivationStragety#isEditorActivationEvent(...) + * (see above) + */ + // FocusCellHighlighter focusCellHighlighter = new + // FocusCellOwnerDrawHighlighter( + // tableViewer); + // TableViewerFocusCellManager focusCellManager = new + // TableViewerFocusCellManager( + // tableViewer, focusCellHighlighter); + + // TableViewerEditor.create(tableViewer, focusCellManager, + // activationSupport, ColumnViewerEditor.TABBING_VERTICAL + // | ColumnViewerEditor.KEYBOARD_ACTIVATION); + + Composite comp = new Composite(container, SWT.NONE); + comp.setLayout(new RowLayout()); + comp.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END)); + + Button btRemove = new Button(comp, SWT.PUSH); + btRemove.setText("Remove"); + btRemove.setImage(BMotionStudioImage + .getImage(EditorImageRegistry.IMG_ICON_DELETE)); + btRemove.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (tableViewer.getSelection().isEmpty()) { + return; + } + PredicateOperation obj = (PredicateOperation) ((IStructuredSelection) tableViewer + .getSelection()).getFirstElement(); + input.remove(obj); + } + }); + + Button btAdd = new Button(comp, SWT.PUSH); + btAdd.setText("Add"); + btAdd.setImage(BMotionStudioImage + .getImage(EditorImageRegistry.IMG_ICON_ADD)); + btAdd.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + PredicateOperation obj = new PredicateOperation(); + input.add(obj); + tableViewer.setSelection(new StructuredSelection(obj)); + } + }); + + } + + private class AttributeObserverValueEditing extends EditingSupport { + + private ComboBoxViewerCellEditor cellEditor = null; + + public AttributeObserverValueEditing(TableViewer cv) { + super(cv); + } + + @Override + protected boolean canEdit(Object element) { + return true; + } + + @Override + protected Object getValue(Object element) { + return ((PredicateOperation) element).getAttribute(); + } + + @Override + protected void setValue(Object element, Object value) { + if (value != null) { + PredicateOperation obj = (PredicateOperation) element; + obj.setAttribute(value.toString()); + obj.setIsExpressionMode(false); + } + } + + @Override + protected CellEditor getCellEditor(Object element) { + if (cellEditor == null) { + + cellEditor = new ComboBoxViewerCellEditor( + (Composite) tableViewer.getControl(), SWT.READ_ONLY); + cellEditor + .setContentProvider(new ObservableListContentProvider()); + cellEditor.setLabelProvider(new LabelProvider() { + public String getText(Object element) { + return getBControl().getAttributes() + .get(element.toString()).getName(); + } + }); + cellEditor.setInput(new ComputedList() { + @Override + protected List<String> calculate() { + ArrayList<String> atrList = new ArrayList<String>(); + for (AbstractAttribute atr : getBControl() + .getAttributes().values()) { + atrList.add(atr.getID()); + } + return atrList; + } + }); + + ((CCombo) cellEditor.getControl()) + .addFocusListener(new FocusListener() { + + String oldValue; + + public void focusGained(FocusEvent e) { + oldValue = ((CCombo) cellEditor + .getControl()).getText(); + + } + + public void focusLost(FocusEvent e) { + + if (!oldValue.equals(((CCombo) cellEditor + .getControl()).getText())) { + + IStructuredSelection selection = (IStructuredSelection) getViewer() + .getSelection(); + + PredicateOperation p = (PredicateOperation) selection + .getFirstElement(); + + AbstractAttribute atr = getBControl() + .getAttributes().get( + p.getAttribute()); + + p.setValue(atr.getValue()); + tableViewer.refresh(); + + } + } + + }); + + } + return cellEditor; + } + + } + + } + + public WizardObserverListenOperationByPredicate(final BControl bcontrol, + final Observer bobserver) { + super(bcontrol, bobserver); + addPage(new ObserverListenOperationByPredicatePage( + "ObserverListenOperationByPredicatePage")); + } + + @Override + protected Boolean prepareToFinish() { + return true; + } + + @Override + public Point getSize() { + return new Point(800, 500); + } + + private class ObserverLabelProvider extends ObservableMapLabelProvider + implements ITableLabelProvider, ITableColorProvider, + ITableFontProvider { + + public ObserverLabelProvider(IObservableMap[] attributeMaps) { + super(attributeMaps); + } + + // private final Color errorColor = Display.getDefault().getSystemColor( + // SWT.COLOR_INFO_BACKGROUND); + + // final Font bold = JFaceResources.getFontRegistry().getBold( + // JFaceResources.BANNER_FONT); + + @Override + public Image getColumnImage(Object element, int columnIndex) { + if (columnIndex == 4) { + return CheckboxCellEditorHelper + .getCellEditorImage(((PredicateOperation) element) + .isExpressionMode()); + } + return null; + } + + @Override + public String getColumnText(Object element, int columnIndex) { + + PredicateOperation obj = (PredicateOperation) element; + + if (columnIndex == 2) { + + String atrID = obj.getAttribute(); + String atrName = ""; + if (atrID != null) { + if (atrID.length() > 0) { + atrName = getBControl().getAttributes().get(atrID) + .getName(); + } + } + return atrName; + + } + if (columnIndex == 3) { + + if (obj.getValue() != null) + return obj.getValue().toString(); + return ""; + + } + + if (columnIndex == 4) + return ""; + + return super.getColumnText(element, columnIndex); + } + + public Color getBackground(final Object element, final int column) { + return null; + } + + public Color getForeground(final Object element, final int column) { + return null; + } + + public Font getFont(final Object element, final int column) { + // return JFaceResources.getFontRegistry().get( + // BMotionStudioConstants.RODIN_FONT_KEY); + return null; + } + + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/wizard/WizardObserverSetAttribute.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/wizard/WizardObserverSetAttribute.java new file mode 100644 index 0000000000000000000000000000000000000000..d55c7a92cc5fb4be0a7119aac5bebda9e97aef72 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/wizard/WizardObserverSetAttribute.java @@ -0,0 +1,379 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.observer.wizard; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.databinding.DataBindingContext; +import org.eclipse.core.databinding.beans.BeansObservables; +import org.eclipse.core.databinding.observable.list.ComputedList; +import org.eclipse.core.databinding.observable.list.WritableList; +import org.eclipse.core.databinding.observable.map.IObservableMap; +import org.eclipse.jface.databinding.viewers.ObservableListContentProvider; +import org.eclipse.jface.databinding.viewers.ObservableMapLabelProvider; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ComboBoxViewerCellEditor; +import org.eclipse.jface.viewers.EditingSupport; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITableColorProvider; +import org.eclipse.jface.viewers.ITableFontProvider; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CCombo; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; + +import de.be4.classicalb.core.parser.BParser; +import de.bmotionstudio.gef.editor.BMotionStudioImage; +import de.bmotionstudio.gef.editor.BMotionStudioSWTConstants; +import de.bmotionstudio.gef.editor.EditorImageRegistry; +import de.bmotionstudio.gef.editor.attribute.AbstractAttribute; +import de.bmotionstudio.gef.editor.edit.AttributeExpressionEdittingSupport; +import de.bmotionstudio.gef.editor.edit.IsExpressionModeEditingSupport; +import de.bmotionstudio.gef.editor.edit.PredicateEditingSupport; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.observer.Observer; +import de.bmotionstudio.gef.editor.observer.ObserverWizard; +import de.bmotionstudio.gef.editor.observer.SetAttribute; +import de.bmotionstudio.gef.editor.observer.SetAttributeObject; +import de.bmotionstudio.gef.editor.property.CheckboxCellEditorHelper; + +public class WizardObserverSetAttribute extends ObserverWizard { + + private class WizardSetAttributePage extends WizardPage { + + private TableViewer tableViewer; + + protected WizardSetAttributePage(final String pageName) { + super(pageName); + } + + public void createControl(Composite parent) { + + DataBindingContext dbc = new DataBindingContext(); + + GridLayout gl = new GridLayout(1, true); + gl.horizontalSpacing = 0; + gl.verticalSpacing = 0; + gl.marginHeight = 0; + gl.marginWidth = 0; + + Composite container = new Composite(parent, SWT.NONE); + container.setLayout(gl); + + tableViewer = new TableViewer(container, SWT.BORDER + | SWT.FULL_SELECTION); + tableViewer.getTable().setLinesVisible(true); + tableViewer.getTable().setHeaderVisible(true); + tableViewer.getTable().setLayoutData( + new GridData(GridData.FILL_BOTH)); + tableViewer.getTable().setFont( + BMotionStudioSWTConstants.fontArial10); + + TableViewerColumn column = new TableViewerColumn(tableViewer, + SWT.NONE); + column.getColumn().setText("Predicate"); + column.getColumn().setWidth(300); + + PredicateEditingSupport pEditingSupport = new PredicateEditingSupport( + tableViewer, dbc, "eval", getBControl().getVisualization(), + getShell()); + column.setEditingSupport(pEditingSupport); + + column = new TableViewerColumn(tableViewer, SWT.NONE); + column.getColumn().setText("Attribute"); + column.getColumn().setWidth(150); + column.setEditingSupport(new AttributeObserverValueEditing( + tableViewer)); + + column = new TableViewerColumn(tableViewer, SWT.NONE); + column.getColumn().setText("Value"); + column.getColumn().setWidth(175); + column.setEditingSupport(new AttributeExpressionEdittingSupport( + tableViewer, getBControl())); + + column = new TableViewerColumn(tableViewer, SWT.NONE); + column.getColumn().setText("Expression?"); + column.getColumn().setWidth(100); + column.setEditingSupport(new IsExpressionModeEditingSupport( + tableViewer, getBControl())); + + ObservableListContentProvider contentProvider = new ObservableListContentProvider(); + tableViewer.setContentProvider(contentProvider); + + tableViewer.setLabelProvider(new ObserverLabelProvider( + BeansObservables.observeMaps( + contentProvider.getKnownElements(), new String[] { + "eval", "attribute", "value", + "isExpressionMode" }))); + final WritableList input = new WritableList( + ((SetAttribute) getObserver()).getSetAttributeObjects(), + SetAttributeObject.class); + tableViewer.setInput(input); + + Composite comp = new Composite(container, SWT.NONE); + comp.setLayout(new RowLayout()); + comp.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END)); + + Button btRemove = new Button(comp, SWT.PUSH); + btRemove.setText("Remove"); + btRemove.setImage(BMotionStudioImage + .getImage(EditorImageRegistry.IMG_ICON_DELETE)); + btRemove.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (tableViewer.getSelection().isEmpty()) { + MessageDialog.openInformation(getShell(), + "Please select an entry.", + "Please select an entry."); + return; + } + SetAttributeObject toggleObj = (SetAttributeObject) ((IStructuredSelection) tableViewer + .getSelection()).getFirstElement(); + input.remove(toggleObj); + } + }); + + Button btAdd = new Button(comp, SWT.PUSH); + btAdd.setText("Add"); + btAdd.setImage(BMotionStudioImage + .getImage(EditorImageRegistry.IMG_ICON_ADD)); + btAdd.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + SetAttributeObject toggleObj = new SetAttributeObject( + BParser.PREDICATE_PREFIX, ""); + input.add(toggleObj); + tableViewer + .setSelection(new StructuredSelection(toggleObj)); + } + }); + + setControl(container); + + } + + private class AttributeObserverValueEditing extends EditingSupport { + + private ComboBoxViewerCellEditor cellEditor = null; + + public AttributeObserverValueEditing(TableViewer cv) { + super(cv); + } + + @Override + protected boolean canEdit(Object element) { + return true; + } + + @Override + protected Object getValue(Object element) { + return ((SetAttributeObject) element).getAttribute(); + } + + @Override + protected void setValue(Object element, Object value) { + if (value != null) { + SetAttributeObject obj = (SetAttributeObject) element; + obj.setAttribute(value.toString()); + obj.setIsExpressionMode(false); + } + } + + @Override + protected CellEditor getCellEditor(Object element) { + if (cellEditor == null) { + + cellEditor = new ComboBoxViewerCellEditor( + (Composite) tableViewer.getControl(), SWT.READ_ONLY); + cellEditor + .setContentProvider(new ObservableListContentProvider()); + cellEditor.setLabelProvider(new LabelProvider() { + public String getText(Object element) { + return getBControl().getAttributes() + .get(element.toString()).getName(); + } + }); + cellEditor.setInput(new ComputedList() { + @Override + protected List<String> calculate() { + ArrayList<String> atrList = new ArrayList<String>(); + for (AbstractAttribute atr : getBControl() + .getAttributes().values()) { + atrList.add(atr.getID()); + } + return atrList; + } + }); + + ((CCombo) cellEditor.getControl()) + .addFocusListener(new FocusListener() { + + String oldValue; + + public void focusGained(FocusEvent e) { + oldValue = ((CCombo) cellEditor + .getControl()).getText(); + + } + + public void focusLost(FocusEvent e) { + + if (!oldValue.equals(((CCombo) cellEditor + .getControl()).getText())) { + + IStructuredSelection selection = (IStructuredSelection) getViewer() + .getSelection(); + + SetAttributeObject p = (SetAttributeObject) selection + .getFirstElement(); + + AbstractAttribute atr = getBControl() + .getAttributes().get( + p.getAttribute()); + + p.setValue(atr.getValue()); + tableViewer.refresh(); + + } + } + + }); + + } + return cellEditor; + } + + } + + } + + public WizardObserverSetAttribute(BControl control, Observer observer) { + super(control, observer); + addPage(new WizardSetAttributePage("WizardSetAttributePage")); + } + + @Override + public Point getSize() { + return new Point(800, 500); + } + + @Override + protected Boolean prepareToFinish() { + if (((SetAttribute) getObserver()).getSetAttributeObjects().size() == 0) { + setObserverDelete(true); + } else { + for (SetAttributeObject obj : ((SetAttribute) getObserver()) + .getSetAttributeObjects()) { + if (obj.getAttribute() == null) { + MessageDialog + .openError(getShell(), "Please check your entries", + "Please check your entries. The attribute field must not be empty."); + return false; + } + } + } + return true; + } + + private class ObserverLabelProvider extends ObservableMapLabelProvider + implements ITableLabelProvider, ITableColorProvider, + ITableFontProvider { + + public ObserverLabelProvider(IObservableMap[] attributeMaps) { + super(attributeMaps); + } + + private final Color errorColor = Display.getDefault().getSystemColor( + SWT.COLOR_INFO_BACKGROUND); + + // final Font bold = JFaceResources.getFontRegistry().getBold( + // JFaceResources.BANNER_FONT); + + @Override + public Image getColumnImage(Object element, int columnIndex) { + if (columnIndex == 3) { + return CheckboxCellEditorHelper + .getCellEditorImage(((SetAttributeObject) element) + .isExpressionMode()); + } + return null; + } + + @Override + public String getColumnText(Object element, int columnIndex) { + + SetAttributeObject attributeObject = (SetAttributeObject) element; + + if (columnIndex == 1) { + + String atrID = attributeObject.getAttribute(); + String atrName = ""; + if (atrID != null) { + if (atrID.length() > 0) { + AbstractAttribute atr = getBControl().getAttributes() + .get(atrID); + if (atr != null) + atrName = atr.getName(); + } + } + return atrName; + + } + if (columnIndex == 2) { + + if (attributeObject.getValue() != null) + return attributeObject.getValue().toString(); + return ""; + + } + + if (columnIndex == 3) + return ""; + + return super.getColumnText(element, columnIndex); + } + + public Color getBackground(final Object element, final int column) { + SetAttributeObject attributeObject = (SetAttributeObject) element; + if (attributeObject.hasError()) + return errorColor; + return null; + } + + public Color getForeground(final Object element, final int column) { + return null; + } + + public Font getFont(final Object element, final int column) { + // return JFaceResources.getFontRegistry().get( + // BMotionStudioConstants.RODIN_FONT_KEY); + return null; + } + + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/wizard/WizardObserverSimpleValueDisplay.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/wizard/WizardObserverSimpleValueDisplay.java new file mode 100644 index 0000000000000000000000000000000000000000..25c9eeea409159ca248eb48c4c0261ab196873e3 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/wizard/WizardObserverSimpleValueDisplay.java @@ -0,0 +1,142 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.observer.wizard; + +import org.eclipse.core.databinding.DataBindingContext; +import org.eclipse.core.databinding.beans.BeansObservables; +import org.eclipse.jface.databinding.swt.SWTObservables; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; + +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.observer.Observer; +import de.bmotionstudio.gef.editor.observer.ObserverWizard; +import de.bmotionstudio.gef.editor.observer.SimpleValueDisplay; + +public class WizardObserverSimpleValueDisplay extends ObserverWizard { + + private class ObserverSimpleValueDisplayPage extends WizardPage { + + private Text txtReplacementString; + private Text txtExpression; + private Text txtPredicate; + + public Text getTxtExpression() { + return txtExpression; + } + + protected ObserverSimpleValueDisplayPage(final String pageName) { + super(pageName); + } + + public void createControl(final Composite parent) { + + final DataBindingContext dbc = new DataBindingContext(); + + Composite container = new Composite(parent, SWT.NONE); + + container.setLayoutData(new GridData(GridData.FILL_BOTH)); + container.setLayout(new GridLayout(2, false)); + + Label lb = new Label(container, SWT.NONE); + lb.setText("Predicate:"); + + txtPredicate = new Text(container, SWT.BORDER); + txtPredicate.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + txtPredicate.setFont(new Font(Display.getDefault(), new FontData( + "Arial", 10, SWT.NONE))); + + lb = new Label(container, SWT.NONE); + lb.setText("Expression:"); + lb.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING)); + + txtExpression = new Text(container, SWT.BORDER | SWT.MULTI + | SWT.WRAP); + txtExpression.setLayoutData(new GridData(GridData.FILL_BOTH)); + // txtExpression.setFont(JFaceResources.getFontRegistry().get( + // BMotionStudioConstants.RODIN_FONT_KEY)); + + lb = new Label(container, SWT.NONE); + lb.setText("Replacement String:"); + + txtReplacementString = new Text(container, SWT.BORDER); + txtReplacementString.setLayoutData(new GridData( + GridData.FILL_HORIZONTAL)); + txtReplacementString.setFont(new Font(Display.getDefault(), + new FontData("Arial", 10, SWT.NONE))); + + initBindings(dbc); + + setControl(container); + + } + + private void initBindings(DataBindingContext dbc) { + + dbc.bindValue(SWTObservables.observeText(txtPredicate, SWT.Modify), + BeansObservables.observeValue( + (SimpleValueDisplay) getObserver(), "predicate")); + + dbc.bindValue( + SWTObservables.observeText(txtExpression, SWT.Modify), + BeansObservables.observeValue( + (SimpleValueDisplay) getObserver(), "eval")); + + dbc.bindValue(SWTObservables.observeText(txtReplacementString, + SWT.Modify), BeansObservables.observeValue( + (SimpleValueDisplay) getObserver(), "replacementString")); + + } + + } + + public WizardObserverSimpleValueDisplay(BControl bcontrol, + Observer bobserver) { + super(bcontrol, bobserver); + addPage(new ObserverSimpleValueDisplayPage( + "ObserverSimpleValueDisplayPage")); + } + + @Override + protected Boolean prepareToFinish() { + + ObserverSimpleValueDisplayPage page = (ObserverSimpleValueDisplayPage) getPage("ObserverSimpleValueDisplayPage"); + + String errorStr = ""; + + if (page.getTxtExpression().getText().length() == 0) + errorStr += "Please enter an expression.\n"; + + if (page.getErrorMessage() != null) + errorStr += "Please check the syntax/parser error.\n"; + + if (errorStr.length() > 0) { + MessageDialog.openError(Display.getDefault().getActiveShell(), + "An Error occured", errorStr); + return false; + } + + return true; + + } + + @Override + public Point getSize() { + return new Point(600, 500); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/wizard/WizardObserverSwitchCoordinates.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/wizard/WizardObserverSwitchCoordinates.java new file mode 100644 index 0000000000000000000000000000000000000000..815bbc9f584f04f54d30c5dfdd273fed3c7e965f --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/wizard/WizardObserverSwitchCoordinates.java @@ -0,0 +1,266 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.observer.wizard; + +import org.eclipse.core.databinding.DataBindingContext; +import org.eclipse.core.databinding.beans.BeansObservables; +import org.eclipse.core.databinding.observable.list.WritableList; +import org.eclipse.core.databinding.observable.map.IObservableMap; +import org.eclipse.jface.databinding.viewers.ObservableListContentProvider; +import org.eclipse.jface.databinding.viewers.ObservableMapLabelProvider; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.CheckboxCellEditor; +import org.eclipse.jface.viewers.EditingSupport; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITableColorProvider; +import org.eclipse.jface.viewers.ITableFontProvider; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; + +import de.be4.classicalb.core.parser.BParser; +import de.bmotionstudio.gef.editor.BMotionStudioImage; +import de.bmotionstudio.gef.editor.EditorImageRegistry; +import de.bmotionstudio.gef.editor.edit.PredicateEditingSupport; +import de.bmotionstudio.gef.editor.edit.TextEditingSupport; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.observer.Observer; +import de.bmotionstudio.gef.editor.observer.ObserverWizard; +import de.bmotionstudio.gef.editor.observer.SwitchCoordinates; +import de.bmotionstudio.gef.editor.observer.ToggleObjectCoordinates; +import de.bmotionstudio.gef.editor.property.CheckboxCellEditorHelper; + +public class WizardObserverSwitchCoordinates extends ObserverWizard { + + private class ObserverToggleCoordinatesPage extends WizardPage { + + private TableViewer tableViewer; + + protected ObserverToggleCoordinatesPage(final String pageName) { + super(pageName); + } + + public void createControl(Composite parent) { + + DataBindingContext dbc = new DataBindingContext(); + + Composite container = new Composite(parent, SWT.NONE); + container.setLayout(new GridLayout(1, true)); + + tableViewer = new TableViewer(container, SWT.BORDER + | SWT.FULL_SELECTION); + tableViewer.getTable().setLinesVisible(true); + tableViewer.getTable().setHeaderVisible(true); + tableViewer.getTable().setLayoutData( + new GridData(GridData.FILL_BOTH)); + tableViewer.getTable().setFont( + new Font(Display.getDefault(), new FontData("Arial", 10, + SWT.NONE))); + + TableViewerColumn column = new TableViewerColumn(tableViewer, + SWT.NONE); + column.getColumn().setText("Predicate"); + column.getColumn().setWidth(200); + column.setEditingSupport(new PredicateEditingSupport(tableViewer, + dbc, "eval", getBControl().getVisualization(), getShell())); + + column = new TableViewerColumn(tableViewer, SWT.NONE); + column.getColumn().setText("X"); + column.getColumn().setWidth(150); + column.setEditingSupport(new TextEditingSupport(tableViewer, dbc, + "x")); + + column = new TableViewerColumn(tableViewer, SWT.NONE); + column.getColumn().setText("Y"); + column.getColumn().setWidth(150); + column.setEditingSupport(new TextEditingSupport(tableViewer, dbc, + "y")); + + column = new TableViewerColumn(tableViewer, SWT.NONE); + column.getColumn().setText("Animate?"); + column.getColumn().setWidth(75); + column.setEditingSupport(new EditingSupport(tableViewer) { + + private CellEditor cellEditor = new CheckboxCellEditor( + (Composite) tableViewer.getControl()); + + @Override + protected void setValue(Object element, Object value) { + ((ToggleObjectCoordinates) element).setAnimate(Boolean + .valueOf(String.valueOf(value))); + } + + @Override + protected Object getValue(Object element) { + Boolean b = ((ToggleObjectCoordinates) element) + .getAnimate(); + return b != null ? b : false; + } + + @Override + protected CellEditor getCellEditor(Object element) { + return cellEditor; + } + + @Override + protected boolean canEdit(Object element) { + return true; + } + + }); + + ObservableListContentProvider contentProvider = new ObservableListContentProvider(); + tableViewer.setContentProvider(contentProvider); + tableViewer.setLabelProvider(new ObserverLabelProvider( + BeansObservables.observeMaps( + contentProvider.getKnownElements(), new String[] { + "eval", "x", "y", "animate" }))); + + final WritableList input = new WritableList( + ((SwitchCoordinates) getObserver()).getToggleObjects(), + ToggleObjectCoordinates.class); + tableViewer.setInput(input); + + Composite comp = new Composite(container, SWT.NONE); + comp.setLayout(new RowLayout()); + comp.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END)); + + Button btRemove = new Button(comp, SWT.PUSH); + btRemove.setText("Remove"); + btRemove.setImage(BMotionStudioImage + .getImage(EditorImageRegistry.IMG_ICON_DELETE)); + btRemove.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (tableViewer.getSelection().isEmpty()) { + return; + } + ToggleObjectCoordinates toggleObj = (ToggleObjectCoordinates) ((IStructuredSelection) tableViewer + .getSelection()).getFirstElement(); + input.remove(toggleObj); + } + }); + + Button btAdd = new Button(comp, SWT.PUSH); + btAdd.setText("Add"); + btAdd.setImage(BMotionStudioImage + .getImage(EditorImageRegistry.IMG_ICON_ADD)); + btAdd.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + ToggleObjectCoordinates toggleObj = new ToggleObjectCoordinates( + BParser.PREDICATE_PREFIX, "", "", "", false); + input.add(toggleObj); + tableViewer + .setSelection(new StructuredSelection(toggleObj)); + } + }); + + setControl(container); + + } + } + + public WizardObserverSwitchCoordinates(final BControl bcontrol, + final Observer bobserver) { + super(bcontrol, bobserver); + addPage(new ObserverToggleCoordinatesPage( + "ObserverToggleCoordinatesPage")); + } + + @Override + protected Boolean prepareToFinish() { + if (((SwitchCoordinates) getObserver()).getToggleObjects().size() == 0) { + setObserverDelete(true); + } else { + for (ToggleObjectCoordinates obj : ((SwitchCoordinates) getObserver()) + .getToggleObjects()) { + if (obj.getX().isEmpty() || obj.getY().isEmpty()) { + MessageDialog + .openError(getShell(), "Please check your entries", + "Please check your entries. The x and y fields must not be empty."); + return false; + } + } + } + return true; + } + + @Override + public Point getSize() { + return new Point(650, 500); + } + + private static class ObserverLabelProvider extends + ObservableMapLabelProvider implements ITableLabelProvider, + ITableColorProvider, ITableFontProvider { + + public ObserverLabelProvider(IObservableMap[] attributeMaps) { + super(attributeMaps); + } + + private final Color errorColor = Display.getDefault().getSystemColor( + SWT.COLOR_INFO_BACKGROUND); + + // final Font bold = JFaceResources.getFontRegistry().getBold( + // JFaceResources.BANNER_FONT); + + @Override + public String getColumnText(Object element, int columnIndex) { + if (columnIndex == 3) { + return ""; + } + return super.getColumnText(element, columnIndex); + } + + @Override + public Image getColumnImage(Object element, int columnIndex) { + if (columnIndex == 3) { + return CheckboxCellEditorHelper + .getCellEditorImage(((ToggleObjectCoordinates) element) + .getAnimate()); + } + return null; + } + + public Color getBackground(final Object element, final int column) { + ToggleObjectCoordinates attributeObject = (ToggleObjectCoordinates) element; + if (attributeObject.hasError()) + return errorColor; + return null; + } + + public Color getForeground(final Object element, final int column) { + return null; + } + + public Font getFont(final Object element, final int column) { + // return JFaceResources.getFontRegistry().get( + // BMotionStudioConstants.RODIN_FONT_KEY); + return null; + } + + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/wizard/WizardObserverSwitchImage.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/wizard/WizardObserverSwitchImage.java new file mode 100644 index 0000000000000000000000000000000000000000..ececb18f447f53cd89e70a9c5e6d19acdfa3c043 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/wizard/WizardObserverSwitchImage.java @@ -0,0 +1,257 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.observer.wizard; + +import org.eclipse.core.databinding.DataBindingContext; +import org.eclipse.core.databinding.beans.BeansObservables; +import org.eclipse.core.databinding.observable.list.WritableList; +import org.eclipse.core.databinding.observable.map.IObservableMap; +import org.eclipse.jface.databinding.viewers.ObservableListContentProvider; +import org.eclipse.jface.databinding.viewers.ObservableMapLabelProvider; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITableColorProvider; +import org.eclipse.jface.viewers.ITableFontProvider; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; + +import de.be4.classicalb.core.parser.BParser; +import de.bmotionstudio.gef.editor.AttributeConstants; +import de.bmotionstudio.gef.editor.BMotionStudioImage; +import de.bmotionstudio.gef.editor.EditorImageRegistry; +import de.bmotionstudio.gef.editor.edit.AttributeExpressionEdittingSupport; +import de.bmotionstudio.gef.editor.edit.IsExpressionModeEditingSupport; +import de.bmotionstudio.gef.editor.edit.PredicateEditingSupport; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.observer.Observer; +import de.bmotionstudio.gef.editor.observer.ObserverWizard; +import de.bmotionstudio.gef.editor.observer.SwitchImage; +import de.bmotionstudio.gef.editor.observer.ToggleObjectImage; +import de.bmotionstudio.gef.editor.property.CheckboxCellEditorHelper; + +public class WizardObserverSwitchImage extends ObserverWizard { + + private class ObserverSwitchImagePage extends WizardPage { + + private TableViewer tableViewer; + + protected ObserverSwitchImagePage(final String pageName) { + super(pageName); + } + + public void createControl(final Composite parent) { + + DataBindingContext dbc = new DataBindingContext(); + + Composite container = new Composite(parent, SWT.NONE); + container.setLayout(new GridLayout(1, true)); + + tableViewer = new TableViewer(container, SWT.BORDER + | SWT.FULL_SELECTION); + tableViewer.getTable().setLinesVisible(true); + tableViewer.getTable().setHeaderVisible(true); + tableViewer.getTable().setLayoutData( + new GridData(GridData.FILL_BOTH)); + tableViewer.getTable().setFont( + new Font(Display.getDefault(), new FontData("Arial", 10, + SWT.NONE))); + + TableViewerColumn column = new TableViewerColumn(tableViewer, + SWT.NONE); + column.getColumn().setText("Predicate"); + column.getColumn().setWidth(300); + column.setEditingSupport(new PredicateEditingSupport(tableViewer, + dbc, "eval", getBControl().getVisualization(), getShell())); + + column = new TableViewerColumn(tableViewer, SWT.NONE); + column.getColumn().setText("Image"); + column.getColumn().setWidth(180); + column.setEditingSupport(new AttributeExpressionEdittingSupport( + tableViewer, getBControl(), + AttributeConstants.ATTRIBUTE_IMAGE) { + + @Override + protected Object getValue(final Object element) { + ToggleObjectImage evalObject = (ToggleObjectImage) element; + return evalObject.getImage(); + } + + @Override + protected void setValue(final Object element, final Object value) { + if (value == null) + return; + ((ToggleObjectImage) element).setImage(value.toString()); + } + + }); + + column = new TableViewerColumn(tableViewer, SWT.NONE); + column.getColumn().setText("Expression?"); + column.getColumn().setWidth(100); + column.setEditingSupport(new IsExpressionModeEditingSupport( + tableViewer, getBControl()) { + + @Override + protected void setValue(final Object element, final Object value) { + Boolean bol = Boolean.valueOf(String.valueOf(value)); + ToggleObjectImage obj = (ToggleObjectImage) element; + obj.setIsExpressionMode(bol); + } + + }); + + ObservableListContentProvider contentProvider = new ObservableListContentProvider(); + tableViewer.setContentProvider(contentProvider); + + tableViewer.setLabelProvider(new ObserverLabelProvider( + BeansObservables.observeMaps( + contentProvider.getKnownElements(), new String[] { + "eval", "image", "isExpressionMode" }))); + final WritableList input = new WritableList( + ((SwitchImage) getObserver()).getToggleObjects(), + ToggleObjectImage.class); + tableViewer.setInput(input); + + Composite comp = new Composite(container, SWT.NONE); + comp.setLayout(new RowLayout()); + comp.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END)); + + Button btRemove = new Button(comp, SWT.PUSH); + btRemove.setImage(BMotionStudioImage + .getImage(EditorImageRegistry.IMG_ICON_DELETE)); + btRemove.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(final SelectionEvent e) { + if (tableViewer.getSelection().isEmpty()) { + return; + } + ToggleObjectImage toggleObj = (ToggleObjectImage) ((IStructuredSelection) tableViewer + .getSelection()).getFirstElement(); + input.remove(toggleObj); + } + }); + + Button btAdd = new Button(comp, SWT.PUSH); + btAdd.setImage(BMotionStudioImage + .getImage(EditorImageRegistry.IMG_ICON_ADD)); + btAdd.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(final SelectionEvent e) { + ToggleObjectImage toggleObj = new ToggleObjectImage( + BParser.PREDICATE_PREFIX, "", ""); + input.add(toggleObj); + tableViewer + .setSelection(new StructuredSelection(toggleObj)); + } + }); + + setControl(container); + + } + + } + + public WizardObserverSwitchImage(final BControl bcontrol, + final Observer bobserver) { + super(bcontrol, bobserver); + addPage(new ObserverSwitchImagePage("ObserverToggleImagePage")); + } + + @Override + protected Boolean prepareToFinish() { + if (((SwitchImage) getObserver()).getToggleObjects().size() == 0) { + setObserverDelete(true); + } else { + for (ToggleObjectImage obj : ((SwitchImage) getObserver()) + .getToggleObjects()) { + if (obj.getImage().isEmpty()) { + MessageDialog + .openError(getShell(), "Please check your entries", + "Please check your entries. The image field must not be empty."); + return false; + } + } + } + return true; + } + + @Override + public Point getSize() { + return new Point(650, 500); + } + + private static class ObserverLabelProvider extends + ObservableMapLabelProvider implements ITableLabelProvider, + ITableColorProvider, ITableFontProvider { + + public ObserverLabelProvider(final IObservableMap[] attributeMaps) { + super(attributeMaps); + } + + private final Color errorColor = Display.getDefault().getSystemColor( + SWT.COLOR_INFO_BACKGROUND); + + // final Font bold = JFaceResources.getFontRegistry().getBold( + // JFaceResources.BANNER_FONT); + + @Override + public Image getColumnImage(final Object element, final int columnIndex) { + if (columnIndex == 2) { + return CheckboxCellEditorHelper + .getCellEditorImage(((ToggleObjectImage) element) + .isExpressionMode()); + } + return null; + } + + @Override + public String getColumnText(final Object element, final int columnIndex) { + + if (columnIndex == 2) + return ""; + + return super.getColumnText(element, columnIndex); + + } + + public Color getBackground(final Object element, final int column) { + ToggleObjectImage attributeObject = (ToggleObjectImage) element; + if (attributeObject.hasError()) + return errorColor; + return null; + } + + public Color getForeground(final Object element, final int column) { + return null; + } + + public Font getFont(final Object element, final int column) { + // return JFaceResources.getFontRegistry().get( + // BMotionStudioConstants.RODIN_FONT_KEY); + return null; + } + + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/AppAbstractEditPart.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/AppAbstractEditPart.java new file mode 100644 index 0000000000000000000000000000000000000000..8bf29b1c02cd753f7c47e624616fd1bb31e1995b --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/AppAbstractEditPart.java @@ -0,0 +1,343 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.part; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map.Entry; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.draw2d.ButtonModel; +import org.eclipse.draw2d.ChangeEvent; +import org.eclipse.draw2d.ChangeListener; +import org.eclipse.draw2d.ChopboxAnchor; +import org.eclipse.draw2d.ConnectionAnchor; +import org.eclipse.draw2d.Figure; +import org.eclipse.draw2d.FlowLayout; +import org.eclipse.draw2d.IFigure; +import org.eclipse.gef.ConnectionEditPart; +import org.eclipse.gef.NodeEditPart; +import org.eclipse.gef.Request; +import org.eclipse.gef.RequestConstants; +import org.eclipse.gef.editparts.AbstractGraphicalEditPart; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Cursor; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; + +import de.bmotionstudio.gef.editor.AttributeConstants; +import de.bmotionstudio.gef.editor.attribute.AbstractAttribute; +import de.bmotionstudio.gef.editor.figure.AbstractBMotionFigure; +import de.bmotionstudio.gef.editor.library.AbstractLibraryCommand; +import de.bmotionstudio.gef.editor.library.AttributeRequest; +import de.bmotionstudio.gef.editor.model.BConnection; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.model.Visualization; +import de.bmotionstudio.gef.editor.observer.IObserverListener; +import de.bmotionstudio.gef.editor.observer.Observer; + +public abstract class AppAbstractEditPart extends AbstractGraphicalEditPart + implements PropertyChangeListener, IObserverListener, IAdaptable, + NodeEditPart { + + private final Cursor cursorHover = new Cursor(Display.getCurrent(), + SWT.CURSOR_HAND); + + protected ConnectionAnchor anchor; + + private ChangeListener changeListener = new ChangeListener() { + @Override + public void handleStateChanged(ChangeEvent event) { + if (getCastedModel().hasEvent(AttributeConstants.EVENT_MOUSECLICK)) { + if (event.getPropertyName().equals( + ButtonModel.MOUSEOVER_PROPERTY)) + getFigure().setCursor(cursorHover); + if (event.getPropertyName() + .equals(ButtonModel.PRESSED_PROPERTY)) { + AbstractBMotionFigure f = (AbstractBMotionFigure) getFigure(); + if (f.getModel().isPressed()) + executeEvent(AttributeConstants.EVENT_MOUSECLICK); + } + } + } + }; + + private String[] layoutAttributes = { BControl.PROPERTY_LAYOUT, + BControl.PROPERTY_LOCATION, AttributeConstants.ATTRIBUTE_X, + AttributeConstants.ATTRIBUTE_Y, AttributeConstants.ATTRIBUTE_WIDTH, + AttributeConstants.ATTRIBUTE_HEIGHT }; + + public void activate() { + if (!isActive()) { + super.activate(); + ((BControl) getModel()).addPropertyChangeListener(this); + ((BControl) getModel()).addObserverListener(this); + if (getFigure() instanceof AbstractBMotionFigure) { + AbstractBMotionFigure af = (AbstractBMotionFigure) getFigure(); + if (isRunning()) + af.addChangeListener(changeListener); + af.activateFigure(); + } + } + } + + public void deactivate() { + if (isActive()) { + super.deactivate(); + ((BControl) getModel()).removePropertyChangeListener(this); + ((BControl) getModel()).removeObserverListener(this); + if (getFigure() instanceof AbstractBMotionFigure) { + AbstractBMotionFigure af = (AbstractBMotionFigure) getFigure(); + if (isRunning()) + af.removeChangeListener(changeListener); + af.deactivateFigure(); + } + } + } + + protected abstract IFigure createEditFigure(); + + @Override + protected void createEditPolicies() { + if (isRunning()) + prepareRunPolicies(); + else + prepareEditPolicies(); + } + + protected abstract void prepareEditPolicies(); + + protected abstract void prepareRunPolicies(); + + protected Boolean isRunning() { + return ((BControl) getModel()).getVisualization().isRunning(); + } + + @Override + protected IFigure createFigure() { + final IFigure figure = createEditFigure(); + IFigure toolTipFigure = getToolTip(); + if (toolTipFigure != null) + figure.setToolTip(toolTipFigure); + if (!isRunning()) { + if (figure instanceof AbstractBMotionFigure) { + ((AbstractBMotionFigure) figure).setEnabled(false); + } + } + return figure; + } + + @Override + public void performRequest(Request req) { + if (!isRunning()) { + if (req.getType().equals(RequestConstants.REQ_OPEN)) { + try { + IWorkbenchPage page = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage(); + page.showView(IPageLayout.ID_PROP_SHEET); + } catch (PartInitException e) { + e.printStackTrace(); + } + } + } + } + + @Override + protected void refreshVisuals() { + IFigure figure = getFigure(); + BControl model = (BControl) getModel(); + for (Entry<String, AbstractAttribute> e : model.getAttributes() + .entrySet()) { + PropertyChangeEvent evt = new PropertyChangeEvent(model, + e.getKey(), null, e.getValue().getValue()); + refreshEditFigure(figure, model, evt); + } + refreshEditLayout(figure, model); + } + + public abstract void refreshEditFigure(IFigure figure, BControl model, + PropertyChangeEvent pEvent); + + protected void refreshEditLayout(IFigure figure, BControl control) { + if (!(control instanceof Visualization)) { + if (getFigure().getParent() != null) + getFigure().getParent().setConstraint((IFigure) figure, + control.getLayout()); + getFigure().setPreferredSize(control.getDimension()); + } + } + + @Override + public void propertyChange(final PropertyChangeEvent evt) { + final IFigure figure = (IFigure) getFigure(); + final BControl model = (BControl) getModel(); + String propName = evt.getPropertyName(); + + if (BControl.SOURCE_CONNECTIONS_PROP.equals(propName)) { + refreshSourceConnections(); + } else if (BControl.TARGET_CONNECTIONS_PROP.equals(propName)) { + refreshTargetConnections(); + } + if (propName.equals(BControl.PROPERTY_ADD) + || propName.equals(BControl.PROPERTY_REMOVE)) { + refreshChildren(); + } else if (Arrays.asList(layoutAttributes).contains(propName)) { + // Layout attribute + if (isRunning()) { + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + refreshEditLayout(figure, model); + } + }); + } else { + refreshEditLayout(figure, model); + } + } else { + + // Custom attribute + if (isRunning()) { + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + refreshEditFigure(figure, model, evt); + } + }); + } else { + refreshEditFigure(figure, model, evt); + } + } + } + + public List<BControl> getModelChildren() { + return new ArrayList<BControl>(); + } + + public void executeEvent(String event) { + getCastedModel().executeEvent(event); + } + + protected IFigure getToolTip() { + + Figure fig = new Figure(); + fig.setLayoutManager(new FlowLayout()); + + Collection<Observer> observerList = ((BControl) getModel()) + .getObservers().values(); + for (Observer observer : observerList) { + IFigure observerFigure = observer.getToolTip((BControl) getModel()); + if (observerFigure != null) { + fig.add(observerFigure); + } + } + + return fig; + + } + + @Override + public void addedObserver(BControl control, Observer observer) { + // Update Tooltip + getFigure().setToolTip(getToolTip()); + } + + @Override + public void removedObserver(BControl control) { + + } + + public AbstractLibraryCommand getLibraryCommand(AttributeRequest request) { + return null; + } + + protected BControl getCastedModel() { + return (BControl) getModel(); + } + + protected ConnectionAnchor getConnectionAnchor() { + if (anchor == null) { + anchor = new ChopboxAnchor(getFigure()); + } + return anchor; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.gef.editparts.AbstractGraphicalEditPart#getModelSourceConnections + * () + */ + protected List<BConnection> getModelSourceConnections() { + return getCastedModel().getSourceConnections(); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.gef.editparts.AbstractGraphicalEditPart#getModelTargetConnections + * () + */ + protected List<BConnection> getModelTargetConnections() { + return getCastedModel().getTargetConnections(); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.gef.NodeEditPart#getSourceConnectionAnchor(org.eclipse.gef + * .ConnectionEditPart) + */ + public ConnectionAnchor getSourceConnectionAnchor( + ConnectionEditPart connection) { + return getConnectionAnchor(); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.gef.NodeEditPart#getSourceConnectionAnchor(org.eclipse.gef + * .Request) + */ + public ConnectionAnchor getSourceConnectionAnchor(Request request) { + return getConnectionAnchor(); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.gef.NodeEditPart#getTargetConnectionAnchor(org.eclipse.gef + * .ConnectionEditPart) + */ + public ConnectionAnchor getTargetConnectionAnchor( + ConnectionEditPart connection) { + return getConnectionAnchor(); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.gef.NodeEditPart#getTargetConnectionAnchor(org.eclipse.gef + * .Request) + */ + public ConnectionAnchor getTargetConnectionAnchor(Request request) { + return getConnectionAnchor(); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/AppAbstractTreeEditPart.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/AppAbstractTreeEditPart.java new file mode 100644 index 0000000000000000000000000000000000000000..d1a5aa44614294ac08b22607eacf2bda477b676d --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/AppAbstractTreeEditPart.java @@ -0,0 +1,58 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.part; + +import java.beans.PropertyChangeListener; + +import org.eclipse.gef.EditPolicy; +import org.eclipse.gef.Request; +import org.eclipse.gef.RequestConstants; +import org.eclipse.gef.editparts.AbstractTreeEditPart; +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; + +import de.bmotionstudio.gef.editor.editpolicy.AppDeletePolicy; +import de.bmotionstudio.gef.editor.model.BControl; + +public abstract class AppAbstractTreeEditPart extends AbstractTreeEditPart + implements PropertyChangeListener { + + public void activate() { + if (!isActive()) { + super.activate(); + ((BControl) getModel()).addPropertyChangeListener(this); + } + } + + public void deactivate() { + if (isActive()) { + super.deactivate(); + ((BControl) getModel()).removePropertyChangeListener(this); + } + } + + @Override + public void performRequest(Request req) { + if (req.getType().equals(RequestConstants.REQ_OPEN)) { + try { + IWorkbenchPage page = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage(); + page.showView(IPageLayout.ID_PROP_SHEET); + } catch (PartInitException e) { + e.printStackTrace(); + } + } + } + + @Override + protected void createEditPolicies() { + installEditPolicy(EditPolicy.COMPONENT_ROLE, new AppDeletePolicy()); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/AppEditPartFactory.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/AppEditPartFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..392ad3670b169c3666385f3b91c512dfa0404ec8 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/AppEditPartFactory.java @@ -0,0 +1,49 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.part; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.gef.EditPart; +import org.eclipse.gef.EditPartFactory; +import org.eclipse.gef.editparts.AbstractGraphicalEditPart; + +import de.bmotionstudio.gef.editor.BMotionEditorPlugin; +import de.bmotionstudio.gef.editor.IBControlService; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.model.Visualization; + +public class AppEditPartFactory implements EditPartFactory { + + @Override + public EditPart createEditPart(EditPart context, Object model) { + + AbstractGraphicalEditPart part = null; + + BControl control = (BControl) model; + + if (control instanceof Visualization) { + part = new VisualizationPart(); + } else { + try { + IBControlService service = (IBControlService) BMotionEditorPlugin + .getControlServices().get(control.getType()) + .createExecutableExtension("service"); + part = service.createEditPart(); + } catch (CoreException e) { + e.printStackTrace(); + } + } + + if (part != null) + part.setModel(control); + + // TODO: check if part == null + return part; + + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/AppTreeEditPartFactory.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/AppTreeEditPartFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..4a0001172af51b81a6a6bcda1f2f7e5878d98fc4 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/AppTreeEditPartFactory.java @@ -0,0 +1,26 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.part; + +import org.eclipse.gef.EditPart; +import org.eclipse.gef.EditPartFactory; + +import de.bmotionstudio.gef.editor.model.BControl; + +public class AppTreeEditPartFactory implements EditPartFactory { + + public EditPart createEditPart(EditPart context, Object model) { + BControlTreeEditPart part = null; + if (model instanceof BControl) { + part = new BControlTreeEditPart(); + if (part != null) + part.setModel(model); + } + return part; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/BButtonPart.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/BButtonPart.java new file mode 100644 index 0000000000000000000000000000000000000000..e242ca8dc02bfff5fa940dba6389aa55ef1da197 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/BButtonPart.java @@ -0,0 +1,86 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.part; + +import java.beans.PropertyChangeEvent; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.gef.EditPolicy; +import org.eclipse.gef.Request; +import org.eclipse.gef.RequestConstants; +import org.eclipse.swt.graphics.RGB; + +import de.bmotionstudio.gef.editor.AttributeConstants; +import de.bmotionstudio.gef.editor.edit.TextCellEditorLocator; +import de.bmotionstudio.gef.editor.edit.TextEditManager; +import de.bmotionstudio.gef.editor.editpolicy.AppDeletePolicy; +import de.bmotionstudio.gef.editor.editpolicy.BMotionNodeEditPolicy; +import de.bmotionstudio.gef.editor.editpolicy.CustomDirectEditPolicy; +import de.bmotionstudio.gef.editor.editpolicy.RenamePolicy; +import de.bmotionstudio.gef.editor.figure.ButtonFigure; +import de.bmotionstudio.gef.editor.model.BControl; + +public class BButtonPart extends AppAbstractEditPart { + + @Override + public void refreshEditFigure(IFigure figure, BControl model, + PropertyChangeEvent evt) { + + Object value = evt.getNewValue(); + String aID = evt.getPropertyName(); + + if (aID.equals(AttributeConstants.ATTRIBUTE_TEXT)) + ((ButtonFigure) figure).setText(value.toString()); + + if (aID.equals(AttributeConstants.ATTRIBUTE_BACKGROUND_COLOR)) + ((ButtonFigure) figure).setBackgroundColor((RGB) value); + + if (aID.equals(AttributeConstants.ATTRIBUTE_TEXT_COLOR)) + ((ButtonFigure) figure).setTextColor((RGB) value); + + if (aID.equals(AttributeConstants.ATTRIBUTE_ENABLED)) + ((ButtonFigure) figure).setBtEnabled(Boolean.valueOf(value.toString())); + + if (aID.equals(AttributeConstants.ATTRIBUTE_VISIBLE)) + ((ButtonFigure) figure).setVisible(Boolean.valueOf(value.toString())); + + } + + @Override + protected IFigure createEditFigure() { + IFigure figure = new ButtonFigure(); + return figure; + } + + private void performDirectEdit() { + new TextEditManager(this, new TextCellEditorLocator( + (IFigure) getFigure())).show(); + } + + @Override + public void performRequest(Request request) { + super.performRequest(request); + if (request.getType() == RequestConstants.REQ_DIRECT_EDIT + && !isRunning()) + performDirectEdit(); + } + + @Override + protected void prepareEditPolicies() { + installEditPolicy(EditPolicy.COMPONENT_ROLE, new AppDeletePolicy()); + installEditPolicy(EditPolicy.NODE_ROLE, new RenamePolicy()); + installEditPolicy(EditPolicy.DIRECT_EDIT_ROLE, + new CustomDirectEditPolicy()); + installEditPolicy(EditPolicy.GRAPHICAL_NODE_ROLE, + new BMotionNodeEditPolicy()); + } + + @Override + protected void prepareRunPolicies() { + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/BCanisterPart.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/BCanisterPart.java new file mode 100644 index 0000000000000000000000000000000000000000..51cacf5bbc729897b50d93ea37d97da0e3dc1960 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/BCanisterPart.java @@ -0,0 +1,60 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.part; + +import java.beans.PropertyChangeEvent; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.swt.graphics.RGB; + +import de.bmotionstudio.gef.editor.AttributeConstants; +import de.bmotionstudio.gef.editor.figure.CanisterFigure; +import de.bmotionstudio.gef.editor.model.BControl; + +public class BCanisterPart extends AppAbstractEditPart { + + @Override + protected IFigure createEditFigure() { + IFigure figure = new CanisterFigure(); + return figure; + } + + @Override + public void refreshEditFigure(IFigure figure, BControl model, + PropertyChangeEvent evt) { + ((CanisterFigure) figure).setAlpha(Integer.valueOf(model + .getAttributeValue(AttributeConstants.ATTRIBUTE_ALPHA) + .toString())); + ((CanisterFigure) figure).setFillColor((RGB) model + .getAttributeValue(AttributeConstants.ATTRIBUTE_FILL_COLOR)); + ((CanisterFigure) figure).setFillHeight(Integer.valueOf(model + .getAttributeValue(AttributeConstants.ATTRIBUTE_FILL_HEIGHT) + .toString())); + ((CanisterFigure) figure).setMaxPos(Integer.valueOf(model + .getAttributeValue(AttributeConstants.ATTRIBUTE_MEASURE_MAXPOS) + .toString())); + ((CanisterFigure) figure).setInterval(Integer.valueOf(model + .getAttributeValue( + AttributeConstants.ATTRIBUTE_MEASURE_INTERVAL) + .toString())); + ((CanisterFigure) figure).setMeasure(Boolean.valueOf(model + .getAttributeValue(AttributeConstants.ATTRIBUTE_SHOWS_MEASURE) + .toString())); + ((CanisterFigure) figure) + .setBackgroundColor((RGB) model + .getAttributeValue(AttributeConstants.ATTRIBUTE_BACKGROUND_COLOR)); + } + + @Override + protected void prepareEditPolicies() { + } + + @Override + protected void prepareRunPolicies() { + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/BCheckboxPart.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/BCheckboxPart.java new file mode 100644 index 0000000000000000000000000000000000000000..a5e6b73978208d8d607bb74dbbaa969e22d3938a --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/BCheckboxPart.java @@ -0,0 +1,103 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.part; + +import java.beans.PropertyChangeEvent; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.gef.EditPolicy; +import org.eclipse.gef.Request; +import org.eclipse.gef.RequestConstants; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Display; + +import de.bmotionstudio.gef.editor.AttributeConstants; +import de.bmotionstudio.gef.editor.BMotionStudioImage; +import de.bmotionstudio.gef.editor.EditorImageRegistry; +import de.bmotionstudio.gef.editor.edit.TextCellEditorLocator; +import de.bmotionstudio.gef.editor.edit.TextEditManager; +import de.bmotionstudio.gef.editor.editpolicy.AppDeletePolicy; +import de.bmotionstudio.gef.editor.editpolicy.BMotionNodeEditPolicy; +import de.bmotionstudio.gef.editor.editpolicy.CustomDirectEditPolicy; +import de.bmotionstudio.gef.editor.editpolicy.RenamePolicy; +import de.bmotionstudio.gef.editor.figure.CheckboxFigure; +import de.bmotionstudio.gef.editor.model.BControl; + +public class BCheckboxPart extends AppAbstractEditPart { + + @Override + protected IFigure createEditFigure() { + CheckboxFigure fig = new CheckboxFigure(); + return fig; + } + + @Override + public void refreshEditFigure(IFigure figure, BControl model, + PropertyChangeEvent pEvent) { + + Object value = pEvent.getNewValue(); + String aID = pEvent.getPropertyName(); + + if (aID.equals(AttributeConstants.ATTRIBUTE_VISIBLE)) + ((CheckboxFigure) figure).setVisible(Boolean.valueOf(value + .toString())); + + if (aID.equals(AttributeConstants.ATTRIBUTE_CHECKED)) { + Boolean bol = Boolean.valueOf(value.toString()); + if (bol) { + ((CheckboxFigure) figure).setImage(BMotionStudioImage + .getImage(EditorImageRegistry.IMG_ICON_CHECKED)); + } else { + ((CheckboxFigure) figure).setImage(BMotionStudioImage + .getImage(EditorImageRegistry.IMG_ICON_UNCHECKED)); + } + + } + + if (aID.equals(AttributeConstants.ATTRIBUTE_TEXT)) { + int addWidth = ((CheckboxFigure) figure).setText(value.toString()); + ((BControl) getModel()).setAttributeValue( + AttributeConstants.ATTRIBUTE_WIDTH, (30 + addWidth)); + } + + if (aID.equals(AttributeConstants.ATTRIBUTE_TEXT_COLOR)) { + RGB rgbText = (RGB) value; + ((CheckboxFigure) figure) + .setTextColor(new org.eclipse.swt.graphics.Color(Display + .getDefault(), rgbText)); + } + + } + + @Override + protected void prepareEditPolicies() { + installEditPolicy(EditPolicy.COMPONENT_ROLE, new AppDeletePolicy()); + installEditPolicy(EditPolicy.NODE_ROLE, new RenamePolicy()); + installEditPolicy(EditPolicy.DIRECT_EDIT_ROLE, + new CustomDirectEditPolicy()); + installEditPolicy(EditPolicy.GRAPHICAL_NODE_ROLE, + new BMotionNodeEditPolicy()); + } + + @Override + protected void prepareRunPolicies() { + } + + private void performDirectEdit() { + new TextEditManager(this, new TextCellEditorLocator( + (IFigure) getFigure())).show(); + } + + @Override + public void performRequest(Request request) { + super.performRequest(request); + if (request.getType() == RequestConstants.REQ_DIRECT_EDIT + && !isRunning()) + performDirectEdit(); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/BCompositePart.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/BCompositePart.java new file mode 100644 index 0000000000000000000000000000000000000000..9774726354aefa07bf454f483e16b8dfaf89923e --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/BCompositePart.java @@ -0,0 +1,147 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.part; + +import java.beans.PropertyChangeEvent; +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.resources.IFile; +import org.eclipse.draw2d.IFigure; +import org.eclipse.gef.CompoundSnapToHelper; +import org.eclipse.gef.EditPolicy; +import org.eclipse.gef.SnapToGeometry; +import org.eclipse.gef.SnapToGrid; +import org.eclipse.gef.SnapToGuides; +import org.eclipse.gef.SnapToHelper; +import org.eclipse.gef.editpolicies.SnapFeedbackPolicy; +import org.eclipse.gef.rulers.RulerProvider; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Display; + +import de.bmotionstudio.gef.editor.AttributeConstants; +import de.bmotionstudio.gef.editor.editpolicy.AppDeletePolicy; +import de.bmotionstudio.gef.editor.editpolicy.AppEditLayoutPolicy; +import de.bmotionstudio.gef.editor.editpolicy.BMotionNodeEditPolicy; +import de.bmotionstudio.gef.editor.editpolicy.ChangeAttributePolicy; +import de.bmotionstudio.gef.editor.figure.CompositeFigure; +import de.bmotionstudio.gef.editor.library.AbstractLibraryCommand; +import de.bmotionstudio.gef.editor.library.AttributeRequest; +import de.bmotionstudio.gef.editor.library.LibraryImageCommand; +import de.bmotionstudio.gef.editor.library.LibraryVariableCommand; +import de.bmotionstudio.gef.editor.model.BControl; + +public class BCompositePart extends AppAbstractEditPart { + + @Override + protected IFigure createEditFigure() { + IFigure figure = new CompositeFigure(); + return figure; + } + + @Override + public void refreshEditFigure(IFigure figure, BControl model, + PropertyChangeEvent evt) { + + Object value = evt.getNewValue(); + String aID = evt.getPropertyName(); + + if (aID.equals(AttributeConstants.ATTRIBUTE_BACKGROUND_COLOR)) + ((CompositeFigure) figure).setBackgroundColor((RGB) value); + + // if (aID.equals(AttributeConstants.ATTRIBUTE_ALPHA)) + // ((BComposite) figure).setAlpha(Integer.valueOf(value.toString())); + + if (aID.equals(AttributeConstants.ATTRIBUTE_IMAGE)) { + if (value != null) { + String imgPath = value.toString(); + if (imgPath.length() > 0) { + IFile pFile = model.getVisualization().getProjectFile(); + String myPath = (pFile.getProject().getLocation() + + "/images/" + imgPath).replace("file:", ""); + if (new File(myPath).exists()) { + ((CompositeFigure) figure).setImage(new Image(Display + .getDefault(), myPath)); + } + } + } + + } + + if (aID.equals(AttributeConstants.ATTRIBUTE_VISIBLE)) + ((CompositeFigure) figure).setVisible(Boolean.valueOf(value + .toString())); + + } + + @Override + public List<BControl> getModelChildren() { + return ((BControl) getModel()).getChildrenArray(); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + public Object getAdapter(Class adapter) { + if (adapter == SnapToHelper.class) { + List snapStrategies = new ArrayList(); + Boolean val = (Boolean) getViewer().getProperty( + RulerProvider.PROPERTY_RULER_VISIBILITY); + if (val != null && val.booleanValue()) + snapStrategies.add(new SnapToGuides(this)); + val = (Boolean) getViewer().getProperty( + SnapToGeometry.PROPERTY_SNAP_ENABLED); + if (val != null && val.booleanValue()) + snapStrategies.add(new SnapToGeometry(this)); + val = (Boolean) getViewer().getProperty( + SnapToGrid.PROPERTY_GRID_ENABLED); + if (val != null && val.booleanValue()) + snapStrategies.add(new SnapToGrid(this)); + + if (snapStrategies.size() == 0) + return null; + if (snapStrategies.size() == 1) + return snapStrategies.get(0); + + SnapToHelper ss[] = new SnapToHelper[snapStrategies.size()]; + for (int i = 0; i < snapStrategies.size(); i++) + ss[i] = (SnapToHelper) snapStrategies.get(i); + return new CompoundSnapToHelper(ss); + } + return super.getAdapter(adapter); + } + + @Override + public AbstractLibraryCommand getLibraryCommand(AttributeRequest request) { + AbstractLibraryCommand command = null; + if (request.getAttributeTransferObject().getLibraryObject().getType() + .equals("variable")) { + command = new LibraryVariableCommand(); + } else if (request.getAttributeTransferObject().getLibraryObject() + .getType().equals("image")) { + command = new LibraryImageCommand(); + } + return command; + } + + @Override + protected void prepareEditPolicies() { + installEditPolicy(EditPolicy.COMPONENT_ROLE, new AppDeletePolicy()); + installEditPolicy(EditPolicy.LAYOUT_ROLE, new AppEditLayoutPolicy()); + installEditPolicy(EditPolicy.SELECTION_FEEDBACK_ROLE, null); + installEditPolicy(EditPolicy.CONTAINER_ROLE, new SnapFeedbackPolicy()); + installEditPolicy(EditPolicy.GRAPHICAL_NODE_ROLE, + new BMotionNodeEditPolicy()); + installEditPolicy(ChangeAttributePolicy.CHANGE_ATTRIBUTE_POLICY, + new ChangeAttributePolicy()); + } + + @Override + protected void prepareRunPolicies() { + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/BConnectionEditPart.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/BConnectionEditPart.java new file mode 100644 index 0000000000000000000000000000000000000000..f8cea36545181980c4cc64e3c6beb9fb98cee255 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/BConnectionEditPart.java @@ -0,0 +1,408 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.part; + +import java.beans.PropertyChangeEvent; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.draw2d.ChopboxAnchor; +import org.eclipse.draw2d.Connection; +import org.eclipse.draw2d.ConnectionAnchor; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.Label; +import org.eclipse.draw2d.MidpointLocator; +import org.eclipse.draw2d.PolygonDecoration; +import org.eclipse.draw2d.PolylineConnection; +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.draw2d.XYAnchor; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.gef.AccessibleAnchorProvider; +import org.eclipse.gef.ConnectionEditPart; +import org.eclipse.gef.DragTracker; +import org.eclipse.gef.EditPart; +import org.eclipse.gef.EditPolicy; +import org.eclipse.gef.GraphicalEditPart; +import org.eclipse.gef.LayerConstants; +import org.eclipse.gef.NodeEditPart; +import org.eclipse.gef.Request; +import org.eclipse.gef.commands.Command; +import org.eclipse.gef.editparts.AbstractConnectionEditPart; +import org.eclipse.gef.editparts.AbstractGraphicalEditPart; +import org.eclipse.gef.editpolicies.ConnectionEditPolicy; +import org.eclipse.gef.editpolicies.ConnectionEndpointEditPolicy; +import org.eclipse.gef.requests.GroupRequest; +import org.eclipse.gef.tools.SelectEditPartTracker; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Display; + +import de.bmotionstudio.gef.editor.AttributeConstants; +import de.bmotionstudio.gef.editor.attribute.BAttributeConnectionSourceDecoration; +import de.bmotionstudio.gef.editor.command.ConnectionDeleteCommand; +import de.bmotionstudio.gef.editor.model.BConnection; +import de.bmotionstudio.gef.editor.model.BControl; + +public class BConnectionEditPart extends AppAbstractEditPart implements + ConnectionEditPart, LayerConstants { + + protected Color foregroundColor; + private Label conLabel; + + private static final ConnectionAnchor DEFAULT_SOURCE_ANCHOR = new XYAnchor( + new Point(10, 10)); + private static final ConnectionAnchor DEFAULT_TARGET_ANCHOR = new XYAnchor( + new Point(100, 100)); + + /* + * (non-Javadoc) + * + * @see de.bmotionstudio.gef.editor.part.AppAbstractEditPart#deactivate() + */ + @Override + public void deactivate() { + super.deactivate(); + if (isActive()) + foregroundColor.dispose(); + } + + @Override + protected void prepareEditPolicies() { + // Selection handle edit policy. + // Makes the connection show a feedback, when selected by the user. + installEditPolicy(EditPolicy.CONNECTION_ENDPOINTS_ROLE, + new ConnectionEndpointEditPolicy()); // Allows the removal of + // the connection model + // element + installEditPolicy(EditPolicy.CONNECTION_ROLE, + new ConnectionEditPolicy() { + protected Command getDeleteCommand(GroupRequest request) { + return new ConnectionDeleteCommand( + (BConnection) getModel()); + } + }); + } + + @Override + protected IFigure createEditFigure() { + PolylineConnection connection = new PolylineConnection(); + conLabel = new Label(); + MidpointLocator locator = new MidpointLocator(connection, 0); + locator.setRelativePosition(PositionConstants.NORTH); + connection.add(conLabel, locator); + return connection; + } + + @Override + public void refreshEditFigure(IFigure figure, BControl model, + PropertyChangeEvent evt) { + + Object value = evt.getNewValue(); + String aID = evt.getPropertyName(); + + if (aID.equals(AttributeConstants.ATTRIBUTE_LINEWIDTH)) + ((PolylineConnection) getFigure()).setLineWidth(Integer + .valueOf(value.toString())); + + if (aID.equals(AttributeConstants.ATTRIBUTE_LINESTYLE)) + ((PolylineConnection) getFigure()).setLineStyle((Integer + .valueOf(value.toString()) + 1)); + + if (aID.equals(AttributeConstants.ATTRIBUTE_FOREGROUND_COLOR)) { + if (foregroundColor != null) + foregroundColor.dispose(); + foregroundColor = new Color(Display.getDefault(), (RGB) value); + ((PolylineConnection) getFigure()) + .setForegroundColor(foregroundColor); + } + + if (aID.equals(AttributeConstants.ATTRIBUTE_CONNECTION_SOURCE_DECORATION)) { + int decoration = Integer.valueOf(value.toString()); + if (decoration == BAttributeConnectionSourceDecoration.DECORATION_TRIANGLE) { + ((PolylineConnection) getFigure()) + .setSourceDecoration(new PolygonDecoration()); + } else { + ((PolylineConnection) getFigure()).setSourceDecoration(null); + } + } + + if (aID.equals(AttributeConstants.ATTRIBUTE_CONNECTION_TARGET_DECORATION)) { + int decoration = Integer.valueOf(value.toString()); + if (decoration == BAttributeConnectionSourceDecoration.DECORATION_TRIANGLE) { + ((PolylineConnection) getFigure()) + .setTargetDecoration(new PolygonDecoration()); + } else { + ((PolylineConnection) getFigure()).setTargetDecoration(null); + } + } + + if (aID.equals(AttributeConstants.ATTRIBUTE_LABEL)) { + conLabel.setText(value.toString()); + } + + } + + /** + * Provides accessibility support for when connections are also themselves + * nodes. If a connection is the source or target of another connection, + * then its midpoint is used as the accessible anchor location. + * + * @author hudsonr + * @since 2.0 + */ + protected final class DefaultAccessibleAnchorProvider implements + AccessibleAnchorProvider { + /** + * This class is internal, but is made protected so that JavaDoc will + * see it. + */ + DefaultAccessibleAnchorProvider() { + } + + /** + * @see AccessibleAnchorProvider#getSourceAnchorLocations() + */ + public List<Point> getSourceAnchorLocations() { + List<Point> list = new ArrayList<Point>(); + if (getFigure() instanceof Connection) { + Point p = ((Connection) getFigure()).getPoints().getMidpoint(); + getFigure().translateToAbsolute(p); + list.add(p); + } + return list; + } + + /** + * @see AccessibleAnchorProvider#getTargetAnchorLocations() + */ + public List<Point> getTargetAnchorLocations() { + return getSourceAnchorLocations(); + } + } + + private EditPart sourceEditPart, targetEditPart; + + /** + * Activates the Figure representing this, by setting up the start and end + * connections, and adding the figure to the Connection Layer. + * + * @see #deactivate() + */ + protected void activateFigure() { + getLayer(CONNECTION_LAYER).add(getFigure()); + } + + /** + * @see org.eclipse.gef.EditPart#addNotify() + */ + public void addNotify() { + activateFigure(); + super.addNotify(); + } + + /** + * Deactivates the Figure representing this, by removing it from the + * connection layer, and resetting the source and target connections to + * <code>null</code>. + */ + protected void deactivateFigure() { + getLayer(CONNECTION_LAYER).remove(getFigure()); + getConnectionFigure().setSourceAnchor(null); + getConnectionFigure().setTargetAnchor(null); + } + + /** + * <code>AbstractConnectionEditPart</code> extends getAdapter() to overrides + * the {@link AccessibleAnchorProvider} adapter returned by the superclass. + * When treating a connection as a node for other connections, it makes + * sense to target its midpoint, and not the edge of its bounds. + * + * @see AbstractConnectionEditPart.DefaultAccessibleAnchorProvider + * @see AbstractGraphicalEditPart#getAdapter(Class) + * @param adapter + * the adapter Class + * @return the adapter + */ + public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) { + if (adapter == AccessibleAnchorProvider.class) + return new DefaultAccessibleAnchorProvider(); + return super.getAdapter(adapter); + } + + /** + * Convenience method for casting this GraphicalEditPart's Figure to a + * {@link Connection} + * + * @return the Figure as a Connection + */ + public Connection getConnectionFigure() { + return (Connection) getFigure(); + } + + /** + * @see org.eclipse.gef.EditPart#getDragTracker(Request) + */ + public DragTracker getDragTracker(Request req) { + return new SelectEditPartTracker(this); + } + + /** + * @see org.eclipse.gef.ConnectionEditPart#getSource() + */ + public EditPart getSource() { + return sourceEditPart; + } + + /** + * @see org.eclipse.gef.ConnectionEditPart#getTarget() + */ + public EditPart getTarget() { + return targetEditPart; + } + + /** + * Returns the <code>ConnectionAnchor</code> for the <i>source</i> end of + * the connection. If the source is an instance of {@link NodeEditPart}, + * that interface will be used to determine the proper ConnectionAnchor. If + * the source is not an instance of <code>NodeEditPart</code>, this method + * should be overridden to return the correct ConnectionAnchor. Failure to + * do this will cause a default anchor to be used so that the connection + * figure will be made visible to the developer. + * + * @return ConnectionAnchor for the source end of the Connection + */ + protected ConnectionAnchor getSourceConnectionAnchor() { + if (getSource() != null) { + if (getSource() instanceof NodeEditPart) { + NodeEditPart editPart = (NodeEditPart) getSource(); + return editPart.getSourceConnectionAnchor(this); + } + IFigure f = ((GraphicalEditPart) getSource()).getFigure(); + return new ChopboxAnchor(f); + } + return DEFAULT_SOURCE_ANCHOR; + } + + /** + * Returns the <code>ConnectionAnchor</code> for the <i>target</i> end of + * the connection. If the target is an instance of {@link NodeEditPart}, + * that interface will be used to determine the proper ConnectionAnchor. If + * the target is not an instance of <code>NodeEditPart</code>, this method + * should be overridden to return the correct ConnectionAnchor. Failure to + * do this will cause a default anchor to be used so that the connection + * figure will be made visible to the developer. + * + * @return ConnectionAnchor for the target end of the Connection + */ + protected ConnectionAnchor getTargetConnectionAnchor() { + if (getTarget() != null) { + if (getTarget() instanceof NodeEditPart) { + NodeEditPart editPart = (NodeEditPart) getTarget(); + return editPart.getTargetConnectionAnchor(this); + } + IFigure f = ((GraphicalEditPart) getTarget()).getFigure(); + return new ChopboxAnchor(f); + } + return DEFAULT_TARGET_ANCHOR; + } + + /** + * Extended here to also refresh the ConnectionAnchors. + * + * @see org.eclipse.gef.EditPart#refresh() + */ + public void refresh() { + refreshSourceAnchor(); + refreshTargetAnchor(); + super.refresh(); + } + + /** + * Updates the source ConnectionAnchor. Subclasses should override + * {@link #getSourceConnectionAnchor()} if necessary, and not this method. + */ + protected void refreshSourceAnchor() { + getConnectionFigure().setSourceAnchor(getSourceConnectionAnchor()); + } + + /** + * Updates the target ConnectionAnchor. Subclasses should override + * {@link #getTargetConnectionAnchor()} if necessary, and not this method. + */ + protected void refreshTargetAnchor() { + getConnectionFigure().setTargetAnchor(getTargetConnectionAnchor()); + } + + /** + * Extended here to remove the ConnectionEditPart's connection figure from + * the connection layer. + * + * @see org.eclipse.gef.EditPart#removeNotify() + */ + public void removeNotify() { + deactivateFigure(); + super.removeNotify(); + } + + /** + * Extended to implement automatic addNotify and removeNotify handling. + * + * @see org.eclipse.gef.EditPart#setParent(EditPart) + */ + public void setParent(EditPart parent) { + boolean wasNull = getParent() == null; + boolean becomingNull = parent == null; + if (becomingNull && !wasNull) + removeNotify(); + super.setParent(parent); + if (wasNull && !becomingNull) + addNotify(); + } + + /** + * Sets the source EditPart of this connection. + * + * @param editPart + * EditPart which is the source. + */ + public void setSource(EditPart editPart) { + if (sourceEditPart == editPart) + return; + sourceEditPart = editPart; + if (sourceEditPart != null) + setParent(sourceEditPart.getRoot()); + else if (getTarget() == null) + setParent(null); + if (sourceEditPart != null && targetEditPart != null) + refresh(); + } + + /** + * Sets the target EditPart of this connection. + * + * @param editPart + * EditPart which is the target. + */ + public void setTarget(EditPart editPart) { + if (targetEditPart == editPart) + return; + targetEditPart = editPart; + if (editPart != null) + setParent(editPart.getRoot()); + else if (getSource() == null) + setParent(null); + if (sourceEditPart != null && targetEditPart != null) + refresh(); + } + + @Override + protected void prepareRunPolicies() { + // TODO Auto-generated method stub + + } + +} \ No newline at end of file diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/BControlTreeEditPart.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/BControlTreeEditPart.java new file mode 100644 index 0000000000000000000000000000000000000000..fd40016a6ab3a0a302bcff1cb29efdc381db59b5 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/BControlTreeEditPart.java @@ -0,0 +1,65 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.part; + +import java.beans.PropertyChangeEvent; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import de.bmotionstudio.gef.editor.AttributeConstants; +import de.bmotionstudio.gef.editor.BMotionStudioImage; +import de.bmotionstudio.gef.editor.model.BConnection; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.model.Visualization; + +public class BControlTreeEditPart extends AppAbstractTreeEditPart { + + @Override + protected List<BControl> getModelChildren() { + Set<BControl> toShowElements = new HashSet<BControl>(); + for (BControl control : ((BControl) getModel()).getChildrenArray()) { + if (control.showInOutlineView()) + toShowElements.add(control); + List<BConnection> sourceConnections = control + .getSourceConnections(); + for (BConnection con : sourceConnections) { + if (con.showInOutlineView()) + toShowElements.add(con); + } + List<BConnection> targetConnections = control + .getTargetConnections(); + for (BConnection con : targetConnections) { + if (con.showInOutlineView()) + toShowElements.add(con); + } + } + return new ArrayList<BControl>(toShowElements); + } + + public void propertyChange(final PropertyChangeEvent evt) { + if (evt.getPropertyName().equals(BControl.PROPERTY_ADD) + || evt.getPropertyName().equals(BControl.PROPERTY_REMOVE)) { + refreshChildren(); + } + if (evt.getPropertyName().equals(AttributeConstants.ATTRIBUTE_ID)) + refreshVisuals(); + } + + @Override + public void refreshVisuals() { + BControl bcontrol = (BControl) getModel(); + if (!(bcontrol instanceof Visualization)) { + setWidgetText(bcontrol.getAttributeValue( + AttributeConstants.ATTRIBUTE_ID).toString()); + setWidgetImage(BMotionStudioImage.getBControlImage(bcontrol + .getType())); + } + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/BImagePart.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/BImagePart.java new file mode 100644 index 0000000000000000000000000000000000000000..c8077e6ef27e76b01036776304069d1b2e9e64f5 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/BImagePart.java @@ -0,0 +1,97 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.part; + +import java.beans.PropertyChangeEvent; +import java.io.File; +import java.util.HashMap; + +import org.eclipse.core.resources.IFile; +import org.eclipse.draw2d.IFigure; +import org.eclipse.gef.EditPolicy; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; + +import de.bmotionstudio.gef.editor.AttributeConstants; +import de.bmotionstudio.gef.editor.editpolicy.AppDeletePolicy; +import de.bmotionstudio.gef.editor.editpolicy.BMotionNodeEditPolicy; +import de.bmotionstudio.gef.editor.editpolicy.ChangeAttributePolicy; +import de.bmotionstudio.gef.editor.figure.BMSImageFigure; +import de.bmotionstudio.gef.editor.library.AbstractLibraryCommand; +import de.bmotionstudio.gef.editor.library.AttributeRequest; +import de.bmotionstudio.gef.editor.library.LibraryImageCommand; +import de.bmotionstudio.gef.editor.model.BControl; + +public class BImagePart extends AppAbstractEditPart { + + private HashMap<String, File> fileMap = new HashMap<String, File>(); + + @Override + public void refreshEditFigure(IFigure figure, BControl model, + PropertyChangeEvent evt) { + + Object value = evt.getNewValue(); + String aID = evt.getPropertyName(); + + if (aID.equals(AttributeConstants.ATTRIBUTE_IMAGE)) { + if (value != null) { + String imgPath = value.toString(); + if (imgPath.length() > 0) { + IFile pFile = model.getVisualization().getProjectFile(); + String myPath = (pFile.getProject().getLocation() + + "/images/" + imgPath).replace("file:", ""); + File file = null; + if (fileMap.containsKey(myPath)) { + file = fileMap.get(myPath); + } else { + file = new File(myPath); + fileMap.put(myPath, file); + } + if (file.exists()) { + ((BMSImageFigure) figure).setImage(new Image(Display + .getDefault(), myPath)); + } + } + } + } + + if (aID.equals(AttributeConstants.ATTRIBUTE_VISIBLE)) + ((BMSImageFigure) figure).setVisible(Boolean.valueOf(value + .toString())); + + } + + @Override + protected IFigure createEditFigure() { + IFigure figure = new BMSImageFigure(); + return figure; + } + + @Override + public AbstractLibraryCommand getLibraryCommand(AttributeRequest request) { + AbstractLibraryCommand command = null; + if (request.getAttributeTransferObject().getLibraryObject().getType() + .equals("image")) { + command = new LibraryImageCommand(); + } + return command; + } + + @Override + protected void prepareEditPolicies() { + installEditPolicy(EditPolicy.COMPONENT_ROLE, new AppDeletePolicy()); + installEditPolicy(EditPolicy.GRAPHICAL_NODE_ROLE, + new BMotionNodeEditPolicy()); + installEditPolicy(ChangeAttributePolicy.CHANGE_ATTRIBUTE_POLICY, + new ChangeAttributePolicy()); + } + + @Override + protected void prepareRunPolicies() { + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/BRadioButtonPart.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/BRadioButtonPart.java new file mode 100644 index 0000000000000000000000000000000000000000..21c60a92a8a0d2c76e17e8db8ce6d7140d264153 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/BRadioButtonPart.java @@ -0,0 +1,110 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.part; + +import java.beans.PropertyChangeEvent; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.gef.EditPolicy; +import org.eclipse.gef.Request; +import org.eclipse.gef.RequestConstants; +import org.eclipse.swt.graphics.RGB; + +import de.bmotionstudio.gef.editor.AttributeConstants; +import de.bmotionstudio.gef.editor.BMotionStudioImage; +import de.bmotionstudio.gef.editor.ButtonGroupHelper; +import de.bmotionstudio.gef.editor.ImageRegistry; +import de.bmotionstudio.gef.editor.edit.TextCellEditorLocator; +import de.bmotionstudio.gef.editor.edit.TextEditManager; +import de.bmotionstudio.gef.editor.editpolicy.AppDeletePolicy; +import de.bmotionstudio.gef.editor.editpolicy.BMotionNodeEditPolicy; +import de.bmotionstudio.gef.editor.editpolicy.CustomDirectEditPolicy; +import de.bmotionstudio.gef.editor.editpolicy.RenamePolicy; +import de.bmotionstudio.gef.editor.figure.RadioButtonFigure; +import de.bmotionstudio.gef.editor.model.BControl; + +public class BRadioButtonPart extends AppAbstractEditPart { + + @Override + protected IFigure createEditFigure() { + RadioButtonFigure fig = new RadioButtonFigure(); + return fig; + } + + @Override + public void refreshEditFigure(IFigure figure, BControl model, + PropertyChangeEvent pEvent) { + + Object value = pEvent.getNewValue(); + String aID = pEvent.getPropertyName(); + + if (aID.equals(AttributeConstants.ATTRIBUTE_VISIBLE)) + ((RadioButtonFigure) figure).setVisible(Boolean.valueOf(value + .toString())); + + if (aID.equals(AttributeConstants.ATTRIBUTE_CHECKED)) { + Boolean bol = Boolean.valueOf(value.toString()); + if (bol) { + ((RadioButtonFigure) figure).setImage(BMotionStudioImage + .getImage(ImageRegistry.IMG_RADIOBUTTON_CHECKED)); + } else { + ((RadioButtonFigure) figure).setImage(BMotionStudioImage + .getImage(ImageRegistry.IMG_RADIOBUTTON_UNCHECKED)); + } + + } + + if (aID.equals(AttributeConstants.ATTRIBUTE_TEXT)) { + int addWidth = ((RadioButtonFigure) figure).setText(value + .toString()); + ((BControl) getModel()).setAttributeValue( + AttributeConstants.ATTRIBUTE_WIDTH, (30 + addWidth)); + } + + if (aID.equals(AttributeConstants.ATTRIBUTE_TEXT_COLOR)) { + RGB rgbText = (RGB) value; + ((RadioButtonFigure) figure).setTextColor(rgbText); + } + + if (aID.equals(AttributeConstants.ATTRIBUTE_BUTTONGROUP)) { + String btgroup = value.toString(); + if (!btgroup.trim().equals("")) { + ButtonGroupHelper.addToButtonGroup(btgroup, + (BControl) getModel()); + } + } + + } + + @Override + protected void prepareEditPolicies() { + installEditPolicy(EditPolicy.COMPONENT_ROLE, new AppDeletePolicy()); + installEditPolicy(EditPolicy.NODE_ROLE, new RenamePolicy()); + installEditPolicy(EditPolicy.DIRECT_EDIT_ROLE, + new CustomDirectEditPolicy()); + installEditPolicy(EditPolicy.GRAPHICAL_NODE_ROLE, + new BMotionNodeEditPolicy()); + } + + @Override + protected void prepareRunPolicies() { + } + + private void performDirectEdit() { + new TextEditManager(this, new TextCellEditorLocator( + (IFigure) getFigure())).show(); + } + + @Override + public void performRequest(Request request) { + super.performRequest(request); + if (request.getType() == RequestConstants.REQ_DIRECT_EDIT + && !isRunning()) + performDirectEdit(); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/BShapePart.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/BShapePart.java new file mode 100644 index 0000000000000000000000000000000000000000..247e9c658eda973343d6627c8a5763525645a401 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/BShapePart.java @@ -0,0 +1,129 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.part; + +import java.beans.PropertyChangeEvent; +import java.io.File; + +import org.eclipse.core.resources.IFile; +import org.eclipse.draw2d.IFigure; +import org.eclipse.gef.EditPolicy; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Display; + +import de.bmotionstudio.gef.editor.AttributeConstants; +import de.bmotionstudio.gef.editor.editpolicy.AppDeletePolicy; +import de.bmotionstudio.gef.editor.editpolicy.BMotionNodeEditPolicy; +import de.bmotionstudio.gef.editor.figure.ShapeFigure; +import de.bmotionstudio.gef.editor.model.BControl; + +public class BShapePart extends AppAbstractEditPart { + + @Override + public void refreshEditFigure(IFigure figure, BControl model, + PropertyChangeEvent evt) { + + Object value = evt.getNewValue(); + String aID = evt.getPropertyName(); + + if (aID.equals(AttributeConstants.ATTRIBUTE_BACKGROUND_COLOR)) + ((ShapeFigure) figure).setBackgroundColor((RGB) value); + + if (aID.equals(AttributeConstants.ATTRIBUTE_FOREGROUND_COLOR)) + ((ShapeFigure) figure).setForegroundColor((RGB) value); + + if (aID.equals(AttributeConstants.ATTRIBUTE_ALPHA)) + ((ShapeFigure) figure).setAlpha(Integer.valueOf(value.toString())); + + if (aID.equals(AttributeConstants.ATTRIBUTE_OUTLINEALPHA)) + ((ShapeFigure) figure) + .setOutlineAlpha(Integer.valueOf(value.toString())); + + if (aID.equals(AttributeConstants.ATTRIBUTE_VISIBLE)) + ((ShapeFigure) figure).setVisible(Boolean.valueOf(value.toString())); + + if (aID.equals(AttributeConstants.ATTRIBUTE_SHAPE)) + ((ShapeFigure) figure).setShape(Integer.valueOf(value.toString())); + + if (aID.equals(AttributeConstants.ATTRIBUTE_ORIENTATION)) + ((ShapeFigure) figure).setOrientation(Integer.valueOf(value.toString())); + + if (aID.equals(AttributeConstants.ATTRIBUTE_FILLTYPE)) + ((ShapeFigure) figure).setFillType(Integer.valueOf(value.toString())); + + // /** North */ + // int NORTH = 1; + // /** South */ + // int SOUTH = 4; + // /** West */ + // int WEST = 8; + // /** East */ + // int EAST = 16; + + if (aID.equals(AttributeConstants.ATTRIBUTE_DIRECTION)) { + + int direction = Integer.valueOf(value.toString()); + int fval = 1; + + switch (direction) { + case 0: + fval = 1; + break; + case 1: + fval = 4; + break; + case 2: + fval = 8; + break; + case 3: + fval = 16; + break; + default: + break; + } + + ((ShapeFigure) figure).setDirection(fval); + + } + + if (aID.equals(AttributeConstants.ATTRIBUTE_IMAGE)) { + Image img = null; + if (value != null) { + String imgPath = value.toString(); + if (imgPath.length() > 0) { + IFile pFile = model.getVisualization().getProjectFile(); + String myPath = (pFile.getProject().getLocation() + + "/images/" + imgPath).replace("file:", ""); + if (new File(myPath).exists()) { + img = new Image(Display.getDefault(), myPath); + } + } + } + ((ShapeFigure) figure).setImage(img); + } + + } + + @Override + protected IFigure createEditFigure() { + IFigure figure = new ShapeFigure(); + return figure; + } + + @Override + protected void prepareEditPolicies() { + installEditPolicy(EditPolicy.COMPONENT_ROLE, new AppDeletePolicy()); + installEditPolicy(EditPolicy.GRAPHICAL_NODE_ROLE, + new BMotionNodeEditPolicy()); + } + + @Override + protected void prepareRunPolicies() { + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/BTextPart.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/BTextPart.java new file mode 100644 index 0000000000000000000000000000000000000000..eeead135623a30523879ed597afe3d8c3cb2627d --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/BTextPart.java @@ -0,0 +1,114 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.part; + +import java.beans.PropertyChangeEvent; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.gef.EditPolicy; +import org.eclipse.gef.Request; +import org.eclipse.gef.RequestConstants; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Display; + +import de.bmotionstudio.gef.editor.AttributeConstants; +import de.bmotionstudio.gef.editor.edit.TextCellEditorLocator; +import de.bmotionstudio.gef.editor.edit.TextEditManager; +import de.bmotionstudio.gef.editor.editpolicy.AppDeletePolicy; +import de.bmotionstudio.gef.editor.editpolicy.BMotionNodeEditPolicy; +import de.bmotionstudio.gef.editor.editpolicy.ChangeAttributePolicy; +import de.bmotionstudio.gef.editor.editpolicy.CustomDirectEditPolicy; +import de.bmotionstudio.gef.editor.editpolicy.RenamePolicy; +import de.bmotionstudio.gef.editor.figure.TextFigure; +import de.bmotionstudio.gef.editor.library.AbstractLibraryCommand; +import de.bmotionstudio.gef.editor.library.AttributeRequest; +import de.bmotionstudio.gef.editor.library.LibraryVariableCommand; +import de.bmotionstudio.gef.editor.model.BControl; + +public class BTextPart extends AppAbstractEditPart { + + @Override + public void refreshEditFigure(IFigure figure, BControl model, + PropertyChangeEvent evt) { + + Object value = evt.getNewValue(); + String aID = evt.getPropertyName(); + + if (aID.equals(AttributeConstants.ATTRIBUTE_TEXT)) + ((TextFigure) figure).setText(value.toString()); + + if (aID.equals(AttributeConstants.ATTRIBUTE_BACKGROUND_COLOR)) + ((TextFigure) figure) + .setBackgroundColor(new org.eclipse.swt.graphics.Color( + Display.getDefault(), (RGB) value)); + + if (aID.equals(AttributeConstants.ATTRIBUTE_TEXT_COLOR)) + ((TextFigure) figure).setTextColor(((RGB) value)); + + if (aID.equals(AttributeConstants.ATTRIBUTE_FONT)) + ((TextFigure) figure).setFont((value.toString())); + + if (aID.equals(AttributeConstants.ATTRIBUTE_BACKGROUND_VISIBLE)) + ((TextFigure) figure).setBackgroundVisible(Boolean.valueOf(value + .toString())); + + if (aID.equals(AttributeConstants.ATTRIBUTE_VISIBLE)) + ((TextFigure) figure).setVisible(Boolean.valueOf(value.toString())); + + } + + @Override + protected IFigure createEditFigure() { + IFigure figure = new TextFigure(); + return figure; + } + + private void performDirectEdit() { + new TextEditManager(this, new TextCellEditorLocator( + (IFigure) getFigure())).show(); + } + + @Override + public void performRequest(Request request) { + super.performRequest(request); + if (request.getType() == RequestConstants.REQ_DIRECT_EDIT) + performDirectEdit(); + } + + // @Override + // public String getValueOfData() { + // return ((BControl) getModel()).getAttributeValue( + // AttributeConstants.ATTRIBUTE_CUSTOM).toString(); + // } + + @Override + public AbstractLibraryCommand getLibraryCommand(AttributeRequest request) { + AbstractLibraryCommand command = null; + if (request.getAttributeTransferObject().getLibraryObject().getType() + .equals("variable")) { + command = new LibraryVariableCommand(); + } + return command; + } + + @Override + protected void prepareEditPolicies() { + installEditPolicy(EditPolicy.COMPONENT_ROLE, new AppDeletePolicy()); + installEditPolicy(EditPolicy.NODE_ROLE, new RenamePolicy()); + installEditPolicy(EditPolicy.DIRECT_EDIT_ROLE, + new CustomDirectEditPolicy()); + installEditPolicy(EditPolicy.GRAPHICAL_NODE_ROLE, + new BMotionNodeEditPolicy()); + installEditPolicy(ChangeAttributePolicy.CHANGE_ATTRIBUTE_POLICY, + new ChangeAttributePolicy()); + } + + @Override + protected void prepareRunPolicies() { + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/BTextfieldPart.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/BTextfieldPart.java new file mode 100644 index 0000000000000000000000000000000000000000..424e6da84bae178d6f899f815bec15bea6d630fe --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/BTextfieldPart.java @@ -0,0 +1,128 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.part; + +import java.beans.PropertyChangeEvent; + +import org.eclipse.draw2d.ButtonModel; +import org.eclipse.draw2d.ChangeEvent; +import org.eclipse.draw2d.ChangeListener; +import org.eclipse.draw2d.IFigure; +import org.eclipse.gef.EditPolicy; +import org.eclipse.gef.Request; +import org.eclipse.gef.RequestConstants; + +import de.bmotionstudio.gef.editor.AttributeConstants; +import de.bmotionstudio.gef.editor.edit.TextCellEditorLocator; +import de.bmotionstudio.gef.editor.edit.TextEditManager; +import de.bmotionstudio.gef.editor.editpolicy.AppDeletePolicy; +import de.bmotionstudio.gef.editor.editpolicy.BMotionNodeEditPolicy; +import de.bmotionstudio.gef.editor.editpolicy.CustomDirectEditPolicy; +import de.bmotionstudio.gef.editor.editpolicy.RenamePolicy; +import de.bmotionstudio.gef.editor.figure.AbstractBMotionFigure; +import de.bmotionstudio.gef.editor.figure.TextfieldFigure; +import de.bmotionstudio.gef.editor.model.BControl; + +public class BTextfieldPart extends AppAbstractEditPart { + + private TextEditManager textEditManager; + + private ChangeListener changeListener = new ChangeListener() { + @Override + public void handleStateChanged(ChangeEvent event) { + if (event.getPropertyName().equals(ButtonModel.PRESSED_PROPERTY)) { + AbstractBMotionFigure f = (AbstractBMotionFigure) getFigure(); + if (f.getModel().isPressed()) { + if (textEditManager == null) + textEditManager = new TextEditManager( + BTextfieldPart.this, new TextCellEditorLocator( + (IFigure) getFigure())) { + @Override + protected void bringDown() { + super.bringDown(); + ((BControl) getModel()).getVisualization() + .getAnimation().checkObserver(); + } + + }; + textEditManager.show(); + } + } + } + }; + + @Override + protected IFigure createEditFigure() { + TextfieldFigure figure = new TextfieldFigure(); + return figure; + } + + @Override + public void refreshEditFigure(IFigure figure, BControl model, + PropertyChangeEvent evt) { + + Object value = evt.getNewValue(); + String aID = evt.getPropertyName(); + + if (aID.equals(AttributeConstants.ATTRIBUTE_TEXT)) + ((TextfieldFigure) figure).setText(value.toString()); + + if (aID.equals(AttributeConstants.ATTRIBUTE_VISIBLE)) + ((TextfieldFigure) figure).setVisible(Boolean.valueOf(value + .toString())); + + } + + private void performDirectEdit() { + new TextEditManager(BTextfieldPart.this, new TextCellEditorLocator( + (IFigure) getFigure())).show(); + } + + @Override + public void performRequest(Request request) { + super.performRequest(request); + if (request.getType() == RequestConstants.REQ_DIRECT_EDIT) + performDirectEdit(); + } + + @Override + public void activate() { + super.activate(); + if (isRunning()) { + if (getFigure() instanceof AbstractBMotionFigure) + ((AbstractBMotionFigure) getFigure()) + .addChangeListener(changeListener); + } + } + + @Override + public void deactivate() { + if (isRunning()) { + if (getFigure() instanceof AbstractBMotionFigure) + ((AbstractBMotionFigure) getFigure()) + .removeChangeListener(changeListener); + } + super.deactivate(); + } + + @Override + protected void prepareEditPolicies() { + installEditPolicy(EditPolicy.COMPONENT_ROLE, new AppDeletePolicy()); + installEditPolicy(EditPolicy.NODE_ROLE, new RenamePolicy()); + installEditPolicy(EditPolicy.DIRECT_EDIT_ROLE, + new CustomDirectEditPolicy()); + installEditPolicy(EditPolicy.GRAPHICAL_NODE_ROLE, + new BMotionNodeEditPolicy()); + } + + @Override + protected void prepareRunPolicies() { + installEditPolicy(EditPolicy.DIRECT_EDIT_ROLE, + new CustomDirectEditPolicy()); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/UnknownPart.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/UnknownPart.java new file mode 100644 index 0000000000000000000000000000000000000000..4e2c15c13f0025e9d23598a4ffd37c1ac31a17ca --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/UnknownPart.java @@ -0,0 +1,46 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.part; + +import java.beans.PropertyChangeEvent; + +import org.eclipse.draw2d.IFigure; + +import de.bmotionstudio.gef.editor.figure.UnknownBControl; +import de.bmotionstudio.gef.editor.model.BControl; + +public class UnknownPart extends AppAbstractEditPart { + + public static String ID = "de.bmotionstudio.gef.editor.unknown"; + + private String type; + + @Override + protected IFigure createEditFigure() { + IFigure figure = new UnknownBControl(); + return figure; + } + + @Override + public void refreshEditFigure(IFigure figure, BControl model, + PropertyChangeEvent evt) { + ((UnknownBControl) figure).setMessage(type); + } + + public void setType(String type) { + this.type = type; + } + + @Override + protected void prepareEditPolicies() { + } + + @Override + protected void prepareRunPolicies() { + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/VisualizationPart.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/VisualizationPart.java new file mode 100644 index 0000000000000000000000000000000000000000..ffa7230bbf89cbb2e068be3fe99a9102ae33f935 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/part/VisualizationPart.java @@ -0,0 +1,134 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.part; + +import java.beans.PropertyChangeEvent; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.gef.CompoundSnapToHelper; +import org.eclipse.gef.EditPolicy; +import org.eclipse.gef.SnapToGeometry; +import org.eclipse.gef.SnapToGrid; +import org.eclipse.gef.SnapToGuides; +import org.eclipse.gef.SnapToHelper; +import org.eclipse.gef.editpolicies.RootComponentEditPolicy; +import org.eclipse.gef.editpolicies.SnapFeedbackPolicy; +import org.eclipse.gef.rulers.RulerProvider; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Display; + +import de.bmotionstudio.gef.editor.AttributeConstants; +import de.bmotionstudio.gef.editor.editpolicy.AppDeletePolicy; +import de.bmotionstudio.gef.editor.editpolicy.AppEditLayoutPolicy; +import de.bmotionstudio.gef.editor.editpolicy.ChangeAttributePolicy; +import de.bmotionstudio.gef.editor.figure.VisualizationFigure; +import de.bmotionstudio.gef.editor.library.AbstractLibraryCommand; +import de.bmotionstudio.gef.editor.library.AttributeRequest; +import de.bmotionstudio.gef.editor.library.LibraryImageCommand; +import de.bmotionstudio.gef.editor.library.LibraryVariableCommand; +import de.bmotionstudio.gef.editor.model.BControl; + +public class VisualizationPart extends AppAbstractEditPart { + + public static String ID = "de.bmotionstudio.gef.editor.visualization"; + + @Override + public List<BControl> getModelChildren() { + return ((BControl) getModel()).getChildrenArray(); + } + + @Override + protected IFigure createEditFigure() { + return new VisualizationFigure(); + } + + @Override + protected void prepareEditPolicies() { + installEditPolicy(EditPolicy.COMPONENT_ROLE, new AppDeletePolicy()); + installEditPolicy(EditPolicy.LAYOUT_ROLE, new AppEditLayoutPolicy()); + installEditPolicy(EditPolicy.GRAPHICAL_NODE_ROLE, null); + installEditPolicy(EditPolicy.SELECTION_FEEDBACK_ROLE, null); + installEditPolicy(EditPolicy.CONTAINER_ROLE, new SnapFeedbackPolicy()); + installEditPolicy(EditPolicy.COMPONENT_ROLE, + new RootComponentEditPolicy()); + installEditPolicy(ChangeAttributePolicy.CHANGE_ATTRIBUTE_POLICY, + new ChangeAttributePolicy()); + } + + @Override + protected void prepareRunPolicies() { + } + + @Override + public void refreshEditFigure(final IFigure figure, final BControl model, + final PropertyChangeEvent evt) { + + Object value = evt.getNewValue(); + String aID = evt.getPropertyName(); + + if (aID.equals(AttributeConstants.ATTRIBUTE_BACKGROUND_COLOR)) { + RGB rgbBG = (RGB) value; + ((VisualizationFigure) figure) + .setBackgroundColor(new org.eclipse.swt.graphics.Color( + Display.getDefault(), rgbBG.red, rgbBG.green, + rgbBG.blue)); + } + + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + public Object getAdapter(final Class adapter) { + if (adapter == SnapToHelper.class) { + List snapStrategies = new ArrayList(); + Boolean val = (Boolean) getViewer().getProperty( + RulerProvider.PROPERTY_RULER_VISIBILITY); + if (val != null && val.booleanValue()) { + snapStrategies.add(new SnapToGuides(this)); + } + val = (Boolean) getViewer().getProperty( + SnapToGeometry.PROPERTY_SNAP_ENABLED); + if (val != null && val.booleanValue()) { + snapStrategies.add(new SnapToGeometry(this)); + } + val = (Boolean) getViewer().getProperty( + SnapToGrid.PROPERTY_GRID_ENABLED); + if (val != null && val.booleanValue()) { + snapStrategies.add(new SnapToGrid(this)); + } + + if (snapStrategies.size() == 0) { + return null; + } + if (snapStrategies.size() == 1) { + return snapStrategies.get(0); + } + + SnapToHelper ss[] = new SnapToHelper[snapStrategies.size()]; + for (int i = 0; i < snapStrategies.size(); i++) { + ss[i] = (SnapToHelper) snapStrategies.get(i); + } + return new CompoundSnapToHelper(ss); + } + return super.getAdapter(adapter); + } + + @Override + public AbstractLibraryCommand getLibraryCommand(AttributeRequest request) { + AbstractLibraryCommand command = null; + if (request.getAttributeTransferObject().getLibraryObject().getType() + .equals("variable")) { + command = new LibraryVariableCommand(); + } else if (request.getAttributeTransferObject().getLibraryObject() + .getType().equals("image")) { + command = new LibraryImageCommand(); + } + return command; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/property/CheckboxCellEditorHelper.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/property/CheckboxCellEditorHelper.java new file mode 100644 index 0000000000000000000000000000000000000000..f8bc69e4d47a8b117eb27adffdb6427c3cc9a250 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/property/CheckboxCellEditorHelper.java @@ -0,0 +1,63 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.property; + +import org.eclipse.jface.viewers.ICellModifier; +import org.eclipse.swt.graphics.Image; + +import de.bmotionstudio.gef.editor.BMotionStudioImage; +import de.bmotionstudio.gef.editor.EditorImageRegistry; + +public class CheckboxCellEditorHelper { + + public CheckboxCellEditorHelper() { + super(); + } + + /** + * To be used by LabelProviders that whant to display a checked/unchecked + * icon for the CheckboxCellEditor that does not have a Control. + * + * @param cellModifier + * The ICellModifier for the CellEditor to provide the value + * @param element + * The current element + * @param property + * The property the cellModifier should return the value from + */ + public static Image getCellEditorImage(ICellModifier cellModifier, + Object element, String property) { + Boolean value = (Boolean) cellModifier.getValue(element, property); + return getCellEditorImage(value); + } + + /** + * returns an checked checkbox image if value if true and an unchecked + * checkbox image if false + * + * @param value + * the value to get the cooresponding image for + * @param disabled + * determines if the image should be disabled or not + * @return an checked checkbox image if value if true and an unchecked + * checkbox image if false + * + */ + public static Image getCellEditorImage(boolean value) { + Image image = null; + if (value) + image = BMotionStudioImage + .getImage(EditorImageRegistry.IMG_ICON_CHECKED); + else + image = BMotionStudioImage + .getImage(EditorImageRegistry.IMG_ICON_UNCHECKED); + + return image; + + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/property/CheckboxPropertyDescriptor.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/property/CheckboxPropertyDescriptor.java new file mode 100644 index 0000000000000000000000000000000000000000..defac1f00ea74370dad46c99c2c1b3f880679e89 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/property/CheckboxPropertyDescriptor.java @@ -0,0 +1,55 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.property; + +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.CheckboxCellEditor; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.views.properties.PropertyDescriptor; + +public class CheckboxPropertyDescriptor extends PropertyDescriptor { + /** + * @param id + * @param displayName + */ + public CheckboxPropertyDescriptor(Object id, String displayName) { + super(id, displayName); + init(); + } + + protected void init() { + setLabelProvider(new LabelProvider() { + @Override + public Image getImage(Object element) { + if (element instanceof Boolean) { + boolean b = (Boolean) element; + return CheckboxCellEditorHelper.getCellEditorImage(b); + } + return super.getImage(element); + } + + @Override + public String getText(Object element) { + return ""; //$NON-NLS-1$ + } + }); + } + + /* + * @see + * org.eclipse.ui.views.properties.IPropertyDescriptor#createPropertyEditor + * (org.eclipse.swt.widgets.Composite) + */ + @Override + public CellEditor createPropertyEditor(Composite parent) { + CellEditor editor = new CheckboxCellEditor(parent); + return editor; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/property/FileDialogCellEditor.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/property/FileDialogCellEditor.java new file mode 100644 index 0000000000000000000000000000000000000000..5af32e60e90e930380ada668dc87d0d1eb6f5b44 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/property/FileDialogCellEditor.java @@ -0,0 +1,52 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.property; + +import org.eclipse.jface.viewers.DialogCellEditor; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.ui.PlatformUI; + +public class FileDialogCellEditor extends DialogCellEditor { + + /** + * Creates a new File dialog cell editor parented under the given control. + * The cell editor value is <code>null</code> initially, and has no + * validator. + * + * @param parent + * the parent control + */ + protected FileDialogCellEditor(Composite parent) { + super(parent); + } + + /** + * @see org.eclipse.jface.viewers.DialogCellEditor#openDialogBox(Control) + */ + protected Object openDialogBox(Control cellEditorWindow) { + FileDialog ftDialog = new FileDialog(PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getShell()); + + String value = (String) getValue(); + + String fData = ftDialog.open(); + + // if ((value != null) && (value.length() > 0)) { + // ftDialog.setFontList(new FontData[] { new FontData(value) }); + // } + // FontData fData = ftDialog.open(); + + if (fData != null) { + value = fData.toString(); + } + + return value; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/property/FilePropertyDescriptor.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/property/FilePropertyDescriptor.java new file mode 100644 index 0000000000000000000000000000000000000000..9203cd81739015ffa8e25e55d7389c94e87ce07d --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/property/FilePropertyDescriptor.java @@ -0,0 +1,37 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.property; + +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.views.properties.PropertyDescriptor; + +public class FilePropertyDescriptor extends PropertyDescriptor { + + /** + * Creates an property descriptor with the given id and display name. + * + * @param id + * the id of the property + * @param displayName + * the name to display for the property + */ + public FilePropertyDescriptor(Object id, String displayName) { + super(id, displayName); + } + + /** + * @see org.eclipse.ui.views.properties.IPropertyDescriptor#createPropertyEditor(Composite) + */ + public CellEditor createPropertyEditor(Composite parent) { + CellEditor editor = new FileDialogCellEditor(parent); + if (getValidator() != null) + editor.setValidator(getValidator()); + return editor; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/property/FontDialogCellEditor.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/property/FontDialogCellEditor.java new file mode 100644 index 0000000000000000000000000000000000000000..0bc590b12885319bd10f2ce6f627c27bc3625bb2 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/property/FontDialogCellEditor.java @@ -0,0 +1,60 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package de.bmotionstudio.gef.editor.property; + +import org.eclipse.jface.viewers.DialogCellEditor; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.FontDialog; +import org.eclipse.ui.PlatformUI; + +public class FontDialogCellEditor extends DialogCellEditor { + + /** + * Creates a new Font dialog cell editor parented under the given control. + * The cell editor value is <code>null</code> initially, and has no + * validator. + * + * @param parent + * the parent control + */ + protected FontDialogCellEditor(Composite parent) { + super(parent); + } + + /** + * @see org.eclipse.jface.viewers.DialogCellEditor#openDialogBox(Control) + */ + protected Object openDialogBox(Control cellEditorWindow) { + FontDialog ftDialog = new FontDialog(PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getShell()); + + String value = (String) getValue(); + + if ((value != null) && (value.length() > 0)) { + ftDialog.setFontList(new FontData[] { new FontData(value) }); + } + FontData fData = ftDialog.open(); + + if (fData != null) { + value = fData.toString(); + } + return value; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/property/FontPropertyDescriptor.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/property/FontPropertyDescriptor.java new file mode 100644 index 0000000000000000000000000000000000000000..74061a30c31126cb37c254dd1ee1adc9afe36b5a --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/property/FontPropertyDescriptor.java @@ -0,0 +1,54 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package de.bmotionstudio.gef.editor.property; + +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.views.properties.PropertyDescriptor; + +public class FontPropertyDescriptor extends PropertyDescriptor { + + /** + * Creates an property descriptor with the given id and display name. + * + * @param id + * the id of the property + * @param displayName + * the name to display for the property + */ + public FontPropertyDescriptor(Object id, String displayName) { + super(id, displayName); + setLabelProvider(new LabelProvider() { + @Override + public String getText(Object element) { + return super.getText(element); + } + }); + } + + /** + * @see org.eclipse.ui.views.properties.IPropertyDescriptor#createPropertyEditor(Composite) + */ + public CellEditor createPropertyEditor(Composite parent) { + CellEditor editor = new FontDialogCellEditor(parent); + if (getValidator() != null) + editor.setValidator(getValidator()); + return editor; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/property/ImageDialog.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/property/ImageDialog.java new file mode 100644 index 0000000000000000000000000000000000000000..09ed8db26d1af112aa1ffb118672b9e978a6bb03 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/property/ImageDialog.java @@ -0,0 +1,242 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.property; + +import java.io.File; +import java.io.FilenameFilter; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.databinding.observable.list.WritableList; +import org.eclipse.core.resources.IFile; +import org.eclipse.jface.databinding.viewers.ObservableListContentProvider; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.viewers.CellLabelProvider; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.viewers.ViewerCell; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +import de.bmotionstudio.gef.editor.BMotionEditorPlugin; +import de.bmotionstudio.gef.editor.BMotionStudioImage; +import de.bmotionstudio.gef.editor.EditorImageRegistry; +import de.bmotionstudio.gef.editor.library.LibraryImageObject; +import de.bmotionstudio.gef.editor.library.LibraryObject; + +public class ImageDialog extends Dialog { + + private TableViewer tvLibrary; + private Image previewImage; + private Composite preContainer; + private Canvas previewCanvas; + private final ImageDialogCellEditor imageDialogCellEditor; + + protected ImageDialog(final Shell parentShell, + final ImageDialogCellEditor imageDialogCellEditor) { + super(parentShell); + this.imageDialogCellEditor = imageDialogCellEditor; + } + + @Override + protected Control createDialogArea(final Composite parent) { + + Composite container = (Composite) super.createDialogArea(parent); + + GridLayout gl = new GridLayout(1, true); + gl.horizontalSpacing = 0; + container.setLayout(gl); + + GridData gd = new GridData(GridData.FILL_BOTH); + gd.horizontalIndent = 0; + + preContainer = new Composite(container, SWT.NONE); + preContainer.setLayoutData(gd); + preContainer.setLayout(new FillLayout()); + + previewCanvas = new Canvas(preContainer, SWT.BORDER); + previewCanvas.addPaintListener(new PaintListener() { + public void paintControl(final PaintEvent e) { + if (previewImage == null) { + e.gc.drawString("No image selected ...", 0, 0); + } else { + e.gc.drawImage(previewImage, 0, 0); + } + } + }); + + final Composite libContainer = new Composite(container, SWT.NONE); + libContainer.setLayoutData(gd); + libContainer.setLayout(new FillLayout()); + + tvLibrary = new TableViewer(libContainer, SWT.FULL_SELECTION + | SWT.V_SCROLL); + tvLibrary.getTable().setLayoutData(gd); + tvLibrary.addSelectionChangedListener(new ISelectionChangedListener() { + + public void selectionChanged(final SelectionChangedEvent event) { + + IStructuredSelection selection = (IStructuredSelection) event + .getSelection(); + + LibraryObject obj = (LibraryObject) selection.getFirstElement(); + + if (previewImage != null) { + previewImage.dispose(); + } + + previewImage = null; + + if (obj != null) { + if (!obj.getName().equals("noimage")) { + IFile pFile = BMotionEditorPlugin.getActiveEditor() + .getVisualization().getProjectFile(); + if (pFile != null) { + String myPath = (pFile.getProject() + .getLocationURI() + "/images/" + obj + .getName()).replace("file:", ""); + previewImage = new Image(Display.getDefault(), + myPath); + } + } + } + + previewCanvas.redraw(); + + } + + }); + + ObservableListContentProvider contentProvider = new ObservableListContentProvider(); + tvLibrary.setContentProvider(contentProvider); + + tvLibrary.getTable().setLinesVisible(true); + tvLibrary.getTable().setHeaderVisible(true); + + final TableViewerColumn column1 = new TableViewerColumn(tvLibrary, + SWT.NONE); + column1.getColumn().setText("Name"); + column1.getColumn().setWidth(390); + column1.setLabelProvider(new CellLabelProvider() { + @Override + public void update(final ViewerCell cell) { + cell.setText(((LibraryObject) cell.getElement()).getName()); + cell.setImage(((LibraryObject) cell.getElement()).getImage()); + } + }); + + final TableViewerColumn column2 = new TableViewerColumn(tvLibrary, + SWT.NONE); + column2.getColumn().setText("Type"); + column2.getColumn().setWidth(60); + column2.setLabelProvider(new CellLabelProvider() { + @Override + public void update(final ViewerCell cell) { + cell.setText(((LibraryObject) cell.getElement()).getType()); + } + }); + + WritableList input = new WritableList(getLibraryObjects(), + LibraryObject.class); + tvLibrary.setInput(input); + + return container; + + } + + private List<LibraryObject> getLibraryObjects() { + + List<LibraryObject> tmpList = new ArrayList<LibraryObject>(); + tmpList.add(new LibraryObject("noimage", "", BMotionStudioImage + .getImageDescriptor("org.eclipse.ui", + "$nl$/icons/full/etool16/delete_edit.gif") + .createImage())); + + if (BMotionEditorPlugin.getActiveEditor() != null) { + + String basePath = (BMotionEditorPlugin.getActiveEditor() + .getVisualization().getProjectFile().getProject() + .getLocation().toString()).replace("file:", ""); + File dir = new File(basePath + "/images"); + File[] fileList = dir.listFiles(new FilenameFilter() { + public boolean accept(final File dir, final String name) { + if (name.toLowerCase().endsWith(".jpg") + || name.toLowerCase().endsWith(".gif") + || name.toLowerCase().endsWith(".png")) { + return true; + } + return false; + } + }); + if (fileList != null) { + for (File f : fileList) { + Image img = null; + if (f.getName().toLowerCase().endsWith(".jpg")) { + img = BMotionStudioImage + .getImage(EditorImageRegistry.IMG_ICON_JPG); + } else { + img = BMotionStudioImage + .getImage(EditorImageRegistry.IMG_ICON_GIF); + } + tmpList.add(new LibraryImageObject(f.getName(), "image", + img)); + } + } + + } + + return tmpList; + + } + + LibraryObject getSelectedObject() { + IStructuredSelection sel = (IStructuredSelection) tvLibrary + .getSelection(); + LibraryObject lobj = (LibraryObject) sel.getFirstElement(); + return lobj; + } + + @Override + protected Point getInitialSize() { + return new Point(500, 500); + } + + @Override + protected void okPressed() { + LibraryObject sel = getSelectedObject(); + if (sel != null) { + if (!sel.getName().equals("noimage")) { + this.imageDialogCellEditor.setValue(sel.getName()); + } else { + this.imageDialogCellEditor.setValue(""); + } + + } + close(); + } + + @Override + protected void configureShell(final Shell newShell) { + super.configureShell(newShell); + newShell.setText("BMotion Studio - Select image dialog"); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/property/ImageDialogCellEditor.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/property/ImageDialogCellEditor.java new file mode 100644 index 0000000000000000000000000000000000000000..fb88890ec12650af160ae1b33131b4dade7b260d --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/property/ImageDialogCellEditor.java @@ -0,0 +1,42 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.property; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.viewers.DialogCellEditor; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.ui.PlatformUI; + +public class ImageDialogCellEditor extends DialogCellEditor { + + /** + * Creates a new Image dialog cell editor parented under the given control. + * The cell editor value is <code>null</code> initially, and has no + * validator. + * + * @param parent + * the parent control + */ + protected ImageDialogCellEditor(Composite parent) { + super(parent); + } + + /** + * @see org.eclipse.jface.viewers.DialogCellEditor#openDialogBox(Control) + */ + @Override + protected Object openDialogBox(Control arg) { + ImageDialog dialog = new ImageDialog(PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getShell(), this); + if (dialog.open() == Dialog.OK) { + return getValue(); + } + return null; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/property/ImagePropertyDescriptor.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/property/ImagePropertyDescriptor.java new file mode 100644 index 0000000000000000000000000000000000000000..da6325a2fd9bb0b42c9954ac39cbe6e8c6546753 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/property/ImagePropertyDescriptor.java @@ -0,0 +1,37 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.property; + +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.views.properties.PropertyDescriptor; + +public class ImagePropertyDescriptor extends PropertyDescriptor { + + /** + * Creates an property descriptor with the given id and display name. + * + * @param id + * the id of the property + * @param displayName + * the name to display for the property + */ + public ImagePropertyDescriptor(Object id, String displayName) { + super(id, displayName); + } + + /** + * @see org.eclipse.ui.views.properties.IPropertyDescriptor#createPropertyEditor(Composite) + */ + public CellEditor createPropertyEditor(Composite parent) { + CellEditor editor = new ImageDialogCellEditor(parent); + if (getValidator() != null) + editor.setValidator(getValidator()); + return editor; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/property/IntegerCellEditor.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/property/IntegerCellEditor.java new file mode 100644 index 0000000000000000000000000000000000000000..ece6021174e3f4ec8da471400a97b0a291620c10 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/property/IntegerCellEditor.java @@ -0,0 +1,444 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.property; + +import java.text.MessageFormat; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ICellEditorValidator; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.*; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Text; + +public class IntegerCellEditor extends CellEditor { + + /** + * The text control; initially <code>null</code>. + */ + protected Text text; + + private ModifyListener modifyListener; + + /** + * State information for updating action enablement + */ + private boolean isSelection = false; + + private boolean isDeleteable = false; + + private boolean isSelectable = false; + + public IntegerCellEditor(Composite composite) { + super(composite); + setValidator(new ICellEditorValidator() { + public String isValid(Object object) { + if (object instanceof Integer) { + return null; + } else { + String string = (String) object; + try { + Integer.parseInt(string); + return null; + } catch (NumberFormatException exception) { + return exception.getMessage(); + } + } + } + }); + } + + /** + * Checks to see if the "deletable" state (can delete/ nothing to delete) + * has changed and if so fire an enablement changed notification. + */ + private void checkDeleteable() { + boolean oldIsDeleteable = isDeleteable; + isDeleteable = isDeleteEnabled(); + if (oldIsDeleteable != isDeleteable) { + fireEnablementChanged(DELETE); + } + } + + /** + * Checks to see if the "selectable" state (can select) has changed and if + * so fire an enablement changed notification. + */ + private void checkSelectable() { + boolean oldIsSelectable = isSelectable; + isSelectable = isSelectAllEnabled(); + if (oldIsSelectable != isSelectable) { + fireEnablementChanged(SELECT_ALL); + } + } + + /** + * Checks to see if the selection state (selection / no selection) has + * changed and if so fire an enablement changed notification. + */ + private void checkSelection() { + boolean oldIsSelection = isSelection; + isSelection = text.getSelectionCount() > 0; + if (oldIsSelection != isSelection) { + fireEnablementChanged(COPY); + fireEnablementChanged(CUT); + } + } + + /* + * (non-Javadoc) Method declared on CellEditor. + */ + protected Control createControl(Composite parent) { + text = new Text(parent, getStyle()); + text.addSelectionListener(new SelectionAdapter() { + public void widgetDefaultSelected(SelectionEvent e) { + handleDefaultSelection(e); + } + }); + text.addKeyListener(new KeyAdapter() { + // hook key pressed - see PR 14201 + public void keyPressed(KeyEvent e) { + keyReleaseOccured(e); + + // as a result of processing the above call, clients may have + // disposed this cell editor + if ((getControl() == null) || getControl().isDisposed()) { + return; + } + checkSelection(); // see explanation below + checkDeleteable(); + checkSelectable(); + } + }); + text.addTraverseListener(new TraverseListener() { + public void keyTraversed(TraverseEvent e) { + if (e.detail == SWT.TRAVERSE_ESCAPE + || e.detail == SWT.TRAVERSE_RETURN) { + e.doit = false; + } + } + }); + // We really want a selection listener but it is not supported so we + // use a key listener and a mouse listener to know when selection + // changes + // may have occurred + text.addMouseListener(new MouseAdapter() { + public void mouseUp(MouseEvent e) { + checkSelection(); + checkDeleteable(); + checkSelectable(); + } + }); + text.addFocusListener(new FocusAdapter() { + public void focusLost(FocusEvent e) { + IntegerCellEditor.this.focusLost(); + } + }); + text.setFont(parent.getFont()); + text.setBackground(parent.getBackground()); + text.setText("");//$NON-NLS-1$ + text.addModifyListener(getModifyListener()); + return text; + } + + /** + * The <code>TextCellEditor</code> implementation of this + * <code>CellEditor</code> framework method returns the text string. + * + * @return the text string + */ + protected Object doGetValue() { + return Integer.valueOf(Integer.parseInt(text.getText())); + } + + /* + * (non-Javadoc) Method declared on CellEditor. + */ + protected void doSetFocus() { + if (text != null) { + text.selectAll(); + text.setFocus(); + checkSelection(); + checkDeleteable(); + checkSelectable(); + } + } + + /** + * The <code>TextCellEditor</code> implementation of this + * <code>CellEditor</code> framework method accepts a text string (type + * <code>String</code>). + * + * @param value + * a text string (type <code>String</code>) + */ + protected void doSetValue(Object value) { + Assert.isTrue(text != null && (value instanceof Integer)); + text.removeModifyListener(getModifyListener()); + text.setText(String.valueOf(value.toString())); + text.addModifyListener(getModifyListener()); + } + + /** + * Processes a modify event that occurred in this text cell editor. This + * framework method performs validation and sets the error message + * accordingly, and then reports a change via + * <code>fireEditorValueChanged</code>. Subclasses should call this method + * at appropriate times. Subclasses may extend or reimplement. + * + * @param e + * the SWT modify event + */ + protected void editOccured(ModifyEvent e) { + String value = text.getText(); + if (value == null) { + value = "";//$NON-NLS-1$ + } + Object typedValue = value; + boolean oldValidState = isValueValid(); + boolean newValidState = isCorrect(typedValue); + + if (!newValidState) { + // try to insert the current value into the error message. + setErrorMessage(MessageFormat.format(getErrorMessage(), + new Object[] { value })); + } + valueChanged(oldValidState, newValidState); + } + + /** + * Since a text editor field is scrollable we don't set a minimumSize. + */ + public LayoutData getLayoutData() { + return new LayoutData(); + } + + /** + * Return the modify listener. + */ + private ModifyListener getModifyListener() { + if (modifyListener == null) { + modifyListener = new ModifyListener() { + public void modifyText(ModifyEvent e) { + editOccured(e); + } + }; + } + return modifyListener; + } + + /** + * Handles a default selection event from the text control by applying the + * editor value and deactivating this cell editor. + * + * @param event + * the selection event + * + * @since 3.0 + */ + protected void handleDefaultSelection(SelectionEvent event) { + // same with enter-key handling code in keyReleaseOccured(e); + fireApplyEditorValue(); + deactivate(); + } + + /** + * The <code>TextCellEditor</code> implementation of this + * <code>CellEditor</code> method returns <code>true</code> if the current + * selection is not empty. + */ + public boolean isCopyEnabled() { + if (text == null || text.isDisposed()) { + return false; + } + return text.getSelectionCount() > 0; + } + + /** + * The <code>TextCellEditor</code> implementation of this + * <code>CellEditor</code> method returns <code>true</code> if the current + * selection is not empty. + */ + public boolean isCutEnabled() { + if (text == null || text.isDisposed()) { + return false; + } + return text.getSelectionCount() > 0; + } + + /** + * The <code>TextCellEditor</code> implementation of this + * <code>CellEditor</code> method returns <code>true</code> if there is a + * selection or if the caret is not positioned at the end of the text. + */ + public boolean isDeleteEnabled() { + if (text == null || text.isDisposed()) { + return false; + } + return text.getSelectionCount() > 0 + || text.getCaretPosition() < text.getCharCount(); + } + + /** + * The <code>TextCellEditor</code> implementation of this + * <code>CellEditor</code> method always returns <code>true</code>. + */ + public boolean isPasteEnabled() { + if (text == null || text.isDisposed()) { + return false; + } + return true; + } + + /** + * Check if save all is enabled + * + * @return true if it is + */ + public boolean isSaveAllEnabled() { + if (text == null || text.isDisposed()) { + return false; + } + return true; + } + + /** + * Returns <code>true</code> if this cell editor is able to perform the + * select all action. + * <p> + * This default implementation always returns <code>false</code>. + * </p> + * <p> + * Subclasses may override + * </p> + * + * @return <code>true</code> if select all is possible, <code>false</code> + * otherwise + */ + public boolean isSelectAllEnabled() { + if (text == null || text.isDisposed()) { + return false; + } + return text.getCharCount() > 0; + } + + /** + * Processes a key release event that occurred in this cell editor. + * <p> + * The <code>TextCellEditor</code> implementation of this framework method + * ignores when the RETURN key is pressed since this is handled in + * <code>handleDefaultSelection</code>. An exception is made for Ctrl+Enter + * for multi-line texts, since a default selection event is not sent in this + * case. + * </p> + * + * @param keyEvent + * the key event + */ + protected void keyReleaseOccured(KeyEvent keyEvent) { + if (keyEvent.character == '\r') { // Return key + // Enter is handled in handleDefaultSelection. + // Do not apply the editor value in response to an Enter key event + // since this can be received from the IME when the intent is -not- + // to apply the value. + // See bug 39074 [CellEditors] [DBCS] canna input mode fires bogus + // event from Text Control + // + // An exception is made for Ctrl+Enter for multi-line texts, since + // a default selection event is not sent in this case. + if (text != null && !text.isDisposed() + && (text.getStyle() & SWT.MULTI) != 0) { + if ((keyEvent.stateMask & SWT.CTRL) != 0) { + super.keyReleaseOccured(keyEvent); + } + } + return; + } + super.keyReleaseOccured(keyEvent); + } + + /** + * The <code>TextCellEditor</code> implementation of this + * <code>CellEditor</code> method copies the current selection to the + * clipboard. + */ + public void performCopy() { + text.copy(); + } + + /** + * The <code>TextCellEditor</code> implementation of this + * <code>CellEditor</code> method cuts the current selection to the + * clipboard. + */ + public void performCut() { + text.cut(); + checkSelection(); + checkDeleteable(); + checkSelectable(); + } + + /** + * The <code>TextCellEditor</code> implementation of this + * <code>CellEditor</code> method deletes the current selection or, if there + * is no selection, the character next character from the current position. + */ + public void performDelete() { + if (text.getSelectionCount() > 0) { + // remove the contents of the current selection + text.insert(""); //$NON-NLS-1$ + } else { + // remove the next character + int pos = text.getCaretPosition(); + if (pos < text.getCharCount()) { + text.setSelection(pos, pos + 1); + text.insert(""); //$NON-NLS-1$ + } + } + checkSelection(); + checkDeleteable(); + checkSelectable(); + } + + /** + * The <code>TextCellEditor</code> implementation of this + * <code>CellEditor</code> method pastes the the clipboard contents over the + * current selection. + */ + public void performPaste() { + text.paste(); + checkSelection(); + checkDeleteable(); + checkSelectable(); + } + + /** + * The <code>TextCellEditor</code> implementation of this + * <code>CellEditor</code> method selects all of the current text. + */ + public void performSelectAll() { + text.selectAll(); + checkSelection(); + checkDeleteable(); + } + + /** + * This implementation of + * {@link CellEditor#dependsOnExternalFocusListener()} returns false if the + * current instance's class is TextCellEditor, and true otherwise. + * Subclasses that hook their own focus listener should override this method + * and return false. See also bug 58777. + * + * @since 3.4 + */ + protected boolean dependsOnExternalFocusListener() { + return getClass() != IntegerCellEditor.class; + } + +} \ No newline at end of file diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/property/IntegerPropertyDescriptor.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/property/IntegerPropertyDescriptor.java new file mode 100644 index 0000000000000000000000000000000000000000..45b37dc5a542d80761773aca43bd009ef798cfaa --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/property/IntegerPropertyDescriptor.java @@ -0,0 +1,27 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.property; + +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.views.properties.PropertyDescriptor; + +public class IntegerPropertyDescriptor extends PropertyDescriptor { + + public IntegerPropertyDescriptor(Object id, String displayName) { + super(id, displayName); + } + + public CellEditor createPropertyEditor(Composite parent) { + CellEditor editor = new IntegerCellEditor(parent); + if (getValidator() != null) { + editor.setValidator(getValidator()); + } + return editor; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/property/SliderCellEditor.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/property/SliderCellEditor.java new file mode 100644 index 0000000000000000000000000000000000000000..58bb2aff83f5bf15dfb75aacc100d9cc7fc66d65 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/property/SliderCellEditor.java @@ -0,0 +1,252 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.property; + +import java.text.MessageFormat; + +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.*; + +public class SliderCellEditor extends CellEditor { + + /** + * The editor control. + */ + private Composite editor; + + /** + * The slider. + */ + private Slider slider; + + private Label countLabel; + + /** + * Listens for 'focusLost' events and fires the 'apply' event as long as the + * focus wasn't lost because the dialog was opened. + */ + private FocusListener buttonFocusListener; + + /** + * The value of this cell editor; initially null. + */ + private Object value = null; + + /** + * Internal class for laying out the dialog. + */ + private class SliderSampleCellLayout extends Layout { + public void layout(Composite editor, boolean force) { + Rectangle bounds = editor.getClientArea(); + slider.setBounds(30, 0, bounds.width - 30, bounds.height); + countLabel.setBounds(5, 1, 25, bounds.height); + } + + public Point computeSize(Composite editor, int wHint, int hHint, + boolean force) { + if (wHint != SWT.DEFAULT && hHint != SWT.DEFAULT) { + return new Point(wHint, hHint); + } + Point buttonSize = slider.computeSize(SWT.DEFAULT, SWT.DEFAULT, + force); + // Just return the button width to ensure the button is not clipped + // if the label is long. + // The label will just use whatever extra width there is + Point result = new Point(buttonSize.x, buttonSize.y); + return result; + } + } + + /** + * Default DialogCellEditor style + */ + private static final int defaultStyle = SWT.NONE; + + /** + * Creates a new dialog cell editor with no control + * + * @since 2.1 + */ + public SliderCellEditor() { + setStyle(defaultStyle); + } + + /** + * Creates a new dialog cell editor parented under the given control. The + * cell editor value is null initially, and has no * validator. + * + * @param parent + * the parent control + */ + public SliderCellEditor(Composite parent) { + this(parent, defaultStyle); + } + + /** + * Creates a new dialog cell editor parented under the given control. The + * cell editor value is null initially, and has no * validator. + * + * @param parent + * the parent control + * @param style + * the style bits + * @since 2.1 + */ + public SliderCellEditor(Composite parent, int style) { + super(parent, style); + } + + /** + * Creates the button for this cell editor under the given parent control. * + * The default implementation of this framework method creates the button * + * display on the right hand side of the dialog cell editor. Subclasses may + * extend or reimplement. * + * + * @param parent + * the parent control + * @return the new button control + */ + protected Slider createSpinner(Composite parent) { + Slider result = new Slider(parent, SWT.HORIZONTAL); + result.setMaximum(265); + result.setIncrement(1); + //$NON-NLS-1$ + return result; + } + + /* + * (non-Javadoc) Method declared on CellEditor. + */ + protected Control createControl(Composite parent) { + Font font = parent.getFont(); + Color bg = parent.getBackground(); + + editor = new Composite(parent, getStyle()); + editor.setFont(font); + editor.setBackground(bg); + editor.setLayout(new SliderSampleCellLayout()); + + countLabel = new Label(editor, SWT.NONE); + + slider = createSpinner(editor); + slider.setFont(font); + slider.setBackground(editor.getBackground()); + updateContents(value); + + slider.addFocusListener(getButtonFocusListener()); + slider.addListener(SWT.Selection, new Listener() { + public void handleEvent(Event event) { + slider.removeFocusListener(getButtonFocusListener()); + + Object newValue = slider.getSelection(); + if (newValue != null) { + boolean newValidState = isCorrect(newValue); + if (newValidState) { + markDirty(); + doSetValue(newValue); + } else { + // try to insert the current value into the error + // message. + setErrorMessage(MessageFormat.format(getErrorMessage(), + new Object[] { newValue.toString() })); + } + } + } + }); + + slider.addListener(SWT.MouseUp, new Listener() { + public void handleEvent(Event event) { + fireApplyEditorValue(); + } + }); + + setValueValid(true); + + return editor; + } + + /* + * (non-Javadoc) Override in order to remove the button's focus listener if + * the celleditor is deactivating. + */ + public void deactivate() { + if (slider != null && !slider.isDisposed()) { + slider.removeFocusListener(getButtonFocusListener()); + } + + super.deactivate(); + } + + /* + * (non-Javadoc) Method declared on CellEditor. + */ + protected Object doGetValue() { + return value; + } + + /* + * (non-Javadoc) Method declared on CellEditor. The focus is set to the cell + * editor's button. + */ + protected void doSetFocus() { + slider.setFocus(); // add a FocusListener to the button + slider.addFocusListener(getButtonFocusListener()); + } + + /** + * Return a listener for button focus. + * + * @return FocusListener + */ + private FocusListener getButtonFocusListener() { + if (buttonFocusListener == null) { + buttonFocusListener = new FocusListener() { + public void focusGained(FocusEvent e) { + // Do nothing + } + + public void focusLost(FocusEvent e) { + SliderCellEditor.this.focusLost(); + } + }; + } + + return buttonFocusListener; + } + + /* + * (non-Javadoc) Method declared on CellEditor. + */ + protected void doSetValue(Object value) { + this.value = value; + updateContents(value); + } + + /** + * Updates the controls showing the value of this cell editor. * The default + * implementation of this framework method just converts the passed object + * to a string using toString and sets this as the text of the label widget. + */ + protected void updateContents(Object value) { + String text = "";//$NON-NLS-1$ + if (value != null) { + text = value.toString(); + if (slider != null) { + slider.setSelection(Integer.parseInt(text)); + countLabel.setText(value.toString()); + } + } + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/property/SliderPropertyDescriptor.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/property/SliderPropertyDescriptor.java new file mode 100644 index 0000000000000000000000000000000000000000..5be87c1a68fe12a90c70579992f168f2e67b5c31 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/property/SliderPropertyDescriptor.java @@ -0,0 +1,27 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.property; + +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.views.properties.PropertyDescriptor; + +public class SliderPropertyDescriptor extends PropertyDescriptor { + + public SliderPropertyDescriptor(Object id, String displayName) { + super(id, displayName); + } + + public CellEditor createPropertyEditor(Composite parent) { + CellEditor editor = new SliderCellEditor(parent); + if (getValidator() != null) { + editor.setValidator(getValidator()); + } + return editor; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/AnimationScriptObject.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/AnimationScriptObject.java new file mode 100644 index 0000000000000000000000000000000000000000..332a0ffad16ec57344b33dba42c7e9c43da89c86 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/AnimationScriptObject.java @@ -0,0 +1,61 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.scheduler; + +import java.util.Vector; + +import de.bmotionstudio.gef.editor.BindingObject; + +public class AnimationScriptObject extends BindingObject implements Cloneable { + + private Vector<AnimationScriptStep> steps; + + private String predicate; + + public AnimationScriptObject(String predicate) { + this(predicate, new Vector<AnimationScriptStep>()); + } + + public AnimationScriptObject(String predicate, + Vector<AnimationScriptStep> steps) { + this.predicate = predicate; + this.steps = steps; + } + + public void setSteps(Vector<AnimationScriptStep> steps) { + Object oldValue = this.steps; + this.steps = steps; + firePropertyChange("steps", oldValue, this.steps); + } + + public Vector<AnimationScriptStep> getSteps() { + if (this.steps == null) + this.steps = new Vector<AnimationScriptStep>(); + return this.steps; + } + + public void setPredicate(String predicate) { + Object oldValue = this.predicate; + this.predicate = predicate; + firePropertyChange("predicate", oldValue, this.predicate); + } + + public String getPredicate() { + return predicate; + } + + public AnimationScriptObject clone() throws CloneNotSupportedException { + Vector<AnimationScriptStep> tmpVector = new Vector<AnimationScriptStep>(); + for (AnimationScriptStep p : getSteps()) { + tmpVector.add(p.clone()); + } + AnimationScriptObject tmpObj = (AnimationScriptObject) super.clone(); + tmpObj.setSteps(tmpVector); + return tmpObj; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/AnimationScriptStep.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/AnimationScriptStep.java new file mode 100644 index 0000000000000000000000000000000000000000..a1841068c73801ec6aa007efe1e7d558506cecdd --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/AnimationScriptStep.java @@ -0,0 +1,102 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.scheduler; + +import java.util.ArrayList; + +import de.bmotionstudio.gef.editor.BindingObject; + +public class AnimationScriptStep extends BindingObject implements Cloneable { + + private String command; + private String parameter; + private int maxrandom = 1; + private transient ArrayList<ObserverCallBackObject> callBackList; + + public AnimationScriptStep() { + this("", ""); + } + + public AnimationScriptStep(String command, String parameter, + ArrayList<ObserverCallBackObject> callBackList) { + this.command = command; + this.parameter = parameter; + this.callBackList = callBackList; + } + + public AnimationScriptStep(String command, String parameter) { + this(command, parameter, new ArrayList<ObserverCallBackObject>()); + } + + public String getCommand() { + return command; + } + + public void setCommand(String command) { + Object oldValue = this.command; + this.command = command; + firePropertyChange("command", oldValue, this.command); + } + + public String getParameter() { + return parameter; + } + + public void setParameter(String parameter) { + Object oldValue = this.parameter; + this.parameter = parameter; + firePropertyChange("parameter", oldValue, this.parameter); + } + + public void setCallBackList(ArrayList<ObserverCallBackObject> callBackList) { + Object oldValue = this.callBackList; + this.callBackList = callBackList; + firePropertyChange("callBackList", oldValue, this.callBackList); + } + + public ArrayList<ObserverCallBackObject> getCallBackList() { + if (callBackList == null) + this.callBackList = new ArrayList<ObserverCallBackObject>(); + return this.callBackList; + } + + public void addCallBackObject(ObserverCallBackObject callBackObj) { + callBackList.add(callBackObj); + } + + public void removeCallBackObject(ObserverCallBackObject callBackObj) { + callBackList.remove(callBackObj); + } + + public AnimationScriptStep clone() throws CloneNotSupportedException { + ArrayList<ObserverCallBackObject> tmpList = new ArrayList<ObserverCallBackObject>(); + for (ObserverCallBackObject p : getCallBackList()) { + tmpList.add(p.clone()); + } + AnimationScriptStep tmpObj = (AnimationScriptStep) super.clone(); + tmpObj.setCallBackList(tmpList); + return tmpObj; + } + + public int getMaxrandom() { + return maxrandom; + } + + public void setMaxrandom(int maxrandom) { + Object oldValue = this.maxrandom; + this.maxrandom = maxrandom; + firePropertyChange("maxrandom", oldValue, this.maxrandom); + } + + public boolean isRandom() { + if (maxrandom > 1) + return true; + else + return false; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/ExecuteAnimationScript.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/ExecuteAnimationScript.java new file mode 100644 index 0000000000000000000000000000000000000000..3b8d16f6086330968b7ed87274a724f4d7c64ae6 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/ExecuteAnimationScript.java @@ -0,0 +1,161 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.scheduler; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import de.bmotionstudio.gef.editor.internal.Animation; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.scheduler.wizard.WizardExecuteAnimationScript; +import de.prob.core.Animator; +import de.prob.core.command.ExecuteOperationCommand; +import de.prob.core.command.GetCurrentStateIdCommand; +import de.prob.core.domainobjects.Operation; +import de.prob.exceptions.ProBException; + +public class ExecuteAnimationScript extends SchedulerEvent { + + public static String ID = "de.bmotionstudio.gef.editor.scheduler.ExecuteAnimationScript"; + + private List<AnimationScriptObject> list; + + private transient Random random; + + public ExecuteAnimationScript() { + this.list = new ArrayList<AnimationScriptObject>(); + } + + @Override + public void execute(final Animation animation, final BControl control) { + + // new Thread(new Runnable() { + // public void run() { + + // The animator + Animator animator = animation.getAnimator(); + + // Iterate schedulers + for (AnimationScriptObject obj : list) { + + // First evaluate predicate (predicate field) + // If true (execute operation sequence) + if (Boolean.valueOf(parsePredicate(obj.getPredicate(), control, + animation, null))) { + + for (AnimationScriptStep step : obj.getSteps()) { + + try { + + String currentState = GetCurrentStateIdCommand + .getID(animator); + + List<Operation> operations = parseOperation( + step.getCommand(), step.getParameter(), + step.getMaxrandom(), animation, currentState, + control); + + if (operations != null) { + + Operation executeOp; + + if (step.isRandom()) { + executeOp = operations.get(getRandomizer() + .nextInt(operations.size())); + } else { + executeOp = operations.get(0); + } + + ExecuteOperationCommand.executeOperation(animator, + executeOp); + + } else { + // TODO: error message!? + } + + } catch (ProBException e) { + e.printStackTrace(); + } + + } + + return; + + } + + } + // } + + // }).start(); + + } + + @Override + public SchedulerWizard getWizard(final BControl bcontrol) { + return new WizardExecuteAnimationScript(bcontrol, this); + } + + public ExecuteAnimationScript clone() throws CloneNotSupportedException { + ExecuteAnimationScript nse = (ExecuteAnimationScript) super.clone(); + List<AnimationScriptObject> list = new ArrayList<AnimationScriptObject>(); + for (AnimationScriptObject po : this.getList()) { + list.add(po.clone()); + } + nse.setList(list); + return nse; + } + + public void setList(final List<AnimationScriptObject> list) { + this.list = list; + } + + public List<AnimationScriptObject> getList() { + if (this.list == null) { + this.list = new ArrayList<AnimationScriptObject>(); + } + return list; + } + + private Random getRandomizer() { + if (random == null) + random = new Random(); + return random; + } + + // private boolean checkCallBack(ArrayList<ObserverCallBackObject> + // callBackList) { + // + // Boolean callback = false; + // + // for (ObserverCallBackObject callBackObj : callBackList) { + // + // BControl control = callBackObj.getControl(); + // Observer observer = control + // .getObserver(callBackObj.getObserverID()); + // + // Boolean oCallBack; + // + // if (observer != null) { + // oCallBack = observer.isCallBack(); + // } else { + // oCallBack = true; + // } + // + // if (!oCallBack) { + // callback = false; + // } else { + // callback = true; + // } + // + // } + // + // return callback; + // + // } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/ExecuteOperationByPredicate.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/ExecuteOperationByPredicate.java new file mode 100644 index 0000000000000000000000000000000000000000..23d2a1c1c60a8cf83dc8da6ee73c2fdb8e59d3b8 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/ExecuteOperationByPredicate.java @@ -0,0 +1,105 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.scheduler; + +import java.util.List; +import java.util.Random; + +import de.bmotionstudio.gef.editor.internal.Animation; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.scheduler.wizard.WizardSchedulerExecuteOperationByPredicate; +import de.prob.core.Animator; +import de.prob.core.command.ExecuteOperationCommand; +import de.prob.core.command.GetCurrentStateIdCommand; +import de.prob.core.domainobjects.Operation; +import de.prob.exceptions.ProBException; + +public class ExecuteOperationByPredicate extends SchedulerEvent { + + public static String ID = "de.bmotionstudio.gef.editor.scheduler.ExecuteOperationByPredicate"; + + private PredicateOperation predicateOperation; + + private transient Random random; + + @Override + public void execute(final Animation animation, final BControl control) { + + new Thread(new Runnable() { + public void run() { + + try { + // The animator + final Animator animator = animation.getAnimator(); + + String currentState = GetCurrentStateIdCommand + .getID(animator); + + List<Operation> operations = parseOperation( + predicateOperation.getOperationName(), + predicateOperation.getPredicate(), + predicateOperation.getMaxrandom(), animation, + currentState, control); + + if (operations != null) { + + Operation executeOp; + + if (predicateOperation.isRandom()) { + executeOp = operations.get(getRandomizer().nextInt( + operations.size())); + } else { + executeOp = operations.get(0); + } + + ExecuteOperationCommand.executeOperation(animator, + executeOp); + + } else { + // TODO: error message!? + } + + } catch (ProBException e) { + e.printStackTrace(); + } + + } + + }).start(); + + } + + @Override + public SchedulerWizard getWizard(BControl bcontrol) { + return new WizardSchedulerExecuteOperationByPredicate(bcontrol, this); + } + + public void setPredicateOperation(PredicateOperation predicateOperation) { + this.predicateOperation = predicateOperation; + } + + public PredicateOperation getPredicateOperation() { + if (this.predicateOperation == null) + this.predicateOperation = new PredicateOperation(); + return this.predicateOperation; + } + + public ExecuteOperationByPredicate clone() + throws CloneNotSupportedException { + ExecuteOperationByPredicate nse = (ExecuteOperationByPredicate) super + .clone(); + nse.setPredicateOperation(predicateOperation.clone()); + return nse; + } + + private Random getRandomizer() { + if (random == null) + random = new Random(); + return random; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/ExecuteOperationByPredicateMulti.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/ExecuteOperationByPredicateMulti.java new file mode 100644 index 0000000000000000000000000000000000000000..064189f6fd125e410c1bf0c287e54c040fa144a5 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/ExecuteOperationByPredicateMulti.java @@ -0,0 +1,77 @@ +package de.bmotionstudio.gef.editor.scheduler; + +import java.util.ArrayList; + +import de.bmotionstudio.gef.editor.BindingObject; +import de.bmotionstudio.gef.editor.internal.Animation; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.scheduler.wizard.WizardExecuteOperationByPredicateMulti; + +public class ExecuteOperationByPredicateMulti extends SchedulerEvent { + + public static String ID = "de.bmotionstudio.gef.editor.scheduler.ExecuteOperationByPredicateMulti"; + + private ArrayList<BindingObject> operationList; + + public ExecuteOperationByPredicateMulti() { + this.operationList = new ArrayList<BindingObject>(); + } + + @Override + public void execute(final Animation animation, final BControl control) { + + for (BindingObject op : operationList) { + + String bolValue = "true"; + String executePredicate = ((PredicateOperation) op) + .getExecutePredicate(); + + if (executePredicate.length() > 0) { + bolValue = parsePredicate(executePredicate, control, animation, + null); + } + + if (Boolean.valueOf(bolValue)) { // If true + executeOperation(animation, (PredicateOperation) op, control); + break; // Execute only the first operation which is true + } + + } + + } + + private void executeOperation(final Animation animation, + final PredicateOperation predicateOperation, final BControl control) { + ExecuteOperationByPredicate executeCmd = new ExecuteOperationByPredicate(); + executeCmd.setPredicateOperation(predicateOperation); + executeCmd.execute(animation, control); + } + + @Override + public SchedulerWizard getWizard(BControl bcontrol) { + return new WizardExecuteOperationByPredicateMulti(bcontrol, this); + } + + public void setOperationList(ArrayList<BindingObject> operationList) { + this.operationList = operationList; + } + + public ArrayList<BindingObject> getOperationList() { + if (operationList == null) + operationList = new ArrayList<BindingObject>(); + return operationList; + } + + public ExecuteOperationByPredicateMulti clone() + throws CloneNotSupportedException { + ExecuteOperationByPredicateMulti nse = (ExecuteOperationByPredicateMulti) super + .clone(); + ArrayList<BindingObject> opList = new ArrayList<BindingObject>(); + for (BindingObject p : getOperationList()) { + opList.add(((PredicateOperation) p).clone()); + } + nse.setOperationList(opList); + return nse; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/ObserverCallBackObject.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/ObserverCallBackObject.java new file mode 100644 index 0000000000000000000000000000000000000000..c9ace783cc4eb2317dcaf2764b7263374247ca0e --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/ObserverCallBackObject.java @@ -0,0 +1,51 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.scheduler; + +import de.bmotionstudio.gef.editor.BindingObject; +import de.bmotionstudio.gef.editor.model.BControl; + +public class ObserverCallBackObject extends BindingObject implements Cloneable { + + private BControl control; + private String observerID; + + public ObserverCallBackObject(BControl control, String observerID) { + this.control = control; + this.observerID = observerID; + } + + public ObserverCallBackObject() { + this(null, ""); + } + + public BControl getControl() { + return control; + } + + public void setControl(BControl control) { + Object oldValue = this.control; + this.control = control; + firePropertyChange("control", oldValue, this.control); + } + + public String getObserverID() { + return observerID; + } + + public void setObserverID(String observerID) { + Object oldValue = this.observerID; + this.observerID = observerID; + firePropertyChange("observerID", oldValue, this.observerID); + } + + public ObserverCallBackObject clone() throws CloneNotSupportedException { + ObserverCallBackObject tmpObj = (ObserverCallBackObject) super.clone(); + return tmpObj; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/PredicateOperation.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/PredicateOperation.java new file mode 100644 index 0000000000000000000000000000000000000000..5c715bf975ca54048d2b47aae0e72c2e2c4d90c4 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/PredicateOperation.java @@ -0,0 +1,86 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.scheduler; + +import de.bmotionstudio.gef.editor.observer.ObserverEvalObject; + +public class PredicateOperation extends ObserverEvalObject implements Cloneable { + + private String operationName; + private String executePredicate; + private String predicate; + private boolean random; + private int maxrandom = 1; + + public PredicateOperation() { + this("", ""); + } + + public PredicateOperation(String operationName, String predicate) { + this.operationName = operationName; + this.predicate = predicate; + } + + public void setOperationName(String operationName) { + Object oldValue = this.operationName; + this.operationName = operationName; + firePropertyChange("operationName", oldValue, this.operationName); + } + + public String getOperationName() { + return operationName; + } + + public void setPredicate(String predicate) { + Object oldValue = this.predicate; + this.predicate = predicate; + firePropertyChange("predicate", oldValue, this.predicate); + } + + public String getPredicate() { + return predicate; + } + + public void setRandom(boolean random) { + Object oldValue = this.random; + this.random = random; + firePropertyChange("random", oldValue, this.random); + } + + public boolean isRandom() { + return random; + } + + public boolean getIsRandom() { + return isRandom(); + } + + public void setMaxrandom(int maxrandom) { + Object oldValue = this.maxrandom; + this.maxrandom = maxrandom; + firePropertyChange("maxrandom", oldValue, this.maxrandom); + } + + public int getMaxrandom() { + return maxrandom; + } + + public PredicateOperation clone() throws CloneNotSupportedException { + return (PredicateOperation) super.clone(); + } + + public void setExecutePredicate(String executePredicate) { + Object oldValue = this.executePredicate; + this.executePredicate = executePredicate; + firePropertyChange("executePredicate", oldValue, this.executePredicate); + } + + public String getExecutePredicate() { + return executePredicate; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/SchedulerEvent.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/SchedulerEvent.java new file mode 100644 index 0000000000000000000000000000000000000000..c83a6510ffbf326af0990ce77a5f553651c1ca1f --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/SchedulerEvent.java @@ -0,0 +1,90 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.scheduler; + +import org.eclipse.core.runtime.IConfigurationElement; + +import de.bmotionstudio.gef.editor.AbstractExpressionControl; +import de.bmotionstudio.gef.editor.BMotionEditorPlugin; +import de.bmotionstudio.gef.editor.internal.Animation; +import de.bmotionstudio.gef.editor.model.BControl; + +/** + * + * Scheduler Events are assigned to events (i.e. on-click event) or to + * schedulers. A scheduler is an independent thread attempting to execute a set + * of scheduler events. It is very useful when the user does not want to execute + * each scheduler event by hand during an animation. + * + * @author Lukas Ladenberger + * + */ +public abstract class SchedulerEvent extends AbstractExpressionControl + implements Cloneable { + + private transient String eventID; + + public SchedulerEvent() { + init(); + } + + protected Object readResolve() { + init(); + return this; + } + + /** + * Method to initialize the scheduler event. Gets the ID, name and + * description from the corresponding extension point + */ + private void init() { + IConfigurationElement configElement = BMotionEditorPlugin + .getSchedulerExtension(getClass().getName()); + if (configElement != null) { + this.ID = configElement.getAttribute("class"); + this.name = configElement.getAttribute("name"); + this.description = configElement.getAttribute("description"); + } + } + + public void setEventID(String eventID) { + this.eventID = eventID; + } + + public String getEventID() { + return eventID; + } + + /** + * Executes the scheduler event (i.e. execute operation). + * + * @param animation + * The running animation + * @param bcontrol + * The corresponding control + */ + public abstract void execute(Animation animation, BControl bcontrol); + + /** + * Returns a corresponding wizard for the scheduler event. + * + * @param bcontrol + * The corresponding control + * @return the corresponding wizard + */ + public abstract SchedulerWizard getWizard(BControl bcontrol); + + /** + * Makes a copy of the scheduler event + * + * @return the cloned scheduler event + */ + public SchedulerEvent clone() throws CloneNotSupportedException { + return (SchedulerEvent) super.clone(); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/SchedulerWizard.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/SchedulerWizard.java new file mode 100644 index 0000000000000000000000000000000000000000..61cd3a464efda46d1de02480cce6afa177cabcc0 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/SchedulerWizard.java @@ -0,0 +1,60 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.scheduler; + +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.swt.graphics.Point; + +import de.bmotionstudio.gef.editor.model.BControl; + +/** + * + * The BMotion Studio provides an easy way to handle Scheduler Events. For this, + * Scheduler Events can have a corresponding dialog. The user can open it by + * calling the context menu of a B-Control. + * + * @author Lukas Ladenberger + * + */ +public abstract class SchedulerWizard extends Wizard { + + private BControl bcontrol; + private SchedulerEvent event; + + protected Boolean eventDelete = false; + + public SchedulerWizard(BControl bcontrol, SchedulerEvent scheduler) { + this.bcontrol = bcontrol; + this.event = scheduler; + } + + public BControl getBControl() { + return this.bcontrol; + } + + public SchedulerEvent getScheduler() { + return this.event; + } + + protected abstract Boolean prepareToFinish(); + + @Override + public boolean performFinish() { + return prepareToFinish(); + } + + protected void setEventDelete(Boolean b) { + this.eventDelete = b; + } + + public Boolean isEventDelete() { + return this.eventDelete; + } + + public abstract Point getSize(); + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/wizard/AnimationScriptObjectDialog.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/wizard/AnimationScriptObjectDialog.java new file mode 100644 index 0000000000000000000000000000000000000000..614a93d8fad62dfee190e40e4e9249ff8400788d --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/wizard/AnimationScriptObjectDialog.java @@ -0,0 +1,407 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.scheduler.wizard; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Vector; + +import org.eclipse.core.databinding.DataBindingContext; +import org.eclipse.core.databinding.beans.BeansObservables; +import org.eclipse.core.databinding.observable.list.ComputedList; +import org.eclipse.core.databinding.observable.list.WritableList; +import org.eclipse.core.resources.IFile; +import org.eclipse.jface.databinding.viewers.ObservableListContentProvider; +import org.eclipse.jface.databinding.viewers.ObservableMapLabelProvider; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ColumnViewer; +import org.eclipse.jface.viewers.ComboBoxViewerCellEditor; +import org.eclipse.jface.viewers.EditingSupport; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eventb.core.IMachineRoot; +import org.eventb.core.ISCEvent; +import org.eventb.core.ISCGuard; +import org.eventb.core.ISCMachineRoot; +import org.eventb.core.ISCParameter; +import org.rodinp.core.IRodinFile; +import org.rodinp.core.IRodinProject; +import org.rodinp.core.RodinCore; +import org.rodinp.core.RodinDBException; + +import de.bmotionstudio.gef.editor.BMotionStudioImage; +import de.bmotionstudio.gef.editor.EditorImageRegistry; +import de.bmotionstudio.gef.editor.edit.PredicateEditingSupport; +import de.bmotionstudio.gef.editor.eventb.EventBHelper; +import de.bmotionstudio.gef.editor.eventb.MachineContentObject; +import de.bmotionstudio.gef.editor.eventb.MachineOperation; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.model.Visualization; +import de.bmotionstudio.gef.editor.property.IntegerCellEditor; +import de.bmotionstudio.gef.editor.scheduler.AnimationScriptObject; +import de.bmotionstudio.gef.editor.scheduler.AnimationScriptStep; +import de.prob.logging.Logger; + +public class AnimationScriptObjectDialog extends Dialog { + + private ISCMachineRoot getCorrespondingFile(IFile file, + String machineFileName) { + IRodinProject myProject = RodinCore.valueOf(file.getProject()); + IRodinFile rodinSource = myProject.getRodinFile(machineFileName); + ISCMachineRoot machineRoot = ((IMachineRoot) rodinSource.getRoot()) + .getSCMachineRoot(); + return machineRoot; + } + + public List<MachineContentObject> getOperations(Visualization visualization) { + + ISCMachineRoot machineRoot = null; + + machineRoot = getCorrespondingFile(visualization.getProjectFile(), + visualization.getMachineName()); + + ISCEvent[] events = null; + ArrayList<MachineContentObject> tmpSet = new ArrayList<MachineContentObject>(); + + try { + events = machineRoot.getSCEvents(); + + for (ISCEvent event : events) { + + Vector<String> parSet = new Vector<String>(); + Vector<String> guardSet = new Vector<String>(); + + for (ISCParameter par : event.getSCParameters()) { + parSet.insertElementAt(par.getIdentifierString(), + parSet.size()); + } + + for (ISCGuard guard : event.getSCGuards()) { + guardSet.insertElementAt(guard.getPredicateString(), + guardSet.size()); + } + + MachineOperation op = new MachineOperation(event.getLabel(), + parSet, guardSet); + tmpSet.add(op); + + } + } catch (RodinDBException e) { + String message = "Rodin DB Exception while getting operations: " + + e.getLocalizedMessage(); + Logger.notifyUser(message, e); + return Collections + .unmodifiableList(new ArrayList<MachineContentObject>()); + } + + return tmpSet; + + } + + private TableViewer tableViewer; + + private final BControl control; + + private AnimationScriptObject animationScriptObject; + + public AnimationScriptObjectDialog(Shell parentShell, BControl control, + AnimationScriptObject animationScriptObject) { + super(parentShell); + this.control = control; + this.animationScriptObject = animationScriptObject; + } + + @Override + protected Control createDialogArea(final Composite parent) { + + DataBindingContext dbc = new DataBindingContext(); + + Composite container = (Composite) super.createDialogArea(parent); + container.setLayout(new GridLayout(1, true)); + + tableViewer = new TableViewer(container, SWT.BORDER + | SWT.FULL_SELECTION); + tableViewer.getTable().setLinesVisible(true); + tableViewer.getTable().setHeaderVisible(true); + tableViewer.getTable().setLayoutData(new GridData(GridData.FILL_BOTH)); + tableViewer.getTable().setFont( + new Font(Display.getDefault(), new FontData("Arial", 10, + SWT.NONE))); + + TableViewerColumn column = new TableViewerColumn(tableViewer, SWT.NONE); + column.getColumn().setText("Operation"); + column.getColumn().setWidth(175); + column.setEditingSupport(new OperationValueEditing(tableViewer, control)); + + column = new TableViewerColumn(tableViewer, SWT.NONE); + column.getColumn().setText("Predicate"); + column.getColumn().setWidth(300); + column.setEditingSupport(new PredicateEditingSupport(tableViewer, dbc, + "parameter", control.getVisualization(), getShell())); + + column = new TableViewerColumn(tableViewer, SWT.NONE); + column.getColumn().setText("Random Ops"); + column.getColumn().setWidth(100); + column.setEditingSupport(new RandomModeEditingSupport(tableViewer)); + + // column = new TableViewerColumn(tableViewer, SWT.NONE); + // column.getColumn().setText("Callback"); + // column.getColumn().setWidth(100); + // column + // .setEditingSupport(new ObserverCallbackEditingSupport( + // tableViewer)); + + ObservableListContentProvider contentProvider = new ObservableListContentProvider(); + tableViewer.setContentProvider(contentProvider); + tableViewer.setLabelProvider(new ObservableMapLabelProvider( + BeansObservables.observeMaps( + contentProvider.getKnownElements(), new String[] { + "command", "parameter", "maxrandom" })) { + + @Override + public String getColumnText(final Object element, + final int columnIndex) { + // if (columnIndex == 2) { + // return "Edit"; + // } + return super.getColumnText(element, columnIndex); + } + + @Override + public Image getColumnImage(final Object element, + final int columnIndex) { + return null; + } + + }); + + final WritableList input = new WritableList( + animationScriptObject.getSteps(), AnimationScriptStep.class); + + tableViewer.setInput(input); + + Composite comp = new Composite(container, SWT.NONE); + comp.setLayout(new RowLayout()); + comp.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END)); + + Button btRemove = new Button(comp, SWT.PUSH); + btRemove.setText("Remove"); + btRemove.setImage(BMotionStudioImage + .getImage(EditorImageRegistry.IMG_ICON_DELETE)); + btRemove.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(final SelectionEvent e) { + if (tableViewer.getSelection().isEmpty()) { + return; + } + AnimationScriptStep obj = (AnimationScriptStep) ((IStructuredSelection) tableViewer + .getSelection()).getFirstElement(); + input.remove(obj); + } + }); + + Button btAdd = new Button(comp, SWT.PUSH); + btAdd.setText("Add"); + btAdd.setImage(BMotionStudioImage + .getImage(EditorImageRegistry.IMG_ICON_ADD)); + btAdd.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(final SelectionEvent e) { + AnimationScriptStep obj = new AnimationScriptStep(); + input.add(obj); + } + }); + + return container; + + } + + @Override + protected Point getInitialSize() { + return new Point(600, 500); + } + + @Override + protected void okPressed() { + close(); + } + + @Override + protected void configureShell(final Shell newShell) { + super.configureShell(newShell); + newShell.setText("BMotion Studio - Scheduler Editor"); + } + + public void setAnimationScriptObject( + final AnimationScriptObject animationScriptObject) { + this.animationScriptObject = animationScriptObject; + } + + public AnimationScriptObject getAnimationScriptObject() { + return animationScriptObject; + } + + // private class ObserverCallbackEditingSupport extends EditingSupport { + // + // public ObserverCallbackEditingSupport(ColumnViewer viewer) { + // super(viewer); + // } + // + // @Override + // protected boolean canEdit(Object element) { + // return true; + // } + // + // @Override + // protected CellEditor getCellEditor(Object element) { + // return new ObserverCallbackCellEditor((Composite) getViewer() + // .getControl(), (AnimationScriptStep) element); + // } + // + // @Override + // protected Object getValue(Object element) { + // return "Edit"; + // } + // + // @Override + // protected void setValue(Object element, Object value) { + // } + // + // } + + // private class ObserverCallbackCellEditor extends DialogCellEditor { + // + // private final AnimationScriptStep step; + // + // public ObserverCallbackCellEditor(final Composite parent, + // final AnimationScriptStep step) { + // super(parent); + // this.step = step; + // } + // + // @Override + // protected Object openDialogBox(final Control cellEditorWindow) { + // ObserverCallBackDialog dialog = new ObserverCallBackDialog( + // PlatformUI.getWorkbench().getActiveWorkbenchWindow() + // .getShell(), step, control); + // if (dialog.open() == Dialog.OK) { + // return getValue(); + // } + // return null; + // } + // + // } + + private static class OperationValueEditing extends EditingSupport { + + private ComboBoxViewerCellEditor cellEditor = null; + + private final BControl control; + + public OperationValueEditing(final TableViewer cv, + final BControl control) { + super(cv); + this.control = control; + } + + @Override + protected boolean canEdit(final Object element) { + return true; + } + + @Override + protected Object getValue(final Object element) { + return ((AnimationScriptStep) element).getCommand(); + } + + @Override + protected void setValue(final Object element, final Object value) { + if (value != null) { + ((AnimationScriptStep) element).setCommand(value.toString()); + } + } + + @Override + protected CellEditor getCellEditor(final Object element) { + if (cellEditor == null) { + cellEditor = new ComboBoxViewerCellEditor( + (Composite) getViewer().getControl(), SWT.READ_ONLY); + cellEditor + .setContentProvider(new ObservableListContentProvider()); + cellEditor.setInput(new ComputedList() { + @Override + protected List<String> calculate() { + ArrayList<String> tmpList = new ArrayList<String>(); + for (MachineContentObject op : EventBHelper + .getOperations(control.getVisualization())) { + tmpList.add(((MachineOperation) op).getLabel()); + } + return tmpList; + } + }); + } + return cellEditor; + } + } + + private static class RandomModeEditingSupport extends EditingSupport { + + private CellEditor cellEditor; + + public RandomModeEditingSupport(ColumnViewer viewer) { + super(viewer); + } + + @Override + protected void setValue(Object element, Object value) { + if (value != null) { + Integer maxnr = Integer.valueOf(value.toString()); + AnimationScriptStep obj = (AnimationScriptStep) element; + obj.setMaxrandom(maxnr); + } + } + + @Override + protected Object getValue(Object element) { + return ((AnimationScriptStep) element).getMaxrandom(); + } + + @Override + protected CellEditor getCellEditor(Object element) { + if (cellEditor == null) { + cellEditor = new IntegerCellEditor((Composite) getViewer() + .getControl()); + } + return cellEditor; + } + + @Override + protected boolean canEdit(Object element) { + return true; + } + + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/wizard/ObserverCallBackDialog.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/wizard/ObserverCallBackDialog.java new file mode 100644 index 0000000000000000000000000000000000000000..aa06b77236e917a94b64527e61ac52f97732b565 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/wizard/ObserverCallBackDialog.java @@ -0,0 +1,335 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.scheduler.wizard; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.databinding.beans.BeansObservables; +import org.eclipse.core.databinding.observable.list.ComputedList; +import org.eclipse.core.databinding.observable.list.WritableList; +import org.eclipse.jface.databinding.viewers.ObservableListContentProvider; +import org.eclipse.jface.databinding.viewers.ObservableMapLabelProvider; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ComboBoxViewerCellEditor; +import org.eclipse.jface.viewers.EditingSupport; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CCombo; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +import de.bmotionstudio.gef.editor.BMotionStudioImage; +import de.bmotionstudio.gef.editor.EditorImageRegistry; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.scheduler.AnimationScriptStep; +import de.bmotionstudio.gef.editor.scheduler.ObserverCallBackObject; + +@Deprecated +public class ObserverCallBackDialog extends Dialog { + + private TableViewer tableViewer; + + private final AnimationScriptStep animationScriptStep; + + private final BControl control; + + // private IObservableValue controlObservable; + + public ObserverCallBackDialog(final Shell parentShell, + final AnimationScriptStep animationScriptStep, + final BControl control) { + super(parentShell); + this.animationScriptStep = animationScriptStep; + this.control = control; + } + + @Override + protected Control createDialogArea(final Composite parent) { + + // DataBindingContext dbc = new DataBindingContext(); + + Composite container = (Composite) super.createDialogArea(parent); + container.setLayout(new GridLayout(1, true)); + + tableViewer = new TableViewer(container, SWT.BORDER + | SWT.FULL_SELECTION); + tableViewer.getTable().setLinesVisible(true); + tableViewer.getTable().setHeaderVisible(true); + tableViewer.getTable().setLayoutData(new GridData(GridData.FILL_BOTH)); + tableViewer.getTable().setFont( + new Font(Display.getDefault(), new FontData("Arial", 10, + SWT.NONE))); + + TableViewerColumn column = new TableViewerColumn(tableViewer, SWT.NONE); + column.getColumn().setText("Control"); + column.getColumn().setWidth(225); + column.setEditingSupport(new ControlValueEditing(tableViewer, control)); + + column = new TableViewerColumn(tableViewer, SWT.NONE); + column.getColumn().setText("Observer"); + column.getColumn().setWidth(150); + // column.setEditingSupport(new TextEditingSupport(tableViewer, dbc, + // "observerID")); + column.setEditingSupport(new ObserverValueEditing(tableViewer, control)); + + ObservableListContentProvider contentProvider = new ObservableListContentProvider(); + tableViewer.setContentProvider(contentProvider); + tableViewer.setLabelProvider(new ObservableMapLabelProvider( + BeansObservables.observeMaps( + contentProvider.getKnownElements(), new String[] { + "control", "observerID" })) { + + @Override + public String getColumnText(final Object element, + final int columnIndex) { + if (columnIndex == 0) { + + ObserverCallBackObject obj = (ObserverCallBackObject) element; + + if (obj.getControl() != null) { + return obj.getControl().getID(); + } + } + return super.getColumnText(element, columnIndex); + } + + @Override + public Image getColumnImage(final Object element, + final int columnIndex) { + return null; + } + + }); + + final WritableList input = new WritableList( + animationScriptStep.getCallBackList(), + ObserverCallBackObject.class); + + tableViewer.setInput(input); + + Composite comp = new Composite(container, SWT.NONE); + comp.setLayout(new RowLayout()); + comp.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END)); + + Button btRemove = new Button(comp, SWT.PUSH); + btRemove.setText("Remove"); + btRemove.setImage(BMotionStudioImage + .getImage(EditorImageRegistry.IMG_ICON_DELETE)); + btRemove.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(final SelectionEvent e) { + if (tableViewer.getSelection().isEmpty()) { + return; + } + ObserverCallBackObject obj = (ObserverCallBackObject) ((IStructuredSelection) tableViewer + .getSelection()).getFirstElement(); + input.remove(obj); + } + }); + + Button btAdd = new Button(comp, SWT.PUSH); + btAdd.setText("Add"); + btAdd.setImage(BMotionStudioImage + .getImage(EditorImageRegistry.IMG_ICON_ADD)); + btAdd.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(final SelectionEvent e) { + ObserverCallBackObject obj = new ObserverCallBackObject(); + input.add(obj); + } + }); + + return container; + + } + + @Override + protected Point getInitialSize() { + return new Point(600, 500); + } + + @Override + protected void okPressed() { + close(); + } + + @Override + protected void configureShell(final Shell newShell) { + super.configureShell(newShell); + newShell.setText("BMotion Studio - Observer Callback Editor"); + } + + private class ControlValueEditing extends EditingSupport { + + private ComboBoxViewerCellEditor cellEditor = null; + + private final BControl control; + + public ControlValueEditing(final TableViewer cv, final BControl control) { + super(cv); + this.control = control; + } + + @Override + protected boolean canEdit(final Object element) { + return true; + } + + @Override + protected Object getValue(final Object element) { + if (((ObserverCallBackObject) element).getControl() != null) { + return ((ObserverCallBackObject) element).getControl().getID(); + } else { + return ""; + } + } + + @Override + protected void setValue(final Object element, final Object value) { + if (value != null) { + ((ObserverCallBackObject) element).setControl(control + .getVisualization().getBControl(value.toString())); + } + } + + @Override + protected CellEditor getCellEditor(final Object element) { + if (cellEditor == null) { + cellEditor = new ComboBoxViewerCellEditor( + (Composite) getViewer().getControl(), SWT.READ_ONLY); + cellEditor + .setContenProvider(new ObservableListContentProvider()); + cellEditor.setInput(new ComputedList() { + @Override + protected List<String> calculate() { + ArrayList<String> tmpList = new ArrayList<String>(); + for (String controlID : control.getVisualization() + .getAllBControlIDs()) { + tmpList.add(controlID); + } + return tmpList; + } + }); + ((CCombo) cellEditor.getControl()) + .addFocusListener(new FocusListener() { + + String oldValue; + + public void focusGained(final FocusEvent e) { + oldValue = ((CCombo) cellEditor.getControl()) + .getText(); + + } + + public void focusLost(final FocusEvent e) { + + if (!oldValue.equals(((CCombo) cellEditor + .getControl()).getText())) { + + IStructuredSelection selection = (IStructuredSelection) getViewer() + .getSelection(); + + ObserverCallBackObject obj = (ObserverCallBackObject) selection + .getFirstElement(); + obj.setObserverID(""); + tableViewer.refresh(); + + } + } + + }); + } + return cellEditor; + } + } + + private static class ObserverValueEditing extends EditingSupport { + + private ComboBoxViewerCellEditor cellEditor = null; + + // private final BControl control; + + public ObserverValueEditing(final TableViewer cv, final BControl control) { + super(cv); + // this.control = control; + } + + @Override + protected boolean canEdit(final Object element) { + return true; + } + + @Override + protected Object getValue(final Object element) { + if (((ObserverCallBackObject) element).getObserverID() != null) { + return ((ObserverCallBackObject) element).getObserverID(); + } else { + return ""; + } + } + + @Override + protected void setValue(final Object element, final Object value) { + if (value != null) { + ((ObserverCallBackObject) element).setObserverID(value + .toString()); + } + } + + @Override + protected CellEditor getCellEditor(final Object element) { + + if (cellEditor == null) { + cellEditor = new ComboBoxViewerCellEditor( + (Composite) getViewer().getControl(), SWT.READ_ONLY); + cellEditor + .setContenProvider(new ObservableListContentProvider()); + } + // cellEditor.setInput(new ComputedList() { + // @Override + // protected List<String> calculate() { + // + // ArrayList<String> tmpList = new ArrayList<String>(); + // + // ObserverCallBackObject obj = (ObserverCallBackObject) element; + // BControl control = obj.getControl(); + // if (control != null) { + // + // for (String id : control.getObservers().keySet()) { + // tmpList.add(id); + // } + // + // } + // + // return tmpList; + // + // } + // }); + + return cellEditor; + } + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/wizard/WizardExecuteAnimationScript.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/wizard/WizardExecuteAnimationScript.java new file mode 100644 index 0000000000000000000000000000000000000000..92a44580afcb5fd04e30a748da6e615098b084c7 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/wizard/WizardExecuteAnimationScript.java @@ -0,0 +1,226 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.scheduler.wizard; + +import org.eclipse.core.databinding.DataBindingContext; +import org.eclipse.core.databinding.beans.BeansObservables; +import org.eclipse.core.databinding.observable.list.WritableList; +import org.eclipse.jface.databinding.viewers.ObservableListContentProvider; +import org.eclipse.jface.databinding.viewers.ObservableMapLabelProvider; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ColumnViewer; +import org.eclipse.jface.viewers.DialogCellEditor; +import org.eclipse.jface.viewers.EditingSupport; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.PlatformUI; + +import de.bmotionstudio.gef.editor.BMotionStudioImage; +import de.bmotionstudio.gef.editor.EditorImageRegistry; +import de.bmotionstudio.gef.editor.edit.PredicateEditingSupport; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.scheduler.AnimationScriptObject; +import de.bmotionstudio.gef.editor.scheduler.ExecuteAnimationScript; +import de.bmotionstudio.gef.editor.scheduler.SchedulerEvent; +import de.bmotionstudio.gef.editor.scheduler.SchedulerWizard; + +public class WizardExecuteAnimationScript extends SchedulerWizard { + + private class SchedulerPage extends WizardPage { + + private TableViewer tableViewer; + + protected SchedulerPage(String pageName) { + super(pageName); + } + + public void createControl(final Composite parent) { + + DataBindingContext dbc = new DataBindingContext(); + + Composite container = new Composite(parent, SWT.NONE); + container.setLayout(new GridLayout(1, true)); + + setControl(container); + + tableViewer = new TableViewer(container, SWT.BORDER + | SWT.FULL_SELECTION); + tableViewer.getTable().setLinesVisible(true); + tableViewer.getTable().setHeaderVisible(true); + tableViewer.getTable().setLayoutData( + new GridData(GridData.FILL_BOTH)); + tableViewer.getTable().setFont( + new Font(Display.getDefault(), new FontData("Arial", 10, + SWT.NONE))); + + TableViewerColumn column = new TableViewerColumn(tableViewer, + SWT.NONE); + column.getColumn().setText("Predicate"); + column.getColumn().setWidth(225); + column.setEditingSupport(new PredicateEditingSupport(tableViewer, + dbc, "predicate", getBControl().getVisualization(), + getShell())); + + column = new TableViewerColumn(tableViewer, SWT.NONE); + column.getColumn().setText("Edit"); + column.getColumn().setWidth(225); + column.setEditingSupport(new AnimationScriptEditingSupport( + tableViewer)); + + ObservableListContentProvider contentProvider = new ObservableListContentProvider(); + tableViewer.setContentProvider(contentProvider); + + tableViewer.setLabelProvider(new ObservableMapLabelProvider( + BeansObservables.observeMaps( + contentProvider.getKnownElements(), + new String[] { "predicate" })) { + + @Override + public String getColumnText(Object element, int columnIndex) { + if (columnIndex == 1) { + return "Edit Scheduler"; + } + return super.getColumnText(element, columnIndex); + } + + @Override + public Image getColumnImage(Object element, int columnIndex) { + return null; + } + + }); + + final WritableList input = new WritableList( + ((ExecuteAnimationScript) getScheduler()).getList(), + AnimationScriptObject.class); + tableViewer.setInput(input); + + Composite comp = new Composite(container, SWT.NONE); + comp.setLayout(new RowLayout()); + comp.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END)); + + Button btRemove = new Button(comp, SWT.PUSH); + btRemove.setText("Remove"); + btRemove.setImage(BMotionStudioImage + .getImage(EditorImageRegistry.IMG_ICON_DELETE)); + btRemove.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (tableViewer.getSelection().isEmpty()) { + return; + } + AnimationScriptObject obj = (AnimationScriptObject) ((IStructuredSelection) tableViewer + .getSelection()).getFirstElement(); + input.remove(obj); + } + }); + + Button btAdd = new Button(comp, SWT.PUSH); + btAdd.setText("Add"); + btAdd.setImage(BMotionStudioImage + .getImage(EditorImageRegistry.IMG_ICON_ADD)); + btAdd.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + AnimationScriptObject obj = new AnimationScriptObject(""); + input.add(obj); + } + }); + + } + } + + public WizardExecuteAnimationScript(BControl bcontrol, + SchedulerEvent scheduler) { + super(bcontrol, scheduler); + addPage(new SchedulerPage("SchedulerPage")); + } + + @Override + protected Boolean prepareToFinish() { + return true; + } + + @Override + public boolean performCancel() { + return true; + } + + @Override + public Point getSize() { + return new Point(600, 500); + } + + private class AnimationScriptEditingSupport extends EditingSupport { + + public AnimationScriptEditingSupport(ColumnViewer viewer) { + super(viewer); + } + + @Override + protected boolean canEdit(Object element) { + return true; + } + + @Override + protected CellEditor getCellEditor(Object element) { + return new AnimationScriptDialogCellEditor((Composite) getViewer() + .getControl(), (AnimationScriptObject) element); + } + + @Override + protected Object getValue(Object element) { + return "Edit Scheduler"; + } + + @Override + protected void setValue(Object element, Object value) { + } + + } + + private class AnimationScriptDialogCellEditor extends DialogCellEditor { + + private AnimationScriptObject animObj; + + public AnimationScriptDialogCellEditor(Composite parent, + AnimationScriptObject animObj) { + super(parent); + this.animObj = animObj; + } + + @Override + protected Object openDialogBox(Control cellEditorWindow) { + AnimationScriptObjectDialog dialog = new AnimationScriptObjectDialog( + PlatformUI.getWorkbench().getActiveWorkbenchWindow() + .getShell(), getBControl(), animObj); + if (dialog.open() == Dialog.OK) { + return getValue(); + } + return null; + } + + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/wizard/WizardExecuteOperationByPredicateMulti.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/wizard/WizardExecuteOperationByPredicateMulti.java new file mode 100644 index 0000000000000000000000000000000000000000..d301e8ccb815cd2864f76f75cad690b1325d0cd5 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/wizard/WizardExecuteOperationByPredicateMulti.java @@ -0,0 +1,343 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ +package de.bmotionstudio.gef.editor.scheduler.wizard; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.databinding.DataBindingContext; +import org.eclipse.core.databinding.beans.BeansObservables; +import org.eclipse.core.databinding.observable.list.ComputedList; +import org.eclipse.core.databinding.observable.list.WritableList; +import org.eclipse.jface.databinding.viewers.ObservableListContentProvider; +import org.eclipse.jface.databinding.viewers.ObservableMapLabelProvider; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ColumnViewer; +import org.eclipse.jface.viewers.ComboBoxViewerCellEditor; +import org.eclipse.jface.viewers.EditingSupport; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; + +import de.bmotionstudio.gef.editor.BMotionStudioImage; +import de.bmotionstudio.gef.editor.BindingObject; +import de.bmotionstudio.gef.editor.EditorImageRegistry; +import de.bmotionstudio.gef.editor.edit.PredicateEditingSupport; +import de.bmotionstudio.gef.editor.eventb.EventBHelper; +import de.bmotionstudio.gef.editor.eventb.MachineContentObject; +import de.bmotionstudio.gef.editor.eventb.MachineOperation; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.property.IntegerCellEditor; +import de.bmotionstudio.gef.editor.scheduler.ExecuteOperationByPredicateMulti; +import de.bmotionstudio.gef.editor.scheduler.PredicateOperation; +import de.bmotionstudio.gef.editor.scheduler.SchedulerEvent; +import de.bmotionstudio.gef.editor.scheduler.SchedulerWizard; + +/** + * @author Lukas Ladenberger + * + */ +public class WizardExecuteOperationByPredicateMulti extends SchedulerWizard { + + private class MultiPage extends WizardPage { + + private TableViewer tableViewer; + + protected MultiPage(String pageName) { + super(pageName); + } + + public void createControl(final Composite parent) { + + DataBindingContext dbc = new DataBindingContext(); + + Composite container = new Composite(parent, SWT.NONE); + container.setLayout(new GridLayout(1, true)); + + setControl(container); + + tableViewer = new TableViewer(container, SWT.BORDER + | SWT.FULL_SELECTION); + tableViewer.getTable().setLinesVisible(true); + tableViewer.getTable().setHeaderVisible(true); + tableViewer.getTable().setLayoutData( + new GridData(GridData.FILL_BOTH)); + tableViewer.getTable().setFont( + new Font(Display.getDefault(), new FontData("Arial", 10, + SWT.NONE))); + + TableViewerColumn column = new TableViewerColumn(tableViewer, + SWT.NONE); + column.getColumn().setText("Execute Rule"); + column.getColumn().setWidth(190); + column.setEditingSupport(new PredicateEditingSupport(tableViewer, + dbc, "executePredicate", getBControl().getVisualization(), + getShell())); + + column = new TableViewerColumn(tableViewer, SWT.NONE); + column.getColumn().setText("Operation"); + column.getColumn().setWidth(150); + column.setEditingSupport(new OperationValueEditing(tableViewer, + getBControl())); + + column = new TableViewerColumn(tableViewer, SWT.NONE); + column.getColumn().setText("Parameter"); + column.getColumn().setWidth(190); + column.setEditingSupport(new PredicateEditingSupport(tableViewer, + dbc, "predicate", getBControl().getVisualization(), + getShell())); + + column = new TableViewerColumn(tableViewer, SWT.NONE); + column.getColumn().setText("Random Ops"); + column.getColumn().setWidth(100); + column.setEditingSupport(new RandomModeEditingSupport(tableViewer)); + + ObservableListContentProvider contentProvider = new ObservableListContentProvider(); + tableViewer.setContentProvider(contentProvider); + + tableViewer.setLabelProvider(new ObservableMapLabelProvider( + BeansObservables.observeMaps( + contentProvider.getKnownElements(), new String[] { + "executePredicate", "operationName", + "predicate", "maxrandom" }))); + final WritableList input = new WritableList( + ((ExecuteOperationByPredicateMulti) getScheduler()) + .getOperationList(), + PredicateOperation.class); + tableViewer.setInput(input); + + Composite comp = new Composite(container, SWT.NONE); + comp.setLayout(new RowLayout()); + comp.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END)); + + Button btRemove = new Button(comp, SWT.PUSH); + btRemove.setText("Remove"); + btRemove.setImage(BMotionStudioImage + .getImage(EditorImageRegistry.IMG_ICON_DELETE)); + btRemove.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (tableViewer.getSelection().isEmpty()) { + return; + } + PredicateOperation obj = (PredicateOperation) ((IStructuredSelection) tableViewer + .getSelection()).getFirstElement(); + input.remove(obj); + } + }); + + Button btAdd = new Button(comp, SWT.PUSH); + btAdd.setText("Add"); + btAdd.setImage(BMotionStudioImage + .getImage(EditorImageRegistry.IMG_ICON_ADD)); + btAdd.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + PredicateOperation obj = new PredicateOperation(); + input.add(obj); + } + }); + + } + } + + public WizardExecuteOperationByPredicateMulti(BControl bcontrol, + SchedulerEvent scheduler) { + super(bcontrol, scheduler); + addPage(new MultiPage("MultiPage")); + } + + /* + * (non-Javadoc) + * + * @see + * de.bmotionstudio.gef.editor.scheduler.SchedulerWizard#prepareToFinish() + */ + @Override + protected Boolean prepareToFinish() { + if (((ExecuteOperationByPredicateMulti) getScheduler()) + .getOperationList().size() == 0) { + setEventDelete(true); + } else { + for (BindingObject obj : ((ExecuteOperationByPredicateMulti) getScheduler()) + .getOperationList()) { + if (((PredicateOperation) obj).getOperationName() == null + || ((PredicateOperation) obj).getOperationName() + .isEmpty()) { + MessageDialog + .openError(getShell(), "Please check your entries", + "Please check your entries. The operation field must not be empty."); + return false; + } + } + } + return true; + } + + /* + * (non-Javadoc) + * + * @see de.bmotionstudio.gef.editor.scheduler.SchedulerWizard#getSize() + */ + @Override + public Point getSize() { + return new Point(700, 500); + } + + private static class RandomModeEditingSupport extends EditingSupport { + + private CellEditor cellEditor; + + public RandomModeEditingSupport(ColumnViewer viewer) { + super(viewer); + } + + @Override + protected void setValue(Object element, Object value) { + if (value != null) { + Integer maxnr = Integer.valueOf(value.toString()); + PredicateOperation obj = (PredicateOperation) element; + obj.setMaxrandom(maxnr); + if (maxnr > 1) + obj.setRandom(true); + else + obj.setRandom(false); + } + } + + @Override + protected Object getValue(Object element) { + return ((PredicateOperation) element).getMaxrandom(); + } + + @Override + protected CellEditor getCellEditor(Object element) { + if (cellEditor == null) { + cellEditor = new IntegerCellEditor((Composite) getViewer() + .getControl()); + } + return cellEditor; + } + + @Override + protected boolean canEdit(Object element) { + return true; + } + + } + + private static class OperationValueEditing extends EditingSupport { + + private ComboBoxViewerCellEditor cellEditor = null; + + private final BControl control; + + public OperationValueEditing(final TableViewer cv, + final BControl control) { + super(cv); + this.control = control; + } + + @Override + protected boolean canEdit(final Object element) { + return true; + } + + @Override + protected Object getValue(final Object element) { + return ((PredicateOperation) element).getOperationName(); + } + + @Override + protected void setValue(final Object element, final Object value) { + if (value != null) { + ((PredicateOperation) element).setOperationName(value + .toString()); + } + } + + @Override + protected CellEditor getCellEditor(final Object element) { + if (cellEditor == null) { + cellEditor = new ComboBoxViewerCellEditor( + (Composite) getViewer().getControl(), SWT.READ_ONLY); + cellEditor + .setContentProvider(new ObservableListContentProvider()); + cellEditor.setInput(new ComputedList() { + @Override + protected List<String> calculate() { + ArrayList<String> tmpList = new ArrayList<String>(); + for (MachineContentObject op : EventBHelper + .getOperations(control.getVisualization())) { + tmpList.add(((MachineOperation) op).getLabel()); + } + return tmpList; + } + }); + } + return cellEditor; + } + } + + // private class ObserverLabelProvider extends ObservableMapLabelProvider + // implements ITableLabelProvider, ITableColorProvider, + // ITableFontProvider { + // + // public ObserverLabelProvider(final IObservableMap[] attributeMaps) { + // super(attributeMaps); + // } + // + // @Override + // public Image getColumnImage(final Object element, final int columnIndex) + // { + // if (columnIndex == 3) { + // return CheckboxCellEditorHelper + // .getCellEditorImage(((PredicateOperation) element) + // .isRandom()); + // } + // return null; + // } + // + // @Override + // public String getColumnText(final Object element, final int columnIndex) + // { + // + // if (columnIndex == 3) + // return ""; + // + // return super.getColumnText(element, columnIndex); + // + // } + // + // public Color getBackground(final Object element, final int column) { + // return null; + // } + // + // public Color getForeground(final Object element, final int column) { + // return null; + // } + // + // public Font getFont(final Object element, final int column) { + // return null; + // } + // + // } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/wizard/WizardSchedulerExecuteOperationByPredicate.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/wizard/WizardSchedulerExecuteOperationByPredicate.java new file mode 100644 index 0000000000000000000000000000000000000000..c1bc11d03e21e65717db4536a2dc3c0b29f9a846 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/wizard/WizardSchedulerExecuteOperationByPredicate.java @@ -0,0 +1,323 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.scheduler.wizard; + +import org.eclipse.core.databinding.DataBindingContext; +import org.eclipse.core.databinding.beans.BeansObservables; +import org.eclipse.core.databinding.observable.list.WritableList; +import org.eclipse.core.databinding.observable.map.IObservableMap; +import org.eclipse.core.databinding.observable.value.IObservableValue; +import org.eclipse.core.databinding.observable.value.IValueChangeListener; +import org.eclipse.core.databinding.observable.value.ValueChangeEvent; +import org.eclipse.jface.databinding.swt.SWTObservables; +import org.eclipse.jface.databinding.viewers.ObservableListContentProvider; +import org.eclipse.jface.databinding.viewers.ObservableMapLabelProvider; +import org.eclipse.jface.databinding.viewers.ViewersObservables; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.ComboViewer; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.events.VerifyEvent; +import org.eclipse.swt.events.VerifyListener; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; + +import de.bmotionstudio.gef.editor.eventb.EventBHelper; +import de.bmotionstudio.gef.editor.eventb.MachineContentObject; +import de.bmotionstudio.gef.editor.eventb.MachineOperation; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.scheduler.ExecuteOperationByPredicate; +import de.bmotionstudio.gef.editor.scheduler.SchedulerEvent; +import de.bmotionstudio.gef.editor.scheduler.SchedulerWizard; + +public class WizardSchedulerExecuteOperationByPredicate extends SchedulerWizard { + + private class SchedulerExecuteOperationByPredicatePage extends WizardPage { + + private ComboViewer cbOperation; + + private Text txtPredicate; + + private Text txtMaxRandomOperations; + + private Label lbMaxRandomOperations; + + private Composite container; + + private Composite guardContainer; + + private Button checkboxRandomMode; + + public ComboViewer getCbOperation() { + return cbOperation; + } + + public Text getTxtMaxRandomOperations() { + return txtMaxRandomOperations; + } + + protected SchedulerExecuteOperationByPredicatePage(String pageName) { + super(pageName); + } + + public void createControl(final Composite parent) { + + final DataBindingContext dbc = new DataBindingContext(); + + container = new Composite(parent, SWT.NONE); + GridLayout gl = new GridLayout(2, false); + container.setLayout(gl); + + Label lb = new Label(container, SWT.NONE); + lb.setText("Select an operation: "); + + GridData gd = new GridData(GridData.FILL_HORIZONTAL); + gd.heightHint = 50; + + cbOperation = new ComboViewer(container, SWT.NONE); + cbOperation.getCombo().setLayoutData(new GridData(300, 50)); + + lb = new Label(container, SWT.NONE); + lb.setText("Predicate: "); + lb.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING)); + txtPredicate = new Text(container, SWT.BORDER | SWT.WRAP + | SWT.V_SCROLL); + txtPredicate.setLayoutData(gd); + + lb = new Label(container, SWT.NONE); + lb.setText("Random mode: "); + lb.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING)); + checkboxRandomMode = new Button(container, SWT.CHECK); + checkboxRandomMode.addSelectionListener(new SelectionListener() { + @Override + public void widgetSelected(SelectionEvent e) { + setRandomVisibility(checkboxRandomMode.getSelection()); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + } + }); + + lbMaxRandomOperations = new Label(container, SWT.NONE); + lbMaxRandomOperations.setText("Max Random Operations: "); + lbMaxRandomOperations.setLayoutData(new GridData( + GridData.VERTICAL_ALIGN_BEGINNING)); + txtMaxRandomOperations = new Text(container, SWT.BORDER); + txtMaxRandomOperations.setLayoutData(new GridData( + GridData.FILL_HORIZONTAL)); + txtMaxRandomOperations.addVerifyListener(new VerifyListener() { + @Override + public void verifyText(VerifyEvent e) { + String string = e.text; + char[] chars = new char[string.length()]; + string.getChars(0, chars.length, chars, 0); + for (int i = 0; i < chars.length; i++) { + if (!('0' <= chars[i] && chars[i] <= '9')) { + e.doit = false; + return; + } + } + } + }); + setRandomVisibility(((ExecuteOperationByPredicate) getScheduler()) + .getPredicateOperation().isRandom()); + + initBindings(dbc); + + IStructuredSelection structuredSelection = (IStructuredSelection) cbOperation + .getSelection(); + + if (!structuredSelection.isEmpty()) { + createGuardContainer((MachineOperation) structuredSelection + .getFirstElement()); + } + + setControl(container); + + } + + private void setRandomVisibility(boolean b) { + if (lbMaxRandomOperations == null || txtMaxRandomOperations == null) + return; + lbMaxRandomOperations.setVisible(b); + txtMaxRandomOperations.setVisible(b); + } + + private void initBindings(DataBindingContext dbc) { + + // MachineContentList operationList = BMotionEditorPlugin + // .getActiveEditor().getVisualization().getOperationList(); + // operationList.getMap().remove("INITIALISATION"); + + ObservableListContentProvider cbOpContentProvider = new ObservableListContentProvider(); + cbOperation.setContentProvider(cbOpContentProvider); + IObservableMap[] attributeMaps = BeansObservables.observeMaps( + cbOpContentProvider.getKnownElements(), + MachineContentObject.class, new String[] { "label" }); + cbOperation.setLabelProvider(new ObservableMapLabelProvider( + attributeMaps)); + cbOperation.setInput(new WritableList(EventBHelper + .getOperations(getBControl().getVisualization()), + MachineOperation.class)); + cbOperation.getCombo().setFont( + new Font(Display.getDefault(), new FontData("Arial", 10, + SWT.NONE))); + + final IObservableValue observeSelection = ViewersObservables + .observeSingleSelection(cbOperation); + + dbc.bindValue(SWTObservables.observeSelection(cbOperation + .getCombo()), BeansObservables.observeValue( + ((ExecuteOperationByPredicate) getScheduler()) + .getPredicateOperation(), "operationName"), null, + null); + + dbc.bindValue(SWTObservables.observeText(txtPredicate, SWT.Modify), + BeansObservables.observeValue( + ((ExecuteOperationByPredicate) getScheduler()) + .getPredicateOperation(), "predicate")); + + observeSelection.addValueChangeListener(new IValueChangeListener() { + public void handleValueChange(ValueChangeEvent event) { + Object sel = event.getObservableValue().getValue(); + createGuardContainer((MachineOperation) sel); + } + }); + + dbc.bindValue(SWTObservables.observeSelection(checkboxRandomMode), + BeansObservables.observeValue( + ((ExecuteOperationByPredicate) getScheduler()) + .getPredicateOperation(), "random")); + + dbc.bindValue(SWTObservables.observeText(txtMaxRandomOperations, + SWT.Modify), BeansObservables.observeValue( + ((ExecuteOperationByPredicate) getScheduler()) + .getPredicateOperation(), "maxrandom")); + + } + + private void createGuardContainer(MachineOperation op) { + + if (guardContainer != null) + guardContainer.dispose(); + + final StringBuilder allGuardString = new StringBuilder(); + + if (op != null) { + + GridData gd = new GridData(GridData.FILL_HORIZONTAL); + gd.horizontalSpan = 2; + + GridLayout gl = new GridLayout(2, false); + + guardContainer = new Composite(container, SWT.NONE); + guardContainer.setLayoutData(gd); + guardContainer.setLayout(gl); + + for (String guard : op.getGuards()) { + + if (allGuardString.length() == 0) + allGuardString.append(guard); + else + allGuardString.append(" & " + guard); + + Label lb = new Label(guardContainer, SWT.NONE); + lb.setText("Guard: "); + lb.setLayoutData(new GridData(100, 15)); + + final Text txt = new Text(guardContainer, SWT.BORDER + | SWT.READ_ONLY); + txt.setText(guard); + txt.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + // txt.setFont(JFaceResources.getFontRegistry().get( + // BMotionStudioConstants.RODIN_FONT_KEY)); + + } + + container.layout(); + + } + + } + + } + + public WizardSchedulerExecuteOperationByPredicate(BControl bcontrol, + SchedulerEvent scheduler) { + super(bcontrol, scheduler); + addPage(new SchedulerExecuteOperationByPredicatePage( + "SchedulerExecuteOperationByPredicatePage")); + } + + @Override + protected Boolean prepareToFinish() { + + SchedulerExecuteOperationByPredicatePage page = (SchedulerExecuteOperationByPredicatePage) getPage("SchedulerExecuteOperationByPredicatePage"); + + String errorStr = ""; + + if (((ExecuteOperationByPredicate) getScheduler()) + .getPredicateOperation().isRandom() + && !(Integer + .valueOf(page.getTxtMaxRandomOperations().getText()) > 0)) + errorStr += "Max Random Operations must be greater than 0.\n"; + + if (page.getCbOperation().getCombo().getSelectionIndex() == -1) + errorStr += "Please select an operation.\n"; + + if (errorStr.length() > 0) { + MessageDialog.openError(Display.getDefault().getActiveShell(), + "An Error occured", errorStr); + return false; + } + + // PredicateOperation predicateOperation = + // ((ExecuteOperationByPredicate) getScheduler()) + // .getPredicateOperation(); + // + // Observer observer = getBControl().getObserver( + // ListenOperationByPredicate.ID); + // ListenOperationByPredicate listenObserver; + // + // if (observer != null) { + // listenObserver = (ListenOperationByPredicate) observer; + // listenObserver + // .removePredicateOperationByUniqueID(predicateOperation + // .getUniqueID()); + // } else { + // listenObserver = new ListenOperationByPredicate(); + // getBControl().addObserver(listenObserver); + // } + // + // try { + // listenObserver.addPredicateOperation(predicateOperation.clone()); + // } catch (CloneNotSupportedException e) { + // e.printStackTrace(); + // } + + return true; + + } + + @Override + public Point getSize() { + return new Point(600, 600); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/service/BButtonService.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/service/BButtonService.java new file mode 100644 index 0000000000000000000000000000000000000000..e53c63a05dc0f372ca7e1194cdf167cf63de45eb --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/service/BButtonService.java @@ -0,0 +1,46 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.service; + +import de.bmotionstudio.gef.editor.AbstractBControlService; +import de.bmotionstudio.gef.editor.IBControlService; +import de.bmotionstudio.gef.editor.model.BButton; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.model.Visualization; +import de.bmotionstudio.gef.editor.part.AppAbstractEditPart; +import de.bmotionstudio.gef.editor.part.BButtonPart; + +/** + * @author Lukas Ladenberger + * + */ +public class BButtonService extends AbstractBControlService implements + IBControlService { + + /* + * (non-Javadoc) + * + * @see + * de.bmotionstudio.gef.editor.IBControlService#createControl(de.bmotionstudio + * .gef.editor.model.Visualization) + */ + @Override + public BControl createControl(Visualization visualization) { + return new BButton(visualization); + } + + /* + * (non-Javadoc) + * + * @see de.bmotionstudio.gef.editor.IBControlService#createEditPart() + */ + @Override + public AppAbstractEditPart createEditPart() { + return new BButtonPart(); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/service/BCheckboxService.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/service/BCheckboxService.java new file mode 100644 index 0000000000000000000000000000000000000000..7172275ab638423a14842f84b49ef5d6d0119822 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/service/BCheckboxService.java @@ -0,0 +1,46 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.service; + +import de.bmotionstudio.gef.editor.AbstractBControlService; +import de.bmotionstudio.gef.editor.IBControlService; +import de.bmotionstudio.gef.editor.model.BCheckbox; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.model.Visualization; +import de.bmotionstudio.gef.editor.part.AppAbstractEditPart; +import de.bmotionstudio.gef.editor.part.BCheckboxPart; + +/** + * @author Lukas Ladenberger + * + */ +public class BCheckboxService extends AbstractBControlService implements + IBControlService { + + /* + * (non-Javadoc) + * + * @see + * de.bmotionstudio.gef.editor.IBControlService#createControl(de.bmotionstudio + * .gef.editor.model.Visualization) + */ + @Override + public BControl createControl(Visualization visualization) { + return new BCheckbox(visualization); + } + + /* + * (non-Javadoc) + * + * @see de.bmotionstudio.gef.editor.IBControlService#createEditPart() + */ + @Override + public AppAbstractEditPart createEditPart() { + return new BCheckboxPart(); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/service/BCompositeService.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/service/BCompositeService.java new file mode 100644 index 0000000000000000000000000000000000000000..863246a333f93ee035c93db0d7b9a7d92b247f23 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/service/BCompositeService.java @@ -0,0 +1,46 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.service; + +import de.bmotionstudio.gef.editor.AbstractBControlService; +import de.bmotionstudio.gef.editor.IBControlService; +import de.bmotionstudio.gef.editor.model.BComposite; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.model.Visualization; +import de.bmotionstudio.gef.editor.part.AppAbstractEditPart; +import de.bmotionstudio.gef.editor.part.BCompositePart; + +/** + * @author Lukas Ladenberger + * + */ +public class BCompositeService extends AbstractBControlService implements + IBControlService { + + /* + * (non-Javadoc) + * + * @see + * de.bmotionstudio.gef.editor.IBControlService#createControl(de.bmotionstudio + * .gef.editor.model.Visualization) + */ + @Override + public BControl createControl(Visualization visualization) { + return new BComposite(visualization); + } + + /* + * (non-Javadoc) + * + * @see de.bmotionstudio.gef.editor.IBControlService#createEditPart() + */ + @Override + public AppAbstractEditPart createEditPart() { + return new BCompositePart(); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/service/BConnectionService.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/service/BConnectionService.java new file mode 100644 index 0000000000000000000000000000000000000000..f7637a477ae0ca73637f32d42bd9bdefbdc066c5 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/service/BConnectionService.java @@ -0,0 +1,59 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.service; + +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.gef.palette.ConnectionCreationToolEntry; +import org.eclipse.gef.palette.ToolEntry; +import org.eclipse.ui.plugin.AbstractUIPlugin; + +import de.bmotionstudio.gef.editor.AbstractBControlService; +import de.bmotionstudio.gef.editor.BControlCreationFactory; +import de.bmotionstudio.gef.editor.IBControlService; +import de.bmotionstudio.gef.editor.model.BConnection; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.model.Visualization; +import de.bmotionstudio.gef.editor.part.AppAbstractEditPart; +import de.bmotionstudio.gef.editor.part.BConnectionEditPart; + +/** + * @author Lukas Ladenberger + * + */ +public class BConnectionService extends AbstractBControlService implements + IBControlService { + + @Override + public ToolEntry createToolEntry(Visualization visualization, + IConfigurationElement configurationElement) { + String sourcePluginID = configurationElement.getContributor().getName(); + String name = configurationElement.getAttribute("name"); + String icon = configurationElement.getAttribute("icon"); + return new ConnectionCreationToolEntry(name, "Create Control " + name, + new BControlCreationFactory(BConnection.TYPE, visualization), + AbstractUIPlugin + .imageDescriptorFromPlugin(sourcePluginID, icon), + AbstractUIPlugin + .imageDescriptorFromPlugin(sourcePluginID, icon)); + } + + @Override + public BControl createControl(Visualization visualization) { + return new BConnection(visualization); + } + + @Override + public AppAbstractEditPart createEditPart() { + return new BConnectionEditPart(); + } + + @Override + public boolean showInPalette() { + return false; + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/service/BImageService.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/service/BImageService.java new file mode 100644 index 0000000000000000000000000000000000000000..22886fb67758dde65a147b9148d93b48e373301e --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/service/BImageService.java @@ -0,0 +1,46 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.service; + +import de.bmotionstudio.gef.editor.AbstractBControlService; +import de.bmotionstudio.gef.editor.IBControlService; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.model.BImage; +import de.bmotionstudio.gef.editor.model.Visualization; +import de.bmotionstudio.gef.editor.part.AppAbstractEditPart; +import de.bmotionstudio.gef.editor.part.BImagePart; + +/** + * @author Lukas Ladenberger + * + */ +public class BImageService extends AbstractBControlService implements + IBControlService { + + /* + * (non-Javadoc) + * + * @see + * de.bmotionstudio.gef.editor.IBControlService#createControl(de.bmotionstudio + * .gef.editor.model.Visualization) + */ + @Override + public BControl createControl(Visualization visualization) { + return new BImage(visualization); + } + + /* + * (non-Javadoc) + * + * @see de.bmotionstudio.gef.editor.IBControlService#createEditPart() + */ + @Override + public AppAbstractEditPart createEditPart() { + return new BImagePart(); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/service/BRadioButtonService.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/service/BRadioButtonService.java new file mode 100644 index 0000000000000000000000000000000000000000..58d463b8fe2b51f4902841013c619dab5a90e754 --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/service/BRadioButtonService.java @@ -0,0 +1,45 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.service; + +import de.bmotionstudio.gef.editor.AbstractBControlService; +import de.bmotionstudio.gef.editor.IBControlService; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.model.BRadioButton; +import de.bmotionstudio.gef.editor.model.Visualization; +import de.bmotionstudio.gef.editor.part.AppAbstractEditPart; +import de.bmotionstudio.gef.editor.part.BRadioButtonPart; + +/** + * @author Lukas Ladenberger + * + */ +public class BRadioButtonService extends AbstractBControlService implements + IBControlService { + + /* + * (non-Javadoc) + * + * @see + * de.bmotionstudio.gef.editor.IBControlService#createControl(de.bmotionstudio + * .gef.editor.model.Visualization) + */ + @Override + public BControl createControl(Visualization visualization) { + return new BRadioButton(visualization); + } + + /* + * (non-Javadoc) + * + * @see de.bmotionstudio.gef.editor.IBControlService#createEditPart() + */ + @Override + public AppAbstractEditPart createEditPart() { + return new BRadioButtonPart(); + } +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/service/BShapeService.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/service/BShapeService.java new file mode 100644 index 0000000000000000000000000000000000000000..c8951fbd8a55a24b89d34014ec331e7206fc44eb --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/service/BShapeService.java @@ -0,0 +1,46 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.service; + +import de.bmotionstudio.gef.editor.AbstractBControlService; +import de.bmotionstudio.gef.editor.IBControlService; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.model.BShape; +import de.bmotionstudio.gef.editor.model.Visualization; +import de.bmotionstudio.gef.editor.part.AppAbstractEditPart; +import de.bmotionstudio.gef.editor.part.BShapePart; + +/** + * @author Lukas Ladenberger + * + */ +public class BShapeService extends AbstractBControlService implements + IBControlService { + + /* + * (non-Javadoc) + * + * @see + * de.bmotionstudio.gef.editor.IBControlService#createControl(de.bmotionstudio + * .gef.editor.model.Visualization) + */ + @Override + public BControl createControl(Visualization visualization) { + return new BShape(visualization); + } + + /* + * (non-Javadoc) + * + * @see de.bmotionstudio.gef.editor.IBControlService#createEditPart() + */ + @Override + public AppAbstractEditPart createEditPart() { + return new BShapePart(); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/service/BTextService.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/service/BTextService.java new file mode 100644 index 0000000000000000000000000000000000000000..4eb9bc34fedd686cb9f948559c1f141fe7c5bd7e --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/service/BTextService.java @@ -0,0 +1,46 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.service; + +import de.bmotionstudio.gef.editor.AbstractBControlService; +import de.bmotionstudio.gef.editor.IBControlService; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.model.BText; +import de.bmotionstudio.gef.editor.model.Visualization; +import de.bmotionstudio.gef.editor.part.AppAbstractEditPart; +import de.bmotionstudio.gef.editor.part.BTextPart; + +/** + * @author Lukas Ladenberger + * + */ +public class BTextService extends AbstractBControlService implements + IBControlService { + + /* + * (non-Javadoc) + * + * @see + * de.bmotionstudio.gef.editor.IBControlService#createControl(de.bmotionstudio + * .gef.editor.model.Visualization) + */ + @Override + public BControl createControl(Visualization visualization) { + return new BText(visualization); + } + + /* + * (non-Javadoc) + * + * @see de.bmotionstudio.gef.editor.IBControlService#createEditPart() + */ + @Override + public AppAbstractEditPart createEditPart() { + return new BTextPart(); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/service/BTextfieldService.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/service/BTextfieldService.java new file mode 100644 index 0000000000000000000000000000000000000000..1512b76a57cb7d9c82cad81d94f02cf59964597f --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/service/BTextfieldService.java @@ -0,0 +1,46 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.service; + +import de.bmotionstudio.gef.editor.AbstractBControlService; +import de.bmotionstudio.gef.editor.IBControlService; +import de.bmotionstudio.gef.editor.model.BControl; +import de.bmotionstudio.gef.editor.model.BTextfield; +import de.bmotionstudio.gef.editor.model.Visualization; +import de.bmotionstudio.gef.editor.part.AppAbstractEditPart; +import de.bmotionstudio.gef.editor.part.BTextfieldPart; + +/** + * @author Lukas Ladenberger + * + */ +public class BTextfieldService extends AbstractBControlService implements + IBControlService { + + /* + * (non-Javadoc) + * + * @see + * de.bmotionstudio.gef.editor.IBControlService#createControl(de.bmotionstudio + * .gef.editor.model.Visualization) + */ + @Override + public BControl createControl(Visualization visualization) { + return new BTextfield(visualization); + } + + /* + * (non-Javadoc) + * + * @see de.bmotionstudio.gef.editor.IBControlService#createEditPart() + */ + @Override + public AppAbstractEditPart createEditPart() { + return new BTextfieldPart(); + } + +} diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/util/FileUtil.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/util/FileUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..f0087ca90117a51b178e895aaa5446e0d0ab8faf --- /dev/null +++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/util/FileUtil.java @@ -0,0 +1,45 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.gef.editor.util; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; + +public class FileUtil { + + /** Fast & simple file copy. */ + public static void copyFile(File source, File dest) throws IOException { + FileChannel in = null, out = null; + try { + in = new FileInputStream(source).getChannel(); + out = new FileOutputStream(dest).getChannel(); + + long size = in.size(); + MappedByteBuffer buf = in.map(FileChannel.MapMode.READ_ONLY, 0, + size); + + out.write(buf); + } finally { + if (in != null) + in.close(); + if (out != null) + out.close(); + } + } + + public static void deleteFile(File f) { + // Attempt to delete it + boolean success = f.delete(); + if (!success) + throw new IllegalArgumentException("Delete: deletion failed"); + } + +} diff --git a/de.bmotionstudio.rodin/.classpath b/de.bmotionstudio.rodin/.classpath new file mode 100644 index 0000000000000000000000000000000000000000..8a8f1668cdcc5c73a6921162616f01cb556ae7c1 --- /dev/null +++ b/de.bmotionstudio.rodin/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="src" path="src"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/de.bmotionstudio.rodin/.project b/de.bmotionstudio.rodin/.project new file mode 100644 index 0000000000000000000000000000000000000000..8d9f97eff9f9c8ec6a6f9557facc69527e870a19 --- /dev/null +++ b/de.bmotionstudio.rodin/.project @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>de.bmotionstudio.rodin</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/de.bmotionstudio.rodin/META-INF/MANIFEST.MF b/de.bmotionstudio.rodin/META-INF/MANIFEST.MF new file mode 100644 index 0000000000000000000000000000000000000000..14949a23660999f20d5c9384fbb9eb1176c3de9b --- /dev/null +++ b/de.bmotionstudio.rodin/META-INF/MANIFEST.MF @@ -0,0 +1,9 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: BMotion Studio Rodin Integration +Bundle-SymbolicName: de.bmotionstudio.rodin;singleton:=true +Bundle-Version: 1.0.0 +Fragment-Host: de.bmotionstudio.gef.editor;bundle-version="5.2.0" +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Bundle-Vendor: HHU Düsseldorf STUPS Group +Require-Bundle: org.eclipse.ui.navigator;bundle-version="3.5.100" diff --git a/de.bmotionstudio.rodin/build.properties b/de.bmotionstudio.rodin/build.properties new file mode 100644 index 0000000000000000000000000000000000000000..ca10431f8565d50920a8cb18203594ffd27a7a99 --- /dev/null +++ b/de.bmotionstudio.rodin/build.properties @@ -0,0 +1,6 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + fragment.xml,\ + icons/ diff --git a/de.bmotionstudio.rodin/fragment.xml b/de.bmotionstudio.rodin/fragment.xml new file mode 100644 index 0000000000000000000000000000000000000000..5fb8856c321fcf6aced0f36b205ed0ad51bf3536 --- /dev/null +++ b/de.bmotionstudio.rodin/fragment.xml @@ -0,0 +1,152 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?eclipse version="3.4"?> +<fragment> + <extension + point="org.eclipse.ui.perspectives"> + <perspective + class="de.bmotionstudio.rodin.PerspectiveEditFactory" + icon="icons/logo_bmotion.png" + id="de.bmotionstudio.perspective.edit" + name="BMS Edit"> + </perspective> + <perspective + class="de.bmotionstudio.rodin.PerspectiveRunFactory" + icon="icons/icon_run.png" + id="de.bmotionstudio.perspective.run" + name="BMS Run"> + </perspective> + </extension> + <extension + point="org.eclipse.ui.menus"> + <menuContribution + locationURI="popup:fr.systerel.explorer.navigator.view"> + <command + commandId="de.bmotionstudio.rodin.command.startVisualization" + icon="icons/icon_run.png" + label="Start Visualization" + style="push"> + <visibleWhen> + <with + variable="selection"> + <iterate + operator="or"> + <instanceof + value="de.bmotionstudio.rodin.IBMotionSurfaceRoot"> + </instanceof> + </iterate> + </with> + </visibleWhen> + </command> + <command + commandId="de.bmotionstudio.rodin.command.renameVisualization" + label="Rename" + style="push"> + <visibleWhen> + <with + variable="selection"> + <iterate + operator="or"> + <instanceof + value="de.bmotionstudio.rodin.IBMotionSurfaceRoot"> + </instanceof> + </iterate> + </with> + </visibleWhen> + </command> + </menuContribution> + </extension> + <extension + point="org.eclipse.ui.commands"> + <command + defaultHandler="de.bmotionstudio.rodin.StartEventBVisualizationHandler" + id="de.bmotionstudio.rodin.command.startVisualization" + name="Start Visualization"> + </command> + <command + defaultHandler="de.bmotionstudio.rodin.RenameFileHandler" + id="de.bmotionstudio.rodin.command.renameVisualization" + name="Rename"> + </command> + </extension> + <extension + point="org.rodinp.core.fileAssociations"> + <fileAssociation + content-type-id="de.bmotionstudio.gef.editor.BMotionStudioFile" + root-element-type="de.bmotionstudio.gef.editor.BMotionStudioFile"> + </fileAssociation> + </extension> + <extension + point="org.eclipse.core.contenttype.contentTypes"> + <content-type + base-type="org.rodinp.core.rodin" + file-extensions="bmso" + id="BMotionStudioFile" + name="BMotion Studio Surface File" + priority="normal"> + </content-type> + <file-association + content-type="de.bmotionstudio.gef.editor.BMotionStudioFile" + file-extensions="bmso"> + </file-association> + </extension> + <extension + point="org.eclipse.ui.navigator.navigatorContent"> + <navigatorContent + contentProvider="de.bmotionstudio.rodin.BMotionStudioContentProvider" + id="de.bmotionstudio.ui.navigatorContent" + labelProvider="de.bmotionstudio.rodin.BMotionLabelProvider" + name="BMotion Studio Navigator Content" + priority="normal"> + <triggerPoints> + <instanceof + value="org.eclipse.core.resources.IProject"> + </instanceof> + </triggerPoints> + <possibleChildren> + <instanceof + value="de.bmotionstudio.rodin.IBMotionSurfaceRoot"> + </instanceof> + </possibleChildren> + <actionProvider + class="de.bmotionstudio.rodin.BMotionStudioActionProvider" + id="de.bmotionstudio.ui.navigatorAction" + priority="normal"> + <enablement> + <instanceof + value="de.bmotionstudio.rodin.IBMotionSurfaceRoot"> + </instanceof> + </enablement> + </actionProvider> + </navigatorContent> + </extension> + <extension + point="org.eclipse.ui.navigator.viewer"> + <viewerContentBinding + viewerId="fr.systerel.explorer.navigator.view"> + <includes> + <contentExtension + pattern="de.bmotionstudio.ui.navigatorContent"> + </contentExtension> + </includes> + </viewerContentBinding> + <viewerActionBinding + viewerId="fr.systerel.explorer.navigator.view"> + <includes> + <actionExtension + pattern="de.bmotionstudio.ui.navigatorAction"> + </actionExtension> + </includes> + </viewerActionBinding> + </extension> + <extension + point="org.rodinp.core.internalElementTypes"> + <internalElementType + class="de.bmotionstudio.rodin.BMotionSurfaceRoot" + id="BMotionStudioFile" + name="BMotion Studio Surface File"> + </internalElementType> + </extension> + + + +</fragment> diff --git a/de.bmotionstudio.rodin/icons/icon_run.png b/de.bmotionstudio.rodin/icons/icon_run.png new file mode 100644 index 0000000000000000000000000000000000000000..f5808d2dfd5b042b5584ce1c81aa40835ebc8055 Binary files /dev/null and b/de.bmotionstudio.rodin/icons/icon_run.png differ diff --git a/de.bmotionstudio.rodin/icons/logo_bmotion.png b/de.bmotionstudio.rodin/icons/logo_bmotion.png new file mode 100644 index 0000000000000000000000000000000000000000..2bcb148a75ce4d1f5d9257033306b5b12b5d295d Binary files /dev/null and b/de.bmotionstudio.rodin/icons/logo_bmotion.png differ diff --git a/de.bmotionstudio.rodin/src/de/bmotionstudio/rodin/ActionCollection.java b/de.bmotionstudio.rodin/src/de/bmotionstudio/rodin/ActionCollection.java new file mode 100644 index 0000000000000000000000000000000000000000..9ac7a03b70f8ee9a69be3d884193ec0fc255812f --- /dev/null +++ b/de.bmotionstudio.rodin/src/de/bmotionstudio/rodin/ActionCollection.java @@ -0,0 +1,185 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.rodin; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.*; +import org.eclipse.ui.navigator.ICommonActionExtensionSite; +import org.eclipse.ui.part.FileEditorInput; +import org.rodinp.core.IRodinElement; +import org.rodinp.core.IRodinFile; +import org.rodinp.core.RodinDBException; + +import de.bmotionstudio.gef.editor.BMotionEditorPlugin; +import de.bmotionstudio.gef.editor.BMotionStudioImage; + +public class ActionCollection { + + /** + * Provides an open action for the BMotion Studio Editor Project File + * + * @param site + * @return An open action + */ + public static Action getOpenAction(final ICommonActionExtensionSite site) { + + final Action doubleClickAction = new Action("Open") { + @Override + public void run() { + + IRodinFile component; + + final ISelection selection = site.getStructuredViewer() + .getSelection(); + final Object obj = ((IStructuredSelection) selection) + .getFirstElement(); + + if (obj instanceof IBMotionSurfaceRoot) { + + component = (IRodinFile) ((IRodinElement) obj) + .getOpenable(); + + if (component == null) { + return; + } + + try { + + final IEditorDescriptor desc = PlatformUI + .getWorkbench().getEditorRegistry() + .getDefaultEditor( + component.getCorrespondingResource() + .getName()); + + BMotionEditorPlugin.getActivePage().openEditor( + new FileEditorInput(component.getResource()), + desc.getId()); + + // editor.getSite().getSelectionProvider().setSelection( + // new StructuredSelection(obj)); + + } catch (final PartInitException e) { + final String errorMsg = "Error open Editor"; + MessageDialog.openError(null, null, errorMsg); + BMotionEditorPlugin.getDefault().getLog().log( + new Status(IStatus.ERROR, + BMotionEditorPlugin.PLUGIN_ID, + errorMsg, e)); + } + + } + + } + }; + return doubleClickAction; + + } + + /** + * + * @param site + * @return An action for deleting bmotion studio project files + */ + public static Action getDeleteAction(final ICommonActionExtensionSite site) { + Action deleteAction = new Action() { + @Override + public void run() { + if (!(site.getStructuredViewer().getSelection().isEmpty())) { + + Collection<IRodinElement> set = new ArrayList<IRodinElement>(); + + IStructuredSelection ssel = (IStructuredSelection) site + .getStructuredViewer().getSelection(); + + for (Iterator<?> it = ssel.iterator(); it.hasNext();) { + final Object obj = it.next(); + if (!(obj instanceof IBMotionSurfaceRoot)) { + continue; + } + IRodinElement elem = (IRodinElement) obj; + if (elem.isRoot()) { + elem = elem.getParent(); + } + set.add(elem); + } + + int answer = YesToAllMessageDialog.YES; + for (IRodinElement element : set) { + if (element instanceof IRodinFile) { + if (answer != YesToAllMessageDialog.YES_TO_ALL) { + answer = YesToAllMessageDialog + .openYesNoToAllQuestion( + site.getViewSite().getShell(), + "Confirm File Delete", + "Are you sure you want to delete file '" + + ((IRodinFile) element) + .getElementName() + + "' in project '" + + element + .getParent() + .getElementName() + + "' ?"); + } + + if (answer == YesToAllMessageDialog.NO_TO_ALL + || answer == YesToAllMessageDialog.CANCEL) + break; + + if (answer != YesToAllMessageDialog.NO) { + try { + closeOpenedEditor((IRodinFile) element); + ((IRodinFile) element).delete(true, + new NullProgressMonitor()); + } catch (PartInitException e) { + MessageDialog.openError(null, "Error", + "Could not delete file"); + } catch (RodinDBException e) { + MessageDialog.openError(null, "Error", + "Could not delete file"); + } + } + } + } + + } + } + }; + deleteAction.setText("&Delete"); + deleteAction.setToolTipText("Delete these elements"); + deleteAction.setImageDescriptor(BMotionStudioImage.getImageDescriptor( + "org.eclipse.ui", "$nl$/icons/full/etool16/delete_edit.gif")); + + return deleteAction; + } + + static void closeOpenedEditor(IRodinFile file) throws PartInitException { + IEditorReference[] editorReferences = BMotionEditorPlugin + .getActivePage().getEditorReferences(); + for (int j = 0; j < editorReferences.length; j++) { + IFile inputFile = (IFile) editorReferences[j].getEditorInput() + .getAdapter(IFile.class); + + if (file.getResource().equals(inputFile)) { + IEditorPart editor = editorReferences[j].getEditor(true); + IWorkbenchPage page = BMotionEditorPlugin.getActivePage(); + page.closeEditor(editor, false); + } + } + } + +} diff --git a/de.bmotionstudio.rodin/src/de/bmotionstudio/rodin/BMotionLabelProvider.java b/de.bmotionstudio.rodin/src/de/bmotionstudio/rodin/BMotionLabelProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..75c5a1606ec22b546ddd3615de307ef9f7f40c90 --- /dev/null +++ b/de.bmotionstudio.rodin/src/de/bmotionstudio/rodin/BMotionLabelProvider.java @@ -0,0 +1,50 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.rodin; + +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.swt.graphics.Image; +import org.rodinp.core.IInternalElement; +import org.rodinp.core.IRodinFile; + +import de.bmotionstudio.gef.editor.BMotionStudioImage; + +public class BMotionLabelProvider implements ILabelProvider { + + public Image getImage(final Object element) { + return BMotionStudioImage.getImage(BMotionStudioImage.IMG_LOGO_BMOTION); + } + + public String getText(final Object element) { + + if (element instanceof IRodinFile) { + return ((IRodinFile) element).getBareName(); + } else if (element instanceof IInternalElement) { + return ((IInternalElement) element).getRodinFile().getBareName(); + } + return null; + + } + + public void addListener(final ILabelProviderListener listener) { + + } + + public void dispose() { + + } + + public boolean isLabelProperty(final Object element, final String property) { + return false; + } + + public void removeListener(final ILabelProviderListener listener) { + + } + +} diff --git a/de.bmotionstudio.rodin/src/de/bmotionstudio/rodin/BMotionStudioActionProvider.java b/de.bmotionstudio.rodin/src/de/bmotionstudio/rodin/BMotionStudioActionProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..9492e7ac1b2e2861db0646a575546da1a565be1d --- /dev/null +++ b/de.bmotionstudio.rodin/src/de/bmotionstudio/rodin/BMotionStudioActionProvider.java @@ -0,0 +1,70 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.rodin; + +import org.eclipse.jface.action.GroupMarker; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.actions.ActionFactory; +import org.eclipse.ui.actions.OpenWithMenu; +import org.eclipse.ui.navigator.CommonActionProvider; +import org.eclipse.ui.navigator.ICommonActionConstants; +import org.eclipse.ui.navigator.ICommonActionExtensionSite; +import org.eclipse.ui.navigator.ICommonMenuConstants; + +import de.bmotionstudio.gef.editor.BMotionEditorPlugin; + +public class BMotionStudioActionProvider extends CommonActionProvider { + + public static String GROUP_FILEACTIONS = "fileactionsGroup"; + + // StructuredViewer viewer; + + ICommonActionExtensionSite site; + + @Override + public void init(final ICommonActionExtensionSite aSite) { + super.init(aSite); + site = aSite; + // viewer = aSite.getStructuredViewer(); + } + + @Override + public void fillActionBars(final IActionBars actionBars) { + super.fillActionBars(actionBars); + actionBars.setGlobalActionHandler(ICommonActionConstants.OPEN, + ActionCollection.getOpenAction(site)); + actionBars.setGlobalActionHandler(ActionFactory.DELETE.getId(), + ActionCollection.getDeleteAction(site)); + } + + @Override + public void fillContextMenu(IMenuManager menu) { + super.fillContextMenu(menu); + menu.add(new GroupMarker(GROUP_FILEACTIONS)); + menu.appendToGroup(ICommonMenuConstants.GROUP_OPEN, ActionCollection + .getOpenAction(site)); + menu.appendToGroup(ICommonMenuConstants.GROUP_OPEN_WITH, + buildOpenWithMenu()); + menu.appendToGroup(GROUP_FILEACTIONS, ActionCollection + .getDeleteAction(site)); + } + + MenuManager buildOpenWithMenu() { + MenuManager menu = new MenuManager("Open With", + ICommonMenuConstants.GROUP_OPEN_WITH); + ISelection selection = site.getStructuredViewer().getSelection(); + Object obj = ((IStructuredSelection) selection).getFirstElement(); + menu.add(new OpenWithMenu(BMotionEditorPlugin.getActivePage(), + ((IBMotionSurfaceRoot) obj).getRodinFile().getResource())); + return menu; + } + +} diff --git a/de.bmotionstudio.rodin/src/de/bmotionstudio/rodin/BMotionStudioContentProvider.java b/de.bmotionstudio.rodin/src/de/bmotionstudio/rodin/BMotionStudioContentProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..c00e4a4e928dbc393c5b4f55ba3dcd395b56fd14 --- /dev/null +++ b/de.bmotionstudio.rodin/src/de/bmotionstudio/rodin/BMotionStudioContentProvider.java @@ -0,0 +1,67 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.rodin; + +import org.eclipse.core.resources.IProject; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; +import org.rodinp.core.IRodinProject; +import org.rodinp.core.RodinCore; +import org.rodinp.core.RodinDBException; + + +public class BMotionStudioContentProvider implements ITreeContentProvider { + + public Object[] getChildren(final Object parentElement) { + + if (parentElement instanceof IProject) { + + final IProject project = (IProject) parentElement; + + // if it is a RodinProject return the IRodinProject from the DB. + final IRodinProject proj = RodinCore.valueOf(project); + if (proj.exists()) { + + try { + return proj + .getRootElementsOfType(IBMotionSurfaceRoot.ELEMENT_TYPE); + } catch (final RodinDBException e) { + e.printStackTrace(); + } + + } + + } + + return new Object[0]; + + } + + public Object getParent(final Object element) { + // do nothing + return null; + } + + public boolean hasChildren(final Object element) { + return false; + } + + public Object[] getElements(final Object inputElement) { + return getChildren(inputElement); + } + + public void dispose() { + // do nothing + + } + + public void inputChanged(final Viewer viewer, final Object oldInput, + final Object newInput) { + // do nothing + } + +} diff --git a/de.bmotionstudio.rodin/src/de/bmotionstudio/rodin/BMotionSurfaceRoot.java b/de.bmotionstudio.rodin/src/de/bmotionstudio/rodin/BMotionSurfaceRoot.java new file mode 100644 index 0000000000000000000000000000000000000000..32710b10caf8a1c8d23b9e53f765be86e201328c --- /dev/null +++ b/de.bmotionstudio.rodin/src/de/bmotionstudio/rodin/BMotionSurfaceRoot.java @@ -0,0 +1,34 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.rodin; + +import org.rodinp.core.IInternalElementType; +import org.rodinp.core.IRodinElement; +import org.rodinp.core.RodinDBException; +import org.rodinp.core.basis.InternalElement; +import org.rodinp.core.basis.RodinElement; + + + +public class BMotionSurfaceRoot extends InternalElement implements + IBMotionSurfaceRoot { + + public BMotionSurfaceRoot(final String name, final IRodinElement parent) { + super(name, parent); + } + + @Override + public RodinElement[] getChildren() throws RodinDBException { + return NO_ELEMENTS; + } + + @Override + public IInternalElementType<IBMotionSurfaceRoot> getElementType() { + return ELEMENT_TYPE; + } + +} diff --git a/de.bmotionstudio.rodin/src/de/bmotionstudio/rodin/IBMotionSurfaceRoot.java b/de.bmotionstudio.rodin/src/de/bmotionstudio/rodin/IBMotionSurfaceRoot.java new file mode 100644 index 0000000000000000000000000000000000000000..5311a6aa7ee51802bc712e2031081f600555949d --- /dev/null +++ b/de.bmotionstudio.rodin/src/de/bmotionstudio/rodin/IBMotionSurfaceRoot.java @@ -0,0 +1,21 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.rodin; + +import org.rodinp.core.IInternalElement; +import org.rodinp.core.IInternalElementType; +import org.rodinp.core.RodinCore; + +import de.bmotionstudio.gef.editor.BMotionEditorPlugin; + +public interface IBMotionSurfaceRoot extends IInternalElement { + + IInternalElementType<IBMotionSurfaceRoot> ELEMENT_TYPE = RodinCore + .getInternalElementType(BMotionEditorPlugin.PLUGIN_ID + + ".BMotionStudioFile"); //$NON-NLS-1$ + +} diff --git a/de.bmotionstudio.rodin/src/de/bmotionstudio/rodin/PerspectiveEditFactory.java b/de.bmotionstudio.rodin/src/de/bmotionstudio/rodin/PerspectiveEditFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..35a2c477e1ef878b5d40b7a4c796cc53687ebc5c --- /dev/null +++ b/de.bmotionstudio.rodin/src/de/bmotionstudio/rodin/PerspectiveEditFactory.java @@ -0,0 +1,43 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.rodin; + +import org.eclipse.ui.IFolderLayout; +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.IPerspectiveFactory; + +import de.bmotionstudio.gef.editor.library.LibraryView; + +public class PerspectiveEditFactory implements IPerspectiveFactory { + + public void createInitialLayout(final IPageLayout layout) { + + final String editorArea = layout.getEditorArea(); + + // Place the project explorer to left of editor area. + final IFolderLayout left = layout.createFolder("left", + IPageLayout.LEFT, 0.15f, editorArea); + left.addView("fr.systerel.explorer.navigator.view"); + + // Place the outline to right of editor area. + final IFolderLayout righttop = layout.createFolder("right", + IPageLayout.RIGHT, 0.8f, editorArea); + righttop.addView(IPageLayout.ID_OUTLINE); + + // Library view + final IFolderLayout rightbot = layout.createFolder("rightb", + IPageLayout.BOTTOM, 0.6f, "right"); + rightbot.addView(LibraryView.ID); + + final IFolderLayout bottom = layout.createFolder("bottom", + IPageLayout.BOTTOM, 0.75f, editorArea); + // Properties view + bottom.addView(IPageLayout.ID_PROP_SHEET); + + } + +} diff --git a/de.bmotionstudio.rodin/src/de/bmotionstudio/rodin/PerspectiveRunFactory.java b/de.bmotionstudio.rodin/src/de/bmotionstudio/rodin/PerspectiveRunFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..820464bf827ac2e11024700ff5c2cce19c7c8468 --- /dev/null +++ b/de.bmotionstudio.rodin/src/de/bmotionstudio/rodin/PerspectiveRunFactory.java @@ -0,0 +1,43 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.rodin; + +import org.eclipse.ui.IFolderLayout; +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.IPerspectiveFactory; + +public class PerspectiveRunFactory implements IPerspectiveFactory { + + public void createInitialLayout(IPageLayout layout) { + + String editorArea = layout.getEditorArea(); + + // ProB Event View (Top-Left) + IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT, + 0.15f, editorArea); + left.addView("de.prob.ui.OperationView"); + + // Navigator + Rodin Problem View (Bottom-Left) + IFolderLayout leftb = layout.createFolder("leftb", IPageLayout.BOTTOM, + 0.6f, "left"); + leftb.addView("fr.systerel.explorer.navigator.view"); + // leftb.addView("org.eventb.ui.views.RodinProblemView"); + + // ProB State View (Right) + IFolderLayout right1 = layout.createFolder("right1", IPageLayout.RIGHT, + 0.7f, editorArea); + right1.addView("de.prob.ui.StateView"); + + // ProB History + ProB Event Error View (Right) + IFolderLayout right2 = layout.createFolder("right2", IPageLayout.RIGHT, + 0.6f, "right1"); + right2.addView("de.prob.ui.HistoryView"); + right2.addView("de.prob.ui.EventErrorView"); + + } + +} diff --git a/de.bmotionstudio.rodin/src/de/bmotionstudio/rodin/RenameFileHandler.java b/de.bmotionstudio.rodin/src/de/bmotionstudio/rodin/RenameFileHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..01f9f981a41c1baa3c4d0684a2584468bf5c8976 --- /dev/null +++ b/de.bmotionstudio.rodin/src/de/bmotionstudio/rodin/RenameFileHandler.java @@ -0,0 +1,114 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.rodin; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.IHandler; +import org.eclipse.core.resources.IWorkspaceRunnable; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.dialogs.InputDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.handlers.HandlerUtil; +import org.rodinp.core.IRodinFile; +import org.rodinp.core.IRodinProject; +import org.rodinp.core.RodinCore; +import org.rodinp.core.RodinDBException; + +import de.bmotionstudio.gef.editor.BMotionEditorPlugin; +import de.bmotionstudio.gef.editor.internal.BMotionFileInputValidator; + +/** + * @author Lukas Ladenberger + * + */ +public class RenameFileHandler extends AbstractHandler implements IHandler { + + private ISelection fSelection; + private IWorkbenchPart part; + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + + fSelection = HandlerUtil.getCurrentSelection(event); + part = HandlerUtil.getActivePart(event); + + if (fSelection instanceof IStructuredSelection) { + IStructuredSelection ssel = (IStructuredSelection) fSelection; + + if (ssel.size() == 1) { + + Object obj = ssel.getFirstElement(); + + if (obj instanceof IBMotionSurfaceRoot) { + + final IBMotionSurfaceRoot root = (IBMotionSurfaceRoot) obj; + if (root.getParent() instanceof IRodinFile) { + + final IRodinFile file = root.getRodinFile(); + final IRodinProject prj = file.getRodinProject(); + + InputDialog dialog = new InputDialog(part.getSite() + .getShell(), "Rename BMotion Studio Project", + "Please enter the new name for the Project", + getDefaultName(root), + new BMotionFileInputValidator(prj)); + + dialog.open(); + + final String bareName = dialog.getValue(); + + if (dialog.getReturnCode() == InputDialog.CANCEL) + return null; // Cancel + + assert bareName != null; + + try { + RodinCore.run(new IWorkspaceRunnable() { + + public void run(IProgressMonitor monitor) + throws RodinDBException { + String newName = bareName + + "." + + BMotionEditorPlugin.FILEEXT_STUDIO; + if (newName != null) + file.rename(newName, false, monitor); + } + + }, null); + } catch (RodinDBException e) { + e.printStackTrace(); + } + + } + } + + } + } + + return null; + + } + + public void selectionChanged(final IAction action, + final ISelection selection) { + fSelection = selection; + } + + public void setActivePart(IAction action, IWorkbenchPart targetPart) { + part = targetPart; + } + + private String getDefaultName(IBMotionSurfaceRoot root) { + return root.getResource().getName().replace(".bmso", ""); + } + +} diff --git a/de.bmotionstudio.rodin/src/de/bmotionstudio/rodin/StartEventBVisualizationHandler.java b/de.bmotionstudio.rodin/src/de/bmotionstudio/rodin/StartEventBVisualizationHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..f591535b259b59fd71d805118a27db38565c7709 --- /dev/null +++ b/de.bmotionstudio.rodin/src/de/bmotionstudio/rodin/StartEventBVisualizationHandler.java @@ -0,0 +1,29 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.rodin; + +import org.eclipse.core.commands.IHandler; +import org.eclipse.core.resources.IFile; +import org.eclipse.jface.viewers.IStructuredSelection; + +import de.bmotionstudio.gef.editor.internal.StartVisualizationFileHandler; + +/** + * @author Lukas Ladenberger + * + */ +public class StartEventBVisualizationHandler extends + StartVisualizationFileHandler implements IHandler { + + @Override + protected IFile getBmsFileFromSelection(IStructuredSelection ssel) { + if (ssel.getFirstElement() instanceof IBMotionSurfaceRoot) + return ((IBMotionSurfaceRoot) ssel.getFirstElement()).getResource(); + return null; + } + +} diff --git a/de.bmotionstudio.rodin/src/de/bmotionstudio/rodin/YesToAllMessageDialog.java b/de.bmotionstudio.rodin/src/de/bmotionstudio/rodin/YesToAllMessageDialog.java new file mode 100644 index 0000000000000000000000000000000000000000..d46ad6e662d44af603f9b8c0b3c3679f45eccc0f --- /dev/null +++ b/de.bmotionstudio.rodin/src/de/bmotionstudio/rodin/YesToAllMessageDialog.java @@ -0,0 +1,39 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.bmotionstudio.rodin; + +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Shell; + +public class YesToAllMessageDialog extends MessageDialog { + + public static int YES = 0; + public static int NO = 1; + public static int CANCEL = -1; + public static int YES_TO_ALL = 2; + public static int NO_TO_ALL = 3; + + public YesToAllMessageDialog(Shell parentShell, String dialogTitle, + Image dialogTitleImage, String dialogMessage, int dialogImageType, + String[] dialogButtonLabels, int defaultIndex) { + super(parentShell, dialogTitle, dialogTitleImage, dialogMessage, + dialogImageType, dialogButtonLabels, defaultIndex); + } + + public static int openYesNoToAllQuestion(Shell parent, String title, + String message) { + MessageDialog dialog = new MessageDialog(parent, title, null, // accept + message, QUESTION, new String[] { IDialogConstants.YES_LABEL, + IDialogConstants.NO_LABEL, + IDialogConstants.YES_TO_ALL_LABEL, + IDialogConstants.NO_TO_ALL_LABEL }, 0); // yes is the + return dialog.open(); + } + +} diff --git a/de.prob.core/.classpath b/de.prob.core/.classpath new file mode 100644 index 0000000000000000000000000000000000000000..4885470ebba742687047c196a00ccfa781fcb6f0 --- /dev/null +++ b/de.prob.core/.classpath @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry exported="true" kind="lib" path="lib/keyboard.jar"/> + <classpathentry exported="true" kind="lib" path="lib/commons-lang-2.4.jar"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="src" path="src"/> + <classpathentry exported="true" kind="lib" path="lib/probcliparser.jar"/> + <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/de.prob.core/.fbprefs b/de.prob.core/.fbprefs new file mode 100644 index 0000000000000000000000000000000000000000..e77060d8fd54d5eb1e57dab9438ce9c092dc7228 --- /dev/null +++ b/de.prob.core/.fbprefs @@ -0,0 +1,155 @@ +#FindBugs User Preferences +#Thu Feb 11 11:45:44 CET 2010 +detectorAppendingToAnObjectOutputStream=AppendingToAnObjectOutputStream|true +detectorBCPMethodReturnCheck=BCPMethodReturnCheck|false +detectorBadAppletConstructor=BadAppletConstructor|false +detectorBadResultSetAccess=BadResultSetAccess|true +detectorBadSyntaxForRegularExpression=BadSyntaxForRegularExpression|true +detectorBadUseOfReturnValue=BadUseOfReturnValue|true +detectorBadlyOverriddenAdapter=BadlyOverriddenAdapter|true +detectorBooleanReturnNull=BooleanReturnNull|true +detectorCallToUnsupportedMethod=CallToUnsupportedMethod|false +detectorCalledMethods=CalledMethods|true +detectorCheckCalls=CheckCalls|false +detectorCheckImmutableAnnotation=CheckImmutableAnnotation|true +detectorCheckTypeQualifiers=CheckTypeQualifiers|true +detectorCloneIdiom=CloneIdiom|true +detectorComparatorIdiom=ComparatorIdiom|true +detectorConfusedInheritance=ConfusedInheritance|true +detectorConfusionBetweenInheritedAndOuterMethod=ConfusionBetweenInheritedAndOuterMethod|true +detectorCrossSiteScripting=CrossSiteScripting|true +detectorDoInsideDoPrivileged=DoInsideDoPrivileged|true +detectorDontCatchIllegalMonitorStateException=DontCatchIllegalMonitorStateException|true +detectorDontIgnoreResultOfPutIfAbsent=DontIgnoreResultOfPutIfAbsent|true +detectorDontUseEnum=DontUseEnum|true +detectorDroppedException=DroppedException|true +detectorDumbMethodInvocations=DumbMethodInvocations|true +detectorDumbMethods=DumbMethods|true +detectorDuplicateBranches=DuplicateBranches|true +detectorEmptyZipFileEntry=EmptyZipFileEntry|true +detectorEqStringTest=EqStringTest|false +detectorEqualsOperandShouldHaveClassCompatibleWithThis=EqualsOperandShouldHaveClassCompatibleWithThis|true +detectorFinalizerNullsFields=FinalizerNullsFields|true +detectorFindBadCast=FindBadCast|false +detectorFindBadCast2=FindBadCast2|true +detectorFindBadEqualsImplementation=FindBadEqualsImplementation|false +detectorFindBadForLoop=FindBadForLoop|true +detectorFindBugsSummaryStats=FindBugsSummaryStats|true +detectorFindCircularDependencies=FindCircularDependencies|false +detectorFindDeadLocalStores=FindDeadLocalStores|true +detectorFindDoubleCheck=FindDoubleCheck|true +detectorFindEmptySynchronizedBlock=FindEmptySynchronizedBlock|true +detectorFindFieldSelfAssignment=FindFieldSelfAssignment|true +detectorFindFinalizeInvocations=FindFinalizeInvocations|true +detectorFindFloatEquality=FindFloatEquality|true +detectorFindFloatMath=FindFloatMath|false +detectorFindHEmismatch=FindHEmismatch|true +detectorFindInconsistentSync2=FindInconsistentSync2|true +detectorFindJSR166LockMonitorenter=FindJSR166LockMonitorenter|true +detectorFindLocalSelfAssignment2=FindLocalSelfAssignment2|true +detectorFindMaskedFields=FindMaskedFields|true +detectorFindMismatchedWaitOrNotify=FindMismatchedWaitOrNotify|true +detectorFindNakedNotify=FindNakedNotify|true +detectorFindNonSerializableStoreIntoSession=FindNonSerializableStoreIntoSession|true +detectorFindNonSerializableValuePassedToWriteObject=FindNonSerializableValuePassedToWriteObject|true +detectorFindNonShortCircuit=FindNonShortCircuit|true +detectorFindNullDeref=FindNullDeref|true +detectorFindNullDerefsInvolvingNonShortCircuitEvaluation=FindNullDerefsInvolvingNonShortCircuitEvaluation|true +detectorFindOpenStream=FindOpenStream|true +detectorFindPuzzlers=FindPuzzlers|false +detectorFindRefComparison=FindRefComparison|true +detectorFindReturnRef=FindReturnRef|false +detectorFindRunInvocations=FindRunInvocations|true +detectorFindSelfComparison=FindSelfComparison|true +detectorFindSelfComparison2=FindSelfComparison2|true +detectorFindSleepWithLockHeld=FindSleepWithLockHeld|true +detectorFindSpinLoop=FindSpinLoop|true +detectorFindSqlInjection=FindSqlInjection|true +detectorFindTwoLockWait=FindTwoLockWait|true +detectorFindUncalledPrivateMethods=FindUncalledPrivateMethods|true +detectorFindUnconditionalWait=FindUnconditionalWait|true +detectorFindUninitializedGet=FindUninitializedGet|true +detectorFindUnrelatedTypesInGenericContainer=FindUnrelatedTypesInGenericContainer|true +detectorFindUnreleasedLock=FindUnreleasedLock|true +detectorFindUnsatisfiedObligation=FindUnsatisfiedObligation|false +detectorFindUnsyncGet=FindUnsyncGet|true +detectorFindUselessControlFlow=FindUselessControlFlow|true +detectorFormatStringChecker=FormatStringChecker|true +detectorHugeSharedStringConstants=HugeSharedStringConstants|true +detectorIDivResultCastToDouble=IDivResultCastToDouble|true +detectorIncompatMask=IncompatMask|true +detectorInconsistentAnnotations=InconsistentAnnotations|true +detectorInefficientMemberAccess=InefficientMemberAccess|false +detectorInefficientToArray=InefficientToArray|true +detectorInfiniteLoop=InfiniteLoop|true +detectorInfiniteRecursiveLoop=InfiniteRecursiveLoop|true +detectorInfiniteRecursiveLoop2=InfiniteRecursiveLoop2|false +detectorInheritanceUnsafeGetResource=InheritanceUnsafeGetResource|true +detectorInitializationChain=InitializationChain|true +detectorInstantiateStaticClass=InstantiateStaticClass|true +detectorInvalidJUnitTest=InvalidJUnitTest|true +detectorIteratorIdioms=IteratorIdioms|true +detectorLazyInit=LazyInit|true +detectorLoadOfKnownNullValue=LoadOfKnownNullValue|true +detectorLockedFields=LockedFields|false +detectorLostLoggerDueToWeakReference=LostLoggerDueToWeakReference|true +detectorMethodReturnCheck=MethodReturnCheck|true +detectorMethods=Methods|true +detectorMultithreadedInstanceAccess=MultithreadedInstanceAccess|true +detectorMutableLock=MutableLock|true +detectorMutableStaticFields=MutableStaticFields|false +detectorNaming=Naming|false +detectorNoteAnnotationRetention=NoteAnnotationRetention|true +detectorNoteCheckReturnValue=NoteCheckReturnValue|true +detectorNoteCheckReturnValueAnnotations=NoteCheckReturnValueAnnotations|true +detectorNoteDirectlyRelevantTypeQualifiers=NoteDirectlyRelevantTypeQualifiers|true +detectorNoteJCIPAnnotation=NoteJCIPAnnotation|true +detectorNoteNonNullAnnotations=NoteNonNullAnnotations|true +detectorNoteNonnullReturnValues=NoteNonnullReturnValues|true +detectorNoteSuppressedWarnings=NoteSuppressedWarnings|true +detectorNoteUnconditionalParamDerefs=NoteUnconditionalParamDerefs|true +detectorNumberConstructor=NumberConstructor|true +detectorOverridingEqualsNotSymmetrical=OverridingEqualsNotSymmetrical|true +detectorPreferZeroLengthArrays=PreferZeroLengthArrays|true +detectorPublicSemaphores=PublicSemaphores|false +detectorQuestionableBooleanAssignment=QuestionableBooleanAssignment|true +detectorReadOfInstanceFieldInMethodInvokedByConstructorInSuperclass=ReadOfInstanceFieldInMethodInvokedByConstructorInSuperclass|true +detectorReadReturnShouldBeChecked=ReadReturnShouldBeChecked|true +detectorRedundantInterfaces=RedundantInterfaces|true +detectorReflectiveClasses=ReflectiveClasses|true +detectorRepeatedConditionals=RepeatedConditionals|true +detectorResolveAllReferences=ResolveAllReferences|false +detectorRuntimeExceptionCapture=RuntimeExceptionCapture|false +detectorSerializableIdiom=SerializableIdiom|true +detectorStartInConstructor=StartInConstructor|true +detectorStaticCalendarDetector=StaticCalendarDetector|true +detectorStringConcatenation=StringConcatenation|true +detectorSuperfluousInstanceOf=SuperfluousInstanceOf|true +detectorSuspiciousThreadInterrupted=SuspiciousThreadInterrupted|true +detectorSwitchFallthrough=SwitchFallthrough|true +detectorSynchronizationOnSharedBuiltinConstant=SynchronizationOnSharedBuiltinConstant|true +detectorSynchronizeAndNullCheckField=SynchronizeAndNullCheckField|true +detectorSynchronizeOnClassLiteralNotGetClass=SynchronizeOnClassLiteralNotGetClass|true +detectorSynchronizingOnContentsOfFieldToProtectField=SynchronizingOnContentsOfFieldToProtectField|true +detectorTestASM=TestASM|false +detectorTestDataflowAnalysis=TestDataflowAnalysis|false +detectorTestingGround=TestingGround|false +detectorTrainFieldStoreTypes=TrainFieldStoreTypes|true +detectorTrainNonNullAnnotations=TrainNonNullAnnotations|true +detectorTrainUnconditionalDerefParams=TrainUnconditionalDerefParams|true +detectorURLProblems=URLProblems|true +detectorUncallableMethodOfAnonymousClass=UncallableMethodOfAnonymousClass|true +detectorUnnecessaryMath=UnnecessaryMath|true +detectorUnreadFields=UnreadFields|false +detectorUseObjectEquals=UseObjectEquals|false +detectorUselessSubclassMethod=UselessSubclassMethod|false +detectorVarArgsProblems=VarArgsProblems|true +detectorVolatileUsage=VolatileUsage|true +detectorWaitInLoop=WaitInLoop|true +detectorWrongMapIterator=WrongMapIterator|true +detectorXMLFactoryBypass=XMLFactoryBypass|true +detector_threshold=2 +effort=default +filter_settings=Medium|BAD_PRACTICE,CORRECTNESS,EXPERIMENTAL,I18N,MALICIOUS_CODE,MT_CORRECTNESS,PERFORMANCE,SECURITY,STYLE|false +filter_settings_neg=NOISE| +run_at_full_build=false diff --git a/de.prob.core/.pmd b/de.prob.core/.pmd new file mode 100644 index 0000000000000000000000000000000000000000..be0dc3f92ec7fa1778ffd307e922ed7d9b67d9f3 --- /dev/null +++ b/de.prob.core/.pmd @@ -0,0 +1,743 @@ +<?xml version="1.0" encoding="UTF-8"?> +<pmd> + <useProjectRuleSet>false</useProjectRuleSet> + <ruleSetFile>.ruleset</ruleSetFile> + <excludePatterns> + <excludePattern>.*/sablecc/.*</excludePattern> + </excludePatterns> + <rules> + <rule> + <name>AvoidDecimalLiteralsInBigDecimalConstructor</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>AvoidThreadGroup</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>AvoidUsingOctalValues</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>BigIntegerInstantiation</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>BooleanInstantiation</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>BrokenNullCheck</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>ClassCastExceptionWithToArray</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>CollapsibleIfStatements</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>DoubleCheckedLocking</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>EmptyCatchBlock</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>EmptyFinallyBlock</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>EmptyIfStmt</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>EmptyStatementNotInLoop</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>EmptyStaticInitializer</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>EmptySwitchStatements</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>EmptySynchronizedBlock</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>EmptyTryBlock</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>EmptyWhileStmt</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>ForLoopShouldBeWhileLoop</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>JumbledIncrementer</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>MisplacedNullCheck</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>OverrideBothEqualsAndHashcode</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>ReturnFromFinallyBlock</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>UnconditionalIfStatement</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>UnnecessaryConversionTemporary</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>UnnecessaryFinalModifier</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>UnnecessaryReturn</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>UnusedNullCheckInEquals</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>UselessOperationOnImmutable</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>UselessOverridingMethod</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>ForLoopsMustUseBraces</name> + <ruleset>Braces Rules</ruleset> + </rule> + <rule> + <name>IfElseStmtsMustUseBraces</name> + <ruleset>Braces Rules</ruleset> + </rule> + <rule> + <name>IfStmtsMustUseBraces</name> + <ruleset>Braces Rules</ruleset> + </rule> + <rule> + <name>WhileLoopsMustUseBraces</name> + <ruleset>Braces Rules</ruleset> + </rule> + <rule> + <name>CloneThrowsCloneNotSupportedException</name> + <ruleset>Clone Implementation Rules</ruleset> + </rule> + <rule> + <name>ProperCloneImplementation</name> + <ruleset>Clone Implementation Rules</ruleset> + </rule> + <rule> + <name>CyclomaticComplexity</name> + <ruleset>Code Size Rules</ruleset> + </rule> + <rule> + <name>ExcessiveClassLength</name> + <ruleset>Code Size Rules</ruleset> + </rule> + <rule> + <name>ExcessiveMethodLength</name> + <ruleset>Code Size Rules</ruleset> + </rule> + <rule> + <name>ExcessiveParameterList</name> + <ruleset>Code Size Rules</ruleset> + </rule> + <rule> + <name>ExcessivePublicCount</name> + <ruleset>Code Size Rules</ruleset> + </rule> + <rule> + <name>NcssConstructorCount</name> + <ruleset>Code Size Rules</ruleset> + </rule> + <rule> + <name>NcssMethodCount</name> + <ruleset>Code Size Rules</ruleset> + </rule> + <rule> + <name>NcssTypeCount</name> + <ruleset>Code Size Rules</ruleset> + </rule> + <rule> + <name>NPathComplexity</name> + <ruleset>Code Size Rules</ruleset> + </rule> + <rule> + <name>TooManyFields</name> + <ruleset>Code Size Rules</ruleset> + </rule> + <rule> + <name>AssignmentInOperand</name> + <ruleset>Controversial Rules</ruleset> + </rule> + <rule> + <name>BooleanInversion</name> + <ruleset>Controversial Rules</ruleset> + </rule> + <rule> + <name>CallSuperInConstructor</name> + <ruleset>Controversial Rules</ruleset> + </rule> + <rule> + <name>DefaultPackage</name> + <ruleset>Controversial Rules</ruleset> + </rule> + <rule> + <name>DontImportSun</name> + <ruleset>Controversial Rules</ruleset> + </rule> + <rule> + <name>SuspiciousOctalEscape</name> + <ruleset>Controversial Rules</ruleset> + </rule> + <rule> + <name>UnnecessaryConstructor</name> + <ruleset>Controversial Rules</ruleset> + </rule> + <rule> + <name>CouplingBetweenObjects</name> + <ruleset>Coupling Rules</ruleset> + </rule> + <rule> + <name>ExcessiveImports</name> + <ruleset>Coupling Rules</ruleset> + </rule> + <rule> + <name>AccessorClassGeneration</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>AvoidConstantsInterface</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>AvoidDeeplyNestedIfStmts</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>AvoidInstanceofChecksInCatchClause</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>AvoidProtectedFieldInFinalClass</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>AvoidReassigningParameters</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>AvoidSynchronizedAtMethodLevel</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>BadComparison</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>CloseResource</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>CompareObjectsWithEquals</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>ConstructorCallsOverridableMethod</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>DefaultLabelNotLastInSwitchStmt</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>EqualsNull</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>FinalFieldCouldBeStatic</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>IdempotentOperations</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>ImmutableField</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>InstantiationToGetClass</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>MissingBreakInSwitch</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>MissingStaticMethodInNonInstantiatableClass</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>NonCaseLabelInSwitchStatement</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>NonStaticInitializer</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>NonThreadSafeSingleton</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>OptimizableToArrayCall</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>PositionLiteralsFirstInComparisons</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>PreserveStackTrace</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>SimpleDateFormatNeedsLocale</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>SimplifyBooleanExpressions</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>SimplifyBooleanReturns</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>SimplifyConditional</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>SwitchDensity</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>SwitchStmtsShouldHaveDefault</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>UncommentedEmptyConstructor</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>UncommentedEmptyMethod</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>UnnecessaryLocalBeforeReturn</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>UnsynchronizedStaticDateFormatter</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>UseCollectionIsEmpty</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>UseLocaleWithCaseConversions</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>UseNotifyAllInsteadOfNotify</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>UseSingleton</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>AvoidCallingFinalize</name> + <ruleset>Finalizer Rules</ruleset> + </rule> + <rule> + <name>EmptyFinalizer</name> + <ruleset>Finalizer Rules</ruleset> + </rule> + <rule> + <name>FinalizeDoesNotCallSuperFinalize</name> + <ruleset>Finalizer Rules</ruleset> + </rule> + <rule> + <name>FinalizeOnlyCallsSuperFinalize</name> + <ruleset>Finalizer Rules</ruleset> + </rule> + <rule> + <name>FinalizeOverloaded</name> + <ruleset>Finalizer Rules</ruleset> + </rule> + <rule> + <name>FinalizeShouldBeProtected</name> + <ruleset>Finalizer Rules</ruleset> + </rule> + <rule> + <name>DontImportJavaLang</name> + <ruleset>Import Statement Rules</ruleset> + </rule> + <rule> + <name>DuplicateImports</name> + <ruleset>Import Statement Rules</ruleset> + </rule> + <rule> + <name>ImportFromSamePackage</name> + <ruleset>Import Statement Rules</ruleset> + </rule> + <rule> + <name>ProperLogger</name> + <ruleset>Jakarta Commons Logging Rules</ruleset> + </rule> + <rule> + <name>UseCorrectExceptionLogging</name> + <ruleset>Jakarta Commons Logging Rules</ruleset> + </rule> + <rule> + <name>AvoidPrintStackTrace</name> + <ruleset>Java Logging Rules</ruleset> + </rule> + <rule> + <name>LoggerIsNotStaticFinal</name> + <ruleset>Java Logging Rules</ruleset> + </rule> + <rule> + <name>MoreThanOneLogger</name> + <ruleset>Java Logging Rules</ruleset> + </rule> + <rule> + <name>SystemPrintln</name> + <ruleset>Java Logging Rules</ruleset> + </rule> + <rule> + <name>JUnitAssertionsShouldIncludeMessage</name> + <ruleset>JUnit Rules</ruleset> + </rule> + <rule> + <name>JUnitSpelling</name> + <ruleset>JUnit Rules</ruleset> + </rule> + <rule> + <name>JUnitStaticSuite</name> + <ruleset>JUnit Rules</ruleset> + </rule> + <rule> + <name>JUnitTestsShouldIncludeAssert</name> + <ruleset>JUnit Rules</ruleset> + </rule> + <rule> + <name>SimplifyBooleanAssertion</name> + <ruleset>JUnit Rules</ruleset> + </rule> + <rule> + <name>TestClassWithoutTestCases</name> + <ruleset>JUnit Rules</ruleset> + </rule> + <rule> + <name>UnnecessaryBooleanAssertion</name> + <ruleset>JUnit Rules</ruleset> + </rule> + <rule> + <name>UseAssertEqualsInsteadOfAssertTrue</name> + <ruleset>JUnit Rules</ruleset> + </rule> + <rule> + <name>UseAssertNullInsteadOfAssertTrue</name> + <ruleset>JUnit Rules</ruleset> + </rule> + <rule> + <name>UseAssertSameInsteadOfAssertTrue</name> + <ruleset>JUnit Rules</ruleset> + </rule> + <rule> + <name>AvoidAssertAsIdentifier</name> + <ruleset>Migration Rules</ruleset> + </rule> + <rule> + <name>AvoidEnumAsIdentifier</name> + <ruleset>Migration Rules</ruleset> + </rule> + <rule> + <name>ByteInstantiation</name> + <ruleset>Migration Rules</ruleset> + </rule> + <rule> + <name>IntegerInstantiation</name> + <ruleset>Migration Rules</ruleset> + </rule> + <rule> + <name>LongInstantiation</name> + <ruleset>Migration Rules</ruleset> + </rule> + <rule> + <name>ReplaceEnumerationWithIterator</name> + <ruleset>Migration Rules</ruleset> + </rule> + <rule> + <name>ReplaceHashtableWithMap</name> + <ruleset>Migration Rules</ruleset> + </rule> + <rule> + <name>ReplaceVectorWithList</name> + <ruleset>Migration Rules</ruleset> + </rule> + <rule> + <name>ShortInstantiation</name> + <ruleset>Migration Rules</ruleset> + </rule> + <rule> + <name>AbstractNaming</name> + <ruleset>Naming Rules</ruleset> + </rule> + <rule> + <name>AvoidDollarSigns</name> + <ruleset>Naming Rules</ruleset> + </rule> + <rule> + <name>AvoidFieldNameMatchingMethodName</name> + <ruleset>Naming Rules</ruleset> + </rule> + <rule> + <name>AvoidFieldNameMatchingTypeName</name> + <ruleset>Naming Rules</ruleset> + </rule> + <rule> + <name>BooleanGetMethodName</name> + <ruleset>Naming Rules</ruleset> + </rule> + <rule> + <name>ClassNamingConventions</name> + <ruleset>Naming Rules</ruleset> + </rule> + <rule> + <name>MethodNamingConventions</name> + <ruleset>Naming Rules</ruleset> + </rule> + <rule> + <name>MethodWithSameNameAsEnclosingClass</name> + <ruleset>Naming Rules</ruleset> + </rule> + <rule> + <name>MisleadingVariableName</name> + <ruleset>Naming Rules</ruleset> + </rule> + <rule> + <name>NoPackage</name> + <ruleset>Naming Rules</ruleset> + </rule> + <rule> + <name>PackageCase</name> + <ruleset>Naming Rules</ruleset> + </rule> + <rule> + <name>ShortMethodName</name> + <ruleset>Naming Rules</ruleset> + </rule> + <rule> + <name>SuspiciousConstantFieldName</name> + <ruleset>Naming Rules</ruleset> + </rule> + <rule> + <name>SuspiciousEqualsMethodName</name> + <ruleset>Naming Rules</ruleset> + </rule> + <rule> + <name>SuspiciousHashcodeMethodName</name> + <ruleset>Naming Rules</ruleset> + </rule> + <rule> + <name>VariableNamingConventions</name> + <ruleset>Naming Rules</ruleset> + </rule> + <rule> + <name>AddEmptyString</name> + <ruleset>Optimization Rules</ruleset> + </rule> + <rule> + <name>AvoidArrayLoops</name> + <ruleset>Optimization Rules</ruleset> + </rule> + <rule> + <name>LocalVariableCouldBeFinal</name> + <ruleset>Optimization Rules</ruleset> + </rule> + <rule> + <name>MethodArgumentCouldBeFinal</name> + <ruleset>Optimization Rules</ruleset> + </rule> + <rule> + <name>SimplifyStartsWith</name> + <ruleset>Optimization Rules</ruleset> + </rule> + <rule> + <name>UnnecessaryWrapperObjectCreation</name> + <ruleset>Optimization Rules</ruleset> + </rule> + <rule> + <name>UseArrayListInsteadOfVector</name> + <ruleset>Optimization Rules</ruleset> + </rule> + <rule> + <name>UseArraysAsList</name> + <ruleset>Optimization Rules</ruleset> + </rule> + <rule> + <name>UseStringBufferForStringAppends</name> + <ruleset>Optimization Rules</ruleset> + </rule> + <rule> + <name>ArrayIsStoredDirectly</name> + <ruleset>Security Code Guidelines</ruleset> + </rule> + <rule> + <name>MethodReturnsInternalArray</name> + <ruleset>Security Code Guidelines</ruleset> + </rule> + <rule> + <name>AvoidCatchingNPE</name> + <ruleset>Strict Exception Rules</ruleset> + </rule> + <rule> + <name>AvoidCatchingThrowable</name> + <ruleset>Strict Exception Rules</ruleset> + </rule> + <rule> + <name>AvoidRethrowingException</name> + <ruleset>Strict Exception Rules</ruleset> + </rule> + <rule> + <name>AvoidThrowingNullPointerException</name> + <ruleset>Strict Exception Rules</ruleset> + </rule> + <rule> + <name>AvoidThrowingRawExceptionTypes</name> + <ruleset>Strict Exception Rules</ruleset> + </rule> + <rule> + <name>DoNotExtendJavaLangError</name> + <ruleset>Strict Exception Rules</ruleset> + </rule> + <rule> + <name>ExceptionAsFlowControl</name> + <ruleset>Strict Exception Rules</ruleset> + </rule> + <rule> + <name>AppendCharacterWithChar</name> + <ruleset>String and StringBuffer Rules</ruleset> + </rule> + <rule> + <name>AvoidDuplicateLiterals</name> + <ruleset>String and StringBuffer Rules</ruleset> + </rule> + <rule> + <name>ConsecutiveLiteralAppends</name> + <ruleset>String and StringBuffer Rules</ruleset> + </rule> + <rule> + <name>InefficientEmptyStringCheck</name> + <ruleset>String and StringBuffer Rules</ruleset> + </rule> + <rule> + <name>InefficientStringBuffering</name> + <ruleset>String and StringBuffer Rules</ruleset> + </rule> + <rule> + <name>InsufficientStringBufferDeclaration</name> + <ruleset>String and StringBuffer Rules</ruleset> + </rule> + <rule> + <name>StringBufferInstantiationWithChar</name> + <ruleset>String and StringBuffer Rules</ruleset> + </rule> + <rule> + <name>StringInstantiation</name> + <ruleset>String and StringBuffer Rules</ruleset> + </rule> + <rule> + <name>StringToString</name> + <ruleset>String and StringBuffer Rules</ruleset> + </rule> + <rule> + <name>UnnecessaryCaseChange</name> + <ruleset>String and StringBuffer Rules</ruleset> + </rule> + <rule> + <name>UseIndexOfChar</name> + <ruleset>String and StringBuffer Rules</ruleset> + </rule> + <rule> + <name>UselessStringValueOf</name> + <ruleset>String and StringBuffer Rules</ruleset> + </rule> + <rule> + <name>UseStringBufferLength</name> + <ruleset>String and StringBuffer Rules</ruleset> + </rule> + <rule> + <name>CloneMethodMustImplementCloneable</name> + <ruleset>Type Resolution Rules</ruleset> + </rule> + <rule> + <name>LooseCoupling</name> + <ruleset>Type Resolution Rules</ruleset> + </rule> + <rule> + <name>SignatureDeclareThrowsException</name> + <ruleset>Type Resolution Rules</ruleset> + </rule> + <rule> + <name>UnusedImports</name> + <ruleset>Type Resolution Rules</ruleset> + </rule> + <rule> + <name>UnusedFormalParameter</name> + <ruleset>Unused Code Rules</ruleset> + </rule> + <rule> + <name>UnusedLocalVariable</name> + <ruleset>Unused Code Rules</ruleset> + </rule> + <rule> + <name>UnusedPrivateField</name> + <ruleset>Unused Code Rules</ruleset> + </rule> + <rule> + <name>UnusedPrivateMethod</name> + <ruleset>Unused Code Rules</ruleset> + </rule> + </rules> + <includeDerivedFiles>false</includeDerivedFiles> +</pmd> diff --git a/de.prob.core/.project b/de.prob.core/.project new file mode 100644 index 0000000000000000000000000000000000000000..43d0f8ca96519be0a228fd1d90fb7f977ce5caa8 --- /dev/null +++ b/de.prob.core/.project @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>de.prob.core</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>edu.umd.cs.findbugs.plugin.eclipse.findbugsBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + <nature>edu.umd.cs.findbugs.plugin.eclipse.findbugsNature</nature> + </natures> +</projectDescription> diff --git a/de.prob.core/META-INF/MANIFEST.MF b/de.prob.core/META-INF/MANIFEST.MF new file mode 100644 index 0000000000000000000000000000000000000000..02bf7af43e931fafdb151712d41f86a0c9ad0793 --- /dev/null +++ b/de.prob.core/META-INF/MANIFEST.MF @@ -0,0 +1,72 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: ProB Animator Core +Bundle-SymbolicName: de.prob.core;singleton:=true +Bundle-Version: 9.1.1 +Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", + org.rodinp.core;bundle-version="[1.3.1,1.6.0)", + org.eventb.core;bundle-version="[2.1.0,2.4.0)", + org.eclipse.jface;bundle-version="[3.6.0,4.0.0)", + org.eclipse.ui;bundle-version="[3.6.0,4.0.0)" +Bundle-ActivationPolicy: lazy +Bundle-Vendor: HHU Düsseldorf STUPS Group +Export-Package: de.be4.classicalb.core.parser, + de.be4.classicalb.core.parser.analysis;x-friends:="de.prob.eventb.disprover.core", + de.be4.classicalb.core.parser.analysis.prolog;x-friends:="de.prob.eventb.disprover.core", + de.be4.classicalb.core.parser.exceptions, + de.be4.classicalb.core.parser.node;x-friends:="de.prob.eventb.disprover.core", + de.be4.ltl.core.parser, + de.prob.animationscript.parser.analysis, + de.prob.animationscript.parser.lexer, + de.prob.animationscript.parser.node, + de.prob.animationscript.parser.parser;uses:="de.prob.animationscript.parser.lexer,de.prob.animationscript.parser.analysis,de.prob.animationscript.parser.node", + de.prob.core; + uses:="de.prob.core.domainobjects.eval, + de.prob.parserbase, + org.osgi.service.prefs, + de.prob.core.domainobjects, + de.prob.core.command, + de.prob.exceptions", + de.prob.core.command; + uses:="de.prob.core.domainobjects.eval, + de.prob.core, + org.osgi.service.prefs, + de.prob.core.domainobjects, + de.prob.exceptions, + de.prob.prolog.term, + de.prob.prolog.output", + de.prob.core.domainobjects;uses:="de.prob.core,de.prob.core.command,de.prob.prolog.term", + de.prob.core.domainobjects.eval;uses:="de.prob.core,de.be4.classicalb.core.parser.node,org.eventb.core.ast", + de.prob.core.domainobjects.ltl, + de.prob.core.prolog;uses:="de.prob.core.types,de.prob.prolog.term", + de.prob.core.translator;uses:="de.prob.exceptions", + de.prob.core.types, + de.prob.eventb.translator; + uses:="de.be4.classicalb.core.parser.node, + de.prob.eventb.translator.internal, + org.eventb.core.ast, + org.eventb.core, + de.prob.prolog.output", + de.prob.exceptions, + de.prob.logging;uses:="org.eclipse.core.runtime", + de.prob.parser, + de.prob.parserbase;x-friends:="de.prob.ui", + de.prob.prolog.output;x-friends:="de.prob.eventb.disprover.core,de.prob.ui,de.prob.dmc.modelcheck", + de.prob.prolog.term;x-friends:="de.prob.ui,de.prob.dmc.modelcheck", + de.prob.sap.commands, + de.prob.sap.exceptions, + org.apache.commons.lang, + org.apache.commons.lang.builder, + org.apache.commons.lang.enums, + org.apache.commons.lang.exception, + org.apache.commons.lang.math, + org.apache.commons.lang.mutable, + org.apache.commons.lang.text, + org.apache.commons.lang.time +Bundle-Activator: de.prob.core.internal.Activator +Eclipse-BuddyPolicy: registered +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Bundle-ClassPath: ., + lib/probcliparser.jar, + lib/commons-lang-2.4.jar, + lib/keyboard.jar diff --git a/de.prob.core/build.properties b/de.prob.core/build.properties new file mode 100644 index 0000000000000000000000000000000000000000..a160157665756a1881d01008566cb7ba8b013734 --- /dev/null +++ b/de.prob.core/build.properties @@ -0,0 +1,10 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + plugin.xml,\ + .,\ + lib/probcliparser.jar,\ + lib/commons-lang-2.4.jar,\ + prob/,\ + lib/keyboard.jar + diff --git a/de.prob.core/lib/commons-lang-2.4.jar b/de.prob.core/lib/commons-lang-2.4.jar new file mode 100644 index 0000000000000000000000000000000000000000..532939ecab6b77ccb77af3635c55ff9752b70ab7 Binary files /dev/null and b/de.prob.core/lib/commons-lang-2.4.jar differ diff --git a/de.prob.core/lib/keyboard.jar b/de.prob.core/lib/keyboard.jar new file mode 100644 index 0000000000000000000000000000000000000000..6185602505dfdc580db53d2c39aa89ae8cf9ef65 Binary files /dev/null and b/de.prob.core/lib/keyboard.jar differ diff --git a/de.prob.core/lib/probcliparser.jar b/de.prob.core/lib/probcliparser.jar new file mode 100644 index 0000000000000000000000000000000000000000..434f6a1042973d48b62b56d21a439a7cd5f064a1 Binary files /dev/null and b/de.prob.core/lib/probcliparser.jar differ diff --git a/de.prob.core/plugin.xml b/de.prob.core/plugin.xml new file mode 100644 index 0000000000000000000000000000000000000000..2d7b472c3f23462dc53c415d78961b70f7940e2f --- /dev/null +++ b/de.prob.core/plugin.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?eclipse version="3.2"?> +<plugin> + <extension-point id="de.prob.core.lifecycle" name="Lifecycle Events" schema="schema/de.prob.core.lifecycle.exsd"/> + <extension-point id="de.prob.core.computation" name="Computation Events" schema="schema/de.prob.core.computation.exsd"/> + <extension-point id="de.prob.core.animation" name="Animation Events" schema="schema/de.prob.core.animation.exsd"/> + <extension + point="de.prob.core.animation"> + <listener + class="de.prob.core.StaticListenerRegistry"> + </listener> + </extension> + <extension + point="de.prob.core.computation"> + <listener + class="de.prob.core.StaticListenerRegistry"> + </listener> + </extension> + <extension + point="de.prob.core.lifecycle"> + <listener + class="de.prob.core.StaticListenerRegistry"> + </listener> + </extension> +</plugin> diff --git a/de.prob.core/prob/linux/build_info.txt b/de.prob.core/prob/linux/build_info.txt new file mode 100644 index 0000000000000000000000000000000000000000..369f2716f8a39a6014b47834fd38991c9cd06591 --- /dev/null +++ b/de.prob.core/prob/linux/build_info.txt @@ -0,0 +1,4 @@ + + Revision: 8306 + June 28 2011 - 2001 + \ No newline at end of file diff --git a/de.prob.core/prob/linux/lib/graphiso.so b/de.prob.core/prob/linux/lib/graphiso.so new file mode 100755 index 0000000000000000000000000000000000000000..4e4b3a451559da7efc4fc68e4d3c237d3a18ec95 Binary files /dev/null and b/de.prob.core/prob/linux/lib/graphiso.so differ diff --git a/de.prob.core/prob/linux/lib/ltlc.so b/de.prob.core/prob/linux/lib/ltlc.so new file mode 100755 index 0000000000000000000000000000000000000000..310e63a78bd490e0269b69a3b27a391c4048c9bb Binary files /dev/null and b/de.prob.core/prob/linux/lib/ltlc.so differ diff --git a/de.prob.core/prob/linux/lib/user_signal.so b/de.prob.core/prob/linux/lib/user_signal.so new file mode 100755 index 0000000000000000000000000000000000000000..634025d44f39b3585d17b4966305f1444c94b295 Binary files /dev/null and b/de.prob.core/prob/linux/lib/user_signal.so differ diff --git a/de.prob.core/prob/linux/probcli b/de.prob.core/prob/linux/probcli new file mode 100755 index 0000000000000000000000000000000000000000..5e8e0202d9217d1e985fcdbe04be7ea9910e0271 Binary files /dev/null and b/de.prob.core/prob/linux/probcli differ diff --git a/de.prob.core/prob/linux/probcli.sh b/de.prob.core/prob/linux/probcli.sh new file mode 100644 index 0000000000000000000000000000000000000000..9611d3df6b8a0d0b2799921cc4fa5ca6a55bb41b --- /dev/null +++ b/de.prob.core/prob/linux/probcli.sh @@ -0,0 +1,18 @@ +#!/bin/bash +PROBCOMMAND=probcli +INTERRUPT_COMMAND=send_user_interrupt + + +# Shell wrapper for PROBCOMMAND + +echo "Running ProB Command-line Interface" +echo "$PROBCOMMAND" "$@" + +# dirname +dirname=`dirname "$0"` + +ulimit -d unlimited + +chmod a+x "$dirname/$PROBCOMMAND" +chmod a+x "$dirname/$INTERRUPT_COMMAND" +exec "$dirname/$PROBCOMMAND" "$@" diff --git a/de.prob.core/prob/linux/send_user_interrupt b/de.prob.core/prob/linux/send_user_interrupt new file mode 100755 index 0000000000000000000000000000000000000000..c5daa025c2be077b11d0854b839a7dd5f33032c6 Binary files /dev/null and b/de.prob.core/prob/linux/send_user_interrupt differ diff --git a/de.prob.core/prob/macos/build_info.txt b/de.prob.core/prob/macos/build_info.txt new file mode 100644 index 0000000000000000000000000000000000000000..ce200c097fd45a4ca89648394971783695c007f1 --- /dev/null +++ b/de.prob.core/prob/macos/build_info.txt @@ -0,0 +1,4 @@ + + Revision: 8306 + June 28 2011 - 2002 + \ No newline at end of file diff --git a/de.prob.core/prob/macos/lib/graphiso.bundle b/de.prob.core/prob/macos/lib/graphiso.bundle new file mode 100755 index 0000000000000000000000000000000000000000..de34ec7f197755bfa519f234a98abf72a1cb70b5 Binary files /dev/null and b/de.prob.core/prob/macos/lib/graphiso.bundle differ diff --git a/de.prob.core/prob/macos/lib/ltlc.bundle b/de.prob.core/prob/macos/lib/ltlc.bundle new file mode 100755 index 0000000000000000000000000000000000000000..c9ca5e94f707086a7364c3bd8b4e878e79a7daaf Binary files /dev/null and b/de.prob.core/prob/macos/lib/ltlc.bundle differ diff --git a/de.prob.core/prob/macos/lib/user_signal.bundle b/de.prob.core/prob/macos/lib/user_signal.bundle new file mode 100755 index 0000000000000000000000000000000000000000..dade658ef1d82ac0e5bfcb32baeea1bebc6d1f95 Binary files /dev/null and b/de.prob.core/prob/macos/lib/user_signal.bundle differ diff --git a/de.prob.core/prob/macos/probcli b/de.prob.core/prob/macos/probcli new file mode 100755 index 0000000000000000000000000000000000000000..bb7f3fb16b5fb9d10ed690e792a78431a08ce548 Binary files /dev/null and b/de.prob.core/prob/macos/probcli differ diff --git a/de.prob.core/prob/macos/probcli.sh b/de.prob.core/prob/macos/probcli.sh new file mode 100755 index 0000000000000000000000000000000000000000..9611d3df6b8a0d0b2799921cc4fa5ca6a55bb41b --- /dev/null +++ b/de.prob.core/prob/macos/probcli.sh @@ -0,0 +1,18 @@ +#!/bin/bash +PROBCOMMAND=probcli +INTERRUPT_COMMAND=send_user_interrupt + + +# Shell wrapper for PROBCOMMAND + +echo "Running ProB Command-line Interface" +echo "$PROBCOMMAND" "$@" + +# dirname +dirname=`dirname "$0"` + +ulimit -d unlimited + +chmod a+x "$dirname/$PROBCOMMAND" +chmod a+x "$dirname/$INTERRUPT_COMMAND" +exec "$dirname/$PROBCOMMAND" "$@" diff --git a/de.prob.core/prob/macos/send_user_interrupt b/de.prob.core/prob/macos/send_user_interrupt new file mode 100755 index 0000000000000000000000000000000000000000..eb65c6e230622c6658b628df7e2b8ca16a2b1b34 Binary files /dev/null and b/de.prob.core/prob/macos/send_user_interrupt differ diff --git a/de.prob.core/prob/windows/Microsoft.VC80.CRT/Microsoft.VC80.CRT.manifest b/de.prob.core/prob/windows/Microsoft.VC80.CRT/Microsoft.VC80.CRT.manifest new file mode 100755 index 0000000000000000000000000000000000000000..b89cafd782e558d92139f5ec00bb6f17c71ee5df --- /dev/null +++ b/de.prob.core/prob/windows/Microsoft.VC80.CRT/Microsoft.VC80.CRT.manifest @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> + <noInheritable></noInheritable> + <assemblyIdentity type="win32" name="Microsoft.VC80.CRT" version="8.0.50727.762" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity> + <file name="msvcr80.dll" hash="10f4cb2831f1e9288a73387a8734a8b604e5beaa" hashalg="SHA1"><asmv2:hash xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"><dsig:Transforms><dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity"></dsig:Transform></dsig:Transforms><dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></dsig:DigestMethod><dsig:DigestValue>n9On8FItNsK/DmT8UQxu6jYDtWQ=</dsig:DigestValue></asmv2:hash></file> + <file name="msvcp80.dll" hash="b2082dfd3009365c5b287448dcb3b4e2158a6d26" hashalg="SHA1"><asmv2:hash xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"><dsig:Transforms><dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity"></dsig:Transform></dsig:Transforms><dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></dsig:DigestMethod><dsig:DigestValue>0KJ/VTwP4OUHx98HlIW2AdW1kuY=</dsig:DigestValue></asmv2:hash></file> + <file name="msvcm80.dll" hash="542490d0fcf8615c46d0ca487033ccaeb3941f0b" hashalg="SHA1"><asmv2:hash xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"><dsig:Transforms><dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity"></dsig:Transform></dsig:Transforms><dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></dsig:DigestMethod><dsig:DigestValue>YJuB+9Os2oxW4mY+2oC/r8lICZE=</dsig:DigestValue></asmv2:hash></file> +</assembly> \ No newline at end of file diff --git a/de.prob.core/prob/windows/Microsoft.VC80.CRT/msvcm80.dll b/de.prob.core/prob/windows/Microsoft.VC80.CRT/msvcm80.dll new file mode 100755 index 0000000000000000000000000000000000000000..c751385bde3d0d6d43b546e7b25c153cfa52ae7a Binary files /dev/null and b/de.prob.core/prob/windows/Microsoft.VC80.CRT/msvcm80.dll differ diff --git a/de.prob.core/prob/windows/Microsoft.VC80.CRT/msvcp80.dll b/de.prob.core/prob/windows/Microsoft.VC80.CRT/msvcp80.dll new file mode 100755 index 0000000000000000000000000000000000000000..f0b52ebf127ea7dd6a75e4bfc4ca8358336587bd Binary files /dev/null and b/de.prob.core/prob/windows/Microsoft.VC80.CRT/msvcp80.dll differ diff --git a/de.prob.core/prob/windows/Microsoft.VC80.CRT/msvcr80.dll b/de.prob.core/prob/windows/Microsoft.VC80.CRT/msvcr80.dll new file mode 100755 index 0000000000000000000000000000000000000000..53c005efc16042c569d956d3d6ea6793f702dd03 Binary files /dev/null and b/de.prob.core/prob/windows/Microsoft.VC80.CRT/msvcr80.dll differ diff --git a/de.prob.core/prob/windows/build_info.txt b/de.prob.core/prob/windows/build_info.txt new file mode 100644 index 0000000000000000000000000000000000000000..6e8a5c94e0672e77a08320c3a02f054f97cc80f9 --- /dev/null +++ b/de.prob.core/prob/windows/build_info.txt @@ -0,0 +1,4 @@ + + Last build: ${build} Revision: 8306 + June 28 2011 + \ No newline at end of file diff --git a/de.prob.core/prob/windows/lib/graphiso.dll b/de.prob.core/prob/windows/lib/graphiso.dll new file mode 100755 index 0000000000000000000000000000000000000000..e45d8fb0fe8561f79ff04587c507558a95b80251 Binary files /dev/null and b/de.prob.core/prob/windows/lib/graphiso.dll differ diff --git a/de.prob.core/prob/windows/lib/ltlc.dll b/de.prob.core/prob/windows/lib/ltlc.dll new file mode 100755 index 0000000000000000000000000000000000000000..52180048e11a77a1ec5978afa7a38b2610509306 Binary files /dev/null and b/de.prob.core/prob/windows/lib/ltlc.dll differ diff --git a/de.prob.core/prob/windows/lib/myheap.dll b/de.prob.core/prob/windows/lib/myheap.dll new file mode 100644 index 0000000000000000000000000000000000000000..7529b4025d518decf217f0db330b5f1aeebc05e8 Binary files /dev/null and b/de.prob.core/prob/windows/lib/myheap.dll differ diff --git a/de.prob.core/prob/windows/lib/user_signal.dll b/de.prob.core/prob/windows/lib/user_signal.dll new file mode 100644 index 0000000000000000000000000000000000000000..013e0540a3a513e2ce60479216bc772dfce69baf Binary files /dev/null and b/de.prob.core/prob/windows/lib/user_signal.dll differ diff --git a/de.prob.core/prob/windows/probcli.exe b/de.prob.core/prob/windows/probcli.exe new file mode 100644 index 0000000000000000000000000000000000000000..346e163480a796ec7cbbf394e4c81ea043601065 Binary files /dev/null and b/de.prob.core/prob/windows/probcli.exe differ diff --git a/de.prob.core/prob/windows/send_user_interrupt.exe b/de.prob.core/prob/windows/send_user_interrupt.exe new file mode 100644 index 0000000000000000000000000000000000000000..878021faa421be7f43698b2099393233cf9d1def Binary files /dev/null and b/de.prob.core/prob/windows/send_user_interrupt.exe differ diff --git a/de.prob.core/prob_target.target b/de.prob.core/prob_target.target new file mode 100644 index 0000000000000000000000000000000000000000..d56ff857408c15294e358542b1b242037a47554d --- /dev/null +++ b/de.prob.core/prob_target.target @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<?pde version="3.6"?> + +<target name="prob_target" sequenceNumber="7"> +<locations> +<location includeAllPlatforms="true" includeMode="slicer" includeSource="true" type="InstallableUnit"> +<unit id="de.prob.target.feature.feature.group" version="1.0.0.qualifier"/> +<repository location="http://cobra.cs.uni-duesseldorf.de/prob_dev_target"/> +</location> +</locations> +</target> diff --git a/de.prob.core/schema/de.prob.core.animation.exsd b/de.prob.core/schema/de.prob.core.animation.exsd new file mode 100644 index 0000000000000000000000000000000000000000..34f688838dadb8155ef4072aa9495b135ab98cf1 --- /dev/null +++ b/de.prob.core/schema/de.prob.core.animation.exsd @@ -0,0 +1,105 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- Schema file written by PDE --> +<schema targetNamespace="de.prob.core"> +<annotation> + <appInfo> + <meta.schema plugin="de.prob.core" id="de.prob.core.animation" name="Animation Events"/> + </appInfo> + <documentation> + [Enter description of this extension point.] + </documentation> + </annotation> + + <element name="extension"> + <complexType> + <sequence minOccurs="1" maxOccurs="unbounded"> + <element ref="listener"/> + </sequence> + <attribute name="point" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="id" type="string"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="name" type="string"> + <annotation> + <documentation> + + </documentation> + <appInfo> + <meta.attribute translatable="true"/> + </appInfo> + </annotation> + </attribute> + </complexType> + </element> + + <element name="listener"> + <complexType> + <attribute name="class" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + <appInfo> + <meta.attribute kind="java" basedOn=":de.prob.core.IAnimationListener"/> + </appInfo> + </annotation> + </attribute> + </complexType> + </element> + + <annotation> + <appInfo> + <meta.section type="since"/> + </appInfo> + <documentation> + [Enter the first release in which this extension point appears.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="examples"/> + </appInfo> + <documentation> + [Enter extension point usage example here.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="apiInfo"/> + </appInfo> + <documentation> + [Enter API information here.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="implementation"/> + </appInfo> + <documentation> + [Enter information about supplied implementation of this extension point.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="copyright"/> + </appInfo> + <documentation> + + </documentation> + </annotation> + +</schema> diff --git a/de.prob.core/schema/de.prob.core.computation.exsd b/de.prob.core/schema/de.prob.core.computation.exsd new file mode 100644 index 0000000000000000000000000000000000000000..5e4318bd8cb738654c31502554bc1835b44c5e59 --- /dev/null +++ b/de.prob.core/schema/de.prob.core.computation.exsd @@ -0,0 +1,105 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- Schema file written by PDE --> +<schema targetNamespace="de.prob.core"> +<annotation> + <appInfo> + <meta.schema plugin="de.prob.core" id="de.prob.core.computation" name="Computation Events"/> + </appInfo> + <documentation> + [Enter description of this extension point.] + </documentation> + </annotation> + + <element name="extension"> + <complexType> + <sequence minOccurs="1" maxOccurs="unbounded"> + <element ref="listener"/> + </sequence> + <attribute name="point" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="id" type="string"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="name" type="string"> + <annotation> + <documentation> + + </documentation> + <appInfo> + <meta.attribute translatable="true"/> + </appInfo> + </annotation> + </attribute> + </complexType> + </element> + + <element name="listener"> + <complexType> + <attribute name="class" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + <appInfo> + <meta.attribute kind="java" basedOn=":de.prob.core.IComputationListener"/> + </appInfo> + </annotation> + </attribute> + </complexType> + </element> + + <annotation> + <appInfo> + <meta.section type="since"/> + </appInfo> + <documentation> + [Enter the first release in which this extension point appears.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="examples"/> + </appInfo> + <documentation> + [Enter extension point usage example here.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="apiInfo"/> + </appInfo> + <documentation> + [Enter API information here.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="implementation"/> + </appInfo> + <documentation> + [Enter information about supplied implementation of this extension point.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="copyright"/> + </appInfo> + <documentation> + + </documentation> + </annotation> + +</schema> diff --git a/de.prob.core/schema/de.prob.core.lifecycle.exsd b/de.prob.core/schema/de.prob.core.lifecycle.exsd new file mode 100644 index 0000000000000000000000000000000000000000..8b1f69259066f533d920eb7676a140eb6714ec78 --- /dev/null +++ b/de.prob.core/schema/de.prob.core.lifecycle.exsd @@ -0,0 +1,105 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- Schema file written by PDE --> +<schema targetNamespace="de.prob.core"> +<annotation> + <appInfo> + <meta.schema plugin="de.prob.core" id="de.prob.core.lifecycle" name="Lifecycle Events"/> + </appInfo> + <documentation> + [Enter description of this extension point.] + </documentation> + </annotation> + + <element name="extension"> + <complexType> + <sequence minOccurs="1" maxOccurs="unbounded"> + <element ref="listener"/> + </sequence> + <attribute name="point" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="id" type="string"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="name" type="string"> + <annotation> + <documentation> + + </documentation> + <appInfo> + <meta.attribute translatable="true"/> + </appInfo> + </annotation> + </attribute> + </complexType> + </element> + + <element name="listener"> + <complexType> + <attribute name="class" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + <appInfo> + <meta.attribute kind="java" basedOn=":de.prob.core.ILifecycleListener"/> + </appInfo> + </annotation> + </attribute> + </complexType> + </element> + + <annotation> + <appInfo> + <meta.section type="since"/> + </appInfo> + <documentation> + [Enter the first release in which this extension point appears.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="examples"/> + </appInfo> + <documentation> + [Enter extension point usage example here.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="apiInfo"/> + </appInfo> + <documentation> + [Enter API information here.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="implementation"/> + </appInfo> + <documentation> + [Enter information about supplied implementation of this extension point.] + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="copyright"/> + </appInfo> + <documentation> + + </documentation> + </annotation> + +</schema> diff --git a/de.prob.core/src/de/prob/cli/CliException.java b/de.prob.core/src/de/prob/cli/CliException.java new file mode 100644 index 0000000000000000000000000000000000000000..9d1d2b1d901ed1f5797d69a942a4d69d0e7f722f --- /dev/null +++ b/de.prob.core/src/de/prob/cli/CliException.java @@ -0,0 +1,30 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.cli; + +import de.prob.exceptions.ProBException; + +public class CliException extends ProBException { + + private static final long serialVersionUID = -1376277300420758117L; + + public CliException(final Throwable e) { + super(e); + } + + public CliException(final String message, final Throwable e, final boolean b) { + super(message, e, b); + } + + public CliException(final String message, final boolean b) { + super(message, b); + } + + public CliException(final String exception) { + super(exception); + } +} diff --git a/de.prob.core/src/de/prob/cli/CliStarter.java b/de.prob.core/src/de/prob/cli/CliStarter.java new file mode 100644 index 0000000000000000000000000000000000000000..a1fd1bb431a6f0bf2b6a59cd0985662ee12d6a0b --- /dev/null +++ b/de.prob.core/src/de/prob/cli/CliStarter.java @@ -0,0 +1,368 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.cli; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Random; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; + +import de.prob.cli.clipatterns.CliPattern; +import de.prob.cli.clipatterns.InterruptRefPattern; +import de.prob.cli.clipatterns.PortPattern; +import de.prob.core.internal.Activator; +import de.prob.logging.Logger; + +public final class CliStarter { + private static final String[] JARS = new String[] { "BParser.jar", + "ParserAspects.jar", "aspectjrt.jar", "prolog.jar" }; + + private static Map<String, OsSpecificInfo> OSINFOS = createOsInfos(); + + private Process prologProcess; + private String debuggingKey; + + private int port = -1; + private Long userInterruptReference = null; + + private OutputLoggerThread stdLogger; + private OutputLoggerThread errLogger; + + public CliStarter() throws CliException { + this(null); + } + + private static Map<String, OsSpecificInfo> createOsInfos() { + Map<String, OsSpecificInfo> infos = new HashMap<String, CliStarter.OsSpecificInfo>(); + infos.put(Platform.OS_MACOSX, new OsSpecificInfo("macos", "probcli.sh", + "sh", "send_user_interrupt")); + infos.put(Platform.OS_LINUX, new OsSpecificInfo("linux", "probcli.sh", + "sh", "send_user_interrupt")); + infos.put(Platform.OS_WIN32, new OsSpecificInfo("windows", + "probcli.exe", null, "send_user_interrupt.exe")); + return Collections.unmodifiableMap(infos); + } + + public CliStarter(final File file) throws CliException { + startProlog(file); + } + + public int getPort() { + return port; + } + + public void shutdown() { + try { + prologProcess.destroy(); + } catch (RuntimeException e) { + final String message = "XXXXX Error while stopping cli process: " + + e.getLocalizedMessage(); + Logger.notifyUser(message, e); + } finally { + stdLogger.shutdown(); + errLogger.shutdown(); + } + } + + public String getDebuggingKey() { + return debuggingKey; + } + + private void startProlog(final File file) throws CliException { + prologProcess = null; + debuggingKey = null; + + final String os = Platform.getOS(); + final File applicationPath = getCliPath(); + + final String fullcp = createFullClasspath(os, applicationPath); + final OsSpecificInfo osInfo = getOsInfo(os); + + final String osPath = applicationPath + File.separator + osInfo.subdir; + final String executable = osPath + File.separator + osInfo.cliName; + Logger.info("Starting ProB CLI for " + os + " ... Path is " + + executable); + + List<String> command = new ArrayList<String>(); + if (osInfo.helperCmd != null) { + command.add(osInfo.helperCmd); + } + command.add(executable); + // command.add("-ll"); + command.add("-sf"); + command.add("-parsercp"); + command.add(fullcp); + + if (file != null) { + command.add(file.getAbsolutePath()); + } + + createDebuggingKey(); + + final ProcessBuilder pb = new ProcessBuilder(); + pb.command(command); + pb.environment().put("PROB_DEBUGGING_KEY", debuggingKey); + pb.environment().put("TRAILSTKSIZE", "1M"); + pb.environment().put("PROLOGINCSIZE", "50M"); + pb.environment().put("PROB_HOME", osPath); + try { + prologProcess = pb.start(); + } catch (IOException e) { + final String message = "Problem while starting up ProB CLI. Tried to execute:" + + executable; + Logger.notifyUser(message, e); + throw new CliException(message, e, true); + } + + Assert.isNotNull(prologProcess); + + final BufferedReader input = new BufferedReader(new InputStreamReader( + prologProcess.getInputStream())); + final BufferedReader output = new BufferedReader(new InputStreamReader( + prologProcess.getErrorStream())); + + startErrorLogger(output); + + extractCliInformation(input); + // log output from Prolog + startOutputLogger(input); + + final Process p = prologProcess; + + Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { + public void run() { + p.destroy(); + } + })); + + } + + private OsSpecificInfo getOsInfo(final String os) throws CliException { + final OsSpecificInfo osInfo = OSINFOS.get(os); + if (osInfo == null) { + final CliException cliException = new CliException( + "ProB does not support the plattform: " + os); + cliException.notifyUserOnce(); + throw cliException; + } + return osInfo; + } + + @SuppressWarnings("unchecked") + private void extractCliInformation(final BufferedReader input) + throws CliException { + final PortPattern portPattern = new PortPattern(); + final InterruptRefPattern intPattern = new InterruptRefPattern(); + analyseStdout(input, Arrays.asList(portPattern, intPattern)); + port = portPattern.getValue(); + userInterruptReference = intPattern.getValue(); + } + + private static String createFullClasspath(final String os, final File path) + throws CliException { + final File base = new File(path.getParentFile().getParentFile(), + "de.prob.common"); + final File common = new File(base, "common"); + final File lib = new File(common, "lib"); + final StringBuilder sb = new StringBuilder(); + boolean isFirst = true; + for (final String jar : JARS) { + final File entry = new File(lib, jar); + if (!isFirst) { + sb.append(File.pathSeparator); + } + sb.append(entry.getPath()); + isFirst = false; + } + return sb.toString(); + } + + private void startOutputLogger(final BufferedReader input) { + stdLogger = new OutputLoggerThread("(Output " + port + ")", input); + stdLogger.start(); + } + + private void startErrorLogger(final BufferedReader output) { + errLogger = new OutputLoggerThread("(Error " + port + ")", output); + errLogger.start(); + } + + private void createDebuggingKey() { + Random random; + try { + random = SecureRandom.getInstance("SHA1PRNG"); + } catch (NoSuchAlgorithmException e) { + random = new Random(); + } + debuggingKey = Long.toHexString(random.nextLong()); + } + + private void analyseStdout(final BufferedReader input, + Collection<? extends CliPattern<?>> patterns) throws CliException { + patterns = new ArrayList<CliPattern<?>>(patterns); + try { + String line; + boolean endReached = false; + while (!endReached && (line = input.readLine()) != null) { // NOPMD + applyPatterns(patterns, line); + endReached = patterns.isEmpty() + || line.contains("starting command loop"); + } + } catch (IOException e) { + final String message = "Problem while starting ProB. Cannot read from input stream."; + Logger.notifyUser(message, e); + throw new CliException(message, e, true); + } + for (CliPattern<?> p : patterns) { + p.notFound(); + } + } + + private void applyPatterns( + final Collection<? extends CliPattern<?>> patterns, + final String line) { + for (Iterator<? extends CliPattern<?>> it = patterns.iterator(); it + .hasNext();) { + final CliPattern<?> p = it.next(); + if (p.matchesLine(line)) { + it.remove(); + } + } + } + + private File getCliPath() throws CliException { + final Path path = new Path("prob"); + final URL fileURL = FileLocator.find( + Activator.getDefault().getBundle(), path, null); + URL resolved; + try { + resolved = FileLocator.resolve(fileURL); + } catch (IOException e2) { + throw new CliException("Input/output error when trying t find '" + + fileURL + "'"); + } + URI uri; + try { + uri = resolved.toURI(); + } catch (URISyntaxException e) { + try { + uri = new URI("file", null, resolved.getPath(), null); + } catch (URISyntaxException e1) { + throw new CliException("Unable to construct file '" + + resolved.getPath() + "'"); + } + } + return new File(uri); + } + + private static class OutputLoggerThread extends Thread { + + private final BufferedReader in; + + private final String prefix; + + private volatile boolean shutingDown = false; + + public OutputLoggerThread(final String name, final BufferedReader in) { + super(); + prefix = "[" + name + "] "; + this.in = in; + } + + @Override + public void run() { + try { + while (!shutingDown) { + final String line = in.readLine(); + + if (line == null) { + break; + } + // Logger.log(IStatus.INFO, IStatus.OK, prefix + line, + // null); + System.err.println(prefix + line); + } + } catch (IOException e) { + if (!"Stream closed".equals(e.getMessage())) { + final String message = "OutputLogger died with error"; + Logger.log(IStatus.INFO, Logger.DEBUG, message, e); + } + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + } + } + } + } + + public void shutdown() { + shutingDown = true; + + if (isAlive()) { + interrupt(); + } + } + } + + public void sendUserInterruptReference() { + if (userInterruptReference != null) { + try { + final OsSpecificInfo osInfo = getOsInfo(Platform.getOS()); + final String command = getCliPath() + File.separator + + osInfo.subdir + File.separator + + osInfo.userInterruptCmd; + Runtime.getRuntime().exec( + new String[] { command, + userInterruptReference.toString() }); + } catch (CliException e) { + Logger.info("getting the os specific info failed with exception: " + + e.getLocalizedMessage()); + } catch (IOException e) { + Logger.info("calling the send_user_interrupt command failed: " + + e.getLocalizedMessage()); + } + } + } + + private static class OsSpecificInfo { + final String subdir; + final String cliName; + final String helperCmd; + final String userInterruptCmd; + + public OsSpecificInfo(final String subdir, final String cliName, + final String helperCmd, final String userInterruptCmd) { + this.subdir = subdir; + this.cliName = cliName; + this.helperCmd = helperCmd; + this.userInterruptCmd = userInterruptCmd; + } + + } +} diff --git a/de.prob.core/src/de/prob/cli/clipatterns/CliPattern.java b/de.prob.core/src/de/prob/cli/clipatterns/CliPattern.java new file mode 100644 index 0000000000000000000000000000000000000000..5d59454c40c9d2e9323fb6992d4213bdf8bb26c1 --- /dev/null +++ b/de.prob.core/src/de/prob/cli/clipatterns/CliPattern.java @@ -0,0 +1,65 @@ +/** + * + */ +package de.prob.cli.clipatterns; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import de.prob.cli.CliException; + +/** + * Base class for doing pattern matching on the standard output on startup of + * the ProB command line executable. + * + * @author plagge + */ +public abstract class CliPattern<T> { + private final Pattern pattern; + private Matcher matcher; + + protected CliPattern(String regex) { + this.pattern = Pattern.compile(regex); + } + + /** + * Is called for each line of the standard output until this object matches + * a line or until the command loop starts. + * + * @param line + * the standard output line as string + * @return if the line matches + */ + public boolean matchesLine(String line) { + matcher = pattern.matcher(line); + final boolean hit = matcher.find(); + if (hit) { + setValue(matcher); + } + return hit; + } + + /** + * If the current line matches the pattern, this method is called with the + * resulting {@link Matcher} object. An implementation of this method should + * find a value that can be accessed via {@link #getValue()}. + * + * @param matcher + */ + protected abstract void setValue(Matcher matcher); + + /** + * Returns the resulting value determined by the input line. + * + * @return + */ + public abstract T getValue(); + + /** + * This method is called if no line matched on this pattern and the start of + * the command loop is reached. + * + * @throws CliException + */ + public abstract void notFound() throws CliException; +} diff --git a/de.prob.core/src/de/prob/cli/clipatterns/InterruptRefPattern.java b/de.prob.core/src/de/prob/cli/clipatterns/InterruptRefPattern.java new file mode 100644 index 0000000000000000000000000000000000000000..65ab44dd2d3c4b0582a24ca851549d273f1dee3b --- /dev/null +++ b/de.prob.core/src/de/prob/cli/clipatterns/InterruptRefPattern.java @@ -0,0 +1,44 @@ +/** + * + */ +package de.prob.cli.clipatterns; + +import java.util.regex.Matcher; + +import de.prob.cli.CliException; +import de.prob.logging.Logger; + +/** + * Extracts the reference for user interrupt calls from the process' startup + * information. The reference must be later passed to the send_interrupt command + * when an user interrupt should be signalled. + * + * @author plagge + */ +public class InterruptRefPattern extends CliPattern<Long> { + + private Long reference; + + public InterruptRefPattern() { + super("user interrupt reference id: *(\\d+) *$"); + } + + @Override + protected void setValue(final Matcher matcher) { + reference = Long.parseLong(matcher.group(1)); + Logger.info("Server can receive user interrupts via reference " + + reference); + } + + @Override + public Long getValue() { + return reference; + } + + @Override + public void notFound() throws CliException { + Logger.notifyUser("Could not determine user interrupt reference of ProB server. " + + "You might not be able to interrupt a running calculation."); + } + +} diff --git a/de.prob.core/src/de/prob/cli/clipatterns/PortPattern.java b/de.prob.core/src/de/prob/cli/clipatterns/PortPattern.java new file mode 100644 index 0000000000000000000000000000000000000000..3878e2cbc7662fb6fbaf5960c56575985f57d2cc --- /dev/null +++ b/de.prob.core/src/de/prob/cli/clipatterns/PortPattern.java @@ -0,0 +1,52 @@ +/** + * + */ +package de.prob.cli.clipatterns; + +import java.util.regex.Matcher; + +import de.prob.cli.CliException; +import de.prob.logging.Logger; + +/** + * This {@link CliPattern} looks for a network port number where the executable + * listens for commands. + * + * If no port number is found, {@link #notFound()} throws a {@link CliException} + * + * @author plagge + */ +public class PortPattern extends CliPattern<Integer> { + int port; + + public PortPattern() { + super("Port: (\\d+)$"); + } + + @Override + protected void setValue(Matcher matcher) throws IllegalArgumentException { + port = Integer.parseInt(matcher.group(1)); + Logger.info("Server has startet and listens on port " + port); + } + + /** + * Returns the port number. + */ + @Override + public Integer getValue() { + return port; + } + + @Override + public void notFound() throws CliException { + // final String message = "Could not determine port of ProB server"; + // Logger.notifyUser(message); + // throw new CliException(message); + + CliException cliException = new CliException( + "Could not determine port of ProB server"); + cliException.notifyUserOnce(); + throw cliException; + } + +} diff --git a/de.prob.core/src/de/prob/core/Animator.java b/de.prob.core/src/de/prob/core/Animator.java new file mode 100644 index 0000000000000000000000000000000000000000..22b73ded0764bf013dbf7980ba26622489657762 --- /dev/null +++ b/de.prob.core/src/de/prob/core/Animator.java @@ -0,0 +1,341 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.commands.Command; +import org.osgi.service.prefs.Preferences; + +import de.prob.core.command.IComposableCommand; +import de.prob.core.domainobjects.History; +import de.prob.core.domainobjects.MachineDescription; +import de.prob.core.domainobjects.Operation; +import de.prob.core.domainobjects.RandomSeed; +import de.prob.core.domainobjects.State; +import de.prob.core.internal.Activator; +import de.prob.core.internal.AnimatorImpl; +import de.prob.core.internal.ServerTraceConnection; +import de.prob.core.internal.TraceConnectionProvider; +import de.prob.exceptions.ProBException; + +/** + * Animator is a singleton Proxy used to communicate with ProB. The method + * {@link Animator#getAnimator()} returns the current instance, that can be used + * to communicate with the ProB core. {@link Animator#execute(Command)} should + * be used by commands (see {@link Command} for an example), not directly by + * clients. + * + * @author Jens Bendisposto + * + */ + +public final class Animator { + + private static Animator animator = new Animator(); + + /** + * + */ + private IConnectionProvider connectionProvider = null; + private volatile boolean dirty; + private final Map<Object, Object> dataStore = new HashMap<Object, Object>(); + + private AnimatorImpl implementation; + + // ------------------ Container Lifecycle + + /** + * Used to obtain a reference to the animator object. This can be kept + * without problem. If a different animation was started, the reference will + * change accordingly. + * + * <p> + * Note: There is only <b>one</b> model loaded at a time. + * </p> + * + * @return Reference to the singleton instance of Animator + */ + public final static Animator getAnimator() { + return animator; + } + + /** + * Terminates the current animation (forcefully!) and restarts the ProB + * core. After calling this method, all information from the current + * animation will be lost. + * + * Note: This will be automatically called by the ClearLoadedMachine + * command. Typically there is no need to call this method from other + * places. + */ + public final static void killAndReload() { + killAndLoad(null); + } + + public final static void killAndLoad(final File file) { + synchronized (animator) { + animator.killImplementation(); + animator.createNewImplementation(file); + } + + } + + private final synchronized void createNewImplementation(final File file) { + final AnimatorImpl impl = new AnimatorImpl(getIServerConnection(), file); + setImplementation(impl); + StaticListenerRegistry.registerComputationListener(getHistory()); + } + + private synchronized void setImplementation(final AnimatorImpl impl) { + implementation = impl; + } + + private final synchronized void killImplementation() { + if (implementation != null) { + final History history = animator.getHistory(); + StaticListenerRegistry.unregisterComputationListener(history); + implementation.shutdownImplementation(); + implementation = null; + } + } + + // ------------------ Container Lifecycle + + private Animator() { + } + + /** + * This constructor is only for Unit-Tests. Use the + * AnimatorTestFactory#create method to create new Instance instrumented + * with a particular Implementation. Note, that this actually creates a new + * Animator instance, that is different from the one that is received from + * {@link Animator#getAnimator()} + * + * @param impl + */ + private Animator(final AnimatorImpl impl) { + setImplementation(impl); + } + + /** + * Kills the implementation, i.e. the underlying instance of ProB + */ + public final synchronized void shutdown() { + if (implementation != null) { + implementation.shutdownImplementation(); + } + } + + // ------------------ Announce Methods + /** + * Announces the reset event to all registered {@link ILifecycleListener}. + */ + public void announceReset() { + getHistory().reset(); + Activator.reset(); + } + + /** + * Announces the change of ProB's current state to all registered + * {@link IAnimationListener}. For instance after executing an + * operation/event from the UI or replaying a trace. If the model checking + * mode is enabled, the animator does not propagate the information to all + * listeners but only to its own implementation (to prevent the GUI from + * displaying all changes during model checking). + */ + public synchronized void announceCurrentStateChanged(final State state, + final Operation operation) { + Activator.currentStateChanged(state, operation); + } + + /** + * Announces that a new state has been discovered to all registered + * {@link IComputationListener}. Note that this does not mean, that ProB + * changed its state. + */ + public void announceComputedState(final State state) { + Activator.computedState(state); + } + + // ------------------ Delegates + + public final synchronized void execute(final IComposableCommand command) + throws ProBException { + LimitedLogger.getLogger().log("execute command", command, null); + getImplementation().execute(command); + LimitedLogger.getLogger().log("command executed", command, null); + } + + /** + * @return The model's current state + */ + public final synchronized State getCurrentState() { + return getImplementation().getCurrentStateImpl(); + } + + /** + * @return The animation history, i.e. a trace from the root state to the + * current state + */ + public final synchronized History getHistory() { + return getImplementation().getHistoryImpl(); + } + + /** + * @return true, iff there is an animation running + */ + public synchronized boolean isRunning() { + return (implementation != null); + } + + private synchronized AnimatorImpl getImplementation() { + if (implementation == null) { + createNewImplementation(null); + } + return implementation; + } + + /** + * + * @param {@link IConnectionProvider} provider + */ + public final synchronized void setConnectionProvider( + final IConnectionProvider provider) { + connectionProvider = provider; + } + + /** + * @return {@link IServerConnection}, by default (that means + * <code>connectionProvider == null</code>) the + * {@link ServerTraceConnection}. If a {@link IConnectionProvider} + * is set, it is asked to provide a new IServerConnection + * + */ + private final synchronized IServerConnection getIServerConnection() { + if (connectionProvider == null) { + connectionProvider = new TraceConnectionProvider(); + } + return connectionProvider.getISeverConnection(); + } + + /** + * + * @return {@link ITrace}, or null if the IServerConnection is not a + * {@link ServerTraceConnection} + */ + public final synchronized ITrace getTrace() { + if (implementation != null) + return implementation.getTraceImpl(); + return null; + } + + public final synchronized RandomSeed getRandomSeed() { + return getImplementation().getSeed(); + } + + public final synchronized void setRandomSeed(final RandomSeed seed) { + getImplementation().setSeed(seed); + } + + // just for testing + private Preferences customConfiguration; + + public void setCustomConfiguration(final Preferences customConfiguration) { + if (customConfiguration != null) { + this.customConfiguration = customConfiguration; + } + } + + public Preferences getCustomConfiguration() { + return customConfiguration; + } + + /** + * Marks the animation as dirty, i.e., the underlying file has been changed + * and thus the current animation might not reflect the current model. + */ + public void setDirty() { + this.dirty = true; + } + + /** + * Resets the dirty flag. + */ + public void resetDirty() { + this.dirty = false; + } + + /** + * The dirty flag will be set, if one of the model's resources change during + * an animation. + * + * @return true if the model and the animation might be out of sync + */ + public boolean isDirty() { + return dirty; + } + + public void setMachineDescription( + final MachineDescription machineDescription) { + getImplementation().setMachineDescription(machineDescription); + } + + public MachineDescription getMachineDescription() { + return getImplementation().getMachineDescription(); + } + + public boolean isMachineLoaded() { + return getImplementation().isMachineLoaded(); + } + + public String getDebuggingKey() { + return getImplementation().getDebuggingKey(); + } + + public LanguageDependendAnimationPart getLanguageDependendPart() { + return getImplementation().getLangdep(); + } + + public void setLanguageDependendPart( + final LanguageDependendAnimationPart ldPart) { + getImplementation().setLangdep(ldPart); + } + + /** + * Each animator instance provides a possibility to store arbitrary data + * related to this animator. E.g., this can be used for caching. This method + * sets the data using an unique key. + * + * @param key + * @param data + */ + public synchronized void setData(final Object key, final Object data) { + dataStore.put(key, data); + } + + /** + * Each animator instance provides a possibility to store arbitrary data + * related to this animator. E.g., this can be used for caching. + * + * This method returns the data that was previously set by + * {@link #setData(Object, Object)}. + * + * @param key + * @return + */ + public synchronized Object getData(final Object key) { + return dataStore.get(key); + } + + // if synchronized this will produce a deadlock. Ignore findbugs here + public void sendUserInterruptSignal() { + if (implementation != null) implementation.sendUserInterruptSignal(); + } +} diff --git a/de.prob.core/src/de/prob/core/IAnimationListener.java b/de.prob.core/src/de/prob/core/IAnimationListener.java new file mode 100644 index 0000000000000000000000000000000000000000..6605aeb5b0c9a5f4cdfd24c12301c6da477f672f --- /dev/null +++ b/de.prob.core/src/de/prob/core/IAnimationListener.java @@ -0,0 +1,27 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core; + +import de.prob.core.domainobjects.Operation; +import de.prob.core.domainobjects.State; + +public interface IAnimationListener { + + /** + * Event fired, when the current state of an animated machine changes. + * + * @param currentState + * The new current {@link State} of the machine. + * @param operation + * The {@link Operation} which resulted in the new current state. + * May be <code>{@link Operation#NULL_OPERATION}}</code> if no + * existing {@link Operation} was executed (i.e. when loading a + * machine setting the initial current state, history jumps, + * ...). + */ + public void currentStateChanged(State currentState, Operation operation); +} diff --git a/de.prob.core/src/de/prob/core/IComputationListener.java b/de.prob.core/src/de/prob/core/IComputationListener.java new file mode 100644 index 0000000000000000000000000000000000000000..6f789e745235153d44cfce3c2251a39173d93f0b --- /dev/null +++ b/de.prob.core/src/de/prob/core/IComputationListener.java @@ -0,0 +1,20 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core; + +import de.prob.core.domainobjects.State; + +public interface IComputationListener { + /** + * A new state has been computed. i.e. the sucessor states and the status of + * the state's invariant are accessible. + * + * @param ressource + * @param state + */ + public void computedState(State state); +} diff --git a/de.prob.core/src/de/prob/core/IConnectionProvider.java b/de.prob.core/src/de/prob/core/IConnectionProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..8fab6f07f31b088c6fc72f972fa2208ca2f9c1f3 --- /dev/null +++ b/de.prob.core/src/de/prob/core/IConnectionProvider.java @@ -0,0 +1,17 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core; + + + +public interface IConnectionProvider { + /** + * + * @return new {@link IServerConnection} + */ + public IServerConnection getISeverConnection(); +} diff --git a/de.prob.core/src/de/prob/core/ILifecycleListener.java b/de.prob.core/src/de/prob/core/ILifecycleListener.java new file mode 100644 index 0000000000000000000000000000000000000000..2e61b5f6ba32faed6811541ab2a66eaa6b26081f --- /dev/null +++ b/de.prob.core/src/de/prob/core/ILifecycleListener.java @@ -0,0 +1,19 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core; + +public interface ILifecycleListener { + + /** + * A new machine was loaded, marks the start of an animation or model + * checking. + * + * @param ressource + */ + public void reset(); + +} diff --git a/de.prob.core/src/de/prob/core/IServerConnection.java b/de.prob.core/src/de/prob/core/IServerConnection.java new file mode 100644 index 0000000000000000000000000000000000000000..45e7155f87a5b2b687d15a1e56afb80650d3bd6c --- /dev/null +++ b/de.prob.core/src/de/prob/core/IServerConnection.java @@ -0,0 +1,49 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core; + +import java.io.File; + +import de.prob.cli.CliException; +import de.prob.exceptions.ProBException; + +/** + * This interface can be used to mock up a connection to ProB for testing. Don't + * use this in productive code. + * + * An example of such a mock is + * + * <pre> + * IServerConnection mock = EasyMock.createMock(IServerConnection.class); + * mock.startup(); + * EasyMock.expect(mock.sendCommand(COMMAND)).andReturn( + * ProBResultParser.parse(EXPECTED_ANSWER)); + * GetErrorsHelper.expectGetErrors(mock); + * EasyMock.replay(mock); + * Animator animator = new AnimatorImpl(mock); + * EasyMock.verify(mock); + * // [ ... Assertions ...] + * </pre> + * + * @author Jens Bendisposto + * + */ +public interface IServerConnection { + + public abstract int getCliPortNumber(); + + public abstract String sendCommand(final String commandString) + throws ProBException; + + public abstract void shutdown(); + + public abstract void startup(File file) throws CliException; + + String getDebuggingKey(); + + void sendUserInterruptSignal(); +} \ No newline at end of file diff --git a/de.prob.core/src/de/prob/core/ITrace.java b/de.prob.core/src/de/prob/core/ITrace.java new file mode 100644 index 0000000000000000000000000000000000000000..eb7647044dd9ef1a1339f11625b52700a4a79e9b --- /dev/null +++ b/de.prob.core/src/de/prob/core/ITrace.java @@ -0,0 +1,32 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core; + +import java.util.List; + +import de.prob.core.internal.Message; + +public interface ITrace { + + /** + * @return the List of logged messages as a String + */ + public String getTraceAsString(); + + /** + * @return the List of logged messages as unmodifiable List of + * {@link Message} + */ + public List<Message> getTraceAsList(); + + public int size(); + + void setMaximum(Integer max); + + Integer getMaximum(); + +} diff --git a/de.prob.core/src/de/prob/core/LanguageDependendAnimationPart.java b/de.prob.core/src/de/prob/core/LanguageDependendAnimationPart.java new file mode 100644 index 0000000000000000000000000000000000000000..fc907096d1f71c97761268c861a3828363816e95 --- /dev/null +++ b/de.prob.core/src/de/prob/core/LanguageDependendAnimationPart.java @@ -0,0 +1,16 @@ +/** + * + */ +package de.prob.core; + +import de.prob.exceptions.ProBException; +import de.prob.parserbase.ProBParserBase; + +/** + * + * + * @author plagge + */ +public interface LanguageDependendAnimationPart extends ProBParserBase { + void reload(Animator animator) throws ProBException; +} diff --git a/de.prob.core/src/de/prob/core/LimitedLogger.java b/de.prob.core/src/de/prob/core/LimitedLogger.java new file mode 100644 index 0000000000000000000000000000000000000000..168b41629438de52b3f4ecf7990b258c916f001c --- /dev/null +++ b/de.prob.core/src/de/prob/core/LimitedLogger.java @@ -0,0 +1,230 @@ +/** + * + */ +package de.prob.core; + +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedList; + +/** + * This specialized Logger class stores a limited number of log entries in + * memory. None of its information is written to a file nor console. + * + * Listeners can be registered to be notified when a new log entry comes in. A + * separate notification thread ensures that not too many messages will be sent + * by waiting a little bit and collection information. + * + * For each log entry the current time is added to allow performance + * measurements. + * + * @author plagge + */ +public class LimitedLogger { + private final static LogEntry[] EMPTY_ARRAY = new LogEntry[0]; + private final static LimitedLogger LOGGER = new LimitedLogger(); + private final static long DELAY = 300; + + public interface LogListener { + void newLoggingInfo(); + } + + public final static class LogEntry { + private final long id; + private final long time; + private final String category; + private final Object shortDescriptionObj; + private final Object longDescriptionObj; + private String shortDescription; + private String longDescription; + + public LogEntry(final long id, final long time, final String category, + final String shortDescription, final String longDescription) { + this.id = id; + this.time = time; + this.category = category; + this.shortDescription = shortDescription; + this.longDescription = longDescription; + this.shortDescriptionObj = null; + this.longDescriptionObj = null; + } + + public LogEntry(final long id, final long time, final String category, + final Object shortDescription, final Object longDescription) { + this.id = id; + this.time = time; + this.category = category; + this.shortDescriptionObj = shortDescription; + this.longDescriptionObj = longDescription; + } + + public long getId() { + return id; + } + + public long getTime() { + return time; + } + + public String getCategory() { + return category; + } + + public String getShortDescription() { + if (shortDescription == null && shortDescriptionObj != null) { + shortDescription = shortDescriptionObj.toString(); + } + return shortDescription; + } + + public String getLongDescription() { + if (longDescription == null && longDescriptionObj != null) { + longDescription = longDescriptionObj.toString(); + } + return longDescription; + } + } + + private final Object newEventsNotification = new Object(); + + private int limit = 200; + private long currentId = 0; + private final LinkedList<LogEntry> entries = new LinkedList<LogEntry>(); + private final Collection<LogListener> listener = new HashSet<LogListener>(); + private NotificationThread notificationThread = null; + private Long firstTime; + + public synchronized void log(final String category, + final Object shortDescription, final Object longDescription) { + final long now = System.currentTimeMillis(); + final LogEntry entry = new LogEntry(currentId, now, category, + shortDescription, longDescription); + log(now, entry); + } + + public synchronized void log(final String category, + final String shortDescription, final String longDescription) { + final long now = System.currentTimeMillis(); + final LogEntry entry = new LogEntry(currentId, now, category, + shortDescription, longDescription); + log(now, entry); + } + + private void log(final long now, final LogEntry entry) { + if (entries.size() >= limit) { + entries.removeFirst(); + } + if (firstTime == null) { + firstTime = now; + } + entries.addLast(entry); + currentId++; + synchronized (newEventsNotification) { + newEventsNotification.notifyAll(); + } + } + + public synchronized void setLimit(final int limit) { + this.limit = limit; + while (entries.size() > limit) { + entries.removeFirst(); + } + } + + public synchronized LogEntry[] getEntries() { + return entries.toArray(EMPTY_ARRAY); + } + + public static LimitedLogger getLogger() { + return LOGGER; + } + + public void registerListener(final LogListener listener) { + synchronized (listener) { + this.listener.add(listener); + if (notificationThread == null) { + notificationThread = new NotificationThread(this); + notificationThread.setDaemon(true); + notificationThread.start(); + } + } + } + + public void unregisterListener(final LogListener listener) { + synchronized (listener) { + this.listener.remove(listener); + if (this.listener.isEmpty()) { + notificationThread.stopNotification(); + notificationThread = null; + } + } + } + + /** + * Get the time of the first log entry + * + * @return the time in milliseconds since epoch, <code>null</code> if there + * is no entry yet. + */ + public synchronized Long getFirstLoggingTime() { + return firstTime; + } + + /** + * Clear all entries + */ + public synchronized void clear() { + this.entries.clear(); + } + + private static class NotificationThread extends Thread { + private final LimitedLogger logger; + private final static long lastNotification = 0; + private boolean stopped = false; + + public NotificationThread(final LimitedLogger logger) { + super("LimitedLoggerNotification"); + this.logger = logger; + } + + public void stopNotification() { + this.stopped = true; + this.interrupt(); + } + + @Override + public void run() { + while (!stopped) { + try { + // wait for the next new event + synchronized (logger.newEventsNotification) { + if (!stopped) { + logger.newEventsNotification.wait(); + } + } + // then wait a little bit to prevent too many notifications + Thread.sleep(DELAY); + } catch (InterruptedException e) { + // ignore + } + notifyIfNewData(); + } + } + + private void notifyIfNewData() { + final long current; + synchronized (logger) { + current = logger.currentId; + } + if (lastNotification < current) { + synchronized (logger.listener) { + if (!stopped) { + for (LogListener l : logger.listener) { + l.newLoggingInfo(); + } + } + } + } + } + } +} diff --git a/de.prob.core/src/de/prob/core/ListenerRegistry.java b/de.prob.core/src/de/prob/core/ListenerRegistry.java new file mode 100644 index 0000000000000000000000000000000000000000..6c547ba1af7f6d18d669bbab9a6c0f8d6d37e6b8 --- /dev/null +++ b/de.prob.core/src/de/prob/core/ListenerRegistry.java @@ -0,0 +1,90 @@ +/** + * + */ +package de.prob.core; + +import java.util.HashSet; +import java.util.Set; + +import de.prob.core.domainobjects.Operation; +import de.prob.core.domainobjects.State; +import de.prob.logging.Logger; + +/** + * @author plagge + * + */ +public class ListenerRegistry implements ILifecycleListener, + IComputationListener, IAnimationListener { + + private final Set<ILifecycleListener> lifeCycleListeners = new HashSet<ILifecycleListener>(); + private final Set<IComputationListener> computationListeners = new HashSet<IComputationListener>(); + private final Set<IAnimationListener> animationListeners = new HashSet<IAnimationListener>(); + + public void registerLifecycleListener(final ILifecycleListener listener) { + lifeCycleListeners.add(listener); + } + + public void unregisterLifecycleListener(final ILifecycleListener listener) { + lifeCycleListeners.remove(listener); + } + + public void registerComputationListener(final IComputationListener listener) { + computationListeners.add(listener); + } + + public void unregisterComputationListener( + final IComputationListener listener) { + computationListeners.remove(listener); + } + + public void registerAnimationListener(final IAnimationListener listener) { + animationListeners.add(listener); + } + + public void unregisterAnimationListener(final IAnimationListener listener) { + animationListeners.remove(listener); + } + + public void reset() { + for (final ILifecycleListener listener : lifeCycleListeners) { + try { + listener.reset(); + } catch (final RuntimeException e) { + final String classname = listener.getClass().getCanonicalName(); + final String message = "Runtime Exception thrown in bad behaving listener class " + + classname + " while sending reset event"; + Logger.notifyUser(message, e); + } + } + } + + public void computedState(final State state) { + for (final IComputationListener listener : computationListeners) { + try { + listener.computedState(state); + } catch (final RuntimeException e) { + final String classname = listener.getClass().getCanonicalName(); + final String message = "Runtime Exception thrown in bad behaving listener class " + + classname + " while sending computedState event"; + Logger.notifyUser(message, e); + } + } + } + + public void currentStateChanged(final State currentState, + final Operation operation) { + for (final IAnimationListener listener : animationListeners) { + try { + listener.currentStateChanged(currentState, operation); + } catch (final RuntimeException e) { + final String classname = listener.getClass().getCanonicalName(); + final String message = "Runtime Exception thrown in bad behaving listener class " + + classname + + " while sending currentStateChanged event"; + Logger.notifyUser(message, e); + } + } + } + +} diff --git a/de.prob.core/src/de/prob/core/ProBCommandJob.java b/de.prob.core/src/de/prob/core/ProBCommandJob.java new file mode 100644 index 0000000000000000000000000000000000000000..45f4c0fa55f8311930d359cb4f1835b849d0e38f --- /dev/null +++ b/de.prob.core/src/de/prob/core/ProBCommandJob.java @@ -0,0 +1,67 @@ +/** + * + */ +package de.prob.core; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; + +import de.prob.core.command.IComposableCommand; +import de.prob.core.internal.Activator; +import de.prob.exceptions.ProBException; + +/** + * This jobs takes a command as argument and executes its during the run. If the + * user selects cancel, the animator is asked to send an user interruption + * signal to the Prolog core. + * + * @author plagge + */ +public class ProBCommandJob extends Job { + private final Animator animator; + private final IComposableCommand command; + + private boolean commandFailed = false; + + public ProBCommandJob(final String name, final Animator animator, + final IComposableCommand command) { + super(name); + this.animator = animator; + this.command = command; + } + + @Override + protected IStatus run(final IProgressMonitor monitor) { + Activator.getDefault().registerJob(this); + monitor.beginTask(getName(), IProgressMonitor.UNKNOWN); + commandFailed = false; + try { + animator.execute(command); + } catch (ProBException e) { + commandFailed = true; + e.notifyUserOnce(); + return Status.CANCEL_STATUS; + } + return Status.OK_STATUS; + } + + @Override + protected void canceling() { + animator.sendUserInterruptSignal(); + } + + public IComposableCommand getCommand() { + return command; + } + + public Animator getAnimator() { + return animator; + } + + public boolean isCommandFailed() { + return commandFailed; + } + +} diff --git a/de.prob.core/src/de/prob/core/ProBJobFinishedListener.java b/de.prob.core/src/de/prob/core/ProBJobFinishedListener.java new file mode 100644 index 0000000000000000000000000000000000000000..c38986a76313d9eecabb69e96e42b0b4af75c3e0 --- /dev/null +++ b/de.prob.core/src/de/prob/core/ProBJobFinishedListener.java @@ -0,0 +1,34 @@ +package de.prob.core; + +import org.eclipse.core.runtime.jobs.IJobChangeEvent; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.core.runtime.jobs.JobChangeAdapter; + +import de.prob.core.command.IComposableCommand; +import de.prob.logging.Logger; + +public abstract class ProBJobFinishedListener extends JobChangeAdapter { + + public ProBJobFinishedListener() { + super(); + } + + @Override + public void done(final IJobChangeEvent event) { + super.done(event); + Job job = event.getJob(); + if (job instanceof ProBCommandJob) { + final ProBCommandJob checkJob = (ProBCommandJob) job; + if (!checkJob.isCommandFailed()) { + showResult(checkJob.getCommand(), checkJob.getAnimator()); + } + } else { + final String message = "The job has a wrong type. Expected ProBCommandJob but got " + + job.getClass(); + Logger.notifyUserWithoutBugreport(message); + } + } + + abstract protected void showResult(IComposableCommand command, + Animator animator); +} \ No newline at end of file diff --git a/de.prob.core/src/de/prob/core/ProblemHandler.java b/de.prob.core/src/de/prob/core/ProblemHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..71a053deee6387733df75e02b8398bdd55428155 --- /dev/null +++ b/de.prob.core/src/de/prob/core/ProblemHandler.java @@ -0,0 +1,140 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core; + +import java.util.List; + +import org.apache.commons.lang.StringUtils; + +import de.prob.cli.CliException; +import de.prob.core.command.CommandException; +import de.prob.core.internal.ResultParserException; +import de.prob.logging.Logger; + +public class ProblemHandler { + + /** + * Notifies the User about a fatal problem inside a command by adding a + * {@link Logger#FATALERROR} to the log. This method takes a message + * describing the problem.<br> + * + * <b>Note:</b> Calling this method logs the problem and throws a new + * {@link CommandException} that uses the message given <br> + * <b>Note:</b> If the problem is related to the content of a returned + * answer, such as an unexpectedly failed query, use + * {@link #raiseCommandException(String)(String)} + * + * @param message + * Description of the problem + * @throws CommandException + */ + public static void raiseCliException(final String message) + throws CliException { + Logger.notifyUser(message); + throw new CliException(message, true); + } + + /** + * Notifies the User about a fatal problem inside a command by adding a + * {@link Logger#FATALERROR} to the log. This method takes a message + * describing the problem.<br> + * + * <b>Note:</b> Calling this method logs the problem and throws a new + * {@link CliException} that uses the message given <br> + * <b>Note:</b> If the problem is related to a "low level" construct, such + * as exceptions while sending or receiving messages, use + * {@link #raiseCliException(String)} + * + * @param message + * Description of the problem + * @throws CommandException + */ + public static void raiseCommandException(final String message) + throws CommandException { + Logger.notifyUser(message); + throw new CommandException(message); + } + + /** + * Notifies the user, that ProB raised some error messages + * + * @param errors + * The List of Error Messages from ProB + * @throws PrologException + */ + public static void raisePrologException(final List<String> errors) + throws PrologException { + final String message = "ProB reported errors:\n" + + StringUtils.join(errors, '\n'); + Logger.notifyUser(message); + throw new PrologException(message); + } + + /** + * + * Notifies the User about a fatal problem by adding a + * {@link Logger#FATALERROR} to the log. This method takes a message + * describing the problem and the causing exception. + * + * Note: Calling this method logs the problem and throws a CliException that + * wraps the original problem + * + * @param message + * Description of the problem + * @param throwable + * Causing exception + * @throws CommandException + */ + public static void handleCommandException(final String message, + final Throwable t) throws CommandException { + Logger.notifyUser(message, t); + throw new CommandException(message, t); + } + + /** + * + * Notifies the User about a fatal problem by adding a + * {@link Logger#FATALERROR} to the log. This method takes a message + * describing the problem and the causing exception. + * + * Note: Calling this method logs the problem and throws a CliException that + * wraps the original problem + * + * @param message + * Description of the problem + * @param throwable + * Causing exception + * @throws CliException + */ + public static void handleCliException(final String message, + final Throwable t) throws CliException { + Logger.notifyUser(message, t); + throw new CliException(message, t, true); + } + + /** + * + * Notifies the User about a fatal problem by adding a + * {@link Logger#FATALERROR} to the log. This method takes a message + * describing the problem and the causing exception. + * + * Note: Calling this method logs the problem and throws a CliException that + * wraps the original problem + * + * @param message + * Description of the problem + * @param throwable + * Causing exception + * @throws ResultParserException + */ + public static void handleResultPareserException(final String message, + final Throwable t) throws ResultParserException { + Logger.notifyUser(message, t); + throw new ResultParserException(message, t); + } + +} diff --git a/de.prob.core/src/de/prob/core/PrologException.java b/de.prob.core/src/de/prob/core/PrologException.java new file mode 100644 index 0000000000000000000000000000000000000000..f39e0aa8f7c8ce08a4c4de05df6836b4f40c1784 --- /dev/null +++ b/de.prob.core/src/de/prob/core/PrologException.java @@ -0,0 +1,18 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core; + +import de.prob.exceptions.ProBException; + +public class PrologException extends ProBException { + + private static final long serialVersionUID = -7087955720127900792L; + + public PrologException(final String message) { + super(message, true); + } +} diff --git a/de.prob.core/src/de/prob/core/StaticListenerRegistry.java b/de.prob.core/src/de/prob/core/StaticListenerRegistry.java new file mode 100644 index 0000000000000000000000000000000000000000..cd3ebe87e6785ca5fe2217ed91ccb4287119d37f --- /dev/null +++ b/de.prob.core/src/de/prob/core/StaticListenerRegistry.java @@ -0,0 +1,66 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core; + +import de.prob.core.domainobjects.Operation; +import de.prob.core.domainobjects.State; + +/** + * The Registry is registered as a listener to the extension point. It is a + * simple way to dynamically register new listeners without the need to use the + * extension point + * + * @author Jens Bendisposto + */ +public final class StaticListenerRegistry implements ILifecycleListener, + IComputationListener, IAnimationListener { + + private static final ListenerRegistry registry = new ListenerRegistry(); + + public static void registerLifecycleListener( + final ILifecycleListener listener) { + registry.registerLifecycleListener(listener); + } + + public static void unregisterLifecycleListener( + final ILifecycleListener listener) { + registry.unregisterLifecycleListener(listener); + } + + public static void registerComputationListener( + final IComputationListener listener) { + registry.registerComputationListener(listener); + } + + public static void unregisterComputationListener( + final IComputationListener listener) { + registry.unregisterComputationListener(listener); + } + + public static void registerAnimationListener( + final IAnimationListener listener) { + registry.registerAnimationListener(listener); + } + + public static void unregisterAnimationListener( + final IAnimationListener listener) { + registry.unregisterAnimationListener(listener); + } + + public void reset() { + registry.reset(); + } + + public void computedState(final State state) { + registry.computedState(state); + } + + public void currentStateChanged(final State currentState, + final Operation operation) { + registry.currentStateChanged(currentState, operation); + } +} diff --git a/de.prob.core/src/de/prob/core/command/AnalyseInvariantCommand.java b/de.prob.core/src/de/prob/core/command/AnalyseInvariantCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..b5791a4c4efb21dbc3575f313fc9c082c78e3cf4 --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/AnalyseInvariantCommand.java @@ -0,0 +1,48 @@ +package de.prob.core.command; + +import de.prob.parser.ISimplifiedROMap; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.ListPrologTerm; +import de.prob.prolog.term.PrologTerm; + +public class AnalyseInvariantCommand implements ISimpleTextCommand { + + private static final String UNKNOWN = "Unknown"; + private static final String FALSE = "False"; + private static final String TOTAL = "Total"; + private static final String RESULT = "Result"; + private static final String DESCRIPTION = "Desc"; + private StringBuffer text; + + @Override + public void writeCommand(IPrologTermOutput pto) { + // analyse_predicate(Type,Desc,Result,Total,False,Unknown) + pto.openTerm("analyse_predicate").printAtom("invariant") + .printVariable(DESCRIPTION).printVariable(RESULT) + .printVariable(TOTAL).printVariable(FALSE) + .printVariable(UNKNOWN).closeTerm(); + } + + @Override + public void processResult(ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + text = new StringBuffer(); + text.append("Analysed: " + bindings.get(DESCRIPTION) + "\n"); + text.append("-------------------------------------\n"); + ListPrologTerm r = (ListPrologTerm) bindings.get(RESULT); + for (PrologTerm term : r) { + text.append(term); + text.append('\n'); + } + text.append("-------------------------------------\n"); + text.append("Total: " + bindings.get(TOTAL)+ "\n"); + text.append("False: " + bindings.get(FALSE)+ "\n"); + text.append("Unknown: " + bindings.get(UNKNOWN)); + } + + @Override + public String getResultingText() { + return text.toString(); + } + +} diff --git a/de.prob.core/src/de/prob/core/command/CheckBooleanPropertyCommand.java b/de.prob.core/src/de/prob/core/command/CheckBooleanPropertyCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..8756433b07d35e51699f71a2c70fa2f2c25e9afe --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/CheckBooleanPropertyCommand.java @@ -0,0 +1,84 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.command; + +import de.prob.core.Animator; +import de.prob.exceptions.ProBException; +import de.prob.parser.ISimplifiedROMap; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.CompoundPrologTerm; +import de.prob.prolog.term.PrologTerm; + +/* + * This class is quasi abstract, do not instantiate this class. Use the derived + * classes or the static methods to retrieve the boolean values + */ +public class CheckBooleanPropertyCommand implements IComposableCommand { + private static final String PROP_RESULT = "PropResult"; + private static final PrologTerm PROLOG_TRUE = new CompoundPrologTerm("true"); + private static final PrologTerm PROLOG_FALSE = new CompoundPrologTerm( + "false"); + + private final String stateId; + private final String propertyName; + private Boolean result; + + protected CheckBooleanPropertyCommand(final String propertyName, + final String stateId) { + this.propertyName = propertyName; + this.stateId = stateId; + } + + public static boolean isPropertyTrue(final Animator a, + final String propertyName, final String stateId) + throws ProBException { + CheckBooleanPropertyCommand checkPropertyCommand = new CheckBooleanPropertyCommand( + propertyName, stateId); + a.execute(checkPropertyCommand); + return checkPropertyCommand.getResult(); + } + + // + // IComposableCommand + // + + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + PrologTerm answer = bindings.get(PROP_RESULT); + if (PROLOG_TRUE.equals(answer)) { + result = true; + } else if (PROLOG_FALSE.equals(answer)) { + result = false; + } else { + result = null; + throw new CommandException("Expected true or false, but was: " + + answer); + } + } + + private static void writeCommand(final IPrologTermOutput pto, + final String propertyName, final String stateId) { + pto.openTerm("state_property"); + pto.printAtom(propertyName); + pto.printAtomOrNumber(stateId); + pto.printVariable(PROP_RESULT); + pto.closeTerm(); + } + + public void writeCommand(final IPrologTermOutput pto) { + writeCommand(pto, propertyName, stateId); + } + + public boolean getResult() { + if (result == null) + throw new IllegalStateException( + "Cannot get result before finishing query"); + return result; + } + +} diff --git a/de.prob.core/src/de/prob/core/command/CheckInitialisationStatusCommand.java b/de.prob.core/src/de/prob/core/command/CheckInitialisationStatusCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..34c7e350772a5df5399e9a2bbdddc86eb3c0de01 --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/CheckInitialisationStatusCommand.java @@ -0,0 +1,27 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.command; + +import de.prob.core.Animator; +import de.prob.exceptions.ProBException; + +public final class CheckInitialisationStatusCommand extends + CheckBooleanPropertyCommand { + + private static final String IS_INITIALISED_STATE = "isInitialisedState"; + + public static boolean isInitialized(final Animator a, final String stateId) + throws ProBException { + return CheckBooleanPropertyCommand.isPropertyTrue(a, + IS_INITIALISED_STATE, stateId); + } + + public CheckInitialisationStatusCommand(final String stateId) { + super("initialised", stateId); + } + +} diff --git a/de.prob.core/src/de/prob/core/command/CheckInvariantStatusCommand.java b/de.prob.core/src/de/prob/core/command/CheckInvariantStatusCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..7f1d245c3e09afba586359eefff0444a4c37be17 --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/CheckInvariantStatusCommand.java @@ -0,0 +1,27 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.command; + +import de.prob.core.Animator; +import de.prob.exceptions.ProBException; + +public final class CheckInvariantStatusCommand extends + CheckBooleanPropertyCommand { + + private static final String PROPERTY_NAME = "invariantKO"; + + public CheckInvariantStatusCommand(final String stateId) { + super(PROPERTY_NAME, stateId); + } + + public static boolean isInvariantViolated(final Animator a, + final String stateId) throws ProBException { + return CheckBooleanPropertyCommand.isPropertyTrue(a, PROPERTY_NAME, + stateId); + } + +} diff --git a/de.prob.core/src/de/prob/core/command/CheckMaxOperationReachedStatusCommand.java b/de.prob.core/src/de/prob/core/command/CheckMaxOperationReachedStatusCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..d8b8018c031851e311e6ee46adfd5fca1ac65431 --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/CheckMaxOperationReachedStatusCommand.java @@ -0,0 +1,27 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.command; + +import de.prob.core.Animator; +import de.prob.exceptions.ProBException; + +public final class CheckMaxOperationReachedStatusCommand extends + CheckBooleanPropertyCommand { + + private static final String PROPERTY_NAME = "max_operations_reached"; + + public CheckMaxOperationReachedStatusCommand(final String stateId) { + super(PROPERTY_NAME, stateId); + } + + public static boolean maxOperationReached(final Animator a, + final String stateId) throws ProBException { + return CheckBooleanPropertyCommand.isPropertyTrue(a, PROPERTY_NAME, + stateId); + } + +} diff --git a/de.prob.core/src/de/prob/core/command/CheckTimeoutStatusCommand.java b/de.prob.core/src/de/prob/core/command/CheckTimeoutStatusCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..f3d37221e9419d3028205d7cd484fd41765e024c --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/CheckTimeoutStatusCommand.java @@ -0,0 +1,27 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.command; + +import de.prob.core.Animator; +import de.prob.exceptions.ProBException; + +public final class CheckTimeoutStatusCommand extends + CheckBooleanPropertyCommand { + + private static final String PROPERTY_NAME = "timeout_occurred"; + + public CheckTimeoutStatusCommand(final String stateId) { + super(PROPERTY_NAME, stateId); + } + + public static boolean isTimeout(final Animator a, final String stateId) + throws ProBException { + return CheckBooleanPropertyCommand.isPropertyTrue(a, PROPERTY_NAME, + stateId); + } + +} diff --git a/de.prob.core/src/de/prob/core/command/ClearMachineCommand.java b/de.prob.core/src/de/prob/core/command/ClearMachineCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..2cd93def1bbdeb6fb119f9c17651256f0359a017 --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/ClearMachineCommand.java @@ -0,0 +1,55 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.command; + +import de.prob.core.Animator; +import de.prob.exceptions.ProBException; +import de.prob.parser.ISimplifiedROMap; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.PrologTerm; + +public class ClearMachineCommand implements IComposableCommand { + + private static final ClearCmd CLEAR_CMD = new ClearCmd(); + private final GetPrologRandomSeed getRandomSeed; + private final ComposedCommand cmd; + + public ClearMachineCommand() { + this.getRandomSeed = new GetPrologRandomSeed(); + this.cmd = new ComposedCommand(getRandomSeed, CLEAR_CMD); + } + + public static void clearMachine(final Animator animator) + throws ProBException { + animator.execute(new ClearMachineCommand()); + } + + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + cmd.processResult(bindings); + final Animator animator = Animator.getAnimator(); + animator.setRandomSeed(getRandomSeed.getSeed()); + } + + public void writeCommand(final IPrologTermOutput pto) + throws CommandException { + cmd.writeCommand(pto); + } + + private final static class ClearCmd implements IComposableCommand { + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + } + + public void writeCommand(final IPrologTermOutput pto) { + pto.openTerm("clear_loaded_machines").closeTerm(); + } + } + +} diff --git a/de.prob.core/src/de/prob/core/command/CommandException.java b/de.prob.core/src/de/prob/core/command/CommandException.java new file mode 100644 index 0000000000000000000000000000000000000000..04b36b9d9b4d39ae519b8e65edba15c9b1cab15b --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/CommandException.java @@ -0,0 +1,21 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.command; + +import de.prob.exceptions.ProBException; + +public class CommandException extends ProBException { + private static final long serialVersionUID = -533794234155971265L; + + public CommandException(final String message, final Throwable e) { + super(message, e, true); + } + + public CommandException(final String message) { + super(message, true); + } +} diff --git a/de.prob.core/src/de/prob/core/command/ComposedCommand.java b/de.prob.core/src/de/prob/core/command/ComposedCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..a77db17b2c77e5f6ddd4c13745eefeddab5e995d --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/ComposedCommand.java @@ -0,0 +1,135 @@ +/** + * + */ +package de.prob.core.command; + +import java.util.List; + +import org.apache.commons.lang.ArrayUtils; + +import de.prob.parser.ISimplifiedROMap; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.output.PrologTermDelegate; +import de.prob.prolog.term.PrologTerm; + +/** + * A ComposedCommand contains several other commands and writes their query + * strings in one pass to the ProB process. It ensures that no name clashes of + * the variables of the several commands occur. + * + * @author plagge + * + */ +public class ComposedCommand implements IComposableCommand { + private static final char[] LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + .toCharArray(); + + private final IComposableCommand[] cmds; + + public ComposedCommand(final IComposableCommand... cmds) { + this.cmds = cmds; + } + + public ComposedCommand(final List<? extends IComposableCommand> cmds) { + this.cmds = cmds.toArray(new IComposableCommand[0]); + } + + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + final PrefixMap<PrologTerm> prefixMap = new PrefixMap<PrologTerm>( + bindings); + for (int i = 0; i < cmds.length; i++) { + processPrefixedCommand(prefixMap, i); + } + } + + private void processPrefixedCommand(final PrefixMap<PrologTerm> prefixMap, + final int i) throws CommandException { + prefixMap.prefix = createPrefix(i); + cmds[i].processResult(prefixMap); + } + + public void writeCommand(final IPrologTermOutput orig) + throws CommandException { + PrologPrefixVarOutput pto = new PrologPrefixVarOutput(orig); + for (int i = 0; i < cmds.length; i++) { + writePrefixedCommand(pto, i); + } + } + + private void writePrefixedCommand(final PrologPrefixVarOutput pto, + final int i) throws CommandException { + pto.prefix = createPrefix(i); + cmds[i].writeCommand(pto); + } + + private static String createPrefix(final int i) { + if (i < LETTERS.length) + return String.valueOf(LETTERS[i]); + else { + final int letternum = i % LETTERS.length; + final int number = i / LETTERS.length; + return String.valueOf(LETTERS[letternum]) + number; + } + } + + public void reprocessResult(final IComposableCommand command, + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + final int index = ArrayUtils.indexOf(cmds, command); + if (index >= 0) { + final PrefixMap<PrologTerm> prefixMap = new PrefixMap<PrologTerm>( + bindings); + processPrefixedCommand(prefixMap, index); + } else + throw new IllegalArgumentException( + "cannot reprocess command, command unknown"); + } + + /** + * This PrologTermDelegate prefixes every variable with a given string. + */ + private static final class PrologPrefixVarOutput extends PrologTermDelegate { + private String prefix; + + public PrologPrefixVarOutput(final IPrologTermOutput pto) { + super(pto); + } + + @Override + public IPrologTermOutput printVariable(final String var) { + pto.printVariable(prefix == null ? var : prefix + var); + return this; + } + + @Override + public IPrologTermOutput fullstop() { + // ignore the fullstop + return this; + } + } + + /** + * This simplified map prefixes every query to the map with a given string. + */ + private static final class PrefixMap<V> implements + ISimplifiedROMap<String, V> { + private final ISimplifiedROMap<String, V> map; + private String prefix; + + public PrefixMap(final ISimplifiedROMap<String, V> map) { + this.map = map; + } + + public V get(final String key) { + return map.get(prefix == null ? key : prefix + key); + } + + @Override + public String toString() { + return map.toString(); + } + + } +} diff --git a/de.prob.core/src/de/prob/core/command/ComputeCoverageCommand.java b/de.prob.core/src/de/prob/core/command/ComputeCoverageCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..08c2681708764ba456c5f5c9cbff2f67e7b00137 --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/ComputeCoverageCommand.java @@ -0,0 +1,109 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.command; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + +import de.prob.core.Animator; +import de.prob.exceptions.ProBException; +import de.prob.parser.ISimplifiedROMap; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.IntegerPrologTerm; +import de.prob.prolog.term.ListPrologTerm; +import de.prob.prolog.term.PrologTerm; + +public final class ComputeCoverageCommand implements IComposableCommand { + + private ComputeCoverageResult coverageResult; + + public final static class ComputeCoverageResult { + private final BigInteger totalNumberOfNodes; + private final BigInteger totalNumberOfTransitions; + private final List<String> ops = new ArrayList<String>(); + private final List<String> nodes = new ArrayList<String>(); + private final List<String> uncovered = new ArrayList<String>(); + + public ComputeCoverageResult( + final IntegerPrologTerm totalNumberOfNodes, + final IntegerPrologTerm totalNumberOfTransitions, + final ListPrologTerm ops, final ListPrologTerm nodes, + final ListPrologTerm uncovered) { + this.totalNumberOfNodes = totalNumberOfNodes.getValue(); + this.totalNumberOfTransitions = totalNumberOfTransitions.getValue(); + for (PrologTerm op : ops) { + this.getOps().add(op.toString()); + } + for (PrologTerm node : nodes) { + this.getNodes().add(node.toString()); + } + for (PrologTerm unc : uncovered) { + this.getUncovered().add(unc.toString()); + } + + } + + public BigInteger getTotalNumberOfNodes() { + return totalNumberOfNodes; + } + + public BigInteger getTotalNumberOfTransitions() { + return totalNumberOfTransitions; + } + + public List<String> getOps() { + return ops; + } + + public List<String> getNodes() { + return nodes; + } + + public List<String> getUncovered() { + return uncovered; + } + } + + private ComputeCoverageCommand() { + } + + public static ComputeCoverageResult getCoverage(final Animator a) + throws ProBException { + ComputeCoverageCommand computeCoverageCommand = new ComputeCoverageCommand(); + a.execute(computeCoverageCommand); + return computeCoverageCommand.getResult(); + } + + private ComputeCoverageResult getResult() { + return coverageResult; + } + + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + + IntegerPrologTerm totalNodeNr = (IntegerPrologTerm) bindings + .get("TotalNodeNr"); + IntegerPrologTerm totalTransNr = (IntegerPrologTerm) bindings + .get("TotalTransSum"); + + ListPrologTerm ops = (ListPrologTerm) bindings.get("OpStat"); + ListPrologTerm nodes = (ListPrologTerm) bindings.get("NodeStat"); + ListPrologTerm uncovered = (ListPrologTerm) bindings.get("Uncovered"); + coverageResult = new ComputeCoverageResult(totalNodeNr, totalTransNr, + ops, nodes, uncovered); + + } + + public void writeCommand(final IPrologTermOutput pto) { + pto.openTerm("compute_coverage").printVariable("TotalNodeNr") + .printVariable("TotalTransSum").printVariable("NodeStat") + .printVariable("OpStat").printVariable("Uncovered").closeTerm(); + } + +} diff --git a/de.prob.core/src/de/prob/core/command/ConsistencyCheckingCommand.java b/de.prob.core/src/de/prob/core/command/ConsistencyCheckingCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..d2cfdfb9b4a599fb0f27414f115ee1d37b350492 --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/ConsistencyCheckingCommand.java @@ -0,0 +1,72 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.command; + +import java.util.List; + +import de.prob.core.Animator; +import de.prob.exceptions.ProBException; +import de.prob.parser.ISimplifiedROMap; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.CompoundPrologTerm; +import de.prob.prolog.term.PrologTerm; + +public final class ConsistencyCheckingCommand implements IComposableCommand { + private final int time; + private final List<String> options; + private ModelCheckingResult<Result> result; + + public static enum Result { + ok(true), ok_not_all_nodes_considered(true), deadlock(true), invariant_violation( + true), assertion_violation(true), not_yet_finished(false), state_error( + true), well_definedness_error(true), general_error(true); + // I assume true means we can stop the model checking + private final boolean abort; + + private Result(final boolean abort) { + this.abort = abort; + } + + public boolean isAbort() { + return abort; + } + } + + ConsistencyCheckingCommand(final int time, final List<String> options) { + this.time = time; + this.options = options; + } + + public static ModelCheckingResult<Result> modelcheck(final Animator a, + final int time, final List<String> options) throws ProBException { + ConsistencyCheckingCommand command = new ConsistencyCheckingCommand( + time, options); + a.execute(command); + return command.getResult(); + } + + private ModelCheckingResult<Result> getResult() { + return result; + } + + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + + CompoundPrologTerm term = (CompoundPrologTerm) bindings.get("Result"); + result = new ModelCheckingResult<Result>(Result.class, term); + + } + + public void writeCommand(final IPrologTermOutput pto) { + pto.openTerm("do_modelchecking").printNumber(time).openList(); + for (String o : options) { + pto.printAtom(o); + } + pto.closeList().printVariable("Result").closeTerm(); + } +} diff --git a/de.prob.core/src/de/prob/core/command/ConsistencyCheckingSearchOption.java b/de.prob.core/src/de/prob/core/command/ConsistencyCheckingSearchOption.java new file mode 100644 index 0000000000000000000000000000000000000000..13338e27fd2304f0a2da7047d1c0491d2af95daa --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/ConsistencyCheckingSearchOption.java @@ -0,0 +1,59 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +/** + * + */ +package de.prob.core.command; + +import java.util.EnumSet; +import java.util.HashMap; +import java.util.Map; + +public enum ConsistencyCheckingSearchOption { + breadth_first_search(0, "Breadth First Search", false), + find_deadlocks(1,"Find Deadlocks", true), + find_invariant_violations(2,"Find Invariant Violations", true), + find_assertion_violations(3,"Find Theorem Violations", false), + not_inspect_existing_nodes(4,"Search for New Errors", false); + + private final String text; + private final int pos; + private final boolean enabledByDefault; + + private ConsistencyCheckingSearchOption(final int pos, final String text, + final boolean enabledByDefault) { + this.pos = pos; + this.text = text; + this.enabledByDefault = enabledByDefault; + } + + public final String getDescription() { + return text; + } + + private static final Map<Integer, ConsistencyCheckingSearchOption> lookup = new HashMap<Integer, ConsistencyCheckingSearchOption>(); + + static { + for (ConsistencyCheckingSearchOption s : EnumSet + .allOf(ConsistencyCheckingSearchOption.class)) { + lookup.put(s.getPos(), s); + } + } + + public final int getPos() { + return pos; + } + + public final boolean isEnabledByDefault() { + return enabledByDefault; + } + + public final static ConsistencyCheckingSearchOption get(final int code) { + return lookup.get(code); + } + +} \ No newline at end of file diff --git a/de.prob.core/src/de/prob/core/command/ConstraintBasedDeadlockCheckCommand.java b/de.prob.core/src/de/prob/core/command/ConstraintBasedDeadlockCheckCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..5814b36d98cee35a7cd20b20ef215335303cd33d --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/ConstraintBasedDeadlockCheckCommand.java @@ -0,0 +1,95 @@ +/** + * + */ +package de.prob.core.command; + +import de.prob.core.LanguageDependendAnimationPart; +import de.prob.core.domainobjects.Operation; +import de.prob.parser.ISimplifiedROMap; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.CompoundPrologTerm; +import de.prob.prolog.term.PrologTerm; + +/** + * This command makes ProB search for a deadlock with an optional predicate to + * limit the search space. + * + * @author plagge + */ +public class ConstraintBasedDeadlockCheckCommand implements IComposableCommand { + + public static enum ResultType { + DEADLOCK_FOUND, NO_DEADLOCK, ERROR, INTERRUPTED + }; + + private static final String COMMAND_NAME = "deadlock_freedom_check"; + private static final String RESULT_VARIABLE = "R"; + + private final PrologTerm predicate; + + private ResultType result; + private String deadlockStateId; + private Operation deadlockOperation; + + /** + * @param predicate + * is a parsed predicate or <code>null</code> + * @see LanguageDependendAnimationPart#parsePredicate(IPrologTermOutput, + * String, boolean) + */ + public ConstraintBasedDeadlockCheckCommand(final PrologTerm predicate) { + this.predicate = predicate; + } + + public PrologTerm getPredicate() { + return predicate; + } + + public ResultType getResult() { + return result; + } + + public String getDeadlockStateId() { + return deadlockStateId; + } + + public Operation getDeadlockOperation() { + return deadlockOperation; + } + + @Override + public void writeCommand(final IPrologTermOutput pto) { + pto.openTerm(COMMAND_NAME); + if (predicate != null) { + predicate.toTermOutput(pto); + } + pto.printVariable(RESULT_VARIABLE); + pto.closeTerm(); + } + + @Override + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + final PrologTerm resultTerm = bindings.get(RESULT_VARIABLE); + final ResultType result; + if (resultTerm.hasFunctor("no_deadlock_found", 0)) { + result = ResultType.NO_DEADLOCK; + } else if (resultTerm.hasFunctor("errors", 1)) { + result = ResultType.ERROR; + } else if (resultTerm.hasFunctor("interrupted", 0)) { + result = ResultType.INTERRUPTED; + } else if (resultTerm.hasFunctor("deadlock", 2)) { + CompoundPrologTerm deadlockTerm = (CompoundPrologTerm) resultTerm; + result = ResultType.DEADLOCK_FOUND; + deadlockOperation = Operation + .fromPrologTerm((CompoundPrologTerm) deadlockTerm + .getArgument(1)); + deadlockStateId = deadlockTerm.getArgument(2).toString(); + } else + throw new CommandException( + "unexpected result from deadlock check: " + resultTerm); + this.result = result; + + } +} diff --git a/de.prob.core/src/de/prob/core/command/ConstraintBasedInvariantCheckCommand.java b/de.prob.core/src/de/prob/core/command/ConstraintBasedInvariantCheckCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..87c242bc348101422675e85e943577e06de95b79 --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/ConstraintBasedInvariantCheckCommand.java @@ -0,0 +1,142 @@ +/** + * + */ +package de.prob.core.command; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; + +import de.prob.core.domainobjects.Operation; +import de.prob.parser.ISimplifiedROMap; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.CompoundPrologTerm; +import de.prob.prolog.term.ListPrologTerm; +import de.prob.prolog.term.PrologTerm; + +/** + * This command makes ProB search for a invariant violation with an optional + * selection of events. + * + * @author plagge + */ +public class ConstraintBasedInvariantCheckCommand implements IComposableCommand { + + public static enum ResultType { + VIOLATION_FOUND, NO_VIOLATION_FOUND, INTERRUPTED + }; + + public static class InvariantCheckCounterExample { + private final String eventName; + private final Operation step1, step2; + + public InvariantCheckCounterExample(final String eventName, + final Operation step1, final Operation step2) { + this.eventName = eventName; + this.step1 = step1; + this.step2 = step2; + } + + public String getEventName() { + return eventName; + } + + public Operation getStep1() { + return step1; + } + + public Operation getStep2() { + return step2; + } + } + + private static final String COMMAND_NAME = "invariant_check"; + private static final String RESULT_VARIABLE = "R"; + + private final Collection<String> events; + + private ResultType result; + private Collection<InvariantCheckCounterExample> counterexamples; + + /** + * @param events + * is a collection of names of that events that should be + * checked. May be <code>null</code>. In that case, all events + * are checked. + */ + public ConstraintBasedInvariantCheckCommand(final Collection<String> events) { + this.events = events == null ? null : Collections + .unmodifiableCollection(new ArrayList<String>(events)); + } + + public Collection<String> getEvents() { + return events; + } + + public ResultType getResult() { + return result; + } + + public Collection<InvariantCheckCounterExample> getCounterExamples() { + return counterexamples; + } + + @Override + public void writeCommand(final IPrologTermOutput pto) { + pto.openTerm(COMMAND_NAME); + if (events != null && !events.isEmpty()) { + pto.openTerm("ops"); + pto.openList(); + for (final String event : events) { + pto.printAtom(event); + } + pto.closeList(); + pto.closeTerm(); + } else { + pto.printAtom("all"); + } + pto.printVariable(RESULT_VARIABLE); + pto.closeTerm(); + } + + @Override + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + final PrologTerm resultTerm = bindings.get(RESULT_VARIABLE); + final ResultType result; + final Collection<InvariantCheckCounterExample> counterexamples; + if (resultTerm.hasFunctor("interrupted", 0)) { + result = ResultType.INTERRUPTED; + counterexamples = null; + } else if (resultTerm.isList()) { + ListPrologTerm ceTerm = (ListPrologTerm) resultTerm; + result = ceTerm.isEmpty() ? ResultType.NO_VIOLATION_FOUND + : ResultType.VIOLATION_FOUND; + counterexamples = Collections + .unmodifiableCollection(extractExamples(ceTerm)); + } else + throw new CommandException( + "unexpected result from invariant check: " + resultTerm); + this.result = result; + this.counterexamples = counterexamples; + } + + private Collection<InvariantCheckCounterExample> extractExamples( + final ListPrologTerm ceTerm) { + Collection<InvariantCheckCounterExample> examples = new ArrayList<ConstraintBasedInvariantCheckCommand.InvariantCheckCounterExample>(); + for (final PrologTerm t : ceTerm) { + final CompoundPrologTerm term = (CompoundPrologTerm) t; + final String eventName = PrologTerm.atomicString(term + .getArgument(1)); + final Operation step1 = Operation + .fromPrologTerm((CompoundPrologTerm) term.getArgument(2)); + final Operation step2 = Operation + .fromPrologTerm((CompoundPrologTerm) term.getArgument(3)); + final InvariantCheckCounterExample ce = new InvariantCheckCounterExample( + eventName, step1, step2); + examples.add(ce); + } + return examples; + } +} diff --git a/de.prob.core/src/de/prob/core/command/DeserializeStateCommand.java b/de.prob.core/src/de/prob/core/command/DeserializeStateCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..6ff95063b24f92b38f263dd9ce7859a7cf534354 --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/DeserializeStateCommand.java @@ -0,0 +1,43 @@ +package de.prob.core.command; + +import de.prob.core.Animator; +import de.prob.exceptions.ProBException; +import de.prob.parser.ISimplifiedROMap; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.PrologTerm; + +public class DeserializeStateCommand implements IComposableCommand { + + private String id; + private final String state; + + public DeserializeStateCommand(String state) { + this.state = state; + } + + public static String deserialize(Animator a, String state) throws ProBException { + DeserializeStateCommand c = new DeserializeStateCommand(state); + a.execute(c); + return c.id; + } + + @Override + public void processResult(ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + this.id = bindings.get("Id").toString(); + } + + @Override + public void writeCommand(IPrologTermOutput pto) { + pto.openTerm("deserialize").printVariable("Id").printAtom(state).closeTerm(); + } + + public String getId() { + return id; + } + + public String getState() { + return state; + } + +} diff --git a/de.prob.core/src/de/prob/core/command/EvaluateRawExpressionsCommand.java b/de.prob.core/src/de/prob/core/command/EvaluateRawExpressionsCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..34a8ce9231adb3c2b26b7e70093da31ce4b2f92e --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/EvaluateRawExpressionsCommand.java @@ -0,0 +1,84 @@ +package de.prob.core.command; + +import java.util.Collections; +import java.util.List; + +import de.be4.classicalb.core.parser.analysis.prolog.ASTProlog; +import de.prob.core.Animator; +import de.prob.core.domainobjects.eval.AbstractEvalElement; +import de.prob.exceptions.ProBException; +import de.prob.parser.ISimplifiedROMap; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.ListPrologTerm; +import de.prob.prolog.term.PrologTerm; + +public class EvaluateRawExpressionsCommand implements IComposableCommand { + + private static final String EVALUATE_TERM_VARIABLE = "Val"; + private final List<AbstractEvalElement> evalElements; + private final String stateId; + private List<String> values; + + public EvaluateRawExpressionsCommand( + final List<AbstractEvalElement> evalElements, final String id) { + this.evalElements = evalElements; + this.stateId = id; + } + + public static List<String> evaluate(final Animator animator, + final List<AbstractEvalElement> evalElements, final String id) + throws ProBException { + EvaluateRawExpressionsCommand command = new EvaluateRawExpressionsCommand( + evalElements, id); + animator.execute(command); + return command.getValues(); + } + + public static String evaluate(final Animator a, + final AbstractEvalElement e, final String id) throws ProBException { + return evaluate(a, Collections.singletonList(e), id).get(0); + } + + private List<String> getValues() { + return values; + } + + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + ListPrologTerm prologTerm = (ListPrologTerm) bindings + .get(EVALUATE_TERM_VARIABLE); + values = PrologTerm.atomicStrings(prologTerm); + } + + public void writeCommand(final IPrologTermOutput pout) { + pout.openTerm("evaluate_raw_expressions"); + pout.printAtomOrNumber(stateId); + pout.openList(); + + // print parsed expressions/predicates + for (AbstractEvalElement term : evalElements) { + final ASTProlog prolog = new ASTProlog(pout, null); + term.getPrologAst().apply(prolog); + } + pout.closeList(); + pout.printVariable(EVALUATE_TERM_VARIABLE); + pout.closeTerm(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("EvaluateRawExpression("); + boolean first = true; + for (final AbstractEvalElement term : evalElements) { + if (!first) { + sb.append(", "); + } + sb.append(term.getLabel()); + first = false; + } + sb.append(")"); + return sb.toString(); + } +} diff --git a/de.prob.core/src/de/prob/core/command/EvaluationExpandCommand.java b/de.prob.core/src/de/prob/core/command/EvaluationExpandCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..bd3c6a830479c976b8055c477b9d25996caeb897 --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/EvaluationExpandCommand.java @@ -0,0 +1,55 @@ +package de.prob.core.command; + +import java.util.List; + +import de.prob.parser.ISimplifiedROMap; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.CompoundPrologTerm; +import de.prob.prolog.term.ListPrologTerm; +import de.prob.prolog.term.PrologTerm; + +/** + * This command sends the ID of an expression to the ProB core and receives the + * corresponding label (usually the pretty-printed expression) and the IDs of + * the expression's child nodes. + * + * @see EvaluationGetTopLevelCommand + * @see EvaluationGetValuesCommand + * @author plagge + */ +public class EvaluationExpandCommand implements IComposableCommand { + private static final String LABEL_VARNAME = "Lbl"; + private static final String CHILDREN_VARNAME = "Chs"; + + private final PrologTerm evaluationElement; + + private String label; + private List<PrologTerm> children; + + public EvaluationExpandCommand(final PrologTerm evaluationElement) { + this.evaluationElement = evaluationElement; + } + + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + label = ((CompoundPrologTerm) bindings.get(LABEL_VARNAME)).getFunctor(); + children = (ListPrologTerm) bindings.get(CHILDREN_VARNAME); + } + + public void writeCommand(final IPrologTermOutput pto) { + pto.openTerm("evaluation_expand_formula"); + evaluationElement.toTermOutput(pto); + pto.printVariable(LABEL_VARNAME); + pto.printVariable(CHILDREN_VARNAME); + pto.closeTerm(); + } + + public String getLabel() { + return label; + } + + public List<PrologTerm> getChildrenIds() { + return children; + } +} diff --git a/de.prob.core/src/de/prob/core/command/EvaluationGetTopLevelCommand.java b/de.prob.core/src/de/prob/core/command/EvaluationGetTopLevelCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..091564a467ee4abdb12681ef770bcaa063897a3d --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/EvaluationGetTopLevelCommand.java @@ -0,0 +1,83 @@ +/** + * + */ +package de.prob.core.command; + +import java.util.List; + +import de.prob.core.Animator; +import de.prob.core.domainobjects.EvaluationElement; +import de.prob.exceptions.ProBException; +import de.prob.parser.ISimplifiedROMap; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.CompoundPrologTerm; +import de.prob.prolog.term.ListPrologTerm; +import de.prob.prolog.term.PrologTerm; + +/** + * This command retrieves the IDs of the top-level expressions and their labels + * and the IDs of their children. + * + * @see EvaluationExpandCommand + * @see EvaluationGetValuesCommand + * @author plagge + */ +public class EvaluationGetTopLevelCommand implements IComposableCommand { + private static final String FIRST_EXPANSION_VARNAME = "FE"; + + public static EvaluationElement[] retrieveTopLevelElements() + throws ProBException { + final Animator animator = Animator.getAnimator(); + final EvaluationGetTopLevelCommand cmd = new EvaluationGetTopLevelCommand( + animator); + animator.execute(cmd); + return cmd.getTopLevelElements(); + } + + private final Animator animator; + private EvaluationElement[] tops; + + public EvaluationGetTopLevelCommand(final Animator animator) { + this.animator = animator; + } + + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + ListPrologTerm resultList = (ListPrologTerm) bindings + .get(FIRST_EXPANSION_VARNAME); + tops = new EvaluationElement[resultList.size()]; + int i = 0; + for (final PrologTerm elemTerm : resultList) { + tops[i] = createElement(elemTerm); + i++; + } + } + + private EvaluationElement createElement(final PrologTerm elemTerm) + throws CommandException { + final EvaluationElement top; + if (elemTerm.hasFunctor("top", 3)) { + final CompoundPrologTerm elem = (CompoundPrologTerm) elemTerm; + final PrologTerm id = elem.getArgument(1); + final String label = ((CompoundPrologTerm) elem.getArgument(2)) + .getFunctor(); + final List<PrologTerm> childrenIds = ((ListPrologTerm) elem + .getArgument(3)); + top = new EvaluationElement(animator, id, label, childrenIds); + } else + throw new CommandException("ProB core sent unexpected term " + + elemTerm); + return top; + } + + public void writeCommand(final IPrologTermOutput pto) { + pto.openTerm("evaluation_get_top_level"); + pto.printVariable(FIRST_EXPANSION_VARNAME); + pto.closeTerm(); + } + + public EvaluationElement[] getTopLevelElements() { + return tops; + } +} diff --git a/de.prob.core/src/de/prob/core/command/EvaluationGetValuesCommand.java b/de.prob.core/src/de/prob/core/command/EvaluationGetValuesCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..c97e7d08f03827d0603e3fa3b32e4211eae4fd55 --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/EvaluationGetValuesCommand.java @@ -0,0 +1,279 @@ +/** + * + */ +package de.prob.core.command; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; + +import de.prob.core.Animator; +import de.prob.core.domainobjects.EvaluationElement; +import de.prob.core.domainobjects.EvaluationStateElement; +import de.prob.core.domainobjects.History; +import de.prob.core.domainobjects.HistoryBasedCache; +import de.prob.core.domainobjects.State; +import de.prob.eventb.translator.FormulaTranslator; +import de.prob.exceptions.ProBException; +import de.prob.parser.ISimplifiedROMap; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.CompoundPrologTerm; +import de.prob.prolog.term.ListPrologTerm; +import de.prob.prolog.term.PrologTerm; + +/** + * This command sends a list of expression IDs and a state ID to ProB and + * retrieves a list of values of their corresponding values in that state. + * + * @see EvaluationExpandCommand + * @see EvaluationGetTopLevelCommand + * @author plagge + */ +public class EvaluationGetValuesCommand implements IComposableCommand { + private static final String COMMAND_NAME = "evaluation_get_values"; + private static final String VALUE_VARNAME = "Values"; + private static final String TRUE = FormulaTranslator.translate("true"); + private static final String FALSE = FormulaTranslator.translate("false"); + private static final String CACHE_KEY = EvaluationGetValuesCommand.class + .getName() + ".valuecache"; + + /** + * Ask ProB for the values of the given elements in the given state. + * + * @param state + * @param elements + * @return + * @throws ProBException + */ + public static Collection<EvaluationStateElement> getValuesForExpressionsUncached( + final State state, final Collection<EvaluationElement> elements) + throws ProBException { + final Collection<EvaluationStateElement> result; + if (state == null || elements.isEmpty()) { + result = Collections.emptyList(); + } else { + final EvaluationGetValuesCommand cmd = new EvaluationGetValuesCommand( + state.getId(), elements); + Animator.getAnimator().execute(cmd); + Map<EvaluationElement, EvaluationResult> values = cmd.getResult(); + result = new ArrayList<EvaluationStateElement>(values.size()); + for (final Map.Entry<EvaluationElement, EvaluationResult> entry : values + .entrySet()) { + result.add(new EvaluationStateElement(entry.getKey(), state, + entry.getValue())); + } + } + return result; + } + + public static Collection<EvaluationStateElement> getValuesForExpressionsCached( + final State state, final Collection<EvaluationElement> elements) + throws ProBException { + final Collection<EvaluationStateElement> result; + if (state == null || elements.isEmpty()) { + result = Collections.emptyList(); + } else { + final Map<EvaluationElement, EvaluationStateElement> cache = getCache(state); + synchronized (cache) { + Collection<EvaluationElement> toCompute = new HashSet<EvaluationElement>( + elements); + Collection<EvaluationElement> cached = cache.keySet(); + toCompute.removeAll(cached); + Collection<EvaluationStateElement> computed = getValuesForExpressionsUncached( + state, toCompute); + for (final EvaluationStateElement dElement : computed) { + cache.put(dElement.getElement(), dElement); + } + + result = new ArrayList<EvaluationStateElement>(elements.size()); + for (final EvaluationElement sElement : elements) { + result.add(cache.get(sElement)); + } + result.addAll(computed); + } + } + return result; + } + + public static EvaluationStateElement getSingleValueCached( + final State state, final EvaluationElement element) + throws ProBException { + EvaluationStateElement result; + if (state == null) { + result = null; + } else { + final Map<EvaluationElement, EvaluationStateElement> cache = getCache(state); + synchronized (cache) { + result = cache.get(element); + if (result == null) { + Collection<EvaluationStateElement> values = getValuesForExpressionsUncached( + state, Collections.singleton(element)); + result = values.iterator().next(); + cache.put(element, result); + } + } + } + return result; + } + + @SuppressWarnings("unchecked") + private static Map<EvaluationElement, EvaluationStateElement> getCache( + final State state) { + Map<EvaluationElement, EvaluationStateElement> cache; + final Animator animator = Animator.getAnimator(); + synchronized (animator) { + HistoryBasedCache<Map<EvaluationElement, EvaluationStateElement>> hcache = (HistoryBasedCache<Map<EvaluationElement, EvaluationStateElement>>) animator + .getData(CACHE_KEY); + if (hcache == null) { + History history = animator.getHistory(); + hcache = new HistoryBasedCache<Map<EvaluationElement, EvaluationStateElement>>( + history); + history.addListener(hcache); + animator.setData(CACHE_KEY, hcache); + } + cache = hcache.get(state); + if (cache == null) { + cache = new HashMap<EvaluationElement, EvaluationStateElement>(); + hcache.put(state, cache); + } + } + return cache; + } + + private final String stateId; + private final Collection<EvaluationElement> elements; + + private Map<EvaluationElement, EvaluationResult> result; + + public EvaluationGetValuesCommand(final String stateId, + final Collection<EvaluationElement> elements) { + this.stateId = stateId; + this.elements = new ArrayList<EvaluationElement>(elements); + } + + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + final ListPrologTerm valueTerms = (ListPrologTerm) bindings + .get(VALUE_VARNAME); + result = retrieveValues(elements, valueTerms); + } + + public Map<EvaluationElement, EvaluationResult> getResult() { + return result; + } + + private static Map<EvaluationElement, EvaluationResult> retrieveValues( + final Collection<EvaluationElement> elements, + final Collection<PrologTerm> valueTerms) { + if (valueTerms.size() != elements.size()) + throw new IllegalStateException(COMMAND_NAME + + " returned the wrong number of results"); + Map<EvaluationElement, EvaluationResult> results = new HashMap<EvaluationElement, EvaluationResult>(); + Iterator<PrologTerm> it = valueTerms.iterator(); + for (final EvaluationElement element : elements) { + final PrologTerm valueTerm = it.next(); + final EvaluationResult value; + if (valueTerm.hasFunctor("p", 1)) { + final CompoundPrologTerm vc = (CompoundPrologTerm) valueTerm; + final String valString = ((CompoundPrologTerm) vc + .getArgument(1)).getFunctor(); + final boolean predTrue = "true".equals(valString); + final String asString = predTrue ? TRUE : FALSE; + value = new EvaluationResult(asString, true, true, predTrue, + false); + } else if (valueTerm.hasFunctor("v", 1)) { + final CompoundPrologTerm vc = (CompoundPrologTerm) valueTerm; + final String valString = ((CompoundPrologTerm) vc + .getArgument(1)).getFunctor(); + value = new EvaluationResult( + FormulaTranslator.translate(valString), true, false, + false, false); + } else if (valueTerm.hasFunctor("e", 1)) { + final CompoundPrologTerm vc = (CompoundPrologTerm) valueTerm; + final String error = ((CompoundPrologTerm) vc.getArgument(1)) + .getFunctor(); + value = new EvaluationResult(error, true, false, false, true); + } else if (valueTerm.hasFunctor("i", 0)) { + value = new EvaluationResult(null, false, false, false, false); + } else + throw new IllegalArgumentException(COMMAND_NAME + + " returned unexpected term " + valueTerm.toString()); + results.put(element, value); + } + return results; + } + + public void writeCommand(final IPrologTermOutput pto) { + pto.openTerm(COMMAND_NAME); + pto.openList(); + for (final EvaluationElement element : elements) { + element.getId().toTermOutput(pto); + } + pto.closeList(); + pto.printAtomOrNumber(stateId); + pto.printVariable(VALUE_VARNAME); + pto.closeTerm(); + } + + public static class EvaluationResult { + private final String text; + private final boolean isActive; + private final boolean isPredicate; + private final boolean isPredicateTrue; + private final boolean hasError; + + public EvaluationResult(final String text, final boolean isActive, + final boolean isPredicate, final boolean isPredicateTrue, + final boolean hasError) { + this.text = text; + this.isActive = isActive; + this.isPredicate = isPredicate; + this.isPredicateTrue = isPredicateTrue; + this.hasError = hasError; + } + + public String getText() { + return text; + } + + public boolean isActive() { + return isActive; + } + + public boolean isPredicate() { + return isPredicate; + } + + /** + * note: returns arbitrary value if called on something else than a + * predicate. + * + * @return + */ + public boolean isPredicateTrue() { + return isPredicateTrue; + } + + public boolean hasError() { + return hasError; + } + }; + + @Override + public String toString() { + StringBuilder sb = new StringBuilder( + "EvaluationGetValuesCommand[elements="); + for (EvaluationElement element : elements) { + sb.append(element.getId()); + sb.append(','); + } + sb.append(" stateId=").append(stateId).append(']'); + return sb.toString(); + } + +} diff --git a/de.prob.core/src/de/prob/core/command/EvaluationInsertFormulaCommand.java b/de.prob.core/src/de/prob/core/command/EvaluationInsertFormulaCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..e9f12dd56a36272914e6af6c96c62e01061e339b --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/EvaluationInsertFormulaCommand.java @@ -0,0 +1,110 @@ +/** + * + */ +package de.prob.core.command; + +import de.prob.core.Animator; +import de.prob.core.LanguageDependendAnimationPart; +import de.prob.core.domainobjects.EvaluationElement; +import de.prob.exceptions.ProBException; +import de.prob.parser.ISimplifiedROMap; +import de.prob.parserbase.ProBParseException; +import de.prob.parserbase.ProBParserBaseAdapter; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.PrologTerm; + +/** + * This commands registers a formula (given as an already parsed + * {@link PrologTerm}) in the Prolog core and returns an + * {@link EvaluationElement} that can be used to evaluate the formula and + * retrieve its subformulas. + * + * @author plagge + */ +public class EvaluationInsertFormulaCommand implements IComposableCommand { + + public static enum FormulaType { + PREDICATE, EXPRESSION + }; + + private static final String VARNAME_ID = "ID"; + private final PrologTerm rawExpression; + private PrologTerm id; + + public static EvaluationElement insertFormula(final PrologTerm formula) + throws ProBException { + final EvaluationInsertFormulaCommand cmd = new EvaluationInsertFormulaCommand( + formula); + final Animator animator = Animator.getAnimator(); + animator.execute(cmd); + return new EvaluationElement(animator, cmd.getId(), null); + } + + public static EvaluationElement insertPredicate(final String formula) + throws ProBException, UnsupportedOperationException, + ProBParseException { + return insertFormula(getParser().parsePredicate(formula, false)); + } + + public static EvaluationElement insertExpression(final String formula) + throws ProBException, UnsupportedOperationException, + ProBParseException { + return insertFormula(getParser().parseExpression(formula, false)); + } + + public static EvaluationElement insertFormula(final Animator animator, + final FormulaType type, final String formula) throws ProBException, + UnsupportedOperationException, ProBParseException { + final ProBParserBaseAdapter parser = getParser(animator); + final PrologTerm parsed; + switch (type) { + case EXPRESSION: + parsed = parser.parseExpression(formula, false); + break; + case PREDICATE: + parsed = parser.parsePredicate(formula, false); + break; + default: + throw new IllegalArgumentException("Unsupported formula type: " + + type); + } + return insertFormula(parsed); + } + + private static ProBParserBaseAdapter getParser() { + return getParser(Animator.getAnimator()); + } + + private static ProBParserBaseAdapter getParser(final Animator animator) { + final LanguageDependendAnimationPart ldp = animator + .getLanguageDependendPart(); + if (ldp == null) { + throw new UnsupportedOperationException( + "The current formalism does not allow parsing of formulas"); + } else { + return new ProBParserBaseAdapter(ldp); + } + } + + public EvaluationInsertFormulaCommand(final PrologTerm rawExpression) { + this.rawExpression = rawExpression; + } + + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + id = bindings.get(VARNAME_ID); + } + + public void writeCommand(final IPrologTermOutput pto) { + pto.openTerm("evaluation_insert_formula"); + rawExpression.toTermOutput(pto); + pto.printAtom("user"); + pto.printVariable(VARNAME_ID); + pto.closeTerm(); + } + + public PrologTerm getId() { + return id; + } +} diff --git a/de.prob.core/src/de/prob/core/command/ExecuteOperationCommand.java b/de.prob.core/src/de/prob/core/command/ExecuteOperationCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..9e225706dcdcaa4dfe01318944bd63c0f1637717 --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/ExecuteOperationCommand.java @@ -0,0 +1,81 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.command; + +import de.prob.cli.CliException; +import de.prob.core.Animator; +import de.prob.core.LimitedLogger; +import de.prob.core.domainobjects.Operation; +import de.prob.core.domainobjects.State; +import de.prob.exceptions.ProBException; +import de.prob.parser.ISimplifiedROMap; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.PrologTerm; + +public final class ExecuteOperationCommand implements IComposableCommand { + + private final Operation operation; + private final boolean fireCurrentStateChanged; + private final ExploreStateCommand exloreStateCmd; + private final SetStateCommand setStateCmd; + private final IComposableCommand cmds; + + private ExecuteOperationCommand(final Operation operation) { + this(operation, false); + } + + private ExecuteOperationCommand(final Operation operation, + final boolean silent) { + this.operation = operation; + this.fireCurrentStateChanged = !silent; + final String stateId = operation.getDestination(); + this.exloreStateCmd = new ExploreStateCommand(stateId); + this.setStateCmd = new SetStateCommand(stateId); + this.cmds = new ComposedCommand(exloreStateCmd, setStateCmd); + } + + public static void executeOperation(final Animator a, final Operation op) + throws ProBException { + ExecuteOperationCommand executeOperationCommand = new ExecuteOperationCommand( + op); + a.execute(executeOperationCommand); + } + + /** + * If <i>silent</i> is set to true the <i>currentStateChanged</i> event is + * not fired on the Activator. + * + * @throws CliException + */ + public static void executeOperation(final Animator a, final Operation op, + final boolean silent) throws ProBException { + ExecuteOperationCommand executeOperationCommand = new ExecuteOperationCommand( + op, silent); + a.execute(executeOperationCommand); + } + + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + cmds.processResult(bindings); + final Animator animator = Animator.getAnimator(); + final State state = exloreStateCmd.getState(); + + // Change history in Animator + animator.getHistory().add(state, operation); + + if (fireCurrentStateChanged) { + animator.announceCurrentStateChanged(state, operation); + } + } + + public void writeCommand(final IPrologTermOutput pto) throws CommandException { + LimitedLogger.getLogger().log("execute operation", operation.getName(), + null); + cmds.writeCommand(pto); + } +} diff --git a/de.prob.core/src/de/prob/core/command/ExecuteRandomStepsCommand.java b/de.prob.core/src/de/prob/core/command/ExecuteRandomStepsCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..8b04fd24efa72f56461d1ee72c150c79cb769f48 --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/ExecuteRandomStepsCommand.java @@ -0,0 +1,53 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.command; + +import java.util.List; +import java.util.Random; + +import de.prob.core.Animator; +import de.prob.core.ProblemHandler; +import de.prob.core.domainobjects.Operation; +import de.prob.core.domainobjects.State; +import de.prob.exceptions.ProBException; + +public class ExecuteRandomStepsCommand { + + private static final Random random = new Random(); + + public static void executeOperation(final Animator animator, final int count) + throws ProBException { + if (count < 1) { + final String message = "Count for Random Animation must be greater than zero"; + ProblemHandler.raiseCommandException(message); + } + Operation operation = null; + for (int i = 0; i < count; i++) { + State currentState = animator.getCurrentState(); + List<Operation> ops = currentState.getEnabledOperations(); + if (ops.isEmpty()) { + break; // / This is a deadlock + } + + operation = ops.get(random.nextInt(ops.size())); + + ExecuteOperationCommand.executeOperation(animator, operation, true); + + if (animator.getCurrentState().isInvariantViolated()) { + break; // Stop in case of Invariant violation + } + } + + if (operation != null) { + animator.announceCurrentStateChanged(animator.getCurrentState(), + operation); + } + + return; + } + +} diff --git a/de.prob.core/src/de/prob/core/command/ExploreStateCommand.java b/de.prob.core/src/de/prob/core/command/ExploreStateCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..048373bf995655d077971aaf4c85312c3f91bd7d --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/ExploreStateCommand.java @@ -0,0 +1,103 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.command; + +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import de.prob.core.Animator; +import de.prob.core.domainobjects.Operation; +import de.prob.core.domainobjects.State; +import de.prob.core.domainobjects.StateError; +import de.prob.core.domainobjects.Variable; +import de.prob.core.internal.Activator; +import de.prob.exceptions.ProBException; +import de.prob.logging.Logger; +import de.prob.parser.ISimplifiedROMap; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.PrologTerm; + +public final class ExploreStateCommand implements IComposableCommand { + + private final String stateId; + private final GetEnabledOperationsCommand getOpsCmd; + private final GetStateValuesCommand getValuesCmd; + private final CheckBooleanPropertyCommand checkInitialisedCmd; + private final CheckBooleanPropertyCommand checkInvCmd; + private final CheckBooleanPropertyCommand checkMaxOpCmd; + private final CheckBooleanPropertyCommand checkTimeoutCmd; + private final GetStateBasedErrorsCommand getStateErrCmd; + private final ComposedCommand allCommands; + + private State state; + private final GetTimeoutedOperationsCommand checkTimeoutOpsCmd; + + public ExploreStateCommand(final String stateID) { + stateId = stateID; + getOpsCmd = new GetEnabledOperationsCommand(stateId); + getValuesCmd = new GetStateValuesCommand(stateId); + checkInitialisedCmd = new CheckInitialisationStatusCommand(stateId); + checkInvCmd = new CheckInvariantStatusCommand(stateId); + checkMaxOpCmd = new CheckMaxOperationReachedStatusCommand(stateId); + checkTimeoutCmd = new CheckTimeoutStatusCommand(stateId); + checkTimeoutOpsCmd = new GetTimeoutedOperationsCommand(stateId); + getStateErrCmd = new GetStateBasedErrorsCommand(stateId); + this.allCommands = new ComposedCommand(getOpsCmd, getValuesCmd, + checkInitialisedCmd, checkInvCmd, checkMaxOpCmd, + checkTimeoutCmd, checkTimeoutOpsCmd, getStateErrCmd); + } + + public static State exploreState(final Animator a, final String stateID) + throws ProBException { + ExploreStateCommand command = new ExploreStateCommand(stateID); + a.execute(command); + return command.getState(); + } + + public String getStateID() { + return stateId; + } + + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + allCommands.processResult(bindings); + + final boolean initialised = checkInitialisedCmd.getResult(); + final boolean invariantOk = checkInvCmd.getResult(); + final boolean timeoutOccured = checkTimeoutCmd.getResult(); + final boolean maxOperationsReached = checkMaxOpCmd.getResult(); + final List<Operation> enabledOperations = getOpsCmd + .getEnabledOperations(); + final List<Variable> variables = getValuesCmd.getResult(); + final Collection<StateError> stateErrors = getStateErrCmd.getResult(); + + if (!initialised && enabledOperations.isEmpty() && !timeoutOccured) { + Logger.notifyUserWithoutBugreport("ProB could not find valid constants. This might be caused by the animation settings (e.g., Integer range or deferred set size) or by an inconsistency in the axioms"); + } + + Set<String> timeouts = new HashSet<String>( + checkTimeoutOpsCmd.getTimeouts()); + state = new State(stateId, initialised, invariantOk, timeoutOccured, + maxOperationsReached, variables, enabledOperations, + stateErrors, timeouts); + + // Fire computed(state) event + Activator.computedState(state); + } + + public void writeCommand(final IPrologTermOutput pto) throws CommandException { + allCommands.writeCommand(pto); + } + + public State getState() { + return state; + } + +} diff --git a/de.prob.core/src/de/prob/core/command/GetCurrentStateIdCommand.java b/de.prob.core/src/de/prob/core/command/GetCurrentStateIdCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..fde2247dae1677df84d912201425d5517ae07c17 --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/GetCurrentStateIdCommand.java @@ -0,0 +1,63 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.command; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import de.prob.core.Animator; +import de.prob.exceptions.ProBException; +import de.prob.parser.ISimplifiedROMap; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.PrologTerm; + +public final class GetCurrentStateIdCommand implements IComposableCommand { + + public static String getStateID(final PrologTerm term) { + final String result; + if (term.isAtom()) { + result = PrologTerm.atomicString(term); + } else { + result = term.toString(); + } + return result; + } + + public static List<String> getStateIDs(final Collection<PrologTerm> terms) { + final List<String> ids = new ArrayList<String>(terms.size()); + for (final PrologTerm term : terms) { + ids.add(getStateID(term)); + } + return ids; + } + + private String currentID; + + private GetCurrentStateIdCommand() { + } + + public static String getID(final Animator a) throws ProBException { + GetCurrentStateIdCommand cmd = new GetCurrentStateIdCommand(); + a.execute(cmd); + return cmd.getCurrentStateId(); + } + + private String getCurrentStateId() { + return currentID; + } + + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + currentID = getStateID(bindings.get("ID")); + } + + public void writeCommand(final IPrologTermOutput pto) { + pto.openTerm("getCurrentStateID").printVariable("ID").closeTerm(); + } +} diff --git a/de.prob.core/src/de/prob/core/command/GetEnabledOperationsCommand.java b/de.prob.core/src/de/prob/core/command/GetEnabledOperationsCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..dd0f7283115224e4f5bad92408d58d06a80469aa --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/GetEnabledOperationsCommand.java @@ -0,0 +1,65 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.command; + +import java.util.ArrayList; +import java.util.List; + +import de.prob.core.Animator; +import de.prob.core.domainobjects.Operation; +import de.prob.exceptions.ProBException; +import de.prob.parser.ISimplifiedROMap; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.CompoundPrologTerm; +import de.prob.prolog.term.ListPrologTerm; +import de.prob.prolog.term.PrologTerm; + +public final class GetEnabledOperationsCommand implements IComposableCommand { + + private static final String OPERATIONS_VARIABLE = "PLOps"; + private final String id; + private List<Operation> enabledOperations; + + public GetEnabledOperationsCommand(final String id) { + this.id = id; + } + + public static List<Operation> getOperations(final Animator animator, + final String id) throws ProBException { + GetEnabledOperationsCommand command = new GetEnabledOperationsCommand( + id); + animator.execute(command); + return command.getEnabledOperations(); + } + + // + // IComposableCommand + // + + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) { + enabledOperations = new ArrayList<Operation>(); + + final ListPrologTerm prologTerm = (ListPrologTerm) bindings + .get(OPERATIONS_VARIABLE); + for (PrologTerm op : prologTerm) { + final CompoundPrologTerm cpt = (CompoundPrologTerm) op; + enabledOperations.add(Operation.fromPrologTerm(cpt)); + } + } + + public void writeCommand(final IPrologTermOutput pto) { + pto.openTerm("computeOperationsForState"); + pto.printAtomOrNumber(id); + pto.printVariable(OPERATIONS_VARIABLE); + pto.closeTerm(); + } + + public List<Operation> getEnabledOperations() { + return enabledOperations; + } +} diff --git a/de.prob.core/src/de/prob/core/command/GetErrorsCommand.java b/de.prob.core/src/de/prob/core/command/GetErrorsCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..78f42a07f9e185ad4208d96faaa6226b8e7def6b --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/GetErrorsCommand.java @@ -0,0 +1,39 @@ +/** + * + */ +package de.prob.core.command; + +import java.util.List; + +import de.prob.parser.ISimplifiedROMap; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.ListPrologTerm; +import de.prob.prolog.term.PrologTerm; + +/** + * A command to get all the stored errors of ProB's Prolog part as a list of + * strings. + * + * @author plagge + */ +public class GetErrorsCommand implements IComposableCommand { + public static final String ERRORS_VARIABLE = "Errors"; + private List<String> errors; + + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + errors = PrologTerm.atomicStrings((ListPrologTerm) bindings + .get(ERRORS_VARIABLE)); + } + + public void writeCommand(final IPrologTermOutput pto) { + pto.openTerm("getErrorMessages").printVariable(ERRORS_VARIABLE) + .closeTerm(); + } + + public List<String> getErrors() { + return errors; + } + +} diff --git a/de.prob.core/src/de/prob/core/command/GetFullTraceCommand.java b/de.prob.core/src/de/prob/core/command/GetFullTraceCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..0d78d2c895ac6f9c87b4303b3635a9e2db44dc92 --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/GetFullTraceCommand.java @@ -0,0 +1,76 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.command; + +import java.util.Collections; +import java.util.List; + +import org.eclipse.core.runtime.Assert; + +import de.prob.core.Animator; +import de.prob.exceptions.ProBException; +import de.prob.parser.ISimplifiedROMap; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.ListPrologTerm; +import de.prob.prolog.term.PrologTerm; + +public final class GetFullTraceCommand implements IComposableCommand { + + private static final String IDS_VARIABLE = "IDs"; + private static final String ACTIONS_VARIABLE = "Actions"; + + public static class TraceResult { + private final List<String> operations; + private final List<String> states; + + public TraceResult(final List<String> operations, + final List<String> states) { + Assert.isTrue(operations.size() == states.size()); + this.operations = Collections.unmodifiableList(operations); + this.states = Collections.unmodifiableList(states); + } + + public List<String> getOperations() { + return operations; + } + + public List<String> getStates() { + return states; + } + } + + private TraceResult trace; + + private GetFullTraceCommand() { + } + + public static TraceResult getTrace(final Animator a) throws ProBException { + GetFullTraceCommand cmd = new GetFullTraceCommand(); + a.execute(cmd); + return cmd.getTrace(); + } + + private TraceResult getTrace() { + return trace; + } + + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + List<String> operations = PrologTerm + .atomicStrings((ListPrologTerm) bindings.get(ACTIONS_VARIABLE)); + List<String> states = GetCurrentStateIdCommand + .getStateIDs((ListPrologTerm) bindings.get(IDS_VARIABLE)); + trace = new TraceResult(operations, states); + } + + public void writeCommand(final IPrologTermOutput pto) { + pto.openTerm("find_shortest_trace_to_current_state2"); + pto.printVariable(ACTIONS_VARIABLE); + pto.printVariable(IDS_VARIABLE).closeTerm(); + } +} diff --git a/de.prob.core/src/de/prob/core/command/GetMachineObjectsCommand.java b/de.prob.core/src/de/prob/core/command/GetMachineObjectsCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..13ae047c452038dafc98f2a413f0e460a08b7557 --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/GetMachineObjectsCommand.java @@ -0,0 +1,152 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +/** + * + */ +package de.prob.core.command; + +import de.prob.core.Animator; +import de.prob.core.domainobjects.MachineDescription.Section; +import de.prob.core.domainobjects.MachineDescription.SectionType; +import de.prob.core.prolog.TypedIdentifierGenerator; +import de.prob.core.types.TypedIdentifier; +import de.prob.exceptions.ProBException; +import de.prob.parser.ISimplifiedROMap; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.CompoundPrologTerm; +import de.prob.prolog.term.ListPrologTerm; +import de.prob.prolog.term.PrologTerm; + +/** + * With this command, one retrieves some of the properties of a machine: The + * elements of given sets, the constants, variables and the operations. + * + * @author plagge + * + */ +public class GetMachineObjectsCommand implements IComposableCommand { + + public static class MachineObjectsResult { + public final Section[] sections; + public final TypedIdentifier[] setElements; + public final TypedIdentifier[] constants; + public final TypedIdentifier[] variables; + public final TypedIdentifier[] operations; + + public MachineObjectsResult(final Section[] sections, + final TypedIdentifier[] setElements, + final TypedIdentifier[] constants, + final TypedIdentifier[] variables, + final TypedIdentifier[] operations) { + this.sections = sections; + this.setElements = setElements; + this.constants = constants; + this.variables = variables; + this.operations = operations; + } + } + + private MachineObjectsResult machineObjectsResult; + + public static MachineObjectsResult getMachineObjects(final Animator a) + throws ProBException { + GetMachineObjectsCommand getMachineObjectsCommand = new GetMachineObjectsCommand(); + a.execute(getMachineObjectsCommand); + return getMachineObjectsCommand.getResult(); + } + + // FIXME refactor me! + private static Section[] getSections( + final ISimplifiedROMap<String, PrologTerm> binding, final String var) + throws CommandException { + PrologTerm term = getNotNullTerm(binding, var); + if (term.isList()) { + final ListPrologTerm list = (ListPrologTerm) term; + Section[] result = new Section[list.size()]; + for (int i = 0; i < list.size(); i++) { + final PrologTerm elem = list.get(i); + final SectionType sectionType; + if (elem.hasFunctor("model", 1)) { + sectionType = SectionType.MODEL; + } else if (elem.hasFunctor("context", 1)) { + sectionType = SectionType.CONTEXT; + } else { + CommandException cmdException = new CommandException( + "Prolog section list contains non-atomic component"); + cmdException.notifyUserOnce(); + throw cmdException; + } + final PrologTerm arg1 = ((CompoundPrologTerm) elem) + .getArgument(1); + final String name = PrologTerm.atomicString(arg1); + result[i] = new Section(sectionType, name); + } + return result; + } else { + CommandException cmdException = new CommandException( + "Expected section list, but received a term that is not a list"); + cmdException.notifyUserOnce(); + throw cmdException; + } + } + + private static TypedIdentifier[] createTypedIdentifiers( + final ISimplifiedROMap<String, PrologTerm> binding, final String var) + throws CommandException { + TypedIdentifier[] result; + final PrologTerm term = getNotNullTerm(binding, var); + if (term.isList()) { + result = TypedIdentifierGenerator.extract((ListPrologTerm) term); + } else { + CommandException cmdException = new CommandException( + "Expected list in Prolog variable " + var + ", but was: " + + term.toString()); + cmdException.notifyUserOnce(); + throw cmdException; + } + return result; + } + + private static PrologTerm getNotNullTerm( + final ISimplifiedROMap<String, PrologTerm> binding, final String var) + throws CommandException { + PrologTerm term = binding.get(var); + if (term == null) { + CommandException cmdException = new CommandException( + "Prolog variable " + var + " has no associated value"); + cmdException.notifyUserOnce(); + throw cmdException; + } + return term; + } + + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + Section[] sections; + TypedIdentifier[] setElements, constants, variables, operations; + + sections = getSections(bindings, "Sections"); + setElements = createTypedIdentifiers(bindings, "SetElements"); + constants = createTypedIdentifiers(bindings, "Constants"); + variables = createTypedIdentifiers(bindings, "Variables"); + operations = createTypedIdentifiers(bindings, "Operations"); + machineObjectsResult = new MachineObjectsResult(sections, setElements, + constants, variables, operations); + } + + public void writeCommand(final IPrologTermOutput pto) { + pto.openTerm("get_machine_objects").printVariable("Sections") + .printVariable("SetElements").printVariable("Constants") + .printVariable("Variables").printVariable("Operations") + .closeTerm(); + } + + public MachineObjectsResult getResult() { + return machineObjectsResult; + } +} diff --git a/de.prob.core/src/de/prob/core/command/GetOperationByPredicateCommand.java b/de.prob.core/src/de/prob/core/command/GetOperationByPredicateCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..51d42750422363ec023d2556f1af61998007dfab --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/GetOperationByPredicateCommand.java @@ -0,0 +1,159 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.command; + +import java.util.ArrayList; +import java.util.List; + +import de.be4.classicalb.core.parser.analysis.prolog.ASTProlog; +import de.be4.classicalb.core.parser.exceptions.BException; +import de.prob.core.Animator; +import de.prob.core.ProblemHandler; +import de.prob.core.domainobjects.Operation; +import de.prob.core.domainobjects.eval.PredicateEvalElement; +import de.prob.exceptions.ProBException; +import de.prob.parser.ISimplifiedROMap; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.CompoundPrologTerm; +import de.prob.prolog.term.ListPrologTerm; +import de.prob.prolog.term.PrologTerm; + +/** + * Command to execute an event that has not been enumerated by ProB, for further + * information see ({@link #getOperation}) + * + * @author Jens Bendisposto + * + */ +public final class GetOperationByPredicateCommand implements IComposableCommand { + + private static final String NEW_STATE_ID_VARIABLE = "NewStateID"; + private final PredicateEvalElement evalElement; + private final String stateId; + private final String name; + private List<Operation> operation; + private final int nrOfSolutions; + + private GetOperationByPredicateCommand() { + throw new UnsupportedOperationException("Do not call this constructor"); + } + + private GetOperationByPredicateCommand(final String stateId, + final String name, final String predicate, final int nrOfSolutions) + throws CommandException { + this.stateId = stateId; + this.name = name; + this.nrOfSolutions = nrOfSolutions; + PredicateEvalElement parsedEvalElement = null; + try { + parsedEvalElement = PredicateEvalElement.create(predicate); + } catch (BException e) { + String message = "Fatal error when trying to parse " + predicate + + ". Execution of operation " + name + " aborted."; + ProblemHandler.raiseCommandException(message); + parsedEvalElement = null; + } finally { + evalElement = parsedEvalElement; + } + } + + /** + * Works like @see getOperations but returns a single solution + */ + public static Operation getOperation(final Animator a, + final String stateId, final String name, final String predicate) + throws ProBException, BException { + + List<Operation> operations = getOperations(a, stateId, name, predicate, + 1); + + return operations == null ? null : operations.get(0); + } + + /** + * Tries to find a valid transition from the state <em>stateId</em> + * satisfying a B <em>predicate</em> . Returns either null if no event + * satisfying <em></em> was found by ProB or an Operation object that can be + * executed using ExecuteOperationCommand. + * + * @param animator + * - Animator Instance + * @param stateId + * - The state in which the event should be fired + * @param name + * - The event's name + * @param predicate + * - Additional guarding predicate + * @param nrOfSolutions + * - maximum number of solutions + * @return an Operation or null + * @throws BException + * - if the B predicate contains errors + * @throws ProBException + * - if something terrible happens ;-) + */ + public static List<Operation> getOperations(final Animator a, + final String stateId, final String name, final String predicate, + final int nrOfSolutions) throws ProBException, BException { + + GetOperationByPredicateCommand executeOperationCommand = new GetOperationByPredicateCommand( + stateId, name, predicate, nrOfSolutions); + if (executeOperationCommand.evalElement != null) { + a.execute(executeOperationCommand); + } + return executeOperationCommand.getOperation(); + } + + /** + * This method is called when the command is prepared for sending. The + * method is called by the Animator class, most likely it is not interesting + * for other classes. + * + * @see de.prob.core.command.IComposableCommand#writeCommand(de.prob.prolog.output.IPrologTermOutput) + */ + public void writeCommand(final IPrologTermOutput pto) { + pto.openTerm("execute_custom_operations").printAtomOrNumber(stateId) + .printAtom(name); + final ASTProlog prolog = new ASTProlog(pto, null); + evalElement.getPrologAst().apply(prolog); + pto.printNumber(nrOfSolutions); + pto.printVariable(NEW_STATE_ID_VARIABLE); + pto.printVariable("Errors").closeTerm(); + } + + /** + * This method is called to extract relevant information from ProB's answer. + * The method is called by the Animator class, most likely it is not + * interesting for other classes. + * + * @see de.prob.core.command.IComposableCommand#writeCommand(de.prob.prolog.output.IPrologTermOutput) + */ + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + + ListPrologTerm list = (ListPrologTerm) bindings + .get(NEW_STATE_ID_VARIABLE); + + if (list.isEmpty()) { + operation = null; + } else { + ArrayList<Operation> result = new ArrayList<Operation>(); + for (PrologTerm prologTerm : list) { + Operation op = Operation + .fromPrologTerm((CompoundPrologTerm) prologTerm); + result.add(op); + } + operation = result; + } + } + + private List<Operation> getOperation() { + return operation; + } + +} diff --git a/de.prob.core/src/de/prob/core/command/GetOperationNamesCommand.java b/de.prob.core/src/de/prob/core/command/GetOperationNamesCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..f054738434fc5592feb1fabcfc569a9630010024 --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/GetOperationNamesCommand.java @@ -0,0 +1,52 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.command; + +import java.util.ArrayList; +import java.util.List; + +import de.prob.core.Animator; +import de.prob.core.command.internal.GetAllOperationsNamesCommand; +import de.prob.core.command.internal.GetOperationParameterNames; +import de.prob.core.domainobjects.OperationInfo; +import de.prob.exceptions.ProBException; +import de.prob.prolog.term.CompoundPrologTerm; +import de.prob.prolog.term.PrologTerm; + +public final class GetOperationNamesCommand { + + public static List<OperationInfo> getNames(final Animator animator) + throws ProBException { + List<OperationInfo> result = new ArrayList<OperationInfo>(); + + GetAllOperationsNamesCommand namesCmd = new GetAllOperationsNamesCommand(); + animator.execute(namesCmd); + + animator.execute(namesCmd); + for (PrologTerm prologTerm : namesCmd.getNamesTerm()) { + + String opName = ((CompoundPrologTerm) prologTerm).getFunctor(); // FIXME + // this + // looks + // pretty + // weird, + // what + // does + // probcli + // answers? + + GetOperationParameterNames cmd = new GetOperationParameterNames( + opName); + animator.execute(cmd); + List<String> paramNames = cmd.getParameterNames(); + result.add(new OperationInfo(opName, paramNames)); + } + + return result; + } + +} diff --git a/de.prob.core/src/de/prob/core/command/GetPreferencesCommand.java b/de.prob.core/src/de/prob/core/command/GetPreferencesCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..bdf9a11a46f17eeb16fa347954df49b987b8f760 --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/GetPreferencesCommand.java @@ -0,0 +1,73 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.command; + +import java.util.ArrayList; +import java.util.List; + +import de.prob.core.Animator; +import de.prob.core.domainobjects.ProBPreference; +import de.prob.exceptions.ProBException; +import de.prob.parser.BindingGenerator; +import de.prob.parser.ISimplifiedROMap; +import de.prob.parser.ResultParserException; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.CompoundPrologTerm; +import de.prob.prolog.term.ListPrologTerm; +import de.prob.prolog.term.PrologTerm; + +public final class GetPreferencesCommand implements IComposableCommand { + + private static final String PREFS_VARIABLE = "Prefs"; + private List<ProBPreference> prefs; + + private GetPreferencesCommand() { + } + + public static List<ProBPreference> getPreferences(final Animator animator) + throws ProBException { + GetPreferencesCommand getPreferencesCommand = new GetPreferencesCommand(); + animator.execute(getPreferencesCommand); + return getPreferencesCommand.getPrefs(); + } + + private List<ProBPreference> getPrefs() { + return prefs; + } + + private ProBPreference verifyTerm(final PrologTerm term) + throws CommandException { + CompoundPrologTerm compoundTerm; + try { + compoundTerm = BindingGenerator.getCompoundTerm(term, "preference", + 5); + } catch (ResultParserException e) { + CommandException commandException = new CommandException( + e.getLocalizedMessage(), e); + commandException.notifyUserOnce(); + throw commandException; + } + return new ProBPreference(compoundTerm); + } + + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + ListPrologTerm p = (ListPrologTerm) bindings.get(PREFS_VARIABLE); + prefs = new ArrayList<ProBPreference>(); + for (PrologTerm term : p) { + ProBPreference preference = null; + preference = verifyTerm(term); + prefs.add(preference); + } + } + + public void writeCommand(final IPrologTermOutput pto) { + pto.openTerm("list_eclipse_preferences").printVariable(PREFS_VARIABLE) + .closeTerm(); + } +} diff --git a/de.prob.core/src/de/prob/core/command/GetPrintableAtomsList.java b/de.prob.core/src/de/prob/core/command/GetPrintableAtomsList.java new file mode 100644 index 0000000000000000000000000000000000000000..947af6c217e86862f19a347304e0f3092d26674d --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/GetPrintableAtomsList.java @@ -0,0 +1,60 @@ +package de.prob.core.command; + +import java.util.List; + +import de.prob.core.Animator; +import de.prob.exceptions.ProBException; +import de.prob.parser.ISimplifiedROMap; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.ListPrologTerm; +import de.prob.prolog.term.PrologTerm; + +/** + * @author Jens Bendisposto + * + */ +public class GetPrintableAtomsList implements IComposableCommand { + + private static final String PROLOG_VARIABLE = "L"; + private final String prologPredicate; + private List<String> list; + + /** + * Executes the query: prologPredicate(L). Expects L to be a list of + * printable atoms + * + * @param animator + * @param prologPredicate + * @return + * @throws ProBException + */ + + public static List<String> getList(final Animator animator, + final String prologPredicate) throws ProBException { + GetPrintableAtomsList cmd = new GetPrintableAtomsList(prologPredicate); + animator.execute(cmd); + return cmd.getList(); + } + + private List<String> getList() { + return list; + } + + private GetPrintableAtomsList(final String prologPredicate) { + this.prologPredicate = prologPredicate; + } + + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + list = PrologTerm.atomicStrings((ListPrologTerm) bindings + .get(PROLOG_VARIABLE)); + } + + public void writeCommand(final IPrologTermOutput pto) { + pto.openTerm(prologPredicate); + pto.printVariable(PROLOG_VARIABLE); + pto.closeTerm(); + } + +} diff --git a/de.prob.core/src/de/prob/core/command/GetPrologRandomSeed.java b/de.prob.core/src/de/prob/core/command/GetPrologRandomSeed.java new file mode 100644 index 0000000000000000000000000000000000000000..53b952d6a228bba79efd3c63faabee41d038b6a0 --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/GetPrologRandomSeed.java @@ -0,0 +1,58 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.command; + +import java.math.BigInteger; + +import de.prob.core.Animator; +import de.prob.core.domainobjects.RandomSeed; +import de.prob.exceptions.ProBException; +import de.prob.parser.BindingGenerator; +import de.prob.parser.ISimplifiedROMap; +import de.prob.parser.ResultParserException; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.PrologTerm; + +public final class GetPrologRandomSeed implements IComposableCommand { + + private RandomSeed randomSeed; + + public static RandomSeed getSeed(final Animator a) throws ProBException { + final GetPrologRandomSeed cmd = new GetPrologRandomSeed(); + a.execute(cmd); + return cmd.getSeed(); + } + + public RandomSeed getSeed() { + return randomSeed; + } + + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + BigInteger x, y, z, b; + try { + x = BindingGenerator.getInteger(bindings.get("X")).getValue(); + y = BindingGenerator.getInteger(bindings.get("Y")).getValue(); + z = BindingGenerator.getInteger(bindings.get("Z")).getValue(); + b = BindingGenerator.getInteger(bindings.get("B")).getValue(); + } catch (ResultParserException e) { + CommandException commandException = new CommandException( + e.getLocalizedMessage(), e); + commandException.notifyUserOnce(); + throw commandException; + } + + randomSeed = new RandomSeed(x, y, z, b); + } + + public void writeCommand(final IPrologTermOutput pto) { + pto.openTerm("get_rand").printVariable("X").printVariable("Y") + .printVariable("Z").printVariable("B").closeTerm(); + } + +} diff --git a/de.prob.core/src/de/prob/core/command/GetStateBasedErrorsCommand.java b/de.prob.core/src/de/prob/core/command/GetStateBasedErrorsCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..fb16e1ccd954d52f6960df1ce64fde90085b5006 --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/GetStateBasedErrorsCommand.java @@ -0,0 +1,91 @@ +/** + * + */ +package de.prob.core.command; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import de.prob.core.Animator; +import de.prob.core.domainobjects.StateError; +import de.prob.exceptions.ProBException; +import de.prob.parser.BindingGenerator; +import de.prob.parser.ISimplifiedROMap; +import de.prob.parser.ResultParserException; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.CompoundPrologTerm; +import de.prob.prolog.term.ListPrologTerm; +import de.prob.prolog.term.PrologTerm; + +/** + * This command asks ProB if a certain state has errors associated to it. + * + * @author plagge + */ +public class GetStateBasedErrorsCommand implements IComposableCommand { + + private final String stateId; + private Collection<StateError> stateErrors; + + public GetStateBasedErrorsCommand(final String stateId) { + this.stateId = stateId; + } + + public static Collection<StateError> getStateValues(final Animator a, + final String id) throws ProBException { + GetStateBasedErrorsCommand command = new GetStateBasedErrorsCommand(id); + a.execute(command); + return command.getResult(); + } + + // + // ComposableCommand + // + + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + final List<StateError> errors; + ListPrologTerm list; + try { + list = BindingGenerator.getList(bindings, "Errors"); + } catch (ResultParserException e) { + CommandException commandException = new CommandException( + e.getLocalizedMessage(), e); + commandException.notifyUserOnce(); + throw commandException; + } + + if (list.isEmpty()) { + errors = Collections.emptyList(); + } else { + errors = new ArrayList<StateError>(); + for (PrologTerm term : list) { + CompoundPrologTerm compoundTerm; + try { + compoundTerm = BindingGenerator.getCompoundTerm(term, + "error", 3); + } catch (ResultParserException e) { + CommandException commandException = new CommandException( + e.getLocalizedMessage(), e); + commandException.notifyUserOnce(); + throw commandException; + } + errors.add(new StateError(compoundTerm)); + } + } + this.stateErrors = errors; + } + + public void writeCommand(final IPrologTermOutput pto) { + pto.openTerm("get_state_errors").printAtomOrNumber(stateId) + .printVariable("Errors").closeTerm(); + } + + public Collection<StateError> getResult() { + return stateErrors; + } + +} diff --git a/de.prob.core/src/de/prob/core/command/GetStateValuesCommand.java b/de.prob.core/src/de/prob/core/command/GetStateValuesCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..22d58e9ac9298a74e1853909dec0bbe4aeaec4f1 --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/GetStateValuesCommand.java @@ -0,0 +1,70 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.command; + +import java.util.ArrayList; +import java.util.List; + +import de.prob.core.domainobjects.Variable; +import de.prob.parser.BindingGenerator; +import de.prob.parser.ISimplifiedROMap; +import de.prob.parser.ResultParserException; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.CompoundPrologTerm; +import de.prob.prolog.term.ListPrologTerm; +import de.prob.prolog.term.PrologTerm; + +public final class GetStateValuesCommand implements IComposableCommand { + + private final String stateId; + private List<Variable> result; + + public GetStateValuesCommand(final String stateID) { + stateId = stateID; + } + + public List<Variable> getResult() { + return result; + } + + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + final List<Variable> variables = new ArrayList<Variable>(); + + ListPrologTerm list; + try { + list = BindingGenerator.getList(bindings, "Bindings"); + } catch (ResultParserException e) { + CommandException commandException = new CommandException( + e.getLocalizedMessage(), e); + commandException.notifyUserOnce(); + throw commandException; + } + + for (PrologTerm term : list) { + CompoundPrologTerm compoundTerm; + try { + compoundTerm = BindingGenerator.getCompoundTerm(term, + "binding", 3); + } catch (ResultParserException e) { + CommandException commandException = new CommandException( + e.getLocalizedMessage(), e); + commandException.notifyUserOnce(); + throw commandException; + } + variables.add(new Variable(compoundTerm)); + } + result = variables; + } + + public void writeCommand(final IPrologTermOutput pto) { + pto.openTerm("getStateValues").printAtomOrNumber(stateId) + .printVariable("Bindings").closeTerm(); + } + +} diff --git a/de.prob.core/src/de/prob/core/command/GetTimeoutedOperationsCommand.java b/de.prob.core/src/de/prob/core/command/GetTimeoutedOperationsCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..ec4030b68e4b7706d5baaecb5aa4ab27fe65d4a5 --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/GetTimeoutedOperationsCommand.java @@ -0,0 +1,43 @@ +package de.prob.core.command; + +import java.util.List; + +import de.prob.parser.BindingGenerator; +import de.prob.parser.ISimplifiedROMap; +import de.prob.parser.ResultParserException; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.PrologTerm; + +public class GetTimeoutedOperationsCommand implements IComposableCommand { + + private static final String TIMEOUT_VARIABLE = "TO"; + private final String state; + private List<String> timeouts; + + public GetTimeoutedOperationsCommand(final String state) { + this.state = state; + } + + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + try { + timeouts = PrologTerm.atomicStrings(BindingGenerator.getList( + bindings, TIMEOUT_VARIABLE)); + } catch (ResultParserException e) { + CommandException commandException = new CommandException( + e.getLocalizedMessage(), e); + commandException.notifyUserOnce(); + throw commandException; + } + } + + public void writeCommand(final IPrologTermOutput pto) { + pto.openTerm("op_timeout_occurred").printAtomOrNumber(state) + .printVariable(TIMEOUT_VARIABLE).closeTerm(); + } + + public List<String> getTimeouts() { + return timeouts; + } +} diff --git a/de.prob.core/src/de/prob/core/command/GetTraceCommand.java b/de.prob.core/src/de/prob/core/command/GetTraceCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..ad61e041189c519c1e334011ebd0a249beee06ee --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/GetTraceCommand.java @@ -0,0 +1,90 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.command; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +import de.prob.core.Animator; +import de.prob.exceptions.ProBException; +import de.prob.parser.ISimplifiedROMap; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.ListPrologTerm; +import de.prob.prolog.term.PrologTerm; + +public final class GetTraceCommand implements IComposableCommand { + + private static final String TRACE_VARIABLE = "Trace"; + + private final static class Occurence { + private final String text; + + private int count; + + public Occurence(final String text) { + this.text = text; + this.count = 1; + } + + public synchronized void inc() { + this.count++; + } + + @Override + public synchronized String toString() { + return text + ((count > 1) ? " (" + count + " times)" : ""); + } + + } + + private List<String> trace; + + private GetTraceCommand() { + } + + public static List<String> getTrace(final Animator a) throws ProBException { + GetTraceCommand getTraceCommand = new GetTraceCommand(); + a.execute(getTraceCommand); + return getTraceCommand.getTrace(); + } + + private List<String> getTrace() { + return trace; + } + + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + List<Occurence> res = new LinkedList<Occurence>(); + + ListPrologTerm list = (ListPrologTerm) bindings.get(TRACE_VARIABLE); + + Occurence current = null; + for (PrologTerm term : list) { + if (current == null || !current.text.equals(term.toString())) { + current = new Occurence(term.toString()); + res.add(current); + } else { + current.inc(); + } + } + + final List<String> actions = new ArrayList<String>(); + for (Occurence occurence : res) { + actions.add(occurence.toString()); + } + + this.trace = actions; + } + + public void writeCommand(final IPrologTermOutput pto) { + pto.openTerm("find_shortest_trace_to_current_state") + .printVariable(TRACE_VARIABLE).closeTerm(); + } + +} diff --git a/de.prob.core/src/de/prob/core/command/IComposableCommand.java b/de.prob.core/src/de/prob/core/command/IComposableCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..feeac3329b3173559f672fc299e50546c4bc0598 --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/IComposableCommand.java @@ -0,0 +1,30 @@ +/** + * + */ +package de.prob.core.command; + +import org.eclipse.core.commands.Command; + +import de.prob.parser.ISimplifiedROMap; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.PrologTerm; + +/** + * A ComposableCommand defines a ProB command that can be used together with + * other commands in a batch-mode style. + * + * That means that the communication to the ProB core is as simple as a message + * to the core (containing one ore more Prolog terms) and one answer. + * + * @author plagge + * + * @see Command + */ +public interface IComposableCommand { + static IComposableCommand[] EMPTY_ARRAY = new IComposableCommand[0]; + + void writeCommand(IPrologTermOutput pto) throws CommandException; + + void processResult(ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException; +} diff --git a/de.prob.core/src/de/prob/core/command/ISimpleTextCommand.java b/de.prob.core/src/de/prob/core/command/ISimpleTextCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..4abbfc3687137118c7ce4b23c7bb8bba54ea035e --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/ISimpleTextCommand.java @@ -0,0 +1,5 @@ +package de.prob.core.command; + +public interface ISimpleTextCommand extends IComposableCommand{ + String getResultingText(); +} diff --git a/de.prob.core/src/de/prob/core/command/LoadClassicalBModelCommand.java b/de.prob.core/src/de/prob/core/command/LoadClassicalBModelCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..3ad2ffd9751a2258707a3a854389ff02d31b850f --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/LoadClassicalBModelCommand.java @@ -0,0 +1,173 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.command; + +import java.io.File; +import java.io.IOException; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import org.eventb.core.IEventBRoot; +import org.osgi.service.prefs.BackingStoreException; +import org.osgi.service.prefs.Preferences; + +import de.be4.classicalb.core.parser.BParser; +import de.be4.classicalb.core.parser.analysis.prolog.RecursiveMachineLoader; +import de.be4.classicalb.core.parser.exceptions.BException; +import de.be4.classicalb.core.parser.node.Start; +import de.prob.core.Animator; +import de.prob.core.domainobjects.Operation; +import de.prob.core.domainobjects.ProBPreference; +import de.prob.core.domainobjects.State; +import de.prob.exceptions.ProBException; +import de.prob.logging.Logger; +import de.prob.parser.ISimplifiedROMap; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.output.StructuredPrologOutput; +import de.prob.prolog.term.CompoundPrologTerm; +import de.prob.prolog.term.ListPrologTerm; +import de.prob.prolog.term.PrologTerm; + +/** + * Command to load a new Event B Model for animation. + */ +public final class LoadClassicalBModelCommand { + + private static boolean preferencesAlreadyCleanedUp = false; + + private LoadClassicalBModelCommand() { + throw new UnsupportedOperationException("Do not instantiate this class"); + } + + private LoadClassicalBModelCommand(final IEventBRoot model) { + } + + + private static void removeObsoletePreferences(final Animator animator) + throws ProBException { + if (!preferencesAlreadyCleanedUp) { + // get all preference names from ProB + Collection<ProBPreference> prefs = GetPreferencesCommand + .getPreferences(animator); + Set<String> probPrefNames = new HashSet<String>(); + for (ProBPreference probpref : prefs) { + probPrefNames.add(probpref.name); + } + // now check all stored (in Eclipse's store) preferences + // if they still exist + Preferences preferences = SetPreferencesCommand.getPreferences(); + try { + boolean foundObsoletePreference = false; + for (String prefname : preferences.keys()) { + if (!probPrefNames.contains(prefname)) { + // preference does not exists anymore + preferences.remove(prefname); + foundObsoletePreference = true; + String message = "removed obsolete preference from preferences store: " + + prefname; + Logger.info(message); + } + } + if (foundObsoletePreference) { + preferences.flush(); + } + } catch (BackingStoreException e) { + Logger.notifyUser("Error while accessing ProB Preferences", e); + } + preferencesAlreadyCleanedUp = true; + } + } + + public static void load(final Animator animator, final File model, String name) + throws ProBException { + animator.resetDirty(); + removeObsoletePreferences(animator); + + final ClearMachineCommand clear = new ClearMachineCommand(); + final SetPreferencesCommand setPrefs = SetPreferencesCommand + .createSetPreferencesCommand(animator); + final IComposableCommand load = getLoadCommand(model, name); + final StartAnimationCommand start = new StartAnimationCommand(); + final ExploreStateCommand explore = new ExploreStateCommand("root"); + + final ComposedCommand composed = new ComposedCommand(clear, setPrefs, + load, start, explore); + + animator.execute(composed); + + final State commandResult = explore.getState(); + animator.announceCurrentStateChanged(commandResult, + Operation.NULL_OPERATION); + } + + private static IComposableCommand getLoadCommand(final File model, final String name) + throws ProBException { + return new IComposableCommand() { + + @Override + public void writeCommand(final IPrologTermOutput pto) throws CommandException { + pto.openTerm("load_b_project"); + pto.printAtom(name); + pto.printTerm(getLoadTerm(model)); + pto.printVariable("Errors"); + pto.closeTerm(); + pto.printAtom("start_animation"); + } + + @Override + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) { + ListPrologTerm e = (ListPrologTerm) bindings.get("Errors"); + if (!e.isEmpty()) { + StringBuffer errormsg = new StringBuffer("Error from Prolog: "); + for (PrologTerm prologTerm : e) { + errormsg.append(prologTerm); + errormsg.append('\n'); + } + Logger.notifyUser(errormsg.toString()); + } + } + }; + + + } + + private static PrologTerm getLoadTerm(final File model) throws CommandException { + BParser bParser = new BParser(); + try { + Start ast = bParser.parseFile(model, false); + final RecursiveMachineLoader rml = new RecursiveMachineLoader( + model.getParent()); + rml.loadAllMachines(model, ast, null, bParser.getDefinitions()); + StructuredPrologOutput output = new StructuredPrologOutput(); + StructuredPrologOutput out = new StructuredPrologOutput(); + rml.printAsProlog(output); + + Collection<PrologTerm> sentences = output.getSentences(); + out.openList(); + Iterator<PrologTerm> iterator = sentences.iterator(); + iterator.next(); + iterator.next(); + while (iterator.hasNext()) { + CompoundPrologTerm prologTerm = (CompoundPrologTerm) iterator + .next(); + out.printTerm(prologTerm.getArgument(1)); + } + out.closeList(); + out.fullstop(); + return out.getSentences().iterator().next(); + } catch (IOException e) { + Logger.notifyUser("IO Error",e); + throw new CommandException(e.getLocalizedMessage(),e); + } catch (BException e) { + Logger.notifyUser("Parser Error "+e.getLocalizedMessage(),e); + throw new CommandException(e.getLocalizedMessage(),e); + } + } +} diff --git a/de.prob.core/src/de/prob/core/command/LoadEventBModelCommand.java b/de.prob.core/src/de/prob/core/command/LoadEventBModelCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..316d436cfb029a75fd3232548ee3415f178854a1 --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/LoadEventBModelCommand.java @@ -0,0 +1,193 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.command; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import org.eventb.core.IContextRoot; +import org.eventb.core.IEventBRoot; +import org.eventb.core.IMachineRoot; +import org.osgi.service.prefs.BackingStoreException; +import org.osgi.service.prefs.Preferences; +import org.rodinp.core.RodinDBException; + +import de.prob.core.Animator; +import de.prob.core.LanguageDependendAnimationPart; +import de.prob.core.domainobjects.MachineDescription; +import de.prob.core.domainobjects.Operation; +import de.prob.core.domainobjects.ProBPreference; +import de.prob.core.domainobjects.State; +import de.prob.core.langdep.EventBAnimatorPart; +import de.prob.core.translator.TranslationFailedException; +import de.prob.eventb.translator.TranslatorFactory; +import de.prob.exceptions.ProBException; +import de.prob.logging.Logger; +import de.prob.parser.ISimplifiedROMap; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.output.StructuredPrologOutput; +import de.prob.prolog.term.PrologTerm; + +/** + * Command to load a new Event B Model for animation. + */ +public final class LoadEventBModelCommand { + + private static boolean preferencesAlreadyCleanedUp = false; + + private LoadEventBModelCommand() { + throw new UnsupportedOperationException("Do not instantiate this class"); + } + + private LoadEventBModelCommand(final IEventBRoot model) { + } + + private static boolean checkForContexts(final IEventBRoot model) { + if (model instanceof IContextRoot) { + return true; + } + try { + if (model instanceof IMachineRoot) { + IMachineRoot r = (IMachineRoot) model; + return r.getSeesClauses().length != 0; + } + } catch (RodinDBException e) { + // ignore + } + return false; + } + + public static PrologTerm toPrologTerm(IEventBRoot model) + throws CommandException { + StructuredPrologOutput out = new StructuredPrologOutput(); + + final InternalLoadCommand load = new InternalLoadCommand(model); + load.writeCommand(out); + out.fullstop(); + return out.getSentences().iterator().next(); + } + + public static void load(final Animator animator, final IEventBRoot model) + throws ProBException { + boolean context = checkForContexts(model); + animator.resetDirty(); + removeObsoletePreferences(animator); + + final LanguageDependendAnimationPart ldp = new EventBAnimatorPart(model); + + final ClearMachineCommand clear = new ClearMachineCommand(); + final SetPreferencesCommand setPrefs = SetPreferencesCommand + .createSetPreferencesCommand(animator); + final InternalLoadCommand load = new InternalLoadCommand(model); + final StartAnimationCommand start = new StartAnimationCommand(); + final SetMachineObjectsCommand getMObjects = new SetMachineObjectsCommand( + animator, ldp); + final ExploreStateCommand explore = new ExploreStateCommand("root"); + + final ComposedCommand composed = new ComposedCommand(clear, setPrefs, + load, start, getMObjects, explore); + + animator.execute(composed); + + final State commandResult = explore.getState(); + animator.announceCurrentStateChanged(commandResult, + Operation.NULL_OPERATION); + + if (commandResult.isTimeoutOccured() && context) { + final String message = "A timeout occured when finding constants. Typically this means, that your axioms are too complicated for automatical solving. You might create an animation refinement using the context menu to help ProB finding a solution"; + Logger.notifyUserWithoutBugreport(message); + } + + } + + private static void removeObsoletePreferences(final Animator animator) + throws ProBException { + if (!preferencesAlreadyCleanedUp) { + // get all preference names from ProB + Collection<ProBPreference> prefs = GetPreferencesCommand + .getPreferences(animator); + Set<String> probPrefNames = new HashSet<String>(); + for (ProBPreference probpref : prefs) { + probPrefNames.add(probpref.name); + } + // now check all stored (in Eclipse's store) preferences + // if they still exist + Preferences preferences = SetPreferencesCommand.getPreferences(); + try { + boolean foundObsoletePreference = false; + for (String prefname : preferences.keys()) { + if (!probPrefNames.contains(prefname)) { + // preference does not exists anymore + preferences.remove(prefname); + foundObsoletePreference = true; + String message = "removed obsolete preference from preferences store: " + + prefname; + Logger.info(message); + } + } + if (foundObsoletePreference) { + preferences.flush(); + } + } catch (BackingStoreException e) { + Logger.notifyUser("Error while accessing ProB Preferences", e); + } + preferencesAlreadyCleanedUp = true; + } + } + + private static class SetMachineObjectsCommand extends + GetMachineObjectsCommand { + private final Animator animator; + private final LanguageDependendAnimationPart ldp; + + public SetMachineObjectsCommand(final Animator animator, + final LanguageDependendAnimationPart ldp) { + super(); + this.animator = animator; + this.ldp = ldp; + } + + @Override + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + super.processResult(bindings); + animator.setMachineDescription(new MachineDescription(getResult())); + animator.setLanguageDependendPart(ldp); + animator.announceReset(); + } + } + + private static class InternalLoadCommand implements IComposableCommand { + private final IEventBRoot model; + + public InternalLoadCommand(final IEventBRoot model) { + this.model = model; + } + + @Override + public void writeCommand(final IPrologTermOutput pto) + throws CommandException { + try { + TranslatorFactory.translate(model, pto); + } catch (TranslationFailedException e) { + throw new CommandException( + "Translation from Event-B to ProB's internal representation failed", + e); + } + } + + @Override + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + // there are no results to process + } + + } +} diff --git a/de.prob.core/src/de/prob/core/command/LtlCheckingCommand.java b/de.prob.core/src/de/prob/core/command/LtlCheckingCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..ed5320eae01d596e0ce88c803e3c3f441ec0617c --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/LtlCheckingCommand.java @@ -0,0 +1,251 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.command; + +import de.prob.core.Animator; +import de.prob.core.domainobjects.Operation; +import de.prob.exceptions.ProBException; +import de.prob.parser.ISimplifiedROMap; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.CompoundPrologTerm; +import de.prob.prolog.term.IntegerPrologTerm; +import de.prob.prolog.term.ListPrologTerm; +import de.prob.prolog.term.PrologTerm; + +/** + * @ Andriy: Das ist jetzt deine Baustelle :) + */ +public final class LtlCheckingCommand implements IComposableCommand { + + private static final String VARIABLE_NAME_ATOMICS = "A"; + private static final String VARIABLE_NAME_STRUCTURE = "S"; + private static final String VARIABLE_NAME_RESULT = "R"; + + public static enum StartMode { + init, starthere, checkhere + }; + + public static enum Status { + incomplete(false), ok(true), counterexample(true), nostart(true), typeerror( + true); + private final boolean abort; + + private Status(final boolean abort) { + this.abort = abort; + } + + public boolean isAbort() { + return abort; + } + } + + public static enum PathType { + INFINITE, FINITE, REDUCED + }; + + public static class Result { + private final Status status; + private final ListPrologTerm atomics; + private final PrologTerm structure; + private final ListPrologTerm counterexample; + private final PathType pathType; + private final int loopEntry; + private final Operation[] initPathOps; + + public Result(final Status status, final ListPrologTerm atomics, + final PrologTerm structure, + final ListPrologTerm counterexample, final PathType pathType, + final int loopEntry, final Operation[] initPathOps) { + this.status = status; + this.atomics = atomics; + this.structure = structure; + this.counterexample = counterexample; + this.pathType = pathType; + this.loopEntry = loopEntry; + this.initPathOps = initPathOps; + } + + /** + * @return the basic outcome of the model-checking, never + * <code>null</code> + */ + public Status getStatus() { + return status; + } + + /** + * @return if the model-checking is finished after the call. + */ + public boolean isAbort() { + return status.isAbort(); + } + + /** + * Returns list of pretty-printed sub-formulas, each of the form + * ap(Text) or tp(Text). + * + * E.g. for G({x=0} U [start]), the list contains ap('{x=0}') and + * tp('[start]'). + * + * @return A list of atomic formulas, never <code>null</code> + */ + public ListPrologTerm getAtomics() { + return atomics; + } + + /** + * A tree structure representing the formula. Atomic propositions or + * transition propositions are represented by integers, referring to the + * index of the corresponding formula in {@link #atomics} + * + * Lets assume that {@link #getAtomics()} returns the list + * [ap('{x=0}'),ap('{y=1}'),tp('[start]')] for the LTL formula + * + * G({y=1} => ({x=0} U [start])). + * + * The corresponding structure would be: globally(implies(1,until(0,2))) + * + * @return the structure, <code>null</code> in case of a typecheck-error + */ + public PrologTerm getStructure() { + return structure; + } + + /** + * Returns the list of atoms of the counter-example. Each atom is a term + * of the form + * atom(StateId,EvalList,NextOperationId,NextOperationString) where + * StateId is the ID of the corresponding state and NextOperationId is + * the ID of the operation that leads to the next atom. + * NextOperationString is a pretty-printed string of that operation. + * EvalList is a list of 0s and 1s, it has the same length of the list + * returned by {@link #getAtomics()}. Each number represents the + * evaluation of the corresponding atomic formula (in + * {@link #getAtomics()}) in the current atom. 0=false and 1=true. + * + * @return A list of atoms, <code>null</code> if no counter-example is + * found. + */ + public ListPrologTerm getCounterexample() { + return counterexample; + } + + /** + * @return the path type, <code>null</code> if there is no + * counter-example + */ + public PathType getPathType() { + return pathType; + } + + /** + * This value is only defined if {@link #getPathType()} returns LOOP. + * + * @return the index in the counter-example where the loop of the + * lasso-form starts, -1 if there is no counterexample or the + * example is not in lasso form. + */ + public int getLoopEntry() { + return loopEntry; + } + + public Operation[] getInitPathOps() { + return initPathOps; + } + } + + private final PrologTerm ltlFormula; + private final int max; + private final StartMode mode; + private Result result; + + public LtlCheckingCommand(final PrologTerm ltlFormula, final int max, + final StartMode mode) { + this.ltlFormula = ltlFormula; + this.max = max; + this.mode = mode; + } + + public static Result modelCheck(final Animator a, final PrologTerm fomula, + final int max, final StartMode mode) throws ProBException { + LtlCheckingCommand command = new LtlCheckingCommand(fomula, max, mode); + a.execute(command); + return command.getResult(); + } + + private Result getResult() { + return result; + } + + @Override + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + CompoundPrologTerm term = (CompoundPrologTerm) bindings + .get(VARIABLE_NAME_RESULT); + + final Status status = Enum.valueOf(Status.class, term.getFunctor()); + + final ListPrologTerm counterexample; + final PathType pathType; + final int loopEntry; + final Operation[] initPath; + if (term.hasFunctor("counterexample", 3)) { + counterexample = (ListPrologTerm) term.getArgument(1); + CompoundPrologTerm loopStatus = (CompoundPrologTerm) term + .getArgument(2); + if (loopStatus.hasFunctor("no_loop", 0)) { + pathType = PathType.REDUCED; + loopEntry = -1; + } else if (loopStatus.hasFunctor("deadlock", 0)) { + pathType = PathType.FINITE; + loopEntry = -1; + } else if (loopStatus.hasFunctor("loop", 1)) { + pathType = PathType.INFINITE; + loopEntry = ((IntegerPrologTerm) loopStatus.getArgument(1)) + .getValue().intValue(); + } else + throw new CommandException( + "LTL model check returned unexpected loop status: " + + loopStatus); + final ListPrologTerm operationIds = (ListPrologTerm) term + .getArgument(3); + initPath = new Operation[operationIds.size()]; + int i = 0; + for (final PrologTerm opTerm : operationIds) { + initPath[i] = Operation.fromPrologTerm(opTerm); + i++; + } + } else { + counterexample = null; + pathType = null; + loopEntry = -1; + initPath = null; + } + + final ListPrologTerm atomics = (ListPrologTerm) bindings + .get(VARIABLE_NAME_ATOMICS); + final PrologTerm structure = bindings.get(VARIABLE_NAME_STRUCTURE); + final boolean noStructure = (structure instanceof ListPrologTerm) + && ((ListPrologTerm) structure).isEmpty(); + + result = new Result(status, atomics, noStructure ? null : structure, + counterexample, pathType, loopEntry, initPath); + } + + @Override + public void writeCommand(final IPrologTermOutput pto) { + pto.openTerm("do_ltl_modelcheck"); + ltlFormula.toTermOutput(pto); + pto.printNumber(max); + pto.printAtom(mode.toString()); + pto.printVariable(VARIABLE_NAME_ATOMICS); + pto.printVariable(VARIABLE_NAME_STRUCTURE); + pto.printVariable(VARIABLE_NAME_RESULT); + pto.closeTerm(); + } +} diff --git a/de.prob.core/src/de/prob/core/command/ModelCheckingResult.java b/de.prob.core/src/de/prob/core/command/ModelCheckingResult.java new file mode 100644 index 0000000000000000000000000000000000000000..0b5f4b7f02cd3a860ec307fc38795c4760d0f3ce --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/ModelCheckingResult.java @@ -0,0 +1,36 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.command; + +import java.util.ArrayList; +import java.util.List; + +import de.prob.prolog.term.CompoundPrologTerm; +import de.prob.prolog.term.PrologTerm; + +public class ModelCheckingResult<T extends Enum<T>> { + + private final T result; + private final List<PrologTerm> arguments = new ArrayList<PrologTerm>(); + + public ModelCheckingResult(final Class<T> enumeration, + final CompoundPrologTerm term) { + result = Enum.valueOf(enumeration, term.getFunctor()); + for (int i = 1; i <= term.getArity(); i++) { + arguments.add(term.getArgument(i)); + } + } + + public PrologTerm getArgument(final int i) { + return arguments.get(i); + } + + public T getResult() { + return result; + } + +} diff --git a/de.prob.core/src/de/prob/core/command/ReplayTraceCommand.java b/de.prob.core/src/de/prob/core/command/ReplayTraceCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..732ede1dce52d00c1d27130ea94c5788ef838030 --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/ReplayTraceCommand.java @@ -0,0 +1,59 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.command; + +import java.util.Iterator; +import java.util.List; + +import de.prob.core.Animator; +import de.prob.core.command.GetFullTraceCommand.TraceResult; +import de.prob.core.domainobjects.Operation; +import de.prob.core.domainobjects.State; +import de.prob.exceptions.ProBException; + +public final class ReplayTraceCommand { + private static final String ROOT = "root"; + + private ReplayTraceCommand() { + } + + public static void replay(final Animator animator) throws ProBException { + final TraceResult trace = GetFullTraceCommand.getTrace(animator); + animator.getHistory().reset(); + ExploreStateCommand.exploreState(animator, ROOT); + SetStateCommand.setState(animator, ROOT); + for (Iterator<String> it = trace.getStates().iterator(); it.hasNext();) { + final String nextState = it.next(); + final State state = animator.getCurrentState(); + final Operation op = getOperationByDstId(nextState, + state.getEnabledOperations()); + final boolean silent = it.hasNext(); + ExecuteOperationCommand.executeOperation(animator, op, silent); + } + } + + /** + * Find and return the first Operation in <code>operations</code> with + * <code>dstId</code> as destination state. If no such Operation can be + * found, returns <code>null</code>. + * + * @param dstId + * @param operations + * @return + */ + private static Operation getOperationByDstId(final String dstId, + final List<Operation> operations) { + + for (Operation op : operations) { + if (op.getDestination().equals(dstId)) + return op; + } + + return null; + } + +} diff --git a/de.prob.core/src/de/prob/core/command/SerializeStateCommand.java b/de.prob.core/src/de/prob/core/command/SerializeStateCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..7d28161cc2bdbf046f6c74929fabc694c0cb9472 --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/SerializeStateCommand.java @@ -0,0 +1,43 @@ +package de.prob.core.command; + +import de.prob.core.Animator; +import de.prob.exceptions.ProBException; +import de.prob.parser.ISimplifiedROMap; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.PrologTerm; + +public class SerializeStateCommand implements IComposableCommand { + + private final String id; + private String state; + + public SerializeStateCommand(String id) { + this.id = id; + } + + public static String serialize(Animator a, String stateID) throws ProBException { + SerializeStateCommand c = new SerializeStateCommand(stateID); + a.execute(c); + return c.state; + } + + @Override + public void processResult(ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + state = PrologTerm.atomicString(bindings.get("State")); + } + + @Override + public void writeCommand(IPrologTermOutput pto) { + pto.openTerm("serialize").printAtomOrNumber(id).printVariable("State").closeTerm(); + } + + public String getId() { + return id; + } + + public String getState() { + return state; + } + +} diff --git a/de.prob.core/src/de/prob/core/command/SetPreferenceCommand.java b/de.prob.core/src/de/prob/core/command/SetPreferenceCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..fa5103f927f2ab0385ff5fc14da09b5b66c001f9 --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/SetPreferenceCommand.java @@ -0,0 +1,41 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.command; + +import de.prob.core.Animator; +import de.prob.exceptions.ProBException; +import de.prob.parser.ISimplifiedROMap; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.PrologTerm; + +public final class SetPreferenceCommand implements IComposableCommand { + + private final String key; + private final String value; + + public SetPreferenceCommand(final String key, final String value) { + this.key = key; + this.value = value; + } + + public static void setPreference(final Animator a, final String key, + final String value) throws ProBException { + SetPreferenceCommand command = new SetPreferenceCommand(key, value); + a.execute(command); + } + + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + // no result + } + + public void writeCommand(final IPrologTermOutput pto) { + pto.openTerm("set_eclipse_preference").printAtom(key).printAtom(value) + .closeTerm(); + } +} diff --git a/de.prob.core/src/de/prob/core/command/SetPreferencesCommand.java b/de.prob.core/src/de/prob/core/command/SetPreferencesCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..7ff9ee72ce72efada8127ea8fffee23b6f8a7d60 --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/SetPreferencesCommand.java @@ -0,0 +1,97 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.command; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; + +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.osgi.service.prefs.BackingStoreException; +import org.osgi.service.prefs.Preferences; + +import de.prob.core.Animator; +import de.prob.exceptions.ProBException; +import de.prob.logging.Logger; +import de.prob.parser.ISimplifiedROMap; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.PrologTerm; + +public final class SetPreferencesCommand implements IComposableCommand { + + private static final String PROB_ANIMATION_PREFERENCES = "prob_animation_preferences"; + private static final Collection<String> INVALID_PROPERTIES = Collections + .unmodifiableCollection(new HashSet<String>(Arrays.asList("title", + "project", "machine"))); + + private final Preferences preferences; + private final IComposableCommand cmds; + + public static Preferences getPreferences() { + return Platform.getPreferencesService().getRootNode() + .node(InstanceScope.SCOPE).node(PROB_ANIMATION_PREFERENCES); + } + + public SetPreferencesCommand() { + this(getPreferences()); + } + + public SetPreferencesCommand(final Preferences customConfiguration) { + preferences = customConfiguration; + String[] names; + try { + names = preferences.keys(); + } catch (BackingStoreException e) { + names = new String[0]; + Logger.notifyUser("Error while storing ProB Preferences", e); + } + final List<IComposableCommand> commands = new ArrayList<IComposableCommand>( + names.length); + for (String k : names) { + if (validCommand(k)) { + String value = preferences.get(k, null); + commands.add(new SetPreferenceCommand(k, value)); + } + } + this.cmds = new ComposedCommand( + commands.toArray(IComposableCommand.EMPTY_ARRAY)); + } + + public static void setPreferences(final Animator a) throws ProBException { + final SetPreferencesCommand c = createSetPreferencesCommand(a); + a.execute(c); + } + + public static SetPreferencesCommand createSetPreferencesCommand( + final Animator a) { + SetPreferencesCommand c; + if (a.getCustomConfiguration() != null) { + c = new SetPreferencesCommand(a.getCustomConfiguration()); + } else { + c = new SetPreferencesCommand(); + } + return c; + } + + private boolean validCommand(final String key) { + return !INVALID_PROPERTIES.contains(key); + } + + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + cmds.processResult(bindings); + } + + public void writeCommand(final IPrologTermOutput pto) throws CommandException { + cmds.writeCommand(pto); + } +} diff --git a/de.prob.core/src/de/prob/core/command/SetPrologRandomSeed.java b/de.prob.core/src/de/prob/core/command/SetPrologRandomSeed.java new file mode 100644 index 0000000000000000000000000000000000000000..3bed4b7297345f0944ada0f505b592c4396e95cf --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/SetPrologRandomSeed.java @@ -0,0 +1,44 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.command; + +import de.prob.core.Animator; +import de.prob.core.domainobjects.RandomSeed; +import de.prob.exceptions.ProBException; +import de.prob.parser.ISimplifiedROMap; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.PrologTerm; + +public final class SetPrologRandomSeed implements IComposableCommand { + + private final RandomSeed seed; + + public SetPrologRandomSeed(final RandomSeed seed) { + this.seed = seed; + } + + public static void setSeed(final Animator a, final RandomSeed seed) + throws ProBException { + SetPrologRandomSeed cmd = new SetPrologRandomSeed(seed); + a.execute(cmd); + } + + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + // no result, nothing to do + } + + public void writeCommand(final IPrologTermOutput pto) { + pto.openTerm("set_rand"); + pto.printNumber(seed.getSeedX()); + pto.printNumber(seed.getSeedY()); + pto.printNumber(seed.getSeedZ()); + pto.printNumber(seed.getSeedB()); + pto.closeTerm(); + } +} diff --git a/de.prob.core/src/de/prob/core/command/SetStateCommand.java b/de.prob.core/src/de/prob/core/command/SetStateCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..0f4bb4115ffa2761bc54d26a54d10a7d04cc95e9 --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/SetStateCommand.java @@ -0,0 +1,38 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.command; + +import de.prob.core.Animator; +import de.prob.exceptions.ProBException; +import de.prob.parser.ISimplifiedROMap; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.PrologTerm; + +public final class SetStateCommand implements IComposableCommand { + private final String stateId; + + public SetStateCommand(final String stateID) { + stateId = stateID; + } + + public static void setState(final Animator a, final String stateId) + throws ProBException { + final SetStateCommand command = new SetStateCommand(stateId); + a.execute(command); + } + + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + // no results, do nothing + } + + public void writeCommand(final IPrologTermOutput pto) { + pto.openTerm("setCurrentState").printAtomOrNumber(stateId).closeTerm(); + } + +} diff --git a/de.prob.core/src/de/prob/core/command/SetTraceCommand.java b/de.prob.core/src/de/prob/core/command/SetTraceCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..627a5f2e0383367c048fdb33fdcaa45847e504c0 --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/SetTraceCommand.java @@ -0,0 +1,97 @@ +/** + * + */ +package de.prob.core.command; + +import java.util.ArrayList; +import java.util.Collection; + +import de.prob.core.Animator; +import de.prob.core.domainobjects.History; +import de.prob.core.domainobjects.Operation; +import de.prob.core.domainobjects.State; +import de.prob.parser.ISimplifiedROMap; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.PrologTerm; + +/** + * @author plagge + * + */ +public class SetTraceCommand implements IComposableCommand { + + private final Collection<Operation> operations; + private final ExploreStateCommand[] exploreStateCmds; + private final ComposedCommand compExplore; + + private boolean hasBeenProcessed = false; + + public SetTraceCommand(final Collection<Operation> operations) { + super(); + this.operations = new ArrayList<Operation>(operations); + this.exploreStateCmds = toExplore(operations); + compExplore = new ComposedCommand(exploreStateCmds); + } + + private static ExploreStateCommand[] toExplore( + Collection<Operation> operations) { + final int size = operations.size(); + ExploreStateCommand[] states = new ExploreStateCommand[size + 1]; + if (operations.isEmpty()) { + states[0] = new ExploreStateCommand("root"); + } else { + final String initial = operations.iterator().next().getSource(); + states[0] = new ExploreStateCommand(initial); + int i = 1; + for (final Operation op : operations) { + final String dest = op.getDestination(); + states[i] = new ExploreStateCommand(dest); + i++; + } + } + return states; + } + + @Override + public void writeCommand(IPrologTermOutput pto) throws CommandException { + compExplore.writeCommand(pto); + } + + @Override + public void processResult(ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + compExplore.processResult(bindings); + hasBeenProcessed = true; + } + + public void setTraceInHistory(final Animator animator, + final Integer currentPosition) { + if (!hasBeenProcessed) { + throw new IllegalStateException( + "command must be sent to ProB before calling setTraceInHistory."); + } + final History history = animator.getHistory(); + history.reset(); + Operation curOp = null; + State curState = null; + // let's start in the root state + final State rootState = exploreStateCmds[0].getState(); + history.add(rootState, null); + if (currentPosition != null && currentPosition == 0) { + curState = rootState; + } + int pos = 1; + for (final Operation operation : operations) { + final State state = exploreStateCmds[pos].getState(); + history.add(state, operation); + if (currentPosition != null && pos == currentPosition) { + curOp = operation; + curState = state; + } + pos++; + } + if (curState != null) { + animator.announceCurrentStateChanged(curState, curOp); + } + } +} diff --git a/de.prob.core/src/de/prob/core/command/StartAnimationCommand.java b/de.prob.core/src/de/prob/core/command/StartAnimationCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..b6eb46cafc7656f0a374ca01be2e99239270be07 --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/StartAnimationCommand.java @@ -0,0 +1,26 @@ +package de.prob.core.command; + +import de.prob.core.Animator; +import de.prob.exceptions.ProBException; +import de.prob.parser.ISimplifiedROMap; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.PrologTerm; + +public class StartAnimationCommand implements IComposableCommand { + + public static void start(final Animator a) throws ProBException { + StartAnimationCommand cmd = new StartAnimationCommand(); + a.execute(cmd); + } + + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + // nothing to do + } + + public void writeCommand(final IPrologTermOutput pto) { + pto.printAtom("start_animation"); + } + +} diff --git a/de.prob.core/src/de/prob/core/command/SymmetryReductionOption.java b/de.prob.core/src/de/prob/core/command/SymmetryReductionOption.java new file mode 100644 index 0000000000000000000000000000000000000000..78c12f2b6e4a6dacf7718af76341a6baf72531c3 --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/SymmetryReductionOption.java @@ -0,0 +1,50 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.command; + +import java.util.EnumSet; +import java.util.HashMap; +import java.util.Map; + +public enum SymmetryReductionOption { + off(0, "No Symmetry Reduction"), nauty(1, "Nauty"), flood(2, + "Permutation Flooding"), hash(3, "Symmetry Marker (Hash)"); + + private final String description; + private final int pos; + + private SymmetryReductionOption(final int pos, final String description) { + this.pos = pos; + this.description = description; + } + + public final boolean isDefault() { + return this == off; + } + + public final String getDescription() { + return description; + } + + private static final Map<Integer, SymmetryReductionOption> lookup = new HashMap<Integer, SymmetryReductionOption>(); + + static { + for (SymmetryReductionOption s : EnumSet + .allOf(SymmetryReductionOption.class)) { + lookup.put(s.getPos(), s); + } + } + + public final int getPos() { + return pos; + } + + public final static SymmetryReductionOption get(final int code) { + return lookup.get(code); + } + +} diff --git a/de.prob.core/src/de/prob/core/command/internal/GetAllOperationsNamesCommand.java b/de.prob.core/src/de/prob/core/command/internal/GetAllOperationsNamesCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..145d2875ddd7fae8b816aa649a45b809ab6d9c40 --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/internal/GetAllOperationsNamesCommand.java @@ -0,0 +1,30 @@ +package de.prob.core.command.internal; + +import de.prob.core.command.CommandException; +import de.prob.core.command.IComposableCommand; +import de.prob.parser.ISimplifiedROMap; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.ListPrologTerm; +import de.prob.prolog.term.PrologTerm; + +public class GetAllOperationsNamesCommand implements IComposableCommand { + + private static final String NAMES_VARIABLE = "Names"; + private ListPrologTerm term; + + public ListPrologTerm getNamesTerm() { + return term; + } + + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + term = (ListPrologTerm) bindings.get(NAMES_VARIABLE); + } + + public void writeCommand(final IPrologTermOutput pto) { + pto.openTerm("getAllOperations").printVariable(NAMES_VARIABLE) + .closeTerm(); + } + +} diff --git a/de.prob.core/src/de/prob/core/command/internal/GetOperationParameterNames.java b/de.prob.core/src/de/prob/core/command/internal/GetOperationParameterNames.java new file mode 100644 index 0000000000000000000000000000000000000000..2abbb0773eed69dfd513827dc16d1152d1d44175 --- /dev/null +++ b/de.prob.core/src/de/prob/core/command/internal/GetOperationParameterNames.java @@ -0,0 +1,40 @@ +package de.prob.core.command.internal; + +import java.util.List; + +import de.prob.core.command.CommandException; +import de.prob.core.command.IComposableCommand; +import de.prob.parser.ISimplifiedROMap; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.ListPrologTerm; +import de.prob.prolog.term.PrologTerm; + +public class GetOperationParameterNames implements IComposableCommand { + + private static final String PARAMETER_NAMES_VARIABLE = "Names"; + private final String name; + private List<String> paramNames; + + public GetOperationParameterNames(final String name) { + this.name = name; + } + + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + paramNames = PrologTerm.atomicStrings((ListPrologTerm) bindings + .get(PARAMETER_NAMES_VARIABLE)); + } + + public void writeCommand(final IPrologTermOutput pto) { + pto.openTerm("getOperationParameterNames"); + pto.printAtom(name); + pto.printVariable(PARAMETER_NAMES_VARIABLE); + pto.closeTerm(); + } + + public List<String> getParameterNames() { + return paramNames; + } + +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/EvaluationElement.java b/de.prob.core/src/de/prob/core/domainobjects/EvaluationElement.java new file mode 100644 index 0000000000000000000000000000000000000000..82afa345cd2847d36b08b304aa6c230367ac3445 --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/EvaluationElement.java @@ -0,0 +1,116 @@ +package de.prob.core.domainobjects; + +import java.util.Collection; +import java.util.List; + +import de.prob.core.Animator; +import de.prob.core.command.EvaluationExpandCommand; +import de.prob.core.command.EvaluationGetValuesCommand; +import de.prob.eventb.translator.FormulaTranslator; +import de.prob.exceptions.ProBException; +import de.prob.prolog.term.PrologTerm; + +public class EvaluationElement { + private final PrologTerm id; + private final Animator animator; + private final EvaluationElement parent; + + private EvLazyInformation lazy; + + public EvaluationElement(final Animator animator, final PrologTerm id, + final EvaluationElement parent) { + this.id = id; + this.animator = animator; + this.parent = parent; + } + + public EvaluationElement(final Animator animator, final PrologTerm id, + final String label, final List<PrologTerm> childrenIds) { + this(animator, id, null); + EvaluationElement[] children = new EvaluationElement[childrenIds.size()]; + int i = 0; + for (final PrologTerm childId : childrenIds) { + children[i] = new EvaluationElement(animator, childId, this); + i++; + } + this.lazy = new EvLazyInformation(label, children); + } + + public PrologTerm getId() { + return id; + } + + public EvaluationElement getParent() { + return parent; + } + + public EvaluationElement[] getChildren() throws ProBException { + checkForLazyInformation(); + return lazy.children; + } + + public String getLabel() throws ProBException { + checkForLazyInformation(); + return lazy.label; + } + + public EvaluationStateElement evaluateForState(final State state) + throws ProBException { + return EvaluationGetValuesCommand.getSingleValueCached(state, this); + } + + private void checkForLazyInformation() throws ProBException { + if (lazy == null) { + final EvaluationExpandCommand cmd = new EvaluationExpandCommand(id); + animator.execute(cmd); + final Collection<PrologTerm> childIds = cmd.getChildrenIds(); + final EvaluationElement[] children = new EvaluationElement[childIds + .size()]; + int i = 0; + for (final PrologTerm childId : childIds) { + children[i] = new EvaluationElement(animator, childId, this); + i++; + } + final String label = cmd.getLabel(); + lazy = new EvLazyInformation(label, children); + } + } + + private static final class EvLazyInformation { + private final String label; + private final EvaluationElement[] children; + + public EvLazyInformation(final String label, + final EvaluationElement[] children) { + this.label = FormulaTranslator.translate(label); + this.children = children; + } + } + + @Override + public int hashCode() { + return 31 + id.hashCode(); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null || getClass() != obj.getClass()) + return false; + return id.equals(((EvaluationElement) obj).id); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("EvaluationElement[id=").append(id); + if (lazy == null) { + sb.append(",label not yet loaded]"); + } else { + sb.append(",label='").append(lazy.label).append("']"); + } + return sb.toString(); + } + +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/EvaluationStateElement.java b/de.prob.core/src/de/prob/core/domainobjects/EvaluationStateElement.java new file mode 100644 index 0000000000000000000000000000000000000000..81582797111264d9cb1f98ac2ffeff94c0177aaf --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/EvaluationStateElement.java @@ -0,0 +1,92 @@ +/** + * + */ +package de.prob.core.domainobjects; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import de.prob.core.Animator; +import de.prob.core.command.EvaluationGetValuesCommand; +import de.prob.core.command.EvaluationGetValuesCommand.EvaluationResult; +import de.prob.exceptions.ProBException; + +/** + * @author plagge + * + */ +public class EvaluationStateElement { + public final static EvaluationStateElement[] EMPTY_EVALUATION_STATE_ELEMENT_ARRAY = new EvaluationStateElement[0]; + + private final EvaluationElement element; + private final State state; + private final EvaluationResult result; + + private List<EvaluationStateElement> children; + + public EvaluationStateElement(final EvaluationElement element, + final State state, final EvaluationResult result) { + this.element = element; + this.state = state; + this.result = result; + } + + public EvaluationElement getElement() { + return element; + } + + public State getState() { + return state; + } + + public List<EvaluationStateElement> getChildren() throws ProBException { + checkChildren(); + return children; + } + + public EvaluationResult getResult() { + return result; + } + + private void checkChildren() throws ProBException { + if (children == null) { + EvaluationElement[] staticChildren = element.getChildren(); + EvaluationGetValuesCommand cmd = new EvaluationGetValuesCommand( + state.getId(), Arrays.asList(staticChildren)); + Animator.getAnimator().execute(cmd); + Map<EvaluationElement, EvaluationResult> values = cmd.getResult(); + children = new ArrayList<EvaluationStateElement>( + staticChildren.length); + for (final EvaluationElement staticChild : staticChildren) { + final EvaluationResult value = values.get(staticChild); + children.add(new EvaluationStateElement(staticChild, state, + value)); + } + children = Collections.unmodifiableList(children); + } + + } + + @Override + public int hashCode() { + return 19 * (13 + element.hashCode()) + state.hashCode(); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null || getClass() != obj.getClass()) + return false; + EvaluationStateElement other = (EvaluationStateElement) obj; + return element.equals(other.element) && state.equals(other.state); + } + + public String getText() { + return result == null ? null : result.getText(); + } + +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/History.java b/de.prob.core/src/de/prob/core/domainobjects/History.java new file mode 100644 index 0000000000000000000000000000000000000000..fffda952c890e4f4433fa9a28fc4770077e19b15 --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/History.java @@ -0,0 +1,207 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.domainobjects; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +import org.eclipse.core.runtime.Assert; + +import de.prob.core.Animator; +import de.prob.core.IComputationListener; +import de.prob.core.command.SetStateCommand; +import de.prob.exceptions.ProBException; + +public class History implements Iterable<HistoryItem>, IComputationListener { + + private static final HistoryItem[] EMPTY_ITEM_ARRAY = new HistoryItem[0]; + + private final List<HistoryItem> items = new LinkedList<HistoryItem>(); + private int currentPosition = 0; + private final Collection<HistoryListener> listeners = new ArrayList<HistoryListener>(); + + /* + * @ public invariant + * + * @ 0 <= currentPosition && + * + * @ currentPosition < items.size(); + * + * @ + */ + + public synchronized/* @ pure @ */Iterator<HistoryItem> iterator() { + return Collections.unmodifiableList(items).iterator(); + } + + public synchronized void add(final State s, final Operation o) { + if (items.isEmpty()) { + items.add(new HistoryItem(s, null)); + currentPosition = 0; + notifyAboutNewState(s, 0); + } else { + HistoryItem oldItem = items.get(currentPosition); + HistoryItem newItem = new HistoryItem(oldItem.getState(), o); + + for (int i = currentPosition + 1; i < items.size(); i++) { + notifyAboutRemoval(items.get(i).getState(), i); + } + + // Delete all following item (including the current one) + while (items.size() > currentPosition) { + items.remove(currentPosition); + } + items.add(newItem); + // Create a new last item + HistoryItem historyItem = new HistoryItem(s, null); + items.add(historyItem); + currentPosition++; + notifyAboutNewState(s, currentPosition); + } + } + + private void notifyAboutNewState(final State state, final int position) { + for (HistoryListener l : listeners) { + l.stateEntersHistory(state, position); + } + } + + private void notifyAboutRemoval(final State state, final int position) { + for (HistoryListener l : listeners) { + l.stateLeavesHistory(state, position); + } + } + + public synchronized/* @ pure @ */int size() { + return items.size(); + } + + public synchronized/* @ pure @ */boolean isEmpty() { + return items.isEmpty(); + } + + /* + * @ + * + * @ requires pos > 0 & pos < size() & !isEmpty() + * + * @ + */ + public synchronized void gotoPos(final int pos) throws ProBException { + // @StartAssert + Assert.isTrue(!isEmpty(), "History is empty"); + Assert.isTrue(0 <= pos, "Position must be greater or equal 0, was " + + pos); + Assert.isTrue(pos < size(), "Position must be less than history size"); + // @EndAssert + currentPosition = pos; + SetStateCommand.setState(Animator.getAnimator(), getCurrent() + .getStateId()); + + Animator.getAnimator().announceCurrentStateChanged( + getCurrent().getState(), Operation.NULL_OPERATION); + } + + public synchronized HistoryItem getCurrent() { + return getHistoryItem(0); + } + + /** + * Returns an item of the animator history + * + * @param pos + * the position of the item, 0 is the current state, positive + * values refer to next states, negative values refer to previous + * states + * @return the history item or <code>null</code> if there is no such element + */ + public synchronized HistoryItem getHistoryItem(int pos) { + pos = currentPosition + pos; + if (pos >= 0 && pos < items.size()) + return items.get(pos); + else + return null; + } + + /** + * Like, {@link #getHistoryItem(int)}, but the state of the history item is + * returned. + * + * @param pos + * the position of the item, 0 is the current state, positive + * values refer to next states, negative values refer to previous + * states + * @return the state or <code>null</code> if there is no such element + */ + public synchronized State getState(final int pos) { + final HistoryItem item = getHistoryItem(pos); + return item == null ? null : item.getState(); + } + + public synchronized void gotoNext() { + if (currentPosition < items.size() - 1) { + currentPosition++; + announceCurrentState(); + } + } + + /* + * @ + * + * @ requires currentPosition > 0 + * + * @ + */ + public synchronized void gotoPrevious() { + if (currentPosition > 0) { + currentPosition--; + announceCurrentState(); + } + } + + private void announceCurrentState() { + HistoryItem item = getCurrent(); + Animator.getAnimator().announceCurrentStateChanged(item.getState(), + Operation.NULL_OPERATION); + } + + public synchronized void reset() { + // notify listeners about removal of elements + // from last to first state + for (int i = items.size() - 1; i >= 0; i--) { + notifyAboutRemoval(items.get(i).getState(), i); + } + items.clear(); + currentPosition = 0; + } + + public synchronized/* @ pure @ */int getCurrentPosition() { + return currentPosition; + } + + public void computedState(final State state) { + if (isEmpty()) { + add(state, null); + } + } + + public HistoryItem[] getAllItems() { + return items.toArray(EMPTY_ITEM_ARRAY); + } + + synchronized public void addListener(final HistoryListener listener) { + listeners.add(listener); + } + + synchronized public void removeListener(final HistoryListener listener) { + listeners.remove(listener); + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/HistoryBasedCache.java b/de.prob.core/src/de/prob/core/domainobjects/HistoryBasedCache.java new file mode 100644 index 0000000000000000000000000000000000000000..7e5e4d66bd8ae2adb153617af3b5c0c1cf0742df --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/HistoryBasedCache.java @@ -0,0 +1,57 @@ +/** + * + */ +package de.prob.core.domainobjects; + +import java.util.HashMap; +import java.util.Map; + +/** + * This is a container class that stores information belonging to a certain + * state, but removes that information as soon as the state leaves the history. + * + * @author plagge + * + */ +public class HistoryBasedCache<T> implements HistoryListener { + private final Map<State, Integer> stateCounter = new HashMap<State, Integer>(); + private final Map<State, T> store = new HashMap<State, T>(); + + public HistoryBasedCache(final History history) { + HistoryItem[] items = history.getAllItems(); + for (final HistoryItem item : items) { + stateEntersHistory(item.getState(), 0); + } + } + + public void stateEntersHistory(final State state, final int position) { + final Integer counter = stateCounter.get(state); + stateCounter.put(state, counter == null ? 1 : counter + 1); + } + + public void stateLeavesHistory(final State state, final int position) { + final Integer counter = stateCounter.get(state); + if (counter != null) { + if (counter == 1) { + stateCounter.remove(state); + store.remove(state); + } else { + stateCounter.put(state, counter - 1); + } + } + } + + public void put(final State state, final T info) { + if (stateCounter.containsKey(state)) { + store.put(state, info); + } + } + + public T get(final State state) { + return store.get(state); + } + + public void clear() { + store.clear(); + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/HistoryItem.java b/de.prob.core/src/de/prob/core/domainobjects/HistoryItem.java new file mode 100644 index 0000000000000000000000000000000000000000..57ce11f704123d6dd34c12809d78fc218787db45 --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/HistoryItem.java @@ -0,0 +1,77 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.domainobjects; + +import org.eclipse.core.runtime.Assert; + +/** + * <p> + * Contains one entry in the animator history. Immutable representation of an + * history entry. When an entry has to be changed, it is replaced. This is + * happening for example when an {@link Operation} is executed in the current + * {@link State}. Then the last entry of the history is replaced. Thus don't + * rely on the identity of instances. + * </p> + * <p> + * An entry can consist of a {@link State} and an {@link Operation} if this + * {@link Operation} was executed while the {@link State} was currently active. + * </p> + * <p> + * Otherwise, if no {@link Operation} has yet been executed from this + * {@link State}, the {@link Operation} field is <code>null</code>. Be aware to + * check for <code>!= null</code> before accessing the field + * <code>operation</code>. + * </p> + * + */ + +public final class HistoryItem { + private final State state; + private final Operation operation; + + //@requires state != null; + public HistoryItem(final State state, final Operation operation) { + //@StartAssert + Assert.isNotNull(state); + //@EndAssert + + this.state = state; + this.operation = operation; + } + + @Override + public String toString() { + final StringBuilder result = new StringBuilder(); + + result.append("("); + result.append(state.getId()); + result.append(")"); + + if (operation != null) { + result.append(" -"); + result.append(operation.getName()); + result.append("-> ("); + result.append(operation.getDestination()); + result.append(")"); + } + + return result.toString(); + } + + public Operation getOperation() { + return operation; + } + + public State getState() { + return state; + } + + public String getStateId() { + return state.getId(); + } + +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/HistoryListener.java b/de.prob.core/src/de/prob/core/domainobjects/HistoryListener.java new file mode 100644 index 0000000000000000000000000000000000000000..80e0f5fc9842ff92ed4a1415db9646f69b7c7874 --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/HistoryListener.java @@ -0,0 +1,16 @@ +/** + * + */ +package de.prob.core.domainobjects; + +/** + * This listener interface is used to inform clients about states that have been + * added to the history or have left the history. + * + * @author plagge + */ +public interface HistoryListener { + void stateEntersHistory(State state, int position); + + void stateLeavesHistory(State state, int position); +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/MachineDescription.java b/de.prob.core/src/de/prob/core/domainobjects/MachineDescription.java new file mode 100644 index 0000000000000000000000000000000000000000..5582b6491453942252bb1f30904b3948857efd3d --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/MachineDescription.java @@ -0,0 +1,197 @@ +/** + * + */ +package de.prob.core.domainobjects; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import de.prob.core.command.GetMachineObjectsCommand.MachineObjectsResult; +import de.prob.core.types.TypedIdentifier; + +/** + * @author plagge + * + */ +public class MachineDescription { + public enum SectionType { + CONTEXT, MODEL + }; + + public static class Section { + private final SectionType type; + private final String name; + + public Section(SectionType type, String name) { + this.type = type; + this.name = name; + } + + public SectionType getType() { + return type; + } + + public String getName() { + return name; + } + } + + // private final TypedIdentifier[] typedIdentifiers; + private final List<Section> sections, nonEmptySections; + private final Collection<String> identifiers; + private final Map<String, List<String>> sectionIdentifiers; + private final Map<String, String> sectionOfIdentifier; + private final Map<String, Collection<String>> allSectionsOfIdentifier; + private final Map<String, TypedIdentifier> types; + + private final Collection<String> eventNames; + + public MachineDescription(MachineObjectsResult mor) { + final int clen = mor.constants.length; + final int vlen = mor.variables.length; + final TypedIdentifier[] typedIdentifiers = new TypedIdentifier[clen + + vlen]; + System.arraycopy(mor.constants, 0, typedIdentifiers, 0, clen); + System.arraycopy(mor.variables, 0, typedIdentifiers, clen, vlen); + + this.sections = Collections.unmodifiableList(Arrays + .asList(mor.sections)); + + Map<String, List<String>> secIds = new HashMap<String, List<String>>(); + ArrayList<String> ids = new ArrayList<String>(typedIdentifiers.length); + Map<String, String> secOfId = new HashMap<String, String>(); + this.allSectionsOfIdentifier = new HashMap<String, Collection<String>>(); + classifyIdentifiers(typedIdentifiers, secIds, ids, secOfId, + allSectionsOfIdentifier); + + this.identifiers = Collections.unmodifiableCollection(ids); + this.sectionIdentifiers = Collections.unmodifiableMap(secIds); + this.sectionOfIdentifier = Collections.unmodifiableMap(secOfId); + + this.eventNames = extractEvents(mor); + this.nonEmptySections = filterNonEmpty(sections, sectionIdentifiers); + this.types = createTypeMap(typedIdentifiers); + } + + private Map<String, TypedIdentifier> createTypeMap( + TypedIdentifier[] typedIdentifiers) { + Map<String, TypedIdentifier> typeMap = new HashMap<String, TypedIdentifier>(); + for (final TypedIdentifier ti : typedIdentifiers) { + typeMap.put(ti.getName(), ti); + } + return Collections.unmodifiableMap(typeMap); + } + + private static void classifyIdentifiers( + final TypedIdentifier[] typedIdentifiers, + Map<String, List<String>> secIds, ArrayList<String> ids, + Map<String, String> secOfId, + Map<String, Collection<String>> allSecsOfId) { + for (TypedIdentifier tid : typedIdentifiers) { + final String name = tid.getName(); + ids.add(name); + boolean first = true; + final Collection<String> allSections = tid.getSections(); + allSecsOfId.put(name, allSections); + for (String sec : allSections) { + if (first) { + secOfId.put(name, sec); + first = false; + } + List<String> idsOfSection = secIds.get(sec); + if (idsOfSection == null) { + idsOfSection = new ArrayList<String>(); + secIds.put(sec, idsOfSection); + } + idsOfSection.add(name); + } + } + } + + private static Collection<String> extractEvents(MachineObjectsResult mor) { + Collection<String> events = new ArrayList<String>(); + for (TypedIdentifier tevent : mor.operations) { + events.add(tevent.getName()); + } + return Collections.unmodifiableCollection(events); + } + + private static List<Section> filterNonEmpty(List<Section> sections, + Map<String, List<String>> vars) { + List<Section> nonEmpty = new ArrayList<Section>(sections); + for (Iterator<Section> it = nonEmpty.iterator(); it.hasNext();) { + Section sec = it.next(); + List<String> svars = vars.get(sec.getName()); + if (svars == null || svars.isEmpty()) { + it.remove(); + } + } + return Collections.unmodifiableList(nonEmpty); + } + + /** + * Gives the list of all sections, i.e. models or contexts. From the most + * abstract to the most concrete. The contextes come first. + * + * @return a list of sections, never <code>null</code> + */ + public List<Section> getSections() { + return sections; + } + + /** + * Like {@link #getSections()}, but this returns only sections for which + * identifier are registered. + * + * @return a list of sections, never <code>null</code> + */ + public List<Section> getNonEmptySections() { + return nonEmptySections; + } + + public Collection<String> getIdentifiers() { + return identifiers; + } + + /** + * Like {@link #getSections()}, but it returns only the names of the models. + * From the most abstract to the most concrete. + * + * @return a list of model names, never <code>null</code> + */ + public List<String> getModelNames() { + List<String> names = new ArrayList<String>(); + for (final Section section : sections) { + if (section.type == SectionType.MODEL) { + names.add(section.getName()); + } + } + return names; + } + + public List<String> getIdentifiersOfSection(String section) { + return sectionIdentifiers.get(section); + } + + public String getSectionOfIdentifier(String identifier) { + return sectionOfIdentifier.get(identifier); + } + + public Collection<String> getEventNames() { + return eventNames; + } + + public Collection<String> getAllSectionsOfIdentifier(String identifier) { + return allSectionsOfIdentifier.get(identifier); + } + + public TypedIdentifier getTypeOfIdentifier(final String name) { + return types.get(name); + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/Operation.java b/de.prob.core/src/de/prob/core/domainobjects/Operation.java new file mode 100644 index 0000000000000000000000000000000000000000..4009a8719084813755054dc6f3f5a372874d4be3 --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/Operation.java @@ -0,0 +1,325 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.domainobjects; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang.StringUtils; + +import de.prob.eventb.translator.FormulaTranslator; +import de.prob.prolog.term.CompoundPrologTerm; +import de.prob.prolog.term.IntegerPrologTerm; +import de.prob.prolog.term.ListPrologTerm; +import de.prob.prolog.term.PrologTerm; + +public final class Operation { + private static final String INTERNAL_NAME_INITIALISE_MACHINE = "$initialise_machine"; + private static final String INTERNAL_NAME_SETUP_CONSTANTS = "$setup_constants"; + + public static enum EventType { + SETUP_CONTEXT("SETUP_CONTEXT"), INITIALISATION("INITIALISATION"), NORMAL_EVENT( + null); + private final String displayName; + + private EventType(final String displayName) { + this.displayName = displayName; + } + + public String getDisplayName() { + return displayName; + } + } + + public static String getInternalName(final String displayname) { + if (displayname.equals("SETUP_CONTEXT")) { + return INTERNAL_NAME_SETUP_CONSTANTS; + } + if (displayname.equals("INITIALISATION")) { + return INTERNAL_NAME_INITIALISE_MACHINE; + } + return displayname; + } + + public static class EventStackElement { + private final String eventName; + private final List<String> parameters; + + public EventStackElement(final String eventName, + final List<String> parameters) { + this.eventName = eventName; + this.parameters = parameters; + } + + public String getEventName() { + return eventName; + } + + public List<String> getParameters() { + return parameters; + } + } + + private static final Map<String, EventType> SPECIAL_EVENTS = createSpecialEvents(); + + public static final Operation NULL_OPERATION = new Operation("no operation"); + + private final EventType eventType; + private final long id; + private final String name; + private final String dest; + private final String src; + private final List<PrologTerm> args; + private final List<String> argsPretty; + private final List<EventStackElement> eventStack; + + /* + * Positions inside the Result Term + */ + private final static int ID = 1; + private final static int NAME = 2; + private final static int SRC = 3; + private final static int DST = 4; + private final static int ARGS = 5; + private final static int ARGS_PRETTY = 6; + private final static int INFOS = 7; + + private final int hashCode; + + /** + * @param name + * @deprecated This Method is for testing only ! + */ + @Deprecated + Operation(final String name) { + EventType type = SPECIAL_EVENTS.get(name); + this.id = -1; + this.eventType = type == null ? EventType.NORMAL_EVENT : type; + this.name = type == null ? name : type.getDisplayName(); + this.dest = null; + this.src = null; + this.eventStack = null; + args = new ArrayList<PrologTerm>(0); + argsPretty = new ArrayList<String>(0); + hashCode = initHashCode(); + } + + private static Map<String, EventType> createSpecialEvents() { + Map<String, EventType> specialEvents = new HashMap<String, EventType>(); + specialEvents.put(INTERNAL_NAME_SETUP_CONSTANTS, + EventType.SETUP_CONTEXT); + specialEvents.put(INTERNAL_NAME_INITIALISE_MACHINE, + EventType.INITIALISATION); + return Collections.unmodifiableMap(specialEvents); + } + + public static Operation fromPrologTerm(final PrologTerm rawOpTerm) { + final CompoundPrologTerm opTerm = (CompoundPrologTerm) rawOpTerm; + + final IntegerPrologTerm pInt = (IntegerPrologTerm) opTerm + .getArgument(ID); + final long id = pInt.getValue().longValue(); + final String name = PrologTerm.atomicString(opTerm.getArgument(NAME)); + final EventType type = SPECIAL_EVENTS.get(name); + final String destId = getIdFromPrologTerm(opTerm.getArgument(DST)); + final String srcId = getIdFromPrologTerm(opTerm.getArgument(SRC)); + final List<PrologTerm> args = (ListPrologTerm) opTerm.getArgument(ARGS); + final List<String> pargs = create_pretty_arguments((ListPrologTerm) opTerm + .getArgument(ARGS_PRETTY)); + final List<EventStackElement> eventStack = createEventStack((ListPrologTerm) opTerm + .getArgument(INFOS)); + + return new Operation(id, type, name, destId, srcId, args, pargs, + eventStack); + } + + /** + * Creates a new Operation from a ProB answer and the Set Elements Mapping. + * + * @param term + * The term looks like: + * op(move,2,[fd(3,'Floors')],[],0,[],[],'move(Second)')<br> + * op/8 has the following arguments:<br> + * <ol> + * <li>Is of the transition</li> + * <li>Name</li> + * <li>ID of the source (internal ProB node id)</li> + * <li>ID of the destination (internal ProB node id)</li> + * <li>operation's arguments (as list)</li> + * <li>operation's arguments prettyprinted (as list)</li> + * <li>additional informations</li> + * </ol> + * + * @deprecated Use {@link #fromPrologTerm(CompoundPrologTerm)} instead + */ + @Deprecated + public Operation(final CompoundPrologTerm term) { + final String preName = PrologTerm.atomicString(term.getArgument(NAME)); + final EventType type = SPECIAL_EVENTS.get(preName); + this.eventType = type == null ? EventType.NORMAL_EVENT : type; + this.name = type == null ? preName : type.getDisplayName(); + this.dest = getIdFromPrologTerm(term.getArgument(DST)); + this.src = getIdFromPrologTerm(term.getArgument(SRC)); + this.args = (ListPrologTerm) term.getArgument(ARGS); + + this.argsPretty = create_pretty_arguments((ListPrologTerm) term + .getArgument(ARGS_PRETTY)); + this.hashCode = initHashCode(); + + final IntegerPrologTerm pInt = (IntegerPrologTerm) term.getArgument(ID); + this.id = pInt.getValue().longValue(); + this.eventStack = createEventStack((ListPrologTerm) term + .getArgument(INFOS)); + } + + private Operation(final long id, final EventType type, final String name, + final String destId, final String srcId, + final List<PrologTerm> prologArgs, final List<String> stringArgs, + final List<EventStackElement> eventStack) { + this.id = id; + this.eventType = type; + this.name = type == null ? name : type.getDisplayName(); + this.dest = destId; + this.src = srcId; + this.args = prologArgs; + this.argsPretty = stringArgs; + this.eventStack = eventStack; + + this.hashCode = initHashCode(); + } + + private static List<String> create_pretty_arguments( + final List<PrologTerm> argsPrettyTerm) { + List<String> argsPretty = new ArrayList<String>(argsPrettyTerm.size()); + for (final PrologTerm ppTerm : argsPrettyTerm) { + final String ppArg = PrologTerm.atomicString(ppTerm); + final String niceArg = FormulaTranslator.translate(ppArg); + argsPretty.add(niceArg); + } + return Collections.unmodifiableList(argsPretty); + } + + private static List<EventStackElement> createEventStack( + final ListPrologTerm list) { + for (PrologTerm term : list) { + if (term.hasFunctor("event", 1)) { + ListPrologTerm pstack = (ListPrologTerm) ((CompoundPrologTerm) term) + .getArgument(1); + final List<EventStackElement> stack = new ArrayList<EventStackElement>( + pstack.size()); + for (final PrologTerm elem : pstack) { + stack.add(extractStackElement(elem)); + } + return Collections.unmodifiableList(stack); + } + } + return null; + } + + private static EventStackElement extractStackElement(final PrologTerm elem) { + if (elem.hasFunctor("event", 2)) { + CompoundPrologTerm term = (CompoundPrologTerm) elem; + final String name = PrologTerm.atomicString(term.getArgument(1)); + List<PrologTerm> pparams = (ListPrologTerm) term.getArgument(2); + List<String> sparams; + if (pparams.isEmpty()) { + sparams = Collections.emptyList(); + } else { + sparams = new ArrayList<String>(pparams.size()); + for (PrologTerm p : pparams) { + sparams.add(PrologTerm.atomicString(p)); + } + sparams = Collections.unmodifiableList(sparams); + } + return new EventStackElement(name, sparams); + } else { + throw new IllegalArgumentException("expected event/2 but was: " + + elem); + } + } + + private static String getIdFromPrologTerm(final PrologTerm destTerm) { + if (destTerm instanceof IntegerPrologTerm) { + return ((IntegerPrologTerm) destTerm).getValue().toString(); + } + return ((CompoundPrologTerm) destTerm).getFunctor(); + } + + public long getId() { + return id; + } + + public String getName() { + return name; + } + + public String getDestination() { + return dest; + } + + public String getSource() { + return src; + } + + public List<String> getArguments() { + return argsPretty; + } + + public List<PrologTerm> getRawArguments() { + return Collections.unmodifiableList(args); + } + + public EventType getEventType() { + return eventType; + } + + public List<EventStackElement> getEventStack() { + return eventStack; + } + + @Override + public String toString() { + if (argsPretty.isEmpty()) { + return name; + } else { + return name + "(" + StringUtils.join(argsPretty, ',') + ")"; + } + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (o != NULL_OPERATION && o != null && o instanceof Operation) { + final Operation op = (Operation) o; + return id == op.id && op.src.equals(src) && op.dest.equals(dest) + && op.name.equals(name) && op.argsPretty.equals(argsPretty); + } else { + return false; + } + } + + @Override + public int hashCode() { + return hashCode; + } + + private int initHashCode() { + int result = 527 + (src == null ? 0 : src.hashCode()); + result = 31 * result + (dest == null ? 0 : dest.hashCode()); + result = 31 * result + (name == null ? 0 : name.hashCode()); + for (String arg : argsPretty) { + result = 31 * result + (arg == null ? 0 : arg.hashCode()); + } + return result * 31 + ((int) id); + } + +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/OperationInfo.java b/de.prob.core/src/de/prob/core/domainobjects/OperationInfo.java new file mode 100644 index 0000000000000000000000000000000000000000..5f6a6e8aa2f19d85e6934d43167420987f8f533c --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/OperationInfo.java @@ -0,0 +1,50 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ +package de.prob.core.domainobjects; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +public class OperationInfo { + + private final String name; + private final List<String> parameters; + + public OperationInfo(final String name, final List<String> parameters) { + this.name = name; + this.parameters = parameters; + } + + public String getName() { + return name; + } + + public List<String> getParameters() { + return Collections.unmodifiableList(parameters); + } + + public static List<String> extractNames( + final Collection<OperationInfo> names) { + List<String> result = new ArrayList<String>(); + for (OperationInfo operationInfo : names) { + result.add(operationInfo.getName()); + } + return result; + } + + public static OperationInfo getParams(final String name, + final Collection<OperationInfo> names) { + for (OperationInfo info : names) { + if (name.equals(info.getName())) { + return info; + } + } + return null; + } + +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/ProBPreference.java b/de.prob.core/src/de/prob/core/domainobjects/ProBPreference.java new file mode 100644 index 0000000000000000000000000000000000000000..8498a8832353409e091538955555aa3d44481c7d --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ProBPreference.java @@ -0,0 +1,47 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.domainobjects; + +import de.prob.prolog.term.CompoundPrologTerm; +import de.prob.prolog.term.PrologTerm; + +public final class ProBPreference { + + public final String name; + public final PrologTerm type; + public final String description; + public final String category; + public final String defaultValue; + + private final static int NAME = 1; + private final static int TYPE = 2; + private final static int DESC = 3; + private final static int CAT = 4; + private final static int DEFAULT = 5; + + public ProBPreference(final CompoundPrologTerm term) { + name = PrologTerm.atomicString(term.getArgument(NAME)); + type = term.getArgument(TYPE); + description = PrologTerm.atomicString(term.getArgument(DESC)); + category = PrologTerm.atomicString(term.getArgument(CAT)); + final PrologTerm defaultTerm = term.getArgument(DEFAULT); + defaultValue = defaultTerm.isAtom() ? PrologTerm + .atomicString(defaultTerm) : defaultTerm.toString(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(name); + sb.append("(cat. ").append(category); + sb.append(", type ").append(type.toString()); + sb.append(", default ").append(defaultValue); + sb.append(") ").append(description); + return sb.toString(); + } + +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/RandomSeed.java b/de.prob.core/src/de/prob/core/domainobjects/RandomSeed.java new file mode 100644 index 0000000000000000000000000000000000000000..bc6ebb973f7fcb8e51b44f880f3707aa910ac68a --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/RandomSeed.java @@ -0,0 +1,87 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.domainobjects; + +import java.math.BigInteger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class RandomSeed { + + private final BigInteger[] seed; + + public RandomSeed(final BigInteger x, final BigInteger y, + final BigInteger z, final BigInteger b) { + seed = new BigInteger[] { x, y, z, b }; + } + + public BigInteger getSeedX() { + return seed[0]; + } + + public BigInteger getSeedY() { + return seed[1]; + } + + public BigInteger getSeedZ() { + return seed[2]; + } + + public BigInteger getSeedB() { + return seed[3]; + } + + @Override + public String toString() { + return getSeedX() + ":" + getSeedY() + ":" + getSeedZ() + ":" + + getSeedB(); + } + + public static RandomSeed fromString(final String seed) { + Pattern p = Pattern.compile("(\\d*):(\\d*):(\\d*):(\\d*)"); + Matcher m = p.matcher(seed); + if (!m.matches()) { + throw new IllegalArgumentException("Wrong format"); + } + String[] splitSeed = seed.split(":"); + BigInteger x = new BigInteger(splitSeed[0]); + BigInteger y = new BigInteger(splitSeed[1]); + BigInteger z = new BigInteger(splitSeed[2]); + BigInteger b = new BigInteger(splitSeed[3]); + return new RandomSeed(x, y, z, b); + } + + @Override + public boolean equals(final Object obj) { + if (obj instanceof RandomSeed) { + RandomSeed seed = (RandomSeed) obj; + if (!(seed.getSeedX().equals(this.getSeedX()))) { + return false; + } + if (!(seed.getSeedY().equals(this.getSeedY()))) { + return false; + } + if (!(seed.getSeedZ().equals(this.getSeedZ()))) { + return false; + } + if (!(seed.getSeedB().equals(this.getSeedB()))) { + return false; + } + return true; + } + return false; + } + + @Override + public int hashCode() { + final int xHash = getSeedX().hashCode(); + final int yHash = getSeedY().hashCode(); + final int zHash = getSeedZ().hashCode(); + final int bHash = getSeedB().hashCode(); + return xHash + 11 * yHash + 37 * zHash + 43 * bHash; + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/State.java b/de.prob.core/src/de/prob/core/domainobjects/State.java new file mode 100644 index 0000000000000000000000000000000000000000..b623feea947b1de16e4f3ed80aba011ba04c7f21 --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/State.java @@ -0,0 +1,146 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.domainobjects; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import de.prob.logging.Logger; + +public final class State { + + private static final String ERROR_MSG = "Enabled Operations was null, this is most likely an error in the core."; + + private final String id; + private final boolean initialized; + private final boolean invariantViolated; + private final List<Operation> enabledOperations; + private final boolean timeoutOccured; + private final boolean maxOperationReached; + private final Collection<StateError> stateErrors; + private final Map<String, Variable> stateValues; + private final Set<String> timeout; + + public State(final String stateId, final boolean initialised, + final boolean invariantKo, final boolean timeoutOccured, + final boolean maxOperationReached, + final Collection<Variable> stateValues, + final List<Operation> enabledOperations, + final Collection<StateError> stateErrors, + final Set<String> timeoutedOperations) { + this.id = stateId; + this.initialized = initialised; + this.invariantViolated = invariantKo; + this.timeoutOccured = timeoutOccured; + this.maxOperationReached = maxOperationReached; + this.stateErrors = stateErrors; + this.timeout = timeoutedOperations; + + Map<String, Variable> vars = new HashMap<String, Variable>( + stateValues.size()); + for (Variable v : stateValues) { + final String identifier = v.getIdentifier(); + if (vars.containsKey(identifier)) { + Logger.notifyUser("ProB returned a variable twice."); + } else { + vars.put(identifier, v); + } + } + this.stateValues = Collections.unmodifiableMap(vars); + + Logger.assertProB(ERROR_MSG, enabledOperations != null); + + this.enabledOperations = Collections + .unmodifiableList(enabledOperations); + } + + public boolean isInitialized() { + return initialized; + } + + public boolean isInvariantViolated() { + return invariantViolated; + } + + public boolean isInvariantPreserved() { + return !invariantViolated; + } + + public boolean isMaxOperationReached() { + return maxOperationReached; + } + + public boolean isTimeoutOccured() { + return timeoutOccured; + } + + public String getId() { + return id; + } + + /** + * Returns the enabled operations of this state, but only if the operations + * of this state have already been examined. Otherwise <code>null</code> is + * returned. + * + * @return {@link List} of operations or <code>null</code> if not examined + * yet. + */ + public final List<Operation> getEnabledOperations() { + return enabledOperations; + } + + public Map<String, Variable> getValues() { + return stateValues; + } + + public boolean variableHasValue(final String variable) { + return stateValues.containsKey(variable); + } + + @Override + public String toString() { + final StringBuilder result = new StringBuilder(); + result.append(id); + if (isInvariantViolated()) { + result.append(" (Invariant violated)"); + } + result.append(": Var["); + result.append(stateValues.values()); + result.append("]"); + return result.toString(); + } + + @Override + public boolean equals(final Object obj) { + if (obj instanceof State) + return this.id.equals(((State) obj).id); + return false; + } + + @Override + public int hashCode() { + return this.id.hashCode(); + } + + public Collection<StateError> getStateBasedErrors() { + return stateErrors; + } + + public boolean hasStateBasedErrors() { + return !stateErrors.isEmpty(); + } + + public boolean isTimeoutOp(final String opName) { + return timeout.contains(opName); + } + +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/StateError.java b/de.prob.core/src/de/prob/core/domainobjects/StateError.java new file mode 100644 index 0000000000000000000000000000000000000000..da621533625318781ecb2ffca36e9df76715d620 --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/StateError.java @@ -0,0 +1,50 @@ +/** + * + */ +package de.prob.core.domainobjects; + +import de.prob.prolog.term.CompoundPrologTerm; +import de.prob.prolog.term.PrologTerm; + +/** + * An instance of this class represents a state based error. Such errors + * happened in an event starting in a state. + * + * The current implementation is very limited, in future, the error should be + * easy to examine by the user, including visualization of predicates or + * expressions. + * + * @author plagge + */ +public class StateError { + private final String event; + private final String shortDescription; + private final String longDescription; + + public StateError(final String event, final String shortDescription, + final String longDescription) { + super(); + this.event = event; + this.shortDescription = shortDescription; + this.longDescription = longDescription; + } + + public StateError(final CompoundPrologTerm term) { + this.event = PrologTerm.atomicString(term.getArgument(1)); + this.shortDescription = PrologTerm.atomicString(term.getArgument(2)); + this.longDescription = PrologTerm.atomicString(term.getArgument(3)); + } + + public String getEvent() { + return event; + } + + public String getShortDescription() { + return shortDescription; + } + + public String getLongDescription() { + return longDescription; + } + +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/Variable.java b/de.prob.core/src/de/prob/core/domainobjects/Variable.java new file mode 100644 index 0000000000000000000000000000000000000000..4d722869c6a3504ee17f2947c51de03c3b23fbe6 --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/Variable.java @@ -0,0 +1,110 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.domainobjects; + +import org.apache.commons.lang.ObjectUtils; + +import de.prob.core.command.CommandException; +import de.prob.eventb.translator.FormulaTranslator; +import de.prob.parser.BindingGenerator; +import de.prob.parser.ResultParserException; +import de.prob.prolog.term.CompoundPrologTerm; +import de.prob.prolog.term.PrologTerm; + +public final class Variable { + + private final String identifier; + private final String value; + private final PrologTerm rawValue; + + public Variable(final CompoundPrologTerm binding) throws CommandException { + + CompoundPrologTerm variableName; + try { + variableName = BindingGenerator.getCompoundTerm( + binding.getArgument(1), 0); + } catch (ResultParserException e) { + CommandException commandException = new CommandException(e.getLocalizedMessage(), e); + commandException.notifyUserOnce(); + throw commandException; + } + identifier = variableName.getFunctor(); + + final PrologTerm raw = binding.getArgument(2); + if (raw.hasFunctor("?", 0)) { + rawValue = null; + value = null; + } else { + rawValue = raw; + CompoundPrologTerm term; + try { + term = BindingGenerator.getCompoundTerm( + binding.getArgument(3), 0); + } catch (ResultParserException e) { + CommandException commandException = new CommandException(e.getLocalizedMessage(), e); + commandException.notifyUserOnce(); + throw commandException; + } + // value = ReverseTranslate.reverseTranslate(term.getFunctor()); + value = FormulaTranslator.translate( + term.getFunctor()); + } + + } + + public String getIdentifier() { + return identifier; + } + + public String getValue() { + return value; + } + + /** + * This method is for internal usage, it will be replaced when switching to + * a DOM for values + * + * @return + */ + @Deprecated + public PrologTerm getRawValue() { + return rawValue; + } + + public boolean hasValue() { + return rawValue != null; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(identifier); + sb.append(": ").append(value); + return sb.toString(); + } + + @Override + public boolean equals(final Object obj) { + final boolean equal; + if (obj == this) { + equal = true; + } else if (obj != null && obj instanceof Variable) { + Variable other = (Variable) obj; + equal = this.identifier.equals(other.identifier) + && ObjectUtils.equals(this.value, other.value); + } else { + equal = false; + } + return equal; + } + + @Override + public int hashCode() { + return super.hashCode(); + } + +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/eval/AbstractEvalElement.java b/de.prob.core/src/de/prob/core/domainobjects/eval/AbstractEvalElement.java new file mode 100644 index 0000000000000000000000000000000000000000..acf76587124350e940e193362ee62224bcf4b6fd --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/eval/AbstractEvalElement.java @@ -0,0 +1,58 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.domainobjects.eval; + +import de.be4.classicalb.core.parser.BParser; +import de.be4.classicalb.core.parser.exceptions.BException; +import de.be4.classicalb.core.parser.node.Start; +import de.prob.core.Animator; +import de.prob.core.command.EvaluateRawExpressionsCommand; +import de.prob.exceptions.ProBException; +import de.prob.logging.Logger; + +public abstract class AbstractEvalElement { + + private String value = null; + private Animator animator; + + public abstract Start getPrologAst(); + + public abstract boolean hasChildren(); + + public boolean isAtomic() { + return !hasChildren(); + }; + + public abstract String getLabel(); + + protected Start parse(final String prefix, final String code) + throws BException { + final BParser parser = new BParser(); + final Start modelAst = parser.parse(prefix + code, false); + return modelAst; + } + + public synchronized String getValue(final Animator animator, + final String stateId) { + this.animator = animator; + if (value == null) { + value = evaluate(stateId); + } + return value; + } + + private synchronized String evaluate(final String stateId) { + try { + return EvaluateRawExpressionsCommand.evaluate(animator, this, + stateId); + } catch (ProBException e) { + Logger.notifyUser( + "Something went wrong while evaluating: " + getLabel(), e); + } + return "unknown value"; + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/eval/ExpressionEvalElement.java b/de.prob.core/src/de/prob/core/domainobjects/eval/ExpressionEvalElement.java new file mode 100644 index 0000000000000000000000000000000000000000..59f50c99bafaa3d0802a28a356381597cbe350eb --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/eval/ExpressionEvalElement.java @@ -0,0 +1,68 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.domainobjects.eval; + +import java.util.LinkedList; + +import org.eventb.core.ast.Expression; + +import de.be4.classicalb.core.parser.BParser; +import de.be4.classicalb.core.parser.exceptions.BException; +import de.be4.classicalb.core.parser.node.AExpressionParseUnit; +import de.be4.classicalb.core.parser.node.EOF; +import de.be4.classicalb.core.parser.node.Start; +import de.prob.eventb.translator.ExpressionVisitor; + +public final class ExpressionEvalElement extends AbstractEvalElement { + + private final Start parse; + private final String expression; + + public static ExpressionEvalElement fromRodin(final Expression expression) + throws BException { + if (expression == null) { + String message = "Expression input must not be null"; + throw new BException("", new NullPointerException(message)); + } + ExpressionVisitor ev = new ExpressionVisitor(new LinkedList<String>()); + expression.accept(ev); + AExpressionParseUnit epu = new AExpressionParseUnit(ev.getExpression()); + Start start = new Start(epu, new EOF()); + return new ExpressionEvalElement(expression, start); + } + + public static ExpressionEvalElement create(final String expression) + throws BException { + return new ExpressionEvalElement(expression); + } + + public ExpressionEvalElement(final String expression) throws BException { + this.expression = expression; + parse = parse(BParser.EXPRESSION_PREFIX, expression); + } + + public ExpressionEvalElement(final Expression expression, final Start start) { + this.expression = expression.toString(); + this.parse = start; + } + + @Override + public Start getPrologAst() { + return parse; + } + + @Override + public boolean hasChildren() { + return false; + } + + @Override + public String getLabel() { + return expression; + } + +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/eval/PredicateEvalElement.java b/de.prob.core/src/de/prob/core/domainobjects/eval/PredicateEvalElement.java new file mode 100644 index 0000000000000000000000000000000000000000..3f18e24c0d22c9036242617ce1121d956877059e --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/eval/PredicateEvalElement.java @@ -0,0 +1,117 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.domainobjects.eval; + +import org.eventb.core.ast.Predicate; + +import de.be4.classicalb.core.parser.BParser; +import de.be4.classicalb.core.parser.analysis.DepthFirstAdapter; +import de.be4.classicalb.core.parser.exceptions.BException; +import de.be4.classicalb.core.parser.node.AConjunctPredicate; +import de.be4.classicalb.core.parser.node.ADisjunctPredicate; +import de.be4.classicalb.core.parser.node.AEquivalencePredicate; +import de.be4.classicalb.core.parser.node.AExistentialQuantificationPredicate; +import de.be4.classicalb.core.parser.node.AImplicationPredicate; +import de.be4.classicalb.core.parser.node.ANegationPredicate; +import de.be4.classicalb.core.parser.node.APredicateParseUnit; +import de.be4.classicalb.core.parser.node.AUniversalQuantificationPredicate; +import de.be4.classicalb.core.parser.node.EOF; +import de.be4.classicalb.core.parser.node.Start; +import de.prob.eventb.translator.PredicateVisitor; + +public class PredicateEvalElement extends AbstractEvalElement { + + private final Start parse; + private final String predicate; + + public static PredicateEvalElement fromRodin(final Predicate predicate) + throws BException { + if (predicate == null) { + String message = "Predicate input must not be null"; + throw new BException("", new NullPointerException(message)); + } + PredicateVisitor pv = new PredicateVisitor(); + predicate.accept(pv); + APredicateParseUnit ppu = new APredicateParseUnit(pv.getPredicate()); + Start start = new Start(ppu, new EOF()); + return new PredicateEvalElement(predicate, start); + } + + public static PredicateEvalElement create(final String predicate) + throws BException { + return new PredicateEvalElement(predicate); + } + + private PredicateEvalElement(final String predicate) throws BException { + this.predicate = predicate; + parse = parse(BParser.PREDICATE_PREFIX, predicate); + } + + private PredicateEvalElement(final Predicate p, final Start start) { + this.predicate = p.toString(); + this.parse = start; + } + + @Override + public Start getPrologAst() { + return parse; + } + + @Override + public boolean hasChildren() { + ChildScanner scanner = new ChildScanner(); + parse.apply(scanner); + return scanner.hasChildren; + } + + @Override + public String getLabel() { + return predicate; + } + + private static class ChildScanner extends DepthFirstAdapter { + public boolean hasChildren; + + @Override + public void inAConjunctPredicate(final AConjunctPredicate node) { + hasChildren = true; + } + + @Override + public void inANegationPredicate(final ANegationPredicate node) { + hasChildren = true; + } + + @Override + public void inADisjunctPredicate(final ADisjunctPredicate node) { + hasChildren = true; + } + + @Override + public void inAImplicationPredicate(final AImplicationPredicate node) { + hasChildren = true; + } + + @Override + public void inAEquivalencePredicate(final AEquivalencePredicate node) { + hasChildren = true; + } + + @Override + public void inAUniversalQuantificationPredicate( + final AUniversalQuantificationPredicate node) { + hasChildren = true; + } + + @Override + public void inAExistentialQuantificationPredicate( + final AExistentialQuantificationPredicate node) { + hasChildren = true; + } + } + +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExample.java b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExample.java new file mode 100644 index 0000000000000000000000000000000000000000..4daf14b8924a51c30e04af3fe4c7f5a440987444 --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExample.java @@ -0,0 +1,223 @@ +package de.prob.core.domainobjects.ltl; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import de.prob.core.command.LtlCheckingCommand.PathType; +import de.prob.core.command.LtlCheckingCommand.Result; +import de.prob.core.domainobjects.Operation; +import de.prob.logging.Logger; +import de.prob.prolog.term.CompoundPrologTerm; +import de.prob.prolog.term.IntegerPrologTerm; +import de.prob.prolog.term.ListPrologTerm; +import de.prob.prolog.term.PrologTerm; + +/** + * Provides a counter-example. + * + * @author Andriy Tolstoy + * + */ +public final class CounterExample { + private final static PrologTerm NONE = new CompoundPrologTerm("none"); + + private final CounterExampleProposition propositionRoot; + private final List<CounterExampleProposition> propositions = new ArrayList<CounterExampleProposition>(); + private final List<CounterExampleState> states = new ArrayList<CounterExampleState>(); + private final int loopEntry; + private List<ArrayList<Boolean>> predicateValues; + private final List<Operation> initPath; + + private final ListPrologTerm atomics; + private final ListPrologTerm example; + private final PathType pathType; + + public CounterExample(final Result modelCheckingResult) { + atomics = modelCheckingResult.getAtomics(); + example = modelCheckingResult.getCounterexample(); + loopEntry = modelCheckingResult.getLoopEntry(); + pathType = modelCheckingResult.getPathType(); + initPath = Collections.unmodifiableList(Arrays + .asList(modelCheckingResult.getInitPathOps())); + + createStates(example); + + propositionRoot = createExample(modelCheckingResult.getStructure()); + propositionRoot.setVisible(true); + Collections.reverse(propositions); + + } + + private void createStates(final ListPrologTerm example) { + final boolean isLoopType = pathType == PathType.INFINITE; + int index = 0; + for (PrologTerm exampleElement : example) { + CompoundPrologTerm state = (CompoundPrologTerm) exampleElement; + int stateId = ((IntegerPrologTerm) state.getArgument(1)).getValue() + .intValue(); + final ListPrologTerm values = ((ListPrologTerm) state + .getArgument(2)); + final CompoundPrologTerm operationTerm = (CompoundPrologTerm) state + .getArgument(3); + + if (predicateValues == null) { + predicateValues = new ArrayList<ArrayList<Boolean>>(); + + for (int i = 0; i < values.size(); i++) { + predicateValues.add(new ArrayList<Boolean>()); + } + } + + for (int i = 0; i < values.size(); i++) { + int value = ((IntegerPrologTerm) values.get(i)).getValue() + .intValue(); + predicateValues.get(i).add(value == 0 ? false : true); + } + + final boolean inLoop = isLoopType && index >= loopEntry; + final Operation operation = NONE.equals(operationTerm) ? null + : Operation.fromPrologTerm(operationTerm); + final CounterExampleState ceState = new CounterExampleState(index, + stateId, operation, inLoop); + states.add(ceState); + index++; + } + } + + private CounterExampleProposition createExample(final PrologTerm structure) { + CounterExampleProposition proposition = null; + + CompoundPrologTerm term = (CompoundPrologTerm) structure; + String functor = term.getFunctor(); + int arity = term.getArity(); + + CounterExampleValueType[] values = new CounterExampleValueType[states + .size()]; + + if (arity == 0) { + if (functor.equals("true")) { + Arrays.fill(values, CounterExampleValueType.TRUE); + } else if (functor.equals("false")) { + Arrays.fill(values, CounterExampleValueType.FALSE); + } + + proposition = new CounterExamplePredicate(functor, pathType, + loopEntry, Arrays.asList(values)); + } else if (arity == 1) { + if (functor.equals("ap") || functor.equals("tp")) { + IntegerPrologTerm atomic = (IntegerPrologTerm) term + .getArgument(1); + int atomicId = atomic.getValue().intValue(); + + CompoundPrologTerm atomicTerm = (CompoundPrologTerm) atomics + .get(atomicId); + atomicTerm = (CompoundPrologTerm) atomicTerm.getArgument(1); + String name = atomicTerm.getFunctor(); + + Logger.assertProB("CounterExample invalid", + values.length == predicateValues.get(atomicId).size()); + + for (int i = 0; i < predicateValues.get(atomicId).size(); i++) { + values[i] = predicateValues.get(atomicId).get(i) ? CounterExampleValueType.TRUE + : CounterExampleValueType.FALSE; + } + + proposition = functor.equals("ap") ? new CounterExamplePredicate( + name, pathType, loopEntry, Arrays.asList(values)) + : new CounterExampleTransition(name, pathType, + loopEntry, Arrays.asList(values)); + } else { + CounterExampleProposition argument = createExample(term + .getArgument(1)); + if (functor.equals("globally")) { + proposition = new CounterExampleGlobally(pathType, + loopEntry, argument); + } else if (functor.equals("finally")) { + proposition = new CounterExampleFinally(pathType, + loopEntry, argument); + } else if (functor.equals("next")) { + proposition = new CounterExampleNext(pathType, loopEntry, + argument); + } else if (functor.equals("not")) { + proposition = new CounterExampleNegation(pathType, loopEntry, + argument); + } else if (functor.equals("once")) { + proposition = new CounterExampleOnce(pathType, loopEntry, + argument); + } else if (functor.equals("yesterday")) { + proposition = new CounterExampleYesterday(pathType, + loopEntry, argument); + } else if (functor.equals("historically")) { + proposition = new CounterExampleHistory(pathType, + loopEntry, argument); + } + + argument.setParent(proposition); + } + } else if (arity == 2) { + CounterExampleProposition firstArgument = createExample(term + .getArgument(1)); + CounterExampleProposition secondArgument = createExample(term + .getArgument(2)); + + if (functor.equals("and")) { + proposition = new CounterExampleConjunction(pathType, loopEntry, + firstArgument, secondArgument); + } else if (functor.equals("or")) { + proposition = new CounterExampleDisjunction(pathType, loopEntry, + firstArgument, secondArgument); + } else if (functor.equals("implies")) { + proposition = new CounterExampleImplication(pathType, loopEntry, + firstArgument, secondArgument); + } else if (functor.equals("until")) { + proposition = new CounterExampleUntil(pathType, loopEntry, + firstArgument, secondArgument); + } else if (functor.equals("weakuntil")) { + proposition = new CounterExampleWeakUntil(pathType, loopEntry, + firstArgument, secondArgument); + } else if (functor.equals("release")) { + proposition = new CounterExampleRelease(pathType, loopEntry, + firstArgument, secondArgument); + } else if (functor.equals("since")) { + proposition = new CounterExampleSince(pathType, loopEntry, + firstArgument, secondArgument); + } else if (functor.equals("trigger")) { + proposition = new CounterExampleTrigger(pathType, loopEntry, + firstArgument, secondArgument); + } + + firstArgument.setParent(proposition); + secondArgument.setParent(proposition); + } + + propositions.add(proposition); + + return proposition; + } + + public CounterExampleProposition getPropositionRoot() { + return propositionRoot; + } + + public List<CounterExampleProposition> getPropositions() { + return propositions; + } + + public List<CounterExampleState> getStates() { + return states; + } + + public PathType getPathType() { + return pathType; + } + + public List<Operation> getFullPath() { + List<Operation> fullPath = new ArrayList<Operation>(initPath); + for (final CounterExampleState ceState : states) { + fullPath.add(ceState.getOperation()); + } + return fullPath; + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleBinaryOperator.java b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleBinaryOperator.java new file mode 100644 index 0000000000000000000000000000000000000000..158cf26f4cd453ad0ba3c6deb8021f9ae61b3e2f --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleBinaryOperator.java @@ -0,0 +1,100 @@ +package de.prob.core.domainobjects.ltl; + +import java.util.ArrayList; +import java.util.List; + +import de.prob.core.command.LtlCheckingCommand.PathType; +import de.prob.logging.Logger; + +/** + * Provides operators with two parameters. + * + * @author Andriy Tolstoy + * + */ +public abstract class CounterExampleBinaryOperator extends + CounterExampleProposition { + protected final CounterExampleProposition firstArgument; + protected final CounterExampleProposition secondArgument; + protected List<List<Integer>> firstHighlightedPositions = new ArrayList<List<Integer>>(); + protected List<List<Integer>> secondHighlightedPositions = new ArrayList<List<Integer>>(); + + public CounterExampleBinaryOperator(final String name, + final String fullName, final PathType pathType, + final int loopEntry, final CounterExampleProposition firstArgument, + final CounterExampleProposition secondArgument) { + super(name, fullName, pathType, loopEntry); + this.firstArgument = firstArgument; + this.secondArgument = secondArgument; + } + + protected abstract CounterExampleValueType calculate(int position); + + @Override + protected List<CounterExampleValueType> calculate() { + final List<CounterExampleValueType> first = firstArgument.getValues(); + final List<CounterExampleValueType> second = secondArgument.getValues(); + final int size = first.size(); + + Logger.assertProB("Sizes of traces do not match", size == second.size()); + + final List<CounterExampleValueType> values = new ArrayList<CounterExampleValueType>(); + + for (int i = 0; i < size; i++) { + values.add(calculate(i)); + } + + return values; + } + + @Override + public boolean hasChildren() { + return true; + } + + @Override + public List<CounterExampleProposition> getChildren() { + List<CounterExampleProposition> children = super.getChildren(); + children.addAll(firstArgument.getChildren()); + children.addAll(secondArgument.getChildren()); + return children; + } + + public CounterExampleProposition getFirstArgument() { + return firstArgument; + } + + public CounterExampleProposition getSecondArgument() { + return secondArgument; + } + + public List<List<Integer>> getFirstHighlightedPositions() { + return firstHighlightedPositions; + } + + public List<List<Integer>> getSecondHighlightedPositions() { + return secondHighlightedPositions; + } + + @Override + public String toString() { + return new StringBuilder("(" + firstArgument + ")") + .append(" " + name + " ").append("(" + secondArgument + ")") + .toString(); + } + + protected void fillHighlightedPositions(final int position, + final int firstIndex, final int secondIndex, + final int firstCheckedSize, int secondCheckedSize, boolean isPast) { + firstHighlightedPositions.add(fillPositions(position, firstIndex, + firstCheckedSize, isPast)); + secondHighlightedPositions.add(fillPositions(position, secondIndex, + secondCheckedSize, isPast)); + } + + @Override + protected int calculatePosition(int pos) { + int size = getFirstArgument().getValues().size(); + return pos < size ? pos : pos - (size - loopEntry); + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleConjunction.java b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleConjunction.java new file mode 100644 index 0000000000000000000000000000000000000000..181c417fcc696c12702eec66945cbd420f86aa82 --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleConjunction.java @@ -0,0 +1,79 @@ +package de.prob.core.domainobjects.ltl; + +import de.prob.core.command.LtlCheckingCommand.PathType; +import de.prob.logging.Logger; + +/** + * Provides an "And" operator. + * + * @author Andriy Tolstoy + * + */ + +public final class CounterExampleConjunction extends + CounterExampleBinaryOperator { + private final CounterExampleNegation not; + + public CounterExampleConjunction(final PathType pathType, + final int loopEntry, final CounterExampleProposition firstArgument, + final CounterExampleProposition secondArgument) { + super("and", "Conjunction", pathType, loopEntry, firstArgument, + secondArgument); + + CounterExampleNegation notFirstArgument = new CounterExampleNegation( + pathType, loopEntry, firstArgument); + CounterExampleNegation notSecondArgument = new CounterExampleNegation( + pathType, loopEntry, secondArgument); + CounterExampleDisjunction or = new CounterExampleDisjunction(pathType, loopEntry, + notFirstArgument, notSecondArgument); + not = new CounterExampleNegation(pathType, loopEntry, or); + } + + public CounterExampleConjunction(final PathType pathType, + final CounterExampleProposition firstArgument, + final CounterExampleProposition secondArgument) { + this(pathType, -1, firstArgument, secondArgument); + } + + @Override + protected CounterExampleValueType calculate(final int position) { + CounterExampleValueType firstValue = getFirstArgument().getValues() + .get(position); + CounterExampleValueType secondValue = getSecondArgument().getValues() + .get(position); + + int firstCheckedSize = 1; + int secondCheckedSize = 1; + + if (firstValue == CounterExampleValueType.FALSE) { + secondCheckedSize = 0; + } else if (secondValue == CounterExampleValueType.FALSE) { + firstCheckedSize = 0; + } + + fillHighlightedPositions(position, -1, -1, firstCheckedSize, + secondCheckedSize, false); + + CounterExampleValueType value = calculateAnd(firstValue, secondValue); + + Logger.assertProB("And invalid", value == not.getValues().get(position)); + + return value; + } + + public static CounterExampleValueType calculateAnd( + final CounterExampleValueType firstValue, + final CounterExampleValueType secondValue) { + CounterExampleValueType result = CounterExampleValueType.TRUE; + + if (firstValue == CounterExampleValueType.FALSE + || secondValue == CounterExampleValueType.FALSE) { + result = CounterExampleValueType.FALSE; + } else if (firstValue == CounterExampleValueType.UNDEFINED + || secondValue == CounterExampleValueType.UNDEFINED) { + result = CounterExampleValueType.UNDEFINED; + } + + return result; + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleDisjunction.java b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleDisjunction.java new file mode 100644 index 0000000000000000000000000000000000000000..93fcf3f9bf0be3ea6de3d5451f8389f786407dc3 --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleDisjunction.java @@ -0,0 +1,64 @@ +package de.prob.core.domainobjects.ltl; + +import de.prob.core.command.LtlCheckingCommand.PathType; + +/** + * Provides an "Or" operator. + * + * @author Andriy Tolstoy + * + */ + +public final class CounterExampleDisjunction extends + CounterExampleBinaryOperator { + public CounterExampleDisjunction(final PathType pathType, + final int loopEntry, final CounterExampleProposition firstArgument, + final CounterExampleProposition secondArgument) { + super("or", "Disjunction", pathType, loopEntry, firstArgument, + secondArgument); + } + + public CounterExampleDisjunction(final PathType pathType, + final CounterExampleProposition firstArgument, + final CounterExampleProposition secondArgument) { + this(pathType, -1, firstArgument, secondArgument); + } + + @Override + protected CounterExampleValueType calculate(final int position) { + CounterExampleValueType firstValue = getFirstArgument().getValues() + .get(position); + CounterExampleValueType secondValue = getSecondArgument().getValues() + .get(position); + + int firstCheckedSize = 1; + int secondCheckedSize = 1; + + if (firstValue == CounterExampleValueType.TRUE) { + secondCheckedSize = 0; + } else if (secondValue == CounterExampleValueType.TRUE) { + firstCheckedSize = 0; + } + + fillHighlightedPositions(position, -1, -1, firstCheckedSize, + secondCheckedSize, false); + + return calculateOr(firstValue, secondValue); + } + + public static CounterExampleValueType calculateOr( + final CounterExampleValueType firstValue, + final CounterExampleValueType secondValue) { + CounterExampleValueType result = CounterExampleValueType.FALSE; + + if (firstValue == CounterExampleValueType.TRUE + || secondValue == CounterExampleValueType.TRUE) { + result = CounterExampleValueType.TRUE; + } else if (firstValue == CounterExampleValueType.UNDEFINED + || secondValue == CounterExampleValueType.UNDEFINED) { + result = CounterExampleValueType.UNDEFINED; + } + + return result; + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleFinally.java b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleFinally.java new file mode 100644 index 0000000000000000000000000000000000000000..88461cb0b44cf29f6894896f626fe8b5b7cdef62 --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleFinally.java @@ -0,0 +1,74 @@ +package de.prob.core.domainobjects.ltl; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import de.prob.core.command.LtlCheckingCommand.PathType; +import de.prob.logging.Logger; + +/** + * Provides a "Finally" operator. + * + * @author Andriy Tolstoy + * + */ + +public final class CounterExampleFinally extends CounterExampleUnaryOperator { + private final CounterExampleUntil until; + + public CounterExampleFinally(final PathType pathType, final int loopEntry, + final CounterExampleProposition argument) { + super("F", "Finally", pathType, loopEntry, argument); + + CounterExampleValueType[] firstValues = new CounterExampleValueType[argument + .getValues().size()]; + Arrays.fill(firstValues, CounterExampleValueType.TRUE); + + CounterExamplePredicate first = new CounterExamplePredicate(pathType, + loopEntry, Arrays.asList(firstValues)); + + until = new CounterExampleUntil(pathType, loopEntry, first, argument); + } + + @Override + protected CounterExampleValueType calculate(final int position) { + CounterExampleValueType value = calculateFinallyOperator(position); + + List<CounterExampleValueType> untilValues = until.getValues(); + + Logger.assertProB("Finally invalid", value == untilValues.get(position)); + + return value; + } + + private CounterExampleValueType calculateFinallyOperator(final int position) { + CounterExampleValueType result = CounterExampleValueType.UNDEFINED; + + List<CounterExampleValueType> checkedValues = new ArrayList<CounterExampleValueType>( + argument.getValues()); + + // add future values if a path is infinite + if (pathType == PathType.INFINITE && position > loopEntry) { + checkedValues.addAll(checkedValues.subList(loopEntry, position)); + } + + // remove all past values + checkedValues = checkedValues.subList(position, checkedValues.size()); + + // look for a state with a true value + int index = checkedValues.indexOf(CounterExampleValueType.TRUE); + + if (index != -1) { + result = CounterExampleValueType.TRUE; + } else { + if (pathType != PathType.REDUCED) { + result = CounterExampleValueType.FALSE; + } + } + + fillHighlightedPositions(position, index, checkedValues.size(), false); + + return result; + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleGlobally.java b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleGlobally.java new file mode 100644 index 0000000000000000000000000000000000000000..5b51ea63e3f6f1d1a6bffe3619fb989f9f28169c --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleGlobally.java @@ -0,0 +1,106 @@ +package de.prob.core.domainobjects.ltl; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import de.prob.core.command.LtlCheckingCommand.PathType; +import de.prob.logging.Logger; + +/** + * Provides a "Globally" operator. + * + * @author Andriy Tolstoy + * + */ + +public final class CounterExampleGlobally extends CounterExampleUnaryOperator { + private final CounterExampleRelease release; + private final CounterExampleNegation notFinally; + private final CounterExampleNegation notUntil; + + public CounterExampleGlobally(final PathType pathType, final int loopEntry, + final CounterExampleProposition argument) { + super("G", "Globally", pathType, loopEntry, argument); + + CounterExampleValueType[] falseValues = new CounterExampleValueType[argument + .getValues().size()]; + Arrays.fill(falseValues, CounterExampleValueType.FALSE); + + CounterExamplePredicate falsePredicate = new CounterExamplePredicate( + pathType, loopEntry, Arrays.asList(falseValues)); + + release = new CounterExampleRelease(pathType, loopEntry, + falsePredicate, argument); + + CounterExampleNegation notArgument = new CounterExampleNegation( + pathType, loopEntry, argument); + + CounterExampleFinally finallyOperator = new CounterExampleFinally( + pathType, loopEntry, notArgument); + + notFinally = new CounterExampleNegation(pathType, loopEntry, + finallyOperator); + + CounterExampleValueType[] trueValues = new CounterExampleValueType[argument + .getValues().size()]; + Arrays.fill(trueValues, CounterExampleValueType.TRUE); + + CounterExamplePredicate truePredicate = new CounterExamplePredicate( + pathType, loopEntry, Arrays.asList(trueValues)); + + CounterExampleUntil until = new CounterExampleUntil(pathType, + loopEntry, truePredicate, notArgument); + notUntil = new CounterExampleNegation(pathType, loopEntry, until); + } + + @Override + protected CounterExampleValueType calculate(final int position) { + CounterExampleValueType value = calculateGlobally(position); + + List<CounterExampleValueType> releaseValues = release.getValues(); + List<CounterExampleValueType> notFinallyValues = notFinally.getValues(); + List<CounterExampleValueType> notUntilValues = notUntil.getValues(); + + Logger.assertProB("Globally invalid", + value == releaseValues.get(position)); + + Logger.assertProB("Globally invalid", + value == notFinallyValues.get(position)); + + Logger.assertProB("Globally invalid", + value == notUntilValues.get(position)); + + return value; + } + + private CounterExampleValueType calculateGlobally(final int position) { + CounterExampleValueType result = CounterExampleValueType.UNDEFINED; + + List<CounterExampleValueType> checkedValues = new ArrayList<CounterExampleValueType>( + argument.getValues()); + + // add future values if a path is infinite + if (pathType == PathType.INFINITE && position > loopEntry) { + checkedValues.addAll(checkedValues.subList(loopEntry, position)); + } + + // remove all past values + checkedValues = checkedValues.subList(position, checkedValues.size()); + + // look for a state with a false value + int index = checkedValues.indexOf(CounterExampleValueType.FALSE); + + if (index != -1) { + result = CounterExampleValueType.FALSE; + } else { + if (pathType != PathType.REDUCED) { + result = CounterExampleValueType.TRUE; + } + } + + fillHighlightedPositions(position, index, checkedValues.size(), false); + + return result; + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleHistory.java b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleHistory.java new file mode 100644 index 0000000000000000000000000000000000000000..59c4599f8d75ea7691335d43c7d954ae92ee26ce --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleHistory.java @@ -0,0 +1,85 @@ +package de.prob.core.domainobjects.ltl; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import de.prob.core.command.LtlCheckingCommand.PathType; +import de.prob.logging.Logger; + +/** + * Provides a "History" operator. + * + * @author Andriy Tolstoy + * + */ + +public final class CounterExampleHistory extends CounterExampleUnaryOperator { + private final CounterExampleNegation notOnce; + private final CounterExampleNegation notSince; + + public CounterExampleHistory(final PathType pathType, final int loopEntry, + final CounterExampleProposition argument) { + super("H", "History", pathType, loopEntry, argument); + + CounterExampleNegation notArgument = new CounterExampleNegation(pathType, + loopEntry, argument); + + CounterExampleOnce onceOperator = new CounterExampleOnce(pathType, + loopEntry, notArgument); + + notOnce = new CounterExampleNegation(pathType, loopEntry, onceOperator); + + CounterExampleValueType[] trueValues = new CounterExampleValueType[argument + .getValues().size()]; + Arrays.fill(trueValues, CounterExampleValueType.TRUE); + + CounterExamplePredicate truePredicate = new CounterExamplePredicate( + pathType, loopEntry, Arrays.asList(trueValues)); + + CounterExampleSince since = new CounterExampleSince(pathType, + loopEntry, truePredicate, notArgument); + notSince = new CounterExampleNegation(pathType, loopEntry, since); + } + + @Override + public CounterExampleValueType calculate(final int position) { + CounterExampleValueType value = calculateHistoryOperator(position); + + List<CounterExampleValueType> notOnceValues = notOnce.getValues(); + List<CounterExampleValueType> notSinceValues = notSince.getValues(); + + Logger.assertProB("History invalid", + value == notOnceValues.get(position)); + + Logger.assertProB("History invalid", + value == notSinceValues.get(position)); + + return value; + } + + private CounterExampleValueType calculateHistoryOperator(final int position) { + CounterExampleValueType result = CounterExampleValueType.UNDEFINED; + + List<CounterExampleValueType> checkedValues = new ArrayList<CounterExampleValueType>( + argument.getValues()); + + // remove all future values + checkedValues = checkedValues.subList(0, position + 1); + + // look for a state with a false value + int index = checkedValues.lastIndexOf(CounterExampleValueType.FALSE); + + if (index != -1) { + result = CounterExampleValueType.FALSE; + } else { + if (!checkedValues.contains(CounterExampleValueType.UNDEFINED)) { + result = CounterExampleValueType.TRUE; + } + } + + fillHighlightedPositions(position, index, checkedValues.size(), true); + + return result; + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleImplication.java b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleImplication.java new file mode 100644 index 0000000000000000000000000000000000000000..af5d8cbd5971c7e897e30b59d661d9247c950ad2 --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleImplication.java @@ -0,0 +1,50 @@ +package de.prob.core.domainobjects.ltl; + +import de.prob.core.command.LtlCheckingCommand.PathType; + +/** + * Provides an "Imply" operator. + * + * @author Andriy Tolstoy + * + */ + +public final class CounterExampleImplication extends + CounterExampleBinaryOperator { + public CounterExampleImplication(final PathType pathType, + final int loopEntry, final CounterExampleProposition firstArgument, + final CounterExampleProposition secondArgument) { + super("=>", "Implication", pathType, loopEntry, firstArgument, + secondArgument); + } + + public CounterExampleImplication(final PathType pathType, + final CounterExampleProposition firstArgument, + final CounterExampleProposition secondArgument) { + this(pathType, -1, firstArgument, secondArgument); + } + + @Override + protected CounterExampleValueType calculate(final int position) { + CounterExampleValueType firstValue = getFirstArgument().getValues() + .get(position); + firstValue = CounterExampleNegation.calculateNotOperator(firstValue); + + CounterExampleValueType secondValue = getSecondArgument().getValues() + .get(position); + + int firstCheckedSize = 1; + int secondCheckedSize = 1; + + if (firstValue == CounterExampleValueType.TRUE) { + secondCheckedSize = 0; + } else if (secondValue == CounterExampleValueType.TRUE) { + firstCheckedSize = 0; + } + + fillHighlightedPositions(position, -1, -1, firstCheckedSize, + secondCheckedSize, false); + + return CounterExampleDisjunction.calculateOr(firstValue, secondValue); + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleNegation.java b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleNegation.java new file mode 100644 index 0000000000000000000000000000000000000000..8b55b0a3236539227f4bcf76cfaccaa92341c75a --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleNegation.java @@ -0,0 +1,45 @@ +package de.prob.core.domainobjects.ltl; + +import de.prob.core.command.LtlCheckingCommand.PathType; + +/** + * Provides a "Not" operator. + * + * @author Andriy Tolstoy + * + */ + +public final class CounterExampleNegation extends CounterExampleUnaryOperator { + public CounterExampleNegation(final PathType pathType, final int loopEntry, + final CounterExampleProposition argument) { + super("not", "Negation", pathType, loopEntry, argument); + } + + public CounterExampleNegation(final PathType pathType, + final CounterExampleProposition argument) { + this(pathType, -1, argument); + } + + @Override + protected CounterExampleValueType calculate(final int position) { + CounterExampleValueType value = argument.getValues().get(position); + CounterExampleValueType result = calculateNotOperator(value); + + fillHighlightedPositions(position, -1, 1, false); + + return result; + } + + public static CounterExampleValueType calculateNotOperator( + final CounterExampleValueType value) { + CounterExampleValueType result = CounterExampleValueType.UNDEFINED; + + if (value == CounterExampleValueType.TRUE) { + result = CounterExampleValueType.FALSE; + } else if (value == CounterExampleValueType.FALSE) { + result = CounterExampleValueType.TRUE; + } + + return result; + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleNext.java b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleNext.java new file mode 100644 index 0000000000000000000000000000000000000000..c77bedac23cae8999500fb2230955af0c0fa4d73 --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleNext.java @@ -0,0 +1,58 @@ +package de.prob.core.domainobjects.ltl; + +import java.util.ArrayList; +import java.util.List; + +import de.prob.core.command.LtlCheckingCommand.PathType; + +/** + * Provides a "Next" operator. + * + * @author Andriy Tolstoy + * + */ + +public final class CounterExampleNext extends CounterExampleUnaryOperator { + public CounterExampleNext(final PathType pathType, final int loopEntry, + final CounterExampleProposition argument) { + super("X", "Next", pathType, loopEntry, argument); + } + + @Override + public CounterExampleValueType calculate(final int position) { + return calculateNextOperator(position); + } + + private CounterExampleValueType calculateNextOperator(int position) { + CounterExampleValueType result = CounterExampleValueType.UNDEFINED; + + List<CounterExampleValueType> checkedValues = new ArrayList<CounterExampleValueType>( + argument.getValues()); + + // add future values if a path is infinite + if (pathType == PathType.INFINITE && position > loopEntry) { + checkedValues.addAll(checkedValues.subList(loopEntry, position)); + } + + // remove all past values + checkedValues = checkedValues.subList(position, checkedValues.size()); + + int index = -1; + + if (checkedValues.size() > 1) { + index = 1; + result = checkedValues.get(index); + } else { + if (pathType == PathType.FINITE) { + result = CounterExampleValueType.FALSE; + } else if (pathType == PathType.INFINITE) { + index = 0; + result = checkedValues.get(0); + } + } + + fillHighlightedPositions(position, index, -1, false); + + return result; + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleOnce.java b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleOnce.java new file mode 100644 index 0000000000000000000000000000000000000000..d02bad0a7e8c674ccd7b56632c833af08db8af9d --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleOnce.java @@ -0,0 +1,74 @@ +package de.prob.core.domainobjects.ltl; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import de.prob.core.command.LtlCheckingCommand.PathType; +import de.prob.logging.Logger; + +/** + * Provides an "Once" operator. + * + * @author Andriy Tolstoy + * + */ + +public final class CounterExampleOnce extends CounterExampleUnaryOperator { + private final CounterExampleSince since; + + public CounterExampleOnce(final PathType pathType, final int loopEntry, + final CounterExampleProposition argument) { + super("O", "Once", pathType, loopEntry, argument); + + CounterExampleValueType[] firstValues = new CounterExampleValueType[argument + .getValues().size()]; + Arrays.fill(firstValues, CounterExampleValueType.TRUE); + + CounterExamplePredicate first = new CounterExamplePredicate(pathType, + loopEntry, Arrays.asList(firstValues)); + + since = new CounterExampleSince(pathType, loopEntry, first, argument); + } + + public CounterExampleOnce(final PathType pathType, + final CounterExampleProposition argument) { + this(pathType, -1, argument); + } + + @Override + public CounterExampleValueType calculate(final int position) { + CounterExampleValueType value = calculateOnceOperator(position); + + List<CounterExampleValueType> sinceValues = since.getValues(); + + Logger.assertProB("Once invalid", value == sinceValues.get(position)); + + return value; + } + + private CounterExampleValueType calculateOnceOperator(final int position) { + CounterExampleValueType result = CounterExampleValueType.UNDEFINED; + + List<CounterExampleValueType> checkedValues = new ArrayList<CounterExampleValueType>( + argument.getValues()); + + // remove all future values + checkedValues = checkedValues.subList(0, position + 1); + + // look for a state with a true value + int index = checkedValues.lastIndexOf(CounterExampleValueType.TRUE); + + if (index != -1) { + result = CounterExampleValueType.TRUE; + } else { + if (!checkedValues.contains(CounterExampleValueType.UNDEFINED)) { + result = CounterExampleValueType.FALSE; + } + } + + fillHighlightedPositions(position, index, checkedValues.size(), true); + + return result; + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExamplePredicate.java b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExamplePredicate.java new file mode 100644 index 0000000000000000000000000000000000000000..6e4d8857c5af55661ff578f60cd099aa1346a31f --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExamplePredicate.java @@ -0,0 +1,57 @@ +package de.prob.core.domainobjects.ltl; + +import java.util.List; + +import de.prob.core.command.LtlCheckingCommand.PathType; + +/** + * Provides predicates. + * + * @author Andriy Tolstoy + * + */ +public class CounterExamplePredicate extends CounterExampleProposition { + private final List<CounterExampleValueType> values; + + public CounterExamplePredicate(final String name, final PathType pathType, + final int loopEntry, final List<CounterExampleValueType> values) { + super(name, name, pathType, loopEntry); + this.values = values; + } + + public CounterExamplePredicate(final String name, final PathType pathType, + final List<CounterExampleValueType> values) { + this(name, pathType, -1, values); + } + + public CounterExamplePredicate(final PathType pathType, + final int loopEntry, final List<CounterExampleValueType> values) { + this("", pathType, loopEntry, values); + } + + public CounterExamplePredicate(final PathType pathType, + final List<CounterExampleValueType> values) { + this("", pathType, values); + } + + @Override + public List<CounterExampleValueType> calculate() { + return values; + } + + @Override + public boolean hasChildren() { + return false; + } + + @Override + public String toString() { + return name; + } + + @Override + protected int calculatePosition(int pos) { + int size = values.size(); + return pos < size ? pos : pos - (size - loopEntry); + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleProposition.java b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleProposition.java new file mode 100644 index 0000000000000000000000000000000000000000..9770ccf59d7076b5ff8903dbaaa5de018b533e98 --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleProposition.java @@ -0,0 +1,126 @@ +package de.prob.core.domainobjects.ltl; + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.util.ArrayList; +import java.util.List; + +import de.prob.core.command.LtlCheckingCommand.PathType; + +/** + * Provides an abstract class for all types of propositions. + * + * @author Andriy Tolstoy + * + */ +public abstract class CounterExampleProposition { + protected final String name; + protected final String fullName; + protected final int loopEntry; + protected final PathType pathType; + protected CounterExampleProposition parent; + private List<CounterExampleValueType> values; + protected final PropertyChangeSupport listeners = new PropertyChangeSupport( + this); + private boolean visible = false; + protected int stateId = 0; + + public CounterExampleProposition(final String name, final String fullName, + final PathType pathType, final int loopEntry) { + this.name = name; + this.fullName = fullName; + this.loopEntry = loopEntry; + this.pathType = pathType; + } + + abstract protected List<CounterExampleValueType> calculate(); + + public CounterExampleProposition getParent() { + return parent; + } + + public void setParent(final CounterExampleProposition parent) { + this.parent = parent; + } + + public String getFullName() { + return fullName; + } + + public List<CounterExampleValueType> getValues() { + if (values == null) { + values = calculate(); + } + + return values; + } + + public List<CounterExampleProposition> getChildren() { + List<CounterExampleProposition> children = new ArrayList<CounterExampleProposition>(); + children.add(this); + return children; + } + + public abstract boolean hasChildren(); + + public PathType getPathType() { + return pathType; + } + + public int getLoopEntry() { + return loopEntry; + } + + public boolean isVisible() { + return visible; + } + + public void setVisible(boolean visible) { + boolean oldVisible = this.visible; + this.visible = visible; + listeners.firePropertyChange("visible", oldVisible, visible); + } + + public int getStateId() { + return stateId; + } + + public void setStateId(int stateId) { + int oldStateId = this.stateId; + this.stateId = stateId; + listeners.firePropertyChange("stateId", oldStateId, stateId); + } + + public void addPropertyChangeListener(PropertyChangeListener listener) { + listeners.addPropertyChangeListener(listener); + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + listeners.removePropertyChangeListener(listener); + } + + public List<Integer> fillPositions(int position, int index, + int checkedSize, boolean isPastOperator) { + List<Integer> positions = new ArrayList<Integer>(); + + if (index != -1) { + int pos = isPastOperator ? index : index + position; + pos = calculatePosition(pos); + positions.add(pos); + } else { + for (int i = 0; i < checkedSize; i++) { + int pos = isPastOperator ? position - i : position + i; + pos = calculatePosition(pos); + positions.add(pos); + } + } + + return positions; + } + + protected abstract int calculatePosition(int pos); + + public boolean isTransition() { + return false; + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleRelease.java b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleRelease.java new file mode 100644 index 0000000000000000000000000000000000000000..410906cea2869c279ae3e659dd4907ab9f810ad5 --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleRelease.java @@ -0,0 +1,164 @@ +package de.prob.core.domainobjects.ltl; + +import java.util.ArrayList; +import java.util.List; + +import de.prob.core.command.LtlCheckingCommand.PathType; +import de.prob.logging.Logger; + +/** + * Provides a "Release" operator. + * + * @author Andriy Tolstoy + * + */ + +public final class CounterExampleRelease extends CounterExampleBinaryOperator { + private final CounterExampleNegation notUntil; + + public CounterExampleRelease(final PathType pathType, final int loopEntry, + final CounterExampleProposition firstArgument, + final CounterExampleProposition secondArgument) { + super("R", "Release", pathType, loopEntry, firstArgument, + secondArgument); + CounterExampleNegation notFirst = new CounterExampleNegation(pathType, + loopEntry, firstArgument); + CounterExampleNegation notSecond = new CounterExampleNegation(pathType, + loopEntry, secondArgument); + CounterExampleUntil until = new CounterExampleUntil(pathType, + loopEntry, notFirst, notSecond); + notUntil = new CounterExampleNegation(pathType, loopEntry, until); + } + + public CounterExampleRelease(final PathType pathType, + final CounterExampleProposition firstArgument, + final CounterExampleProposition secondArgument) { + this(pathType, -1, firstArgument, secondArgument); + } + + @Override + protected CounterExampleValueType calculate(final int position) { + CounterExampleValueType value = calculateReleaseOperator(position); + + List<CounterExampleValueType> notUntilValues = notUntil.getValues(); + + Logger.assertProB("Release invalid", + value == notUntilValues.get(position)); + + return value; + } + + private CounterExampleValueType calculateReleaseOperator(final int position) { + CounterExampleValueType result = CounterExampleValueType.UNDEFINED; + + List<CounterExampleValueType> firstCheckedValues = new ArrayList<CounterExampleValueType>( + getFirstArgument().getValues()); + List<CounterExampleValueType> secondCheckedValues = new ArrayList<CounterExampleValueType>( + getSecondArgument().getValues()); + + // add future values if a path is infinite + if (pathType == PathType.INFINITE && position > loopEntry) { + firstCheckedValues.addAll(firstCheckedValues.subList(loopEntry, + position)); + secondCheckedValues.addAll(secondCheckedValues.subList(loopEntry, + position)); + } + + // remove all past values + firstCheckedValues = firstCheckedValues.subList(position, + firstCheckedValues.size()); + secondCheckedValues = secondCheckedValues.subList(position, + secondCheckedValues.size()); + + int secondIndex = -1; + + boolean trueOrUnknown = false; + + // look for a state with a true value in first argument + int firstIndex = firstCheckedValues + .indexOf(CounterExampleValueType.TRUE); + + if (firstIndex != -1) { + // look for a state with a false value in second argument + secondCheckedValues = secondCheckedValues + .subList(0, firstIndex + 1); + secondIndex = secondCheckedValues + .indexOf(CounterExampleValueType.FALSE); + + if (secondIndex == -1) { + trueOrUnknown = true; + + if (pathType != PathType.REDUCED) { + result = CounterExampleValueType.TRUE; + } else { + // look for the state with an unknown value in second + // argument + if (secondCheckedValues + .contains(CounterExampleValueType.UNDEFINED)) { + firstCheckedValues = firstCheckedValues.subList(0, + firstIndex + 1); + firstIndex = -1; + } else { + result = CounterExampleValueType.TRUE; + } + } + } + } else { + // look for a state with a false value in second argument + if (!secondCheckedValues.contains(CounterExampleValueType.FALSE)) { + if (pathType != PathType.REDUCED) { + trueOrUnknown = true; + result = CounterExampleValueType.TRUE; + } + } + } + + if (!trueOrUnknown) { + // look for a state with a false value in second argument + secondIndex = secondCheckedValues + .indexOf(CounterExampleValueType.FALSE); + + if (secondIndex != -1) { + firstCheckedValues = firstCheckedValues.subList(0, secondIndex); + firstIndex = -1; + + if (pathType != PathType.REDUCED) { + result = CounterExampleValueType.FALSE; + } else { + // look for a state with an unknown value in first argument + if (firstCheckedValues + .contains(CounterExampleValueType.UNDEFINED)) { + secondCheckedValues = secondCheckedValues.subList(0, + secondIndex + 1); + secondIndex = -1; + } else { + result = CounterExampleValueType.FALSE; + } + } + } else { + if (pathType != PathType.REDUCED) { + result = CounterExampleValueType.FALSE; + } else { + for (int i = 0; i < firstCheckedValues.size(); i++) { + if (firstCheckedValues.get(i).equals( + CounterExampleValueType.UNDEFINED) + && secondCheckedValues.get(i).equals( + CounterExampleValueType.UNDEFINED)) { + firstCheckedValues = firstCheckedValues.subList(0, + i + 1); + secondCheckedValues = secondCheckedValues.subList( + 0, i + 1); + + break; + } + } + } + } + } + + fillHighlightedPositions(position, firstIndex, secondIndex, + firstCheckedValues.size(), secondCheckedValues.size(), false); + + return result; + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleSince.java b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleSince.java new file mode 100644 index 0000000000000000000000000000000000000000..5130959ad342d816e07be967d094a13ce39e9183 --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleSince.java @@ -0,0 +1,134 @@ +package de.prob.core.domainobjects.ltl; + +import java.util.List; + +import de.prob.core.command.LtlCheckingCommand.PathType; + +/** + * Provides a "Since" operator. + * + * @author Andriy Tolstoy + * + */ + +public final class CounterExampleSince extends CounterExampleBinaryOperator { + public CounterExampleSince(final PathType pathType, final int loopEntry, + final CounterExampleProposition firstArgument, + final CounterExampleProposition secondArgument) { + super("S", "Since", pathType, loopEntry, firstArgument, secondArgument); + } + + public CounterExampleSince(final PathType pathType, + final CounterExampleProposition firstArgument, + final CounterExampleProposition secondArgument) { + this(pathType, -1, firstArgument, secondArgument); + } + + @Override + protected CounterExampleValueType calculate(final int position) { + CounterExampleValueType result = calculateSinceOperator(position); + return result; + } + + private CounterExampleValueType calculateSinceOperator(final int position) { + CounterExampleValueType result = CounterExampleValueType.UNDEFINED; + + // remove all future values + List<CounterExampleValueType> firstCheckedValues = getFirstArgument() + .getValues().subList(0, position + 1); + List<CounterExampleValueType> secondCheckedValues = getSecondArgument() + .getValues().subList(0, position + 1); + + int firstIndex = -1; + + boolean trueOrUnknown = false; + + // look for a state with a true value in second argument + int secondIndex = secondCheckedValues + .lastIndexOf(CounterExampleValueType.TRUE); + + if (secondIndex != -1) { + // look for a state with a false value in first argument + firstCheckedValues = firstCheckedValues.subList(secondIndex + 1, + position + 1); + firstIndex = firstCheckedValues + .lastIndexOf(CounterExampleValueType.FALSE); + + if (firstIndex == -1) { + trueOrUnknown = true; + + if (pathType != PathType.REDUCED) { + result = CounterExampleValueType.TRUE; + } else { + // look for the state with an unknown value in first + // argument + if (firstCheckedValues + .contains(CounterExampleValueType.UNDEFINED)) { + secondCheckedValues = secondCheckedValues.subList( + secondIndex, position + 1); + secondIndex = -1; + } else { + result = CounterExampleValueType.TRUE; + } + } + } + } + + if (!trueOrUnknown) { + firstCheckedValues = getFirstArgument().getValues().subList(0, + position + 1); + secondCheckedValues = getSecondArgument().getValues().subList(0, + position + 1); + + // look for a state with a false value in first argument + firstIndex = firstCheckedValues + .lastIndexOf(CounterExampleValueType.FALSE); + + if (firstIndex != -1) { + secondCheckedValues = secondCheckedValues.subList(firstIndex, + position + 1); + secondIndex = -1; + + if (pathType != PathType.REDUCED) { + result = CounterExampleValueType.FALSE; + } else { + // look for a state with an unknown value in second argument + if (secondCheckedValues + .contains(CounterExampleValueType.UNDEFINED)) { + firstCheckedValues = firstCheckedValues.subList( + firstIndex, position + 1); + firstIndex = -1; + } else { + result = CounterExampleValueType.FALSE; + } + } + } else { + if (!firstCheckedValues + .contains(CounterExampleValueType.UNDEFINED) + && !secondCheckedValues + .contains(CounterExampleValueType.UNDEFINED)) { + result = CounterExampleValueType.FALSE; + } else { + for (int i = firstCheckedValues.size() - 1; i >= 0; i--) { + if (firstCheckedValues.get(i).equals( + CounterExampleValueType.UNDEFINED) + && secondCheckedValues.get(i).equals( + CounterExampleValueType.UNDEFINED)) { + firstCheckedValues = firstCheckedValues.subList(i, + position + 1); + secondCheckedValues = secondCheckedValues.subList( + i, position + 1); + + break; + } + } + } + } + } + + fillHighlightedPositions(position, firstIndex, secondIndex, + firstCheckedValues.size(), secondCheckedValues.size(), true); + + return result; + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleState.java b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleState.java new file mode 100644 index 0000000000000000000000000000000000000000..df2425fe212808b493fd6e7417bffcd3afe9e7bc --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleState.java @@ -0,0 +1,45 @@ +package de.prob.core.domainobjects.ltl; + +import de.prob.core.domainobjects.Operation; + +/** + * Provides a state of a counter-example. + * + * @author Andriy Tolstoy + * + */ +public final class CounterExampleState { + private final int index; + private final int stateId; + private final Operation operation; + private final boolean inLoop; + + public CounterExampleState(final int index, final int stateId, + final Operation operation, final boolean inLoop) { + this.index = index; + this.stateId = stateId; + this.operation = operation; + this.inLoop = inLoop; + } + + public CounterExampleState(final int index, final int stateId, + final boolean inLoop) { + this(index, stateId, null, inLoop); + } + + public int getState() { + return stateId; + } + + public Operation getOperation() { + return operation; + } + + public int getIndex() { + return index; + } + + public boolean isInLoop() { + return inLoop; + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleTransition.java b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleTransition.java new file mode 100644 index 0000000000000000000000000000000000000000..c90ed98c13e7d6f5449e72e7935bc0d4832c23bf --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleTransition.java @@ -0,0 +1,32 @@ +package de.prob.core.domainobjects.ltl; + +import java.util.List; + +import de.prob.core.command.LtlCheckingCommand.PathType; + +public class CounterExampleTransition extends CounterExamplePredicate { + public CounterExampleTransition(final String name, final PathType pathType, + final int loopEntry, final List<CounterExampleValueType> values) { + super(name, pathType, loopEntry, values); + } + + public CounterExampleTransition(final String name, final PathType pathType, + final List<CounterExampleValueType> values) { + this(name, pathType, -1, values); + } + + public CounterExampleTransition(final PathType pathType, + final int loopEntry, final List<CounterExampleValueType> values) { + this("", pathType, loopEntry, values); + } + + public CounterExampleTransition(final PathType pathType, + final List<CounterExampleValueType> values) { + this("", pathType, values); + } + + @Override + public boolean isTransition() { + return true; + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleTrigger.java b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleTrigger.java new file mode 100644 index 0000000000000000000000000000000000000000..868460f36c5eb0c4395ae92d3c55621a4204a4ed --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleTrigger.java @@ -0,0 +1,157 @@ +package de.prob.core.domainobjects.ltl; + +import java.util.List; + +import de.prob.core.command.LtlCheckingCommand.PathType; +import de.prob.logging.Logger; + +/** + * Provides a "Trigger" operator. + * + * @author Andriy Tolstoy + * + */ + +public final class CounterExampleTrigger extends CounterExampleBinaryOperator { + private final CounterExampleNegation notSince; + + public CounterExampleTrigger(final PathType pathType, final int loopEntry, + final CounterExampleProposition firstArgument, + final CounterExampleProposition secondArgument) { + super("T", "Trigger", pathType, loopEntry, firstArgument, + secondArgument); + CounterExampleNegation notFirst = new CounterExampleNegation(pathType, + loopEntry, firstArgument); + CounterExampleNegation notSecond = new CounterExampleNegation(pathType, + loopEntry, secondArgument); + CounterExampleSince since = new CounterExampleSince(pathType, + loopEntry, notFirst, notSecond); + notSince = new CounterExampleNegation(pathType, loopEntry, since); + } + + public CounterExampleTrigger(final PathType pathType, + final CounterExampleProposition firstArgument, + final CounterExampleProposition secondArgument) { + this(pathType, -1, firstArgument, secondArgument); + } + + @Override + protected CounterExampleValueType calculate(final int position) { + CounterExampleValueType value = calculateTriggerOperator(position); + + List<CounterExampleValueType> notSinceValues = notSince.getValues(); + + Logger.assertProB("Trigger invalid", + value == notSinceValues.get(position)); + + return value; + } + + private CounterExampleValueType calculateTriggerOperator(final int position) { + CounterExampleValueType result = CounterExampleValueType.UNDEFINED; + + // remove all future values + List<CounterExampleValueType> firstCheckedValues = getFirstArgument() + .getValues().subList(0, position + 1); + List<CounterExampleValueType> secondCheckedValues = getSecondArgument() + .getValues().subList(0, position + 1); + + int secondIndex = -1; + + boolean trueOrUnknown = false; + + // look for a state with a true value in first argument + int firstIndex = firstCheckedValues + .lastIndexOf(CounterExampleValueType.TRUE); + + if (firstIndex != -1) { + // look for a state with a false value in second argument + secondCheckedValues = secondCheckedValues.subList(firstIndex, + position + 1); + secondIndex = secondCheckedValues + .lastIndexOf(CounterExampleValueType.FALSE); + + if (secondIndex == -1) { + trueOrUnknown = true; + + if (pathType != PathType.REDUCED) { + result = CounterExampleValueType.TRUE; + } else { + // look for the state with an unknown value in second + // argument + if (secondCheckedValues + .contains(CounterExampleValueType.UNDEFINED)) { + firstCheckedValues = firstCheckedValues.subList( + firstIndex, position + 1); + firstIndex = -1; + } else { + result = CounterExampleValueType.TRUE; + } + } + } + } else { + if (!firstCheckedValues.contains(CounterExampleValueType.UNDEFINED) + && !secondCheckedValues + .contains(CounterExampleValueType.FALSE) + && !secondCheckedValues + .contains(CounterExampleValueType.UNDEFINED)) { + trueOrUnknown = true; + result = CounterExampleValueType.TRUE; + } + } + + if (!trueOrUnknown) { + firstCheckedValues = getFirstArgument().getValues().subList(0, + position + 1); + secondCheckedValues = getSecondArgument().getValues().subList(0, + position + 1); + + // look for a state with a false value in second argument + secondIndex = secondCheckedValues + .lastIndexOf(CounterExampleValueType.FALSE); + + if (secondIndex != -1) { + firstCheckedValues = firstCheckedValues.subList( + secondIndex + 1, position + 1); + firstIndex = -1; + + if (pathType != PathType.REDUCED) { + result = CounterExampleValueType.FALSE; + } else { + // look for a state with an unknown value in first argument + if (firstCheckedValues + .contains(CounterExampleValueType.UNDEFINED)) { + secondCheckedValues = secondCheckedValues.subList( + secondIndex, position + 1); + secondIndex = -1; + } else { + result = CounterExampleValueType.FALSE; + } + } + } else { + if (pathType != PathType.REDUCED) { + result = CounterExampleValueType.FALSE; + } else { + for (int i = firstCheckedValues.size() - 1; i >= 0; i--) { + if (firstCheckedValues.get(i).equals( + CounterExampleValueType.UNDEFINED) + && secondCheckedValues.get(i).equals( + CounterExampleValueType.UNDEFINED)) { + firstCheckedValues = firstCheckedValues.subList(i, + position + 1); + secondCheckedValues = secondCheckedValues.subList( + i, position + 1); + + break; + } + } + } + } + } + + fillHighlightedPositions(position, firstIndex, secondIndex, + firstCheckedValues.size(), secondCheckedValues.size(), true); + + return result; + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleUnaryOperator.java b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleUnaryOperator.java new file mode 100644 index 0000000000000000000000000000000000000000..fc43702dc5b3ecd91494b6cd1b8180950c474324 --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleUnaryOperator.java @@ -0,0 +1,79 @@ +package de.prob.core.domainobjects.ltl; + +import java.util.ArrayList; +import java.util.List; + +import de.prob.core.command.LtlCheckingCommand.PathType; + +/** + * Provides operators with one parameter. + * + * @author Andriy Tolstoy + * + */ +public abstract class CounterExampleUnaryOperator extends + CounterExampleProposition { + protected final CounterExampleProposition argument; + protected List<List<Integer>> highlightedPositions = new ArrayList<List<Integer>>(); + + public CounterExampleUnaryOperator(final String name, + final String fullName, final PathType pathType, + final int loopEntry, final CounterExampleProposition argument) { + super(name, fullName, pathType, loopEntry); + this.argument = argument; + } + + @Override + public boolean hasChildren() { + return true; + } + + @Override + public List<CounterExampleProposition> getChildren() { + List<CounterExampleProposition> children = super.getChildren(); + children.addAll(argument.getChildren()); + return children; + } + + public CounterExampleProposition getArgument() { + return argument; + } + + public List<List<Integer>> getHighlightedPositions() { + return highlightedPositions; + } + + @Override + public String toString() { + return new StringBuilder(name).append(argument).toString(); + } + + @Override + protected List<CounterExampleValueType> calculate() { + final List<CounterExampleValueType> argumentValues = argument + .getValues(); + + final int size = argumentValues.size(); + final List<CounterExampleValueType> values = new ArrayList<CounterExampleValueType>(); + + for (int i = 0; i < size; i++) { + values.add(calculate(i)); + } + + return values; + } + + protected abstract CounterExampleValueType calculate(int position); + + protected void fillHighlightedPositions(final int position, + final int index, final int checkedSize, boolean isPast) { + highlightedPositions.add(fillPositions(position, index, checkedSize, + isPast)); + } + + @Override + protected int calculatePosition(int pos) { + int size = getArgument().getValues().size(); + return pos < size ? pos : pos - (size - loopEntry); + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleUntil.java b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleUntil.java new file mode 100644 index 0000000000000000000000000000000000000000..e6c53c9040788a57ac942645bff222e61f6731f6 --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleUntil.java @@ -0,0 +1,133 @@ +package de.prob.core.domainobjects.ltl; + +import java.util.ArrayList; +import java.util.List; + +import de.prob.core.command.LtlCheckingCommand.PathType; + +/** + * Provides an "Until" operator. + * + * @author Andriy Tolstoy + * + */ + +public final class CounterExampleUntil extends CounterExampleBinaryOperator { + public CounterExampleUntil(final PathType pathType, final int loopEntry, + final CounterExampleProposition firstArgument, + final CounterExampleProposition secondArgument) { + super("U", "Until", pathType, loopEntry, firstArgument, secondArgument); + } + + @Override + protected CounterExampleValueType calculate(final int position) { + CounterExampleValueType result = calculateUntilOperator(position); + return result; + } + + private CounterExampleValueType calculateUntilOperator(final int position) { + CounterExampleValueType result = CounterExampleValueType.UNDEFINED; + + List<CounterExampleValueType> firstCheckedValues = new ArrayList<CounterExampleValueType>( + getFirstArgument().getValues()); + List<CounterExampleValueType> secondCheckedValues = new ArrayList<CounterExampleValueType>( + getSecondArgument().getValues()); + + // add future values if a path is infinite + if (pathType == PathType.INFINITE && position > loopEntry) { + firstCheckedValues.addAll(firstCheckedValues.subList(loopEntry, + position)); + secondCheckedValues.addAll(secondCheckedValues.subList(loopEntry, + position)); + } + + // remove all past values + firstCheckedValues = firstCheckedValues.subList(position, + firstCheckedValues.size()); + secondCheckedValues = secondCheckedValues.subList(position, + secondCheckedValues.size()); + + int firstIndex = -1; + + boolean trueOrUnknown = false; + + // look for a state with a true value in second argument + int secondIndex = secondCheckedValues + .indexOf(CounterExampleValueType.TRUE); + + if (secondIndex != -1) { + // look for a state with a false value in first argument + firstCheckedValues = firstCheckedValues.subList(0, secondIndex); + firstIndex = firstCheckedValues + .indexOf(CounterExampleValueType.FALSE); + + if (firstIndex == -1) { + trueOrUnknown = true; + + if (pathType != PathType.REDUCED) { + result = CounterExampleValueType.TRUE; + } else { + // look for the state with an unknown value in first + // argument + if (firstCheckedValues + .contains(CounterExampleValueType.UNDEFINED)) { + secondCheckedValues = secondCheckedValues.subList(0, + secondIndex + 1); + secondIndex = -1; + } else { + result = CounterExampleValueType.TRUE; + } + } + } + } + + if (!trueOrUnknown) { + // look for a state with a false value in first argument + firstIndex = firstCheckedValues + .indexOf(CounterExampleValueType.FALSE); + + if (firstIndex != -1) { + secondCheckedValues = secondCheckedValues.subList(0, + firstIndex + 1); + secondIndex = -1; + + if (pathType != PathType.REDUCED) { + result = CounterExampleValueType.FALSE; + } else { + // look for a state with an unknown value in second argument + if (secondCheckedValues + .contains(CounterExampleValueType.UNDEFINED)) { + firstCheckedValues = firstCheckedValues.subList(0, + firstIndex + 1); + firstIndex = -1; + } else { + result = CounterExampleValueType.FALSE; + } + } + } else { + if (pathType != PathType.REDUCED) { + result = CounterExampleValueType.FALSE; + } else { + for (int i = 0; i < firstCheckedValues.size(); i++) { + if (firstCheckedValues.get(i).equals( + CounterExampleValueType.UNDEFINED) + && secondCheckedValues.get(i).equals( + CounterExampleValueType.UNDEFINED)) { + firstCheckedValues = firstCheckedValues.subList(0, + i + 1); + secondCheckedValues = secondCheckedValues.subList( + 0, i + 1); + + break; + } + } + } + } + } + + fillHighlightedPositions(position, firstIndex, secondIndex, + firstCheckedValues.size(), secondCheckedValues.size(), false); + + return result; + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleValueType.java b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleValueType.java new file mode 100644 index 0000000000000000000000000000000000000000..9acb6b1fa72d51107985f1e05156d8f583becc18 --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleValueType.java @@ -0,0 +1,10 @@ +package de.prob.core.domainobjects.ltl; + +public enum CounterExampleValueType { + TRUE, FALSE, UNDEFINED; + + @Override + public String toString() { + return name().substring(0, 1); + } +}; diff --git a/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleWeakUntil.java b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleWeakUntil.java new file mode 100644 index 0000000000000000000000000000000000000000..8a4431a7964b79f5338f06eb64394aac63ef7e58 --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleWeakUntil.java @@ -0,0 +1,185 @@ +package de.prob.core.domainobjects.ltl; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import de.prob.core.command.LtlCheckingCommand.PathType; +import de.prob.logging.Logger; + +/** + * Provides a "Weak Until" operator. + * + * @author Andriy Tolstoy + * + */ + +public final class CounterExampleWeakUntil extends CounterExampleBinaryOperator { + private final CounterExampleRelease release; + private final CounterExampleDisjunction or1; + private final CounterExampleDisjunction or2; + + public CounterExampleWeakUntil(final PathType pathType, + final int loopEntry, final CounterExampleProposition firstArgument, + final CounterExampleProposition secondArgument) { + super("W", "Weak Until", pathType, loopEntry, firstArgument, + secondArgument); + + release = new CounterExampleRelease(pathType, loopEntry, + secondArgument, new CounterExampleDisjunction(pathType, + loopEntry, secondArgument, firstArgument)); + + CounterExampleNegation not = new CounterExampleNegation(pathType, + loopEntry, firstArgument); + + CounterExampleValueType[] trueValues = new CounterExampleValueType[firstArgument + .getValues().size()]; + Arrays.fill(trueValues, CounterExampleValueType.TRUE); + + CounterExamplePredicate truePredicate = new CounterExamplePredicate( + pathType, loopEntry, Arrays.asList(trueValues)); + + CounterExampleNegation notUntil = new CounterExampleNegation(pathType, + loopEntry, new CounterExampleUntil(pathType, loopEntry, + truePredicate, not)); + + CounterExampleUntil until = new CounterExampleUntil(pathType, + loopEntry, firstArgument, secondArgument); + + or1 = new CounterExampleDisjunction(pathType, loopEntry, notUntil, + until); + or2 = new CounterExampleDisjunction(pathType, loopEntry, until, + new CounterExampleGlobally(pathType, loopEntry, firstArgument)); + } + + @Override + protected CounterExampleValueType calculate(final int position) { + CounterExampleValueType value = calculateWeakUntilOperator(position); + + Logger.assertProB("Weak Until invalid", value == release.getValues() + .get(position)); + + Logger.assertProB("Weak Until invalid", + value == or1.getValues().get(position)); + + Logger.assertProB("Weak Until invalid", + value == or2.getValues().get(position)); + + return value; + } + + private CounterExampleValueType calculateWeakUntilOperator( + final int position) { + CounterExampleValueType result = CounterExampleValueType.UNDEFINED; + + List<CounterExampleValueType> firstCheckedValues = new ArrayList<CounterExampleValueType>( + getFirstArgument().getValues()); + List<CounterExampleValueType> secondCheckedValues = new ArrayList<CounterExampleValueType>( + getSecondArgument().getValues()); + + // add future values if a path is infinite + if (pathType == PathType.INFINITE && position > loopEntry) { + firstCheckedValues.addAll(firstCheckedValues.subList(loopEntry, + position)); + secondCheckedValues.addAll(secondCheckedValues.subList(loopEntry, + position)); + } + + // remove all past values + firstCheckedValues = firstCheckedValues.subList(position, + firstCheckedValues.size()); + secondCheckedValues = secondCheckedValues.subList(position, + secondCheckedValues.size()); + + int firstIndex = -1; + + boolean trueOrUnknown = false; + + // look for a state with a true value in second argument + int secondIndex = secondCheckedValues + .indexOf(CounterExampleValueType.TRUE); + + if (secondIndex != -1) { + // look for a state with a false value in first argument + firstCheckedValues = firstCheckedValues.subList(0, secondIndex); + firstIndex = firstCheckedValues + .indexOf(CounterExampleValueType.FALSE); + + if (firstIndex == -1) { + trueOrUnknown = true; + + if (pathType != PathType.REDUCED) { + result = CounterExampleValueType.TRUE; + } else { + // look for the state with an unknown value in first + // argument + if (firstCheckedValues + .contains(CounterExampleValueType.UNDEFINED)) { + secondCheckedValues = secondCheckedValues.subList(0, + secondIndex + 1); + secondIndex = -1; + } else { + result = CounterExampleValueType.TRUE; + } + } + } + } else { + // look for a state with a false value in first argument + if (!firstCheckedValues.contains(CounterExampleValueType.FALSE)) { + if (pathType != PathType.REDUCED) { + trueOrUnknown = true; + result = CounterExampleValueType.TRUE; + } + } + } + + if (!trueOrUnknown) { + // look for a state with a false value in first argument + firstIndex = firstCheckedValues + .indexOf(CounterExampleValueType.FALSE); + + if (firstIndex != -1) { + secondCheckedValues = secondCheckedValues.subList(0, + firstIndex + 1); + secondIndex = -1; + + if (pathType != PathType.REDUCED) { + result = CounterExampleValueType.FALSE; + } else { + // look for a state with an unknown value in second argument + if (secondCheckedValues + .contains(CounterExampleValueType.UNDEFINED)) { + firstCheckedValues = firstCheckedValues.subList(0, + firstIndex + 1); + firstIndex = -1; + } else { + result = CounterExampleValueType.FALSE; + } + } + } else { + if (pathType != PathType.REDUCED) { + result = CounterExampleValueType.FALSE; + } else { + for (int i = 0; i < firstCheckedValues.size(); i++) { + if (firstCheckedValues.get(i).equals( + CounterExampleValueType.UNDEFINED) + && secondCheckedValues.get(i).equals( + CounterExampleValueType.UNDEFINED)) { + firstCheckedValues = firstCheckedValues.subList(0, + i + 1); + secondCheckedValues = secondCheckedValues.subList( + 0, i + 1); + + break; + } + } + } + } + } + + fillHighlightedPositions(position, firstIndex, secondIndex, + firstCheckedValues.size(), secondCheckedValues.size(), false); + + return result; + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleYesterday.java b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleYesterday.java new file mode 100644 index 0000000000000000000000000000000000000000..157a2a22a742cd5db47c0bf69155aee5f374f675 --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ltl/CounterExampleYesterday.java @@ -0,0 +1,52 @@ +package de.prob.core.domainobjects.ltl; + +import java.util.ArrayList; +import java.util.List; + +import de.prob.core.command.LtlCheckingCommand.PathType; + +/** + * Provides a "Yesterday" operator. + * + * @author Andriy Tolstoy + * + */ + +public final class CounterExampleYesterday extends CounterExampleUnaryOperator { + public CounterExampleYesterday(final PathType pathType, + final int loopEntry, final CounterExampleProposition argument) { + super("Y", "Yesterday", pathType, loopEntry, argument); + } + + public CounterExampleYesterday(final PathType pathType, + final CounterExampleProposition argument) { + this(pathType, -1, argument); + } + + @Override + public CounterExampleValueType calculate(final int position) { + CounterExampleValueType result = calculateYesterday(position); + return result; + } + + private CounterExampleValueType calculateYesterday(int position) { + CounterExampleValueType result = CounterExampleValueType.FALSE; + + List<CounterExampleValueType> checkedValues = new ArrayList<CounterExampleValueType>( + argument.getValues()); + + // remove all future values + checkedValues = checkedValues.subList(0, position + 1); + + int index = -1; + + if (checkedValues.size() > 1) { + index = position - 1; + result = argument.getValues().get(index); + } + + fillHighlightedPositions(position, index, -1, true); + + return result; + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleAllUnitTests.java b/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleAllUnitTests.java new file mode 100644 index 0000000000000000000000000000000000000000..5059dd8e15617b843e837bcaf4db3d4e68be17f7 --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleAllUnitTests.java @@ -0,0 +1,18 @@ +package de.prob.core.domainobjects.ltl.unittests; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +@RunWith(Suite.class) +@Suite.SuiteClasses({ CounterExampleFinallyUnitTest.class, + CounterExampleGloballyUnitTest.class, CounterExampleNextUnitTest.class, + CounterExampleUntilUnitTest.class, + CounterExampleWeakUntilUnitTest.class, + CounterExampleReleaseUnitTest.class, CounterExampleOnceUnitTest.class, + CounterExampleHistoryUnitTest.class, + CounterExampleYesterdayUnitTest.class, + CounterExampleSinceUnitTest.class, CounterExampleTriggerUnitTest.class, + CounterExampleNotUnitTest.class, CounterExampleAndUnitTest.class, + CounterExampleOrUnitTest.class, CounterExampleImplyUnitTest.class }) +public class CounterExampleAllUnitTests { +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleAndUnitTest.java b/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleAndUnitTest.java new file mode 100644 index 0000000000000000000000000000000000000000..8cd75a81286a18ee3e9aef3244d5f765c87a2f5d --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleAndUnitTest.java @@ -0,0 +1,546 @@ +package de.prob.core.domainobjects.ltl.unittests; + +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +import de.prob.core.command.LtlCheckingCommand.PathType; +import de.prob.core.domainobjects.ltl.CounterExampleBinaryOperator; +import de.prob.core.domainobjects.ltl.CounterExampleConjunction; +import de.prob.core.domainobjects.ltl.CounterExamplePredicate; +import de.prob.core.domainobjects.ltl.CounterExampleProposition; +import de.prob.core.domainobjects.ltl.CounterExampleValueType; + +public class CounterExampleAndUnitTest { + /* + * f-FTTF, g-TTFF, f And g-FTFF + */ + @Test + public void testAndOnFinitePath() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.FINITE, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.FINITE, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator andOperator = new CounterExampleConjunction( + PathType.FINITE, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = andOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = andOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = andOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 0); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 0); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 0); + } + + /* + * f-FTTF, g-TTFF, f And g-FTFF + */ + @Test + public void testAndOnInfinitePath() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // Loop entry = 0 + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.INFINITE, 0, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.INFINITE, 0, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator andOperator = new CounterExampleConjunction( + PathType.INFINITE, 0, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = andOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = andOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = andOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 0); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 0); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 0); + + // Loop entry = 1 + // create first argument + firstArgument = new CounterExamplePredicate(PathType.INFINITE, 1, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate(PathType.INFINITE, 1, + secondArgumentValues); + + // create an operator + andOperator = new CounterExampleConjunction(PathType.INFINITE, 1, + firstArgument, secondArgument); + + // check result values + values = andOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + firstHighlightedPositions = andOperator.getFirstHighlightedPositions(); + secondHighlightedPositions = andOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 0); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 0); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 0); + + // Loop entry = 2 + // create first argument + firstArgument = new CounterExamplePredicate("", PathType.INFINITE, 2, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate("", PathType.INFINITE, 2, + secondArgumentValues); + + // create an operator + andOperator = new CounterExampleConjunction(PathType.INFINITE, 2, + firstArgument, secondArgument); + + // check result values + values = andOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + firstHighlightedPositions = andOperator.getFirstHighlightedPositions(); + secondHighlightedPositions = andOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 0); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 0); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 0); + + // Loop entry = 3 + // create first argument + firstArgument = new CounterExamplePredicate("", PathType.INFINITE, 3, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate("", PathType.INFINITE, 3, + secondArgumentValues); + + // create an operator + andOperator = new CounterExampleConjunction(PathType.INFINITE, 3, + firstArgument, secondArgument); + + // check result values + values = andOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + firstHighlightedPositions = andOperator.getFirstHighlightedPositions(); + secondHighlightedPositions = andOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 0); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 0); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 0); + } + + /* + * f-FTTF, g-TTFF, f And g-FTFF + */ + @Test + public void testAndOnReducedPath1() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.REDUCED, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.REDUCED, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator andOperator = new CounterExampleConjunction( + PathType.REDUCED, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = andOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = andOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = andOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 0); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 0); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 0); + } + + /* + * f-FUUT, g-UTUU, f And g-FUUU + */ + @Test + public void testAndOnReducedPath2() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.REDUCED, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.REDUCED, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator andOperator = new CounterExampleConjunction( + PathType.REDUCED, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = andOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(2) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(3) == CounterExampleValueType.UNDEFINED); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = andOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = andOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 0); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleFinallyUnitTest.java b/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleFinallyUnitTest.java new file mode 100644 index 0000000000000000000000000000000000000000..2597a2d7976de88d0973fdc8a177ffa844b4fc34 --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleFinallyUnitTest.java @@ -0,0 +1,294 @@ +package de.prob.core.domainobjects.ltl.unittests; + +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +import de.prob.core.command.LtlCheckingCommand.PathType; +import de.prob.core.domainobjects.ltl.CounterExampleFinally; +import de.prob.core.domainobjects.ltl.CounterExamplePredicate; +import de.prob.core.domainobjects.ltl.CounterExampleProposition; +import de.prob.core.domainobjects.ltl.CounterExampleUnaryOperator; +import de.prob.core.domainobjects.ltl.CounterExampleValueType; + +/** + * Unit test for a "Finally" operator. + * + * @author Andriy Tolstoy + * + */ +public final class CounterExampleFinallyUnitTest { + @Test + public void testFinallyOnFinitePath() { + // create argument values + List<CounterExampleValueType> argumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create an argument + CounterExampleProposition argument = new CounterExamplePredicate("", + PathType.FINITE, -1, argumentValues); + + // create an operator + CounterExampleUnaryOperator finallyOperator = new CounterExampleFinally( + PathType.FINITE, -1, argument); + + // check result values + List<CounterExampleValueType> values = finallyOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> highlightedPositions = finallyOperator + .getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + @Test + public void testFinallyOnInfinitePath() { + // create argument values + List<CounterExampleValueType> argumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // Loop entry = 0 + // create an argument + CounterExampleProposition argument = new CounterExamplePredicate("", + PathType.INFINITE, 0, argumentValues); + + // create an operator + CounterExampleUnaryOperator finallyOperator = new CounterExampleFinally( + PathType.INFINITE, 0, argument); + + // check result values + List<CounterExampleValueType> values = finallyOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> highlightedPositions = finallyOperator + .getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 1 })); + + // Loop entry = 1 + // create an argument + argument = new CounterExamplePredicate("", PathType.INFINITE, 1, + argumentValues); + + // create an operator + finallyOperator = new CounterExampleFinally(PathType.INFINITE, 1, argument); + + // check result values + values = finallyOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + highlightedPositions = finallyOperator.getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 1 })); + + // Loop entry = 2 + // create an argument + argument = new CounterExamplePredicate("", PathType.INFINITE, 2, + argumentValues); + + // create an operator + finallyOperator = new CounterExampleFinally(PathType.INFINITE, 2, argument); + + // check result values + values = finallyOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + highlightedPositions = finallyOperator.getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + + assertTrue(highlightedPositions.get(3).size() == 2); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2 })); + + // Loop entry = 3 + // create an argument + argument = new CounterExamplePredicate("", PathType.INFINITE, 3, + argumentValues); + + // create an operator + finallyOperator = new CounterExampleFinally(PathType.INFINITE, 3, argument); + + // check result values + values = finallyOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + highlightedPositions = finallyOperator.getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + @Test + public void testFinallyOnReducedPath() { + // create argument values + List<CounterExampleValueType> argumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create an argument + CounterExampleProposition argument = new CounterExamplePredicate("", + PathType.REDUCED, -1, argumentValues); + + // create an operator + CounterExampleUnaryOperator finallyOperator = new CounterExampleFinally( + PathType.REDUCED, -1, argument); + + // check result values + List<CounterExampleValueType> values = finallyOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(2) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(3) == CounterExampleValueType.UNDEFINED); + + // check highlighted positions + List<List<Integer>> highlightedPositions = finallyOperator + .getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + assertTrue(highlightedPositions.get(1).size() == 3); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2, 3 })); + + assertTrue(highlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleGloballyUnitTest.java b/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleGloballyUnitTest.java new file mode 100644 index 0000000000000000000000000000000000000000..cfc87bbef66577627996c75843634688cc13efe1 --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleGloballyUnitTest.java @@ -0,0 +1,297 @@ +package de.prob.core.domainobjects.ltl.unittests; + +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +import de.prob.core.command.LtlCheckingCommand.PathType; +import de.prob.core.domainobjects.ltl.CounterExampleGlobally; +import de.prob.core.domainobjects.ltl.CounterExamplePredicate; +import de.prob.core.domainobjects.ltl.CounterExampleProposition; +import de.prob.core.domainobjects.ltl.CounterExampleUnaryOperator; +import de.prob.core.domainobjects.ltl.CounterExampleValueType; + +/** + * Unit test for a "Globally" operator. + * + * @author Andriy Tolstoy + * + */ +public final class CounterExampleGloballyUnitTest { + @Test + public void testGloballyOnFinitePath() { + // create argument values + List<CounterExampleValueType> argumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // create an argument + CounterExampleProposition argument = new CounterExamplePredicate("", + PathType.FINITE, -1, argumentValues); + + // create an operator + CounterExampleUnaryOperator globallyOperator = new CounterExampleGlobally( + PathType.FINITE, -1, argument); + + // check result values + List<CounterExampleValueType> values = globallyOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> highlightedPositions = globallyOperator + .getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + @Test + public void testGloballyOnInfinitePath() { + // create argument values + List<CounterExampleValueType> argumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // Loop entry = 0 + // create an argument + CounterExampleProposition argument = new CounterExamplePredicate("", + PathType.INFINITE, 0, argumentValues); + + // create an operator + CounterExampleUnaryOperator globallyOperator = new CounterExampleGlobally( + PathType.INFINITE, 0, argument); + + // check result values + List<CounterExampleValueType> values = globallyOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> highlightedPositions = globallyOperator + .getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 1 })); + + // Loop entry = 1 + // create an argument + argument = new CounterExamplePredicate("", PathType.INFINITE, 1, + argumentValues); + + // create an operator + globallyOperator = new CounterExampleGlobally(PathType.INFINITE, 1, + argument); + + // check result values + values = globallyOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + highlightedPositions = globallyOperator.getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 1 })); + + // Loop entry = 2 + // create an argument + argument = new CounterExamplePredicate("", PathType.INFINITE, 2, + argumentValues); + + // create an operator + globallyOperator = new CounterExampleGlobally(PathType.INFINITE, 2, + argument); + + // check result values + values = globallyOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + highlightedPositions = globallyOperator.getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + + assertTrue(highlightedPositions.get(3).size() == 2); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2 })); + + // Loop entry = 3 + // create an argument + argument = new CounterExamplePredicate("", PathType.INFINITE, 3, + argumentValues); + + // create an operator + globallyOperator = new CounterExampleGlobally(PathType.INFINITE, 3, + argument); + + // check result values + values = globallyOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + highlightedPositions = globallyOperator.getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + @Test + public void testGloballyOnReducedPath() { + // create argument values + List<CounterExampleValueType> argumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // create an argument + CounterExampleProposition argument = new CounterExamplePredicate("", + PathType.REDUCED, -1, argumentValues); + + // create an operator + CounterExampleUnaryOperator globallyOperator = new CounterExampleGlobally( + PathType.REDUCED, -1, argument); + + // check result values + List<CounterExampleValueType> values = globallyOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(2) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(3) == CounterExampleValueType.UNDEFINED); + + // check highlighted positions + List<List<Integer>> highlightedPositions = globallyOperator + .getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + assertTrue(highlightedPositions.get(1).size() == 3); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2, 3 })); + + assertTrue(highlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleHistoryUnitTest.java b/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleHistoryUnitTest.java new file mode 100644 index 0000000000000000000000000000000000000000..6616f9ed4425d93d18ad96cbac3b0ac62e8b58f2 --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleHistoryUnitTest.java @@ -0,0 +1,691 @@ +package de.prob.core.domainobjects.ltl.unittests; + +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +import de.prob.core.command.LtlCheckingCommand.PathType; +import de.prob.core.domainobjects.ltl.CounterExampleHistory; +import de.prob.core.domainobjects.ltl.CounterExamplePredicate; +import de.prob.core.domainobjects.ltl.CounterExampleProposition; +import de.prob.core.domainobjects.ltl.CounterExampleUnaryOperator; +import de.prob.core.domainobjects.ltl.CounterExampleValueType; + +/** + * Unit test for a "History" operator. + * + * @author Andriy Tolstoy + * + */ +public class CounterExampleHistoryUnitTest { + /* + * f-TTTT, O f-TTTT + */ + @Test + public void testHistoryTrueDefinitionOnFinitePath() { + // create argument values + List<CounterExampleValueType> argumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // create an argument + CounterExampleProposition argument = new CounterExamplePredicate("", + PathType.FINITE, -1, argumentValues); + + // create an operator + CounterExampleUnaryOperator historyOperator = new CounterExampleHistory( + PathType.FINITE, -1, argument); + + // check result values + List<CounterExampleValueType> values = historyOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> highlightedPositions = historyOperator + .getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + assertTrue(highlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + assertTrue(highlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + assertTrue(highlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + } + + /* + * f-TTFF, O f-TTFF + */ + @Test + public void testHistoryFalseDefinitionOnFinitePath() { + // create argument values + List<CounterExampleValueType> argumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create an argument + CounterExampleProposition argument = new CounterExamplePredicate("", + PathType.FINITE, -1, argumentValues); + + // create an operator + CounterExampleUnaryOperator historyOperator = new CounterExampleHistory( + PathType.FINITE, -1, argument); + + // check result values + List<CounterExampleValueType> values = historyOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> highlightedPositions = historyOperator + .getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + assertTrue(highlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + assertTrue(highlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-TTTT, O f-TTTT + */ + @Test + public void testHistoryTrueDefinitionOnInfinitePath() { + // create argument values + List<CounterExampleValueType> argumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // Loop entry = 0 + // create an argument + CounterExampleProposition argument = new CounterExamplePredicate("", + PathType.INFINITE, 0, argumentValues); + + // create an operator + CounterExampleUnaryOperator historyOperator = new CounterExampleHistory( + PathType.INFINITE, 0, argument); + + // check result values + List<CounterExampleValueType> values = historyOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> highlightedPositions = historyOperator + .getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + assertTrue(highlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + assertTrue(highlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + assertTrue(highlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + + // Loop entry = 1 + // create an argument + argument = new CounterExamplePredicate("", PathType.INFINITE, 1, + argumentValues); + + // create an operator + historyOperator = new CounterExampleHistory(PathType.INFINITE, 1, argument); + + // check result values + values = historyOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + highlightedPositions = historyOperator.getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + assertTrue(highlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + assertTrue(highlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + assertTrue(highlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + + // Loop entry = 2 + // create an argument + argument = new CounterExamplePredicate("", PathType.INFINITE, 2, + argumentValues); + + // create an operator + historyOperator = new CounterExampleHistory(PathType.INFINITE, 2, argument); + + // check result values + values = historyOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + highlightedPositions = historyOperator.getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + assertTrue(highlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + assertTrue(highlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + assertTrue(highlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + + // Loop entry = 3 + // create an argument + argument = new CounterExamplePredicate("", PathType.INFINITE, 3, + argumentValues); + + // create an operator + historyOperator = new CounterExampleHistory(PathType.INFINITE, 3, argument); + + // check result values + values = historyOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + highlightedPositions = historyOperator.getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + assertTrue(highlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + assertTrue(highlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + assertTrue(highlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + } + + /* + * f-TTFF, O f-TTFF + */ + @Test + public void testHistoryFalseDefinitionOnInFinitePath() { + // create argument values + List<CounterExampleValueType> argumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // Loop entry = 0 + // create an argument + CounterExampleProposition argument = new CounterExamplePredicate("", + PathType.INFINITE, 0, argumentValues); + + // create an operator + CounterExampleUnaryOperator historyOperator = new CounterExampleHistory( + PathType.INFINITE, 0, argument); + + // check result values + List<CounterExampleValueType> values = historyOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> highlightedPositions = historyOperator + .getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + assertTrue(highlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + assertTrue(highlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + + // Loop entry = 1 + // create an argument + argument = new CounterExamplePredicate("", PathType.INFINITE, 1, + argumentValues); + + // create an operator + historyOperator = new CounterExampleHistory(PathType.INFINITE, 1, argument); + + // check result values + values = historyOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + highlightedPositions = historyOperator.getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + assertTrue(highlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + assertTrue(highlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + + // Loop entry = 2 + // create an argument + argument = new CounterExamplePredicate("", PathType.INFINITE, 2, + argumentValues); + + // create an operator + historyOperator = new CounterExampleHistory(PathType.INFINITE, 2, argument); + + // check result values + values = historyOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + highlightedPositions = historyOperator.getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + assertTrue(highlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + assertTrue(highlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + + // Loop entry = 3 + // create an argument + argument = new CounterExamplePredicate("", PathType.INFINITE, 3, + argumentValues); + + // create an operator + historyOperator = new CounterExampleHistory(PathType.INFINITE, 3, argument); + + // check result values + values = historyOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + highlightedPositions = historyOperator.getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + assertTrue(highlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + assertTrue(highlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-TTTT, O f-TTTT + */ + @Test + public void testHistoryTrueDefinitionOnReducedPath() { + // create argument values + List<CounterExampleValueType> argumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // create an argument + CounterExampleProposition argument = new CounterExamplePredicate("", + PathType.REDUCED, -1, argumentValues); + + // create an operator + CounterExampleUnaryOperator historyOperator = new CounterExampleHistory( + PathType.REDUCED, -1, argument); + + // check result values + List<CounterExampleValueType> values = historyOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> highlightedPositions = historyOperator + .getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + assertTrue(highlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + assertTrue(highlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + assertTrue(highlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + } + + /* + * f-TTFF, O f-TTFF + */ + @Test + public void testHistoryFalseDefinitionOnReducedPath() { + // create argument values + List<CounterExampleValueType> argumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create an argument + CounterExampleProposition argument = new CounterExamplePredicate("", + PathType.REDUCED, -1, argumentValues); + + // create an operator + CounterExampleUnaryOperator historyOperator = new CounterExampleHistory( + PathType.REDUCED, -1, argument); + + // check result values + List<CounterExampleValueType> values = historyOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> highlightedPositions = historyOperator + .getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + assertTrue(highlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + assertTrue(highlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-UTUT, O f-UUUU + */ + @Test + public void testHistoryUnknownDefinitionOnReducedPath() { + // create argument values + List<CounterExampleValueType> argumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE }); + + // create an argument + CounterExampleProposition argument = new CounterExamplePredicate("", + PathType.REDUCED, -1, argumentValues); + + // create an operator + CounterExampleUnaryOperator historyOperator = new CounterExampleHistory( + PathType.REDUCED, -1, argument); + + // check result values + List<CounterExampleValueType> values = historyOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(1) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(2) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(3) == CounterExampleValueType.UNDEFINED); + + // check highlighted positions + List<List<Integer>> highlightedPositions = historyOperator + .getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + assertTrue(highlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + assertTrue(highlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + assertTrue(highlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + } + + /* + * f-TUTF, O f-TUUF + */ + @Test + public void testHistoryOnReducedPath() { + // create argument values + List<CounterExampleValueType> argumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE }); + + // create an argument + CounterExampleProposition argument = new CounterExamplePredicate("", + PathType.REDUCED, -1, argumentValues); + + // create an operator + CounterExampleUnaryOperator historyOperator = new CounterExampleHistory( + PathType.REDUCED, -1, argument); + + // check result values + List<CounterExampleValueType> values = historyOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(2) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> highlightedPositions = historyOperator + .getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + assertTrue(highlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + assertTrue(highlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleImplyUnitTest.java b/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleImplyUnitTest.java new file mode 100644 index 0000000000000000000000000000000000000000..0e94ed0b6aab0f28b036392402268ff3b1982ab8 --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleImplyUnitTest.java @@ -0,0 +1,636 @@ +package de.prob.core.domainobjects.ltl.unittests; + +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +import de.prob.core.command.LtlCheckingCommand.PathType; +import de.prob.core.domainobjects.ltl.CounterExampleBinaryOperator; +import de.prob.core.domainobjects.ltl.CounterExampleImplication; +import de.prob.core.domainobjects.ltl.CounterExamplePredicate; +import de.prob.core.domainobjects.ltl.CounterExampleProposition; +import de.prob.core.domainobjects.ltl.CounterExampleValueType; + +public class CounterExampleImplyUnitTest { + /* + * f-TTFF, g-TFTF, f Imply g-TFTT + */ + @Test + public void testImplyOnFinitePath() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.FINITE, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.FINITE, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator implyOperator = new CounterExampleImplication( + PathType.FINITE, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = implyOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = implyOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = implyOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 0); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 0); + } + + /* + * f-TTFF, g-TFTF, f Imply g-TFTT + */ + @Test + public void testImplyOnInfinitePath() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE }); + + // Loop entry = 0 + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.INFINITE, 0, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.INFINITE, 0, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator implyOperator = new CounterExampleImplication( + PathType.INFINITE, 0, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = implyOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = implyOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = implyOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 0); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 0); + + // Loop entry = 1 + // create first argument + firstArgument = new CounterExamplePredicate(PathType.INFINITE, 1, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate(PathType.INFINITE, 1, + secondArgumentValues); + + // create an operator + implyOperator = new CounterExampleImplication(PathType.INFINITE, 1, + firstArgument, secondArgument); + + // check result values + values = implyOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + firstHighlightedPositions = implyOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = implyOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 0); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 0); + + // Loop entry = 2 + // create first argument + firstArgument = new CounterExamplePredicate("", PathType.INFINITE, 2, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate("", PathType.INFINITE, 2, + secondArgumentValues); + + // create an operator + implyOperator = new CounterExampleImplication(PathType.INFINITE, 2, + firstArgument, secondArgument); + + // check result values + values = implyOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + firstHighlightedPositions = implyOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = implyOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 0); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 0); + + // Loop entry = 3 + // create first argument + firstArgument = new CounterExamplePredicate("", PathType.INFINITE, 3, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate("", PathType.INFINITE, 3, + secondArgumentValues); + + // create an operator + implyOperator = new CounterExampleImplication(PathType.INFINITE, 3, + firstArgument, secondArgument); + + // check result values + values = implyOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + firstHighlightedPositions = implyOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = implyOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 0); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 0); + } + + /* + * f-TTFF, g-TFTF, f Imply g-TFTT + */ + @Test + public void testImplyOnReducedPath1() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.REDUCED, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.REDUCED, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator implyOperator = new CounterExampleImplication( + PathType.REDUCED, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = implyOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = implyOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = implyOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 0); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 0); + } + + /* + * f-UUTU, g-UTUF, f Imply g-UTUU + */ + @Test + public void testImplyOnReducedPath2() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE, + CounterExampleValueType.UNDEFINED }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.FALSE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.REDUCED, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.REDUCED, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator implyOperator = new CounterExampleImplication( + PathType.REDUCED, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = implyOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(3) == CounterExampleValueType.UNDEFINED); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = implyOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = implyOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 0); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-UUTF, g-UTUU, f Imply g-UTUT + */ + @Test + public void testImplyOnReducedPath3() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.REDUCED, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.REDUCED, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator implyOperator = new CounterExampleImplication( + PathType.REDUCED, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = implyOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = implyOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = implyOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 0); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 0); + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleNextUnitTest.java b/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleNextUnitTest.java new file mode 100644 index 0000000000000000000000000000000000000000..8f9b8d675ce978cec6f2dbe97583c36e18c8655c --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleNextUnitTest.java @@ -0,0 +1,288 @@ +package de.prob.core.domainobjects.ltl.unittests; + +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +import de.prob.core.command.LtlCheckingCommand.PathType; +import de.prob.core.domainobjects.ltl.CounterExampleNext; +import de.prob.core.domainobjects.ltl.CounterExamplePredicate; +import de.prob.core.domainobjects.ltl.CounterExampleProposition; +import de.prob.core.domainobjects.ltl.CounterExampleUnaryOperator; +import de.prob.core.domainobjects.ltl.CounterExampleValueType; + +/** + * Unit test for a "Next" operator. + * + * @author Andriy Tolstoy + * + */ +public final class CounterExampleNextUnitTest { + @Test + public void testNextOnFinitePath() { + // create argument values + List<CounterExampleValueType> argumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE }); + + // create an argument + CounterExampleProposition argument = new CounterExamplePredicate("", + PathType.FINITE, -1, argumentValues); + + // create an operator + CounterExampleUnaryOperator nextOperator = new CounterExampleNext( + PathType.FINITE, -1, argument); + + // check result values + List<CounterExampleValueType> values = nextOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> highlightedPositions = nextOperator + .getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 2 })); + + assertTrue(highlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 3 })); + + assertTrue(highlightedPositions.get(3).size() == 0); + } + + @Test + public void testNextOnInfinitePath() { + // create argument values + List<CounterExampleValueType> argumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE }); + + // Loop entry = 0 + // create an argument + CounterExampleProposition argument = new CounterExamplePredicate("", + PathType.INFINITE, 0, argumentValues); + + // create an operator + CounterExampleUnaryOperator nextOperator = new CounterExampleNext( + PathType.INFINITE, 0, argument); + + // check result values + List<CounterExampleValueType> values = nextOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> highlightedPositions = nextOperator + .getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 2 })); + + assertTrue(highlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 3 })); + + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 0 })); + + // Loop entry = 1 + // create an argument + argument = new CounterExamplePredicate("", PathType.INFINITE, 1, + argumentValues); + + // create an operator + nextOperator = new CounterExampleNext(PathType.INFINITE, 1, argument); + + // check result values + values = nextOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + highlightedPositions = nextOperator.getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 2 })); + + assertTrue(highlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 3 })); + + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 1 })); + + // Loop entry = 2 + // create an argument + argument = new CounterExamplePredicate("", PathType.INFINITE, 2, + argumentValues); + + // create an operator + nextOperator = new CounterExampleNext(PathType.INFINITE, 2, argument); + + // check result values + values = nextOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + highlightedPositions = nextOperator.getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 2 })); + + assertTrue(highlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 3 })); + + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 2 })); + + // Loop entry = 3 + // create an argument + argument = new CounterExamplePredicate("", PathType.INFINITE, 3, + argumentValues); + + // create an operator + nextOperator = new CounterExampleNext(PathType.INFINITE, 3, argument); + + // check result values + values = nextOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + highlightedPositions = nextOperator.getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 2 })); + + assertTrue(highlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 3 })); + + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + @Test + public void testNextOnReducedPath() { + // create argument values + List<CounterExampleValueType> argumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE }); + + // create an argument + CounterExampleProposition argument = new CounterExamplePredicate("", + PathType.REDUCED, -1, argumentValues); + + // create an operator + CounterExampleUnaryOperator nextOperator = new CounterExampleNext( + PathType.REDUCED, -1, argument); + + // check result values + List<CounterExampleValueType> values = nextOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.UNDEFINED); + + // check highlighted positions + List<List<Integer>> highlightedPositions = nextOperator + .getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 2 })); + + assertTrue(highlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 3 })); + + assertTrue(highlightedPositions.get(3).size() == 0); + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleNotUnitTest.java b/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleNotUnitTest.java new file mode 100644 index 0000000000000000000000000000000000000000..0adbaeaa6551afac01f8963d4c34976ff003f0f6 --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleNotUnitTest.java @@ -0,0 +1,390 @@ +package de.prob.core.domainobjects.ltl.unittests; + +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +import de.prob.core.command.LtlCheckingCommand.PathType; +import de.prob.core.domainobjects.ltl.CounterExampleNegation; +import de.prob.core.domainobjects.ltl.CounterExamplePredicate; +import de.prob.core.domainobjects.ltl.CounterExampleProposition; +import de.prob.core.domainobjects.ltl.CounterExampleUnaryOperator; +import de.prob.core.domainobjects.ltl.CounterExampleValueType; + +/** + * Unit test for a "Not" operator. + * + * @author Andriy Tolstoy + * + */ +public class CounterExampleNotUnitTest { + + /* + * f-TFFT, Not f-FTTF + */ + @Test + public void testNotOnFinitePath() { + // create argument values + List<CounterExampleValueType> argumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE }); + + // create an argument + CounterExampleProposition argument = new CounterExamplePredicate("", + PathType.FINITE, argumentValues); + + // create an operator + CounterExampleUnaryOperator notOperator = new CounterExampleNegation( + PathType.FINITE, argument); + + // check result values + List<CounterExampleValueType> values = notOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + // State 0 + List<List<Integer>> highlightedPositions = notOperator + .getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(highlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(highlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-TFFT, Not f-FTTF + */ + @Test + public void testNotOnInFinitePath() { + // create argument values + List<CounterExampleValueType> argumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE }); + + // Loop entry = 0 + // create argument + CounterExampleProposition argument = new CounterExamplePredicate("", + PathType.INFINITE, 0, argumentValues); + + // create an operator + CounterExampleUnaryOperator notOperator = new CounterExampleNegation( + PathType.INFINITE, 0, argument); + + // check result values + List<CounterExampleValueType> values = notOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> highlightedPositions = notOperator + .getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + + // State 0 + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(highlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(highlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + + // Loop entry = 1 + // create argument + argument = new CounterExamplePredicate("", PathType.INFINITE, 1, + argumentValues); + + // create an operator + notOperator = new CounterExampleNegation(PathType.INFINITE, 1, argument); + + // check result values + values = notOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + highlightedPositions = notOperator.getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + + // State 0 + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(highlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(highlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + + // Loop entry = 2 + // create argument + argument = new CounterExamplePredicate("", PathType.INFINITE, 2, + argumentValues); + + // create an operator + notOperator = new CounterExampleNegation(PathType.INFINITE, 2, argument); + + // check result values + values = notOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + highlightedPositions = notOperator.getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + + // State 0 + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(highlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(highlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + + // Loop entry = 3 + // create argument + argument = new CounterExamplePredicate("", PathType.INFINITE, 3, + argumentValues); + + // create an operator + notOperator = new CounterExampleNegation(PathType.INFINITE, 3, argument); + + // check result values + values = notOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + highlightedPositions = notOperator.getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + + // State 0 + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(highlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(highlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-TFFT, Not f-FTTF + */ + @Test + public void testNotOnReducedPath1() { + // create argument values + List<CounterExampleValueType> argumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE }); + + // create an argument + CounterExampleProposition argument = new CounterExamplePredicate("", + PathType.REDUCED, argumentValues); + + // create an operator + CounterExampleUnaryOperator notOperator = new CounterExampleNegation( + PathType.REDUCED, argument); + + // check result values + List<CounterExampleValueType> values = notOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + // State 0 + List<List<Integer>> highlightedPositions = notOperator + .getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(highlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(highlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-TUFU, Not f-FUTU + */ + @Test + public void testNotOnReducedPath2() { + // create argument values + List<CounterExampleValueType> argumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.FALSE, + CounterExampleValueType.UNDEFINED }); + + // create an argument + CounterExampleProposition argument = new CounterExamplePredicate("", + PathType.REDUCED, argumentValues); + + // create an operator + CounterExampleUnaryOperator notOperator = new CounterExampleNegation( + PathType.REDUCED, argument); + + // check result values + List<CounterExampleValueType> values = notOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.UNDEFINED); + + // check highlighted positions + // State 0 + List<List<Integer>> highlightedPositions = notOperator + .getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(highlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(highlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleOnceUnitTest.java b/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleOnceUnitTest.java new file mode 100644 index 0000000000000000000000000000000000000000..9ef7cc5308ffd5a771d906adbb81c106d0d88dd9 --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleOnceUnitTest.java @@ -0,0 +1,691 @@ +package de.prob.core.domainobjects.ltl.unittests; + +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +import de.prob.core.command.LtlCheckingCommand.PathType; +import de.prob.core.domainobjects.ltl.CounterExampleOnce; +import de.prob.core.domainobjects.ltl.CounterExamplePredicate; +import de.prob.core.domainobjects.ltl.CounterExampleProposition; +import de.prob.core.domainobjects.ltl.CounterExampleUnaryOperator; +import de.prob.core.domainobjects.ltl.CounterExampleValueType; + +/** + * Unit test for a "Once" operator. + * + * @author Andriy Tolstoy + * + */ +public class CounterExampleOnceUnitTest { + /* + * f-FTFT, O f-FTTT + */ + @Test + public void testOnceTrueDefinitionOnFinitePath() { + // create argument values + List<CounterExampleValueType> argumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE }); + + // create an argument + CounterExampleProposition argument = new CounterExamplePredicate("", + PathType.FINITE, -1, argumentValues); + + // create an operator + CounterExampleUnaryOperator onceOperator = new CounterExampleOnce( + PathType.FINITE, argument); + + // check result values + List<CounterExampleValueType> values = onceOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> highlightedPositions = onceOperator + .getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + assertTrue(highlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-FFFF, O f-FFFF + */ + @Test + public void testOnceFalseDefinitionOnFinitePath() { + // create argument values + List<CounterExampleValueType> argumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create an argument + CounterExampleProposition argument = new CounterExamplePredicate("", + PathType.FINITE, -1, argumentValues); + + // create an operator + CounterExampleUnaryOperator onceOperator = new CounterExampleOnce( + PathType.FINITE, -1, argument); + + // check result values + List<CounterExampleValueType> values = onceOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> highlightedPositions = onceOperator + .getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + assertTrue(highlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + assertTrue(highlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + assertTrue(highlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + } + + /* + * f-TFTF, O f-FTTT + */ + @Test + public void testOnceTrueDefinitionOnInfinitePath() { + // create argument values + List<CounterExampleValueType> argumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE }); + + // Loop entry = 0 + // create an argument + CounterExampleProposition argument = new CounterExamplePredicate("", + PathType.INFINITE, 0, argumentValues); + + // create an operator + CounterExampleUnaryOperator onceOperator = new CounterExampleOnce( + PathType.INFINITE, 0, argument); + + // check result values + List<CounterExampleValueType> values = onceOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> highlightedPositions = onceOperator + .getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + assertTrue(highlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + + // Loop entry = 1 + // create an argument + argument = new CounterExamplePredicate("", PathType.INFINITE, 1, + argumentValues); + + // create an operator + onceOperator = new CounterExampleOnce(PathType.INFINITE, 1, argument); + + // check result values + values = onceOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + highlightedPositions = onceOperator.getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + assertTrue(highlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + + // Loop entry = 2 + // create an argument + argument = new CounterExamplePredicate("", PathType.INFINITE, 2, + argumentValues); + + // create an operator + onceOperator = new CounterExampleOnce(PathType.INFINITE, 2, argument); + + // check result values + values = onceOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + highlightedPositions = onceOperator.getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + assertTrue(highlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + + // Loop entry = 3 + // create an argument + argument = new CounterExamplePredicate("", PathType.INFINITE, 3, + argumentValues); + + // create an operator + onceOperator = new CounterExampleOnce(PathType.INFINITE, 3, argument); + + // check result values + values = onceOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + highlightedPositions = onceOperator.getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + assertTrue(highlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-FFFF, O f-FFFF + */ + @Test + public void testOnceFalseDefinitionOnInfinitePath() { + // create argument values + List<CounterExampleValueType> argumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // Loop entry = 0 + // create an argument + CounterExampleProposition argument = new CounterExamplePredicate("", + PathType.INFINITE, 0, argumentValues); + + // create an operator + CounterExampleUnaryOperator onceOperator = new CounterExampleOnce( + PathType.INFINITE, 0, argument); + + // check result values + List<CounterExampleValueType> values = onceOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> highlightedPositions = onceOperator + .getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + assertTrue(highlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + assertTrue(highlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + assertTrue(highlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + + // Loop entry = 1 + // create an argument + argument = new CounterExamplePredicate("", PathType.INFINITE, 1, + argumentValues); + + // create an operator + onceOperator = new CounterExampleOnce(PathType.INFINITE, 1, argument); + + // check result values + values = onceOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + highlightedPositions = onceOperator.getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + assertTrue(highlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + assertTrue(highlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + assertTrue(highlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + + // Loop entry = 2 + // create an argument + argument = new CounterExamplePredicate("", PathType.INFINITE, 2, + argumentValues); + + // create an operator + onceOperator = new CounterExampleOnce(PathType.INFINITE, 2, argument); + + // check result values + values = onceOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + highlightedPositions = onceOperator.getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + assertTrue(highlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + assertTrue(highlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + assertTrue(highlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + + // Loop entry = 3 + // create an argument + argument = new CounterExamplePredicate("", PathType.INFINITE, 3, + argumentValues); + + // create an operator + onceOperator = new CounterExampleOnce(PathType.INFINITE, 3, argument); + + // check result values + values = onceOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + highlightedPositions = onceOperator.getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + assertTrue(highlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + assertTrue(highlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + assertTrue(highlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + } + + /* + * f-FTFT, O f-FTTT + */ + @Test + public void testOnceTrueDefinitionOnReducedPath() { + // create argument values + List<CounterExampleValueType> argumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE }); + + // create an argument + CounterExampleProposition argument = new CounterExamplePredicate("", + PathType.REDUCED, -1, argumentValues); + + // create an operator + CounterExampleUnaryOperator onceOperator = new CounterExampleOnce( + PathType.REDUCED, -1, argument); + + // check result values + List<CounterExampleValueType> values = onceOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> highlightedPositions = onceOperator + .getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + assertTrue(highlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-FFFF, O f-FFFF + */ + @Test + public void testOnceFalseDefinitionOnReducedPath() { + // create argument values + List<CounterExampleValueType> argumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create an argument + CounterExampleProposition argument = new CounterExamplePredicate("", + PathType.REDUCED, -1, argumentValues); + + // create an operator + CounterExampleUnaryOperator onceOperator = new CounterExampleOnce( + PathType.REDUCED, -1, argument); + + // check result values + List<CounterExampleValueType> values = onceOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> highlightedPositions = onceOperator + .getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + assertTrue(highlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + assertTrue(highlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + assertTrue(highlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + } + + /* + * f-UFUF, O f-UUUU + */ + @Test + public void testOnceUnknownDefinitionOnReducedPath() { + // create argument values + List<CounterExampleValueType> argumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.FALSE, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.FALSE }); + + // create an argument + CounterExampleProposition argument = new CounterExamplePredicate("", + PathType.REDUCED, -1, argumentValues); + + // create an operator + CounterExampleUnaryOperator onceOperator = new CounterExampleOnce( + PathType.REDUCED, -1, argument); + + // check result values + List<CounterExampleValueType> values = onceOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(1) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(2) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(3) == CounterExampleValueType.UNDEFINED); + + // check highlighted positions + List<List<Integer>> highlightedPositions = onceOperator + .getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + assertTrue(highlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + assertTrue(highlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + assertTrue(highlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + } + + /* + * f-FUTU, O f-FUTT + */ + @Test + public void testOnceOnReducedPath() { + // create argument values + List<CounterExampleValueType> argumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE, + CounterExampleValueType.UNDEFINED }); + + // create an argument + CounterExampleProposition argument = new CounterExamplePredicate("", + PathType.REDUCED, -1, argumentValues); + + // create an operator + CounterExampleUnaryOperator onceOperator = new CounterExampleOnce( + PathType.REDUCED, -1, argument); + + // check result values + List<CounterExampleValueType> values = onceOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> highlightedPositions = onceOperator + .getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + assertTrue(highlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + assertTrue(highlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + assertTrue(highlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 2 })); + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleOrUnitTest.java b/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleOrUnitTest.java new file mode 100644 index 0000000000000000000000000000000000000000..e285dce3756256a4a36bd76b7ddc84b34fcbbe39 --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleOrUnitTest.java @@ -0,0 +1,543 @@ +package de.prob.core.domainobjects.ltl.unittests; + +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +import de.prob.core.command.LtlCheckingCommand.PathType; +import de.prob.core.domainobjects.ltl.CounterExampleBinaryOperator; +import de.prob.core.domainobjects.ltl.CounterExampleDisjunction; +import de.prob.core.domainobjects.ltl.CounterExamplePredicate; +import de.prob.core.domainobjects.ltl.CounterExampleProposition; +import de.prob.core.domainobjects.ltl.CounterExampleValueType; + +public class CounterExampleOrUnitTest { + /* + * f-FTTF, g-TTFF, f Or g-TTTF + */ + @Test + public void testOrOnFinitePath() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.FINITE, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.FINITE, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator orOperator = new CounterExampleDisjunction( + PathType.FINITE, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = orOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = orOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = orOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 0); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 0); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-FTTF, g-TTFF, f Or g-FTFF + */ + @Test + public void testOrOnInfinitePath() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // Loop entry = 0 + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.INFINITE, 0, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.INFINITE, 0, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator orOperator = new CounterExampleDisjunction( + PathType.INFINITE, 0, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = orOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = orOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = orOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 0); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 0); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + + // Loop entry = 1 + // create first argument + firstArgument = new CounterExamplePredicate(PathType.INFINITE, 1, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate(PathType.INFINITE, 1, + secondArgumentValues); + + // create an operator + orOperator = new CounterExampleDisjunction(PathType.INFINITE, 1, + firstArgument, secondArgument); + + // check result values + values = orOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + firstHighlightedPositions = orOperator.getFirstHighlightedPositions(); + secondHighlightedPositions = orOperator.getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 0); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 0); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + + // Loop entry = 2 + // create first argument + firstArgument = new CounterExamplePredicate("", PathType.INFINITE, 2, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate("", PathType.INFINITE, 2, + secondArgumentValues); + + // create an operator + orOperator = new CounterExampleDisjunction(PathType.INFINITE, 2, + firstArgument, secondArgument); + + // check result values + values = orOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + firstHighlightedPositions = orOperator.getFirstHighlightedPositions(); + secondHighlightedPositions = orOperator.getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 0); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 0); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + + // Loop entry = 3 + // create first argument + firstArgument = new CounterExamplePredicate("", PathType.INFINITE, 3, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate("", PathType.INFINITE, 3, + secondArgumentValues); + + // create an operator + orOperator = new CounterExampleDisjunction(PathType.INFINITE, 3, + firstArgument, secondArgument); + + // check result values + values = orOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + firstHighlightedPositions = orOperator.getFirstHighlightedPositions(); + secondHighlightedPositions = orOperator.getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 0); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 0); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-FTTF, g-TTFF, f Or g-TTTF + */ + @Test + public void testOrOnReducedPath1() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.REDUCED, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.REDUCED, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator orOperator = new CounterExampleDisjunction( + PathType.REDUCED, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = orOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = orOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = orOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 0); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 0); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-FUUU, g-UTUF, f Or g-UTUU + */ + @Test + public void testOrOnReducedPath2() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.FALSE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.REDUCED, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.REDUCED, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator orOperator = new CounterExampleDisjunction( + PathType.REDUCED, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = orOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(3) == CounterExampleValueType.UNDEFINED); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = orOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = orOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 0); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleReleaseUnitTest.java b/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleReleaseUnitTest.java new file mode 100644 index 0000000000000000000000000000000000000000..90ef2d20a203032ab37f79430ad7dcc1ddba3328 --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleReleaseUnitTest.java @@ -0,0 +1,2713 @@ +package de.prob.core.domainobjects.ltl.unittests; + +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +import de.prob.core.command.LtlCheckingCommand.PathType; +import de.prob.core.domainobjects.ltl.CounterExampleBinaryOperator; +import de.prob.core.domainobjects.ltl.CounterExamplePredicate; +import de.prob.core.domainobjects.ltl.CounterExampleProposition; +import de.prob.core.domainobjects.ltl.CounterExampleRelease; +import de.prob.core.domainobjects.ltl.CounterExampleValueType; + +/** + * Unit test for a "Release" operator. + * + * @author Andriy Tolstoy + * + */ +public class CounterExampleReleaseUnitTest { + /* + * f-FFFT, g-TTTT, f R g-TTTT + */ + @Test + public void testReleaseOnFinitePathTrueDefinition1() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.FINITE, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.FINITE, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator releaseOperator = new CounterExampleRelease( + PathType.FINITE, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = releaseOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = releaseOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = releaseOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(0).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2, 3 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(1).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2, 3 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-FFFF, g-TTTT, f R g-TTTT + */ + @Test + public void testReleaseOnFinitePathTrueDefinition2() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.FINITE, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.FINITE, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator releaseOperator = new CounterExampleRelease( + PathType.FINITE, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = releaseOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = releaseOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = releaseOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 4); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2, 3 })); + assertTrue(secondHighlightedPositions.get(0).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2, 3 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2, 3 })); + assertTrue(secondHighlightedPositions.get(1).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2, 3 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + assertTrue(secondHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-FFFT, g-TTTF, f R g-FFFF + */ + @Test + public void testReleaseFalseDefinitionOnFinitePath1() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.FINITE, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.FINITE, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator releaseOperator = new CounterExampleRelease( + PathType.FINITE, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = releaseOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = releaseOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = releaseOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 0); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-FFFF, g-TTTF, f R g-FFFF + */ + @Test + public void testReleaseFalseDefinitionOnFinitePath2() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.FINITE, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.FINITE, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator releaseOperator = new CounterExampleRelease( + PathType.FINITE, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = releaseOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = releaseOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = releaseOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 0); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-TFTF, g-TFFT, f R g-TFFT + */ + @Test + public void testReleaseOnFinitePath() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.FINITE, -1, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.FINITE, -1, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator releaseOperator = new CounterExampleRelease( + PathType.FINITE, -1, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = releaseOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = releaseOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = releaseOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 0); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 0); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-FFFT, g-TTTT, f R g-TTTT + */ + @Test + public void testReleaseTrueDefinitionOnInfinitePath1() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // Loop entry = 0 + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.INFINITE, 0, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.INFINITE, 0, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator releaseOperator = new CounterExampleRelease( + PathType.INFINITE, 0, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = releaseOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = releaseOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = releaseOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(0).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2, 3 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(1).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2, 3 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + + // Loop entry = 1 + // create first argument + firstArgument = new CounterExamplePredicate(PathType.INFINITE, 1, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate(PathType.INFINITE, 1, + secondArgumentValues); + + // create an operator + releaseOperator = new CounterExampleRelease(PathType.INFINITE, 1, + firstArgument, secondArgument); + + // check result values + values = releaseOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + firstHighlightedPositions = releaseOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = releaseOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(0).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2, 3 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(1).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2, 3 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + + // Loop entry = 2 + // create first argument + firstArgument = new CounterExamplePredicate("", PathType.INFINITE, 2, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate("", PathType.INFINITE, 2, + secondArgumentValues); + + // create an operator + releaseOperator = new CounterExampleRelease(PathType.INFINITE, 2, + firstArgument, secondArgument); + + // check result values + values = releaseOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + firstHighlightedPositions = releaseOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = releaseOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(0).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2, 3 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(1).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2, 3 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + + // Loop entry = 3 + // create first argument + firstArgument = new CounterExamplePredicate("", PathType.INFINITE, 3, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate("", PathType.INFINITE, 3, + secondArgumentValues); + + // create an operator + releaseOperator = new CounterExampleRelease(PathType.INFINITE, 3, + firstArgument, secondArgument); + + // check result values + values = releaseOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + firstHighlightedPositions = releaseOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = releaseOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(0).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2, 3 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(1).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2, 3 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-FFFF, g-TTTT, f R g-TTTT + */ + @Test + public void testReleaseTrueDefinitionOnInfinitePath2() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // Loop entry = 0 + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.INFINITE, 0, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.INFINITE, 0, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator releaseOperator = new CounterExampleRelease( + PathType.INFINITE, 0, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = releaseOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = releaseOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = releaseOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 4); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2, 3 })); + assertTrue(secondHighlightedPositions.get(0).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2, 3 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 4); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2, 3, 0 })); + assertTrue(secondHighlightedPositions.get(1).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2, 3, 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 4); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3, 0, 1 })); + assertTrue(secondHighlightedPositions.get(2).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3, 0, 1 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 0, 1, 2 })); + assertTrue(secondHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 0, 1, 2 })); + + // Loop entry = 1 + // create first argument + firstArgument = new CounterExamplePredicate(PathType.INFINITE, 1, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate(PathType.INFINITE, 1, + secondArgumentValues); + + // create an operator + releaseOperator = new CounterExampleRelease(PathType.INFINITE, 1, + firstArgument, secondArgument); + + // check result values + values = releaseOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + firstHighlightedPositions = releaseOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = releaseOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 4); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2, 3 })); + assertTrue(secondHighlightedPositions.get(0).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2, 3 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2, 3 })); + assertTrue(secondHighlightedPositions.get(1).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2, 3 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3, 1 })); + assertTrue(secondHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3, 1 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 1, 2 })); + assertTrue(secondHighlightedPositions.get(3).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 1, 2 })); + + // Loop entry = 2 + // create first argument + firstArgument = new CounterExamplePredicate("", PathType.INFINITE, 2, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate("", PathType.INFINITE, 2, + secondArgumentValues); + + // create an operator + releaseOperator = new CounterExampleRelease(PathType.INFINITE, 2, + firstArgument, secondArgument); + + // check result values + values = releaseOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + firstHighlightedPositions = releaseOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = releaseOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 4); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2, 3 })); + assertTrue(secondHighlightedPositions.get(0).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2, 3 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2, 3 })); + assertTrue(secondHighlightedPositions.get(1).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2, 3 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + assertTrue(secondHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2 })); + assertTrue(secondHighlightedPositions.get(3).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2 })); + + // Loop entry = 3 + // create first argument + firstArgument = new CounterExamplePredicate("", PathType.INFINITE, 3, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate("", PathType.INFINITE, 3, + secondArgumentValues); + + // create an operator + releaseOperator = new CounterExampleRelease(PathType.INFINITE, 3, + firstArgument, secondArgument); + + // check result values + values = releaseOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + firstHighlightedPositions = releaseOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = releaseOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 4); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2, 3 })); + assertTrue(secondHighlightedPositions.get(0).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2, 3 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2, 3 })); + assertTrue(secondHighlightedPositions.get(1).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2, 3 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + assertTrue(secondHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-FFFT, g-TTTF, f R g-FFFF + */ + @Test + public void testReleaseFalseDefinitionOnInfinitePath1() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE }); + + // Loop entry = 0 + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.INFINITE, 0, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.INFINITE, 0, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator releaseOperator = new CounterExampleRelease( + PathType.INFINITE, 0, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = releaseOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = releaseOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = releaseOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 0); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + + // Loop entry = 1 + // create first argument + firstArgument = new CounterExamplePredicate(PathType.INFINITE, 1, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate(PathType.INFINITE, 1, + secondArgumentValues); + + // create an operator + releaseOperator = new CounterExampleRelease(PathType.INFINITE, 1, + firstArgument, secondArgument); + + // check result values + values = releaseOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + firstHighlightedPositions = releaseOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = releaseOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 0); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + + // Loop entry = 2 + // create first argument + firstArgument = new CounterExamplePredicate("", PathType.INFINITE, 2, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate("", PathType.INFINITE, 2, + secondArgumentValues); + + // create an operator + releaseOperator = new CounterExampleRelease(PathType.INFINITE, 2, + firstArgument, secondArgument); + + // check result values + values = releaseOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + firstHighlightedPositions = releaseOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = releaseOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 0); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + + // Loop entry = 3 + // create first argument + firstArgument = new CounterExamplePredicate("", PathType.INFINITE, 3, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate("", PathType.INFINITE, 3, + secondArgumentValues); + + // create an operator + releaseOperator = new CounterExampleRelease(PathType.INFINITE, 3, + firstArgument, secondArgument); + + // check result values + values = releaseOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + firstHighlightedPositions = releaseOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = releaseOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 0); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-FFFF, g-TTTF, f R g-FFFF + */ + @Test + public void testReleaseFalseDefinitionOnInfinitePath2() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE }); + + // Loop entry = 0 + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.INFINITE, 0, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.INFINITE, 0, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator releaseOperator = new CounterExampleRelease( + PathType.INFINITE, 0, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = releaseOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = releaseOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = releaseOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 0); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + + // Loop entry = 1 + // create first argument + firstArgument = new CounterExamplePredicate(PathType.INFINITE, 1, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate(PathType.INFINITE, 1, + secondArgumentValues); + + // create an operator + releaseOperator = new CounterExampleRelease(PathType.INFINITE, 1, + firstArgument, secondArgument); + + // check result values + values = releaseOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + firstHighlightedPositions = releaseOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = releaseOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 0); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + + // Loop entry = 2 + // create first argument + firstArgument = new CounterExamplePredicate("", PathType.INFINITE, 2, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate("", PathType.INFINITE, 2, + secondArgumentValues); + + // create an operator + releaseOperator = new CounterExampleRelease(PathType.INFINITE, 2, + firstArgument, secondArgument); + + // check result values + values = releaseOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + firstHighlightedPositions = releaseOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = releaseOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 0); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + + // Loop entry = 3 + // create first argument + firstArgument = new CounterExamplePredicate("", PathType.INFINITE, 3, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate("", PathType.INFINITE, 3, + secondArgumentValues); + + // create an operator + releaseOperator = new CounterExampleRelease(PathType.INFINITE, 3, + firstArgument, secondArgument); + + // check result values + values = releaseOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + firstHighlightedPositions = releaseOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = releaseOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 0); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-TFTF, g-TFFT, f R g-TFFT + */ + @Test + public void testReleaseOnInfinitePath() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE }); + + // Loop entry = 0 + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.INFINITE, 0, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.INFINITE, 0, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator releaseOperator = new CounterExampleRelease( + PathType.INFINITE, 0, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = releaseOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = releaseOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = releaseOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 0); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 0); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(3).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 0 })); + + // Loop entry = 1 + // create first argument + firstArgument = new CounterExamplePredicate(PathType.INFINITE, 1, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate(PathType.INFINITE, 1, + secondArgumentValues); + + // create an operator + releaseOperator = new CounterExampleRelease(PathType.INFINITE, 1, + firstArgument, secondArgument); + + // check result values + values = releaseOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + firstHighlightedPositions = releaseOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = releaseOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 0); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 0); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 1 })); + + // Loop entry = 2 + // create first argument + firstArgument = new CounterExamplePredicate("", PathType.INFINITE, 2, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate("", PathType.INFINITE, 2, + secondArgumentValues); + + // create an operator + releaseOperator = new CounterExampleRelease(PathType.INFINITE, 2, + firstArgument, secondArgument); + + // check result values + values = releaseOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + firstHighlightedPositions = releaseOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = releaseOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 0); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 0); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 2 })); + + // Loop entry = 3 + // create first argument + firstArgument = new CounterExamplePredicate("", PathType.INFINITE, 3, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate("", PathType.INFINITE, 3, + secondArgumentValues); + + // create an operator + releaseOperator = new CounterExampleRelease(PathType.INFINITE, 3, + firstArgument, secondArgument); + + // check result values + values = releaseOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + firstHighlightedPositions = releaseOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = releaseOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 0); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 0); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-UUUT, g-TTTT, f R g-TTTT + */ + @Test + public void testReleaseTrueDefinitionOnReducedPath() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.REDUCED, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.REDUCED, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator releaseOperator = new CounterExampleRelease( + PathType.REDUCED, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = releaseOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = releaseOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = releaseOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(0).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2, 3 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(1).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2, 3 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-FFFT, g-TTTF, f R g-FFFF + */ + @Test + public void testReleaseFalseDefinitionOnReducedPath() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.REDUCED, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.REDUCED, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator releaseOperator = new CounterExampleRelease( + PathType.REDUCED, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = releaseOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = releaseOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = releaseOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 0); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-FUTU, g-UTUU, f R g-UTTU + */ + @Test + public void testReleaseUnknownDefinitionOnReducedPath1() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE, + CounterExampleValueType.UNDEFINED }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.REDUCED, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.REDUCED, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator releaseOperator = new CounterExampleRelease( + PathType.REDUCED, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = releaseOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(1) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(2) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(3) == CounterExampleValueType.UNDEFINED); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = releaseOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = releaseOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2 })); + assertTrue(secondHighlightedPositions.get(0).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2 })); + assertTrue(secondHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-FUUU, g-UTFU, f R g-UUFU + */ + @Test + public void testReleaseUnknownDefinitionOnReducedPath2() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.UNDEFINED }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.REDUCED, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.REDUCED, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator releaseOperator = new CounterExampleRelease( + PathType.REDUCED, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = releaseOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(1) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.UNDEFINED); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = releaseOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = releaseOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1 })); + assertTrue(secondHighlightedPositions.get(0).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 0); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-FUUU, g-UTUU, f R g-UUUU + */ + @Test + public void testReleaseUnknownDefinitionOnReducedPath3() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.REDUCED, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.REDUCED, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator releaseOperator = new CounterExampleRelease( + PathType.REDUCED, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = releaseOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(1) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(2) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(3) == CounterExampleValueType.UNDEFINED); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = releaseOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = releaseOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2 })); + assertTrue(secondHighlightedPositions.get(0).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2 })); + assertTrue(secondHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-FFFF, g-TTTT, f R g-UUUU + */ + @Test + public void testReleaseUnknownDefinitionOnReducedPath4() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.REDUCED, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.REDUCED, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator releaseOperator = new CounterExampleRelease( + PathType.REDUCED, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = releaseOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(1) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(2) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(3) == CounterExampleValueType.UNDEFINED); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = releaseOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = releaseOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 4); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2, 3 })); + assertTrue(secondHighlightedPositions.get(0).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2, 3 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2, 3 })); + assertTrue(secondHighlightedPositions.get(1).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2, 3 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + assertTrue(secondHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-UUUU, g-UUUU, f R g-UUUU + */ + @Test + public void testReleaseUnknownDefinitionOnReducedPath5() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.REDUCED, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.REDUCED, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator releaseOperator = new CounterExampleRelease( + PathType.REDUCED, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = releaseOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(1) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(2) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(3) == CounterExampleValueType.UNDEFINED); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = releaseOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = releaseOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-UUTF, g-FTTT, f R g-FTTU + */ + @Test + public void testReleaseOnReducedPath() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.REDUCED, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.REDUCED, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator releaseOperator = new CounterExampleRelease( + PathType.REDUCED, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = releaseOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.UNDEFINED); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = releaseOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = releaseOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleSinceUnitTest.java b/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleSinceUnitTest.java new file mode 100644 index 0000000000000000000000000000000000000000..08b691cfa1c9708988e7d214a8edde8b25b2e558 --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleSinceUnitTest.java @@ -0,0 +1,2592 @@ +package de.prob.core.domainobjects.ltl.unittests; + +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +import de.prob.core.command.LtlCheckingCommand.PathType; +import de.prob.core.domainobjects.ltl.CounterExampleBinaryOperator; +import de.prob.core.domainobjects.ltl.CounterExamplePredicate; +import de.prob.core.domainobjects.ltl.CounterExampleProposition; +import de.prob.core.domainobjects.ltl.CounterExampleSince; +import de.prob.core.domainobjects.ltl.CounterExampleValueType; + +/** + * Unit test for a "Since" operator. + * + * @author Andriy Tolstoy + * + */ +public class CounterExampleSinceUnitTest { + /* + * f-FTTT, g-TFFF, f S g-TTTT + */ + @Test + public void testSinceTrueDefinitionOnFinitePath() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.FINITE, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.FINITE, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator sinceOperator = new CounterExampleSince( + PathType.FINITE, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = sinceOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = sinceOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = sinceOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 0 })); + } + + /* + * f-FFTT, g-TFFF, f S g-TFFF + */ + @Test + public void testSinceFalseDefinitionOnFinitePath1() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.FINITE, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.FINITE, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator sinceOperator = new CounterExampleSince( + PathType.FINITE, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = sinceOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = sinceOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = sinceOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(3).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1 })); + } + + /* + * f-FTTT, g-FFFF, f S g-FFFF + */ + @Test + public void testSinceFalseDefinitionOnFinitePath2() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.FINITE, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.FINITE, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator sinceOperator = new CounterExampleSince( + PathType.FINITE, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = sinceOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = sinceOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = sinceOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + } + + /* + * f-TTTT, g-FFFF, f S g-FFFF + */ + @Test + public void testSinceFalseDefinitionOnFinitePath3() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.FINITE, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.FINITE, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator sinceOperator = new CounterExampleSince( + PathType.FINITE, -1, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = sinceOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = sinceOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = sinceOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + assertTrue(secondHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + assertTrue(secondHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + assertTrue(secondHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + } + + /* + * f - TFFT g - FTFF f S g - FTFF + */ + @Test + public void testSinceOnFinitePath() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.FINITE, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.FINITE, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator sinceOperator = new CounterExampleSince( + PathType.FINITE, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = sinceOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = sinceOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = sinceOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 0); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(3).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2 })); + } + + /* + * f-FTTT, g-TFFF, f S g-TTTT + */ + @Test + public void testSinceTrueDefinitionOnInfinitePath() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // Loop entry = 0 + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.INFINITE, 0, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.INFINITE, 0, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator sinceOperator = new CounterExampleSince( + PathType.INFINITE, 0, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = sinceOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = sinceOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = sinceOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 0 })); + + // Loop entry = 1 + // create first argument + firstArgument = new CounterExamplePredicate("", PathType.INFINITE, 1, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate("", PathType.INFINITE, 1, + secondArgumentValues); + + // create an operator + sinceOperator = new CounterExampleSince(PathType.INFINITE, 1, + firstArgument, secondArgument); + + // check result values + values = sinceOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + firstHighlightedPositions = sinceOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = sinceOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 0 })); + + // Loop entry = 2 + // create first argument + firstArgument = new CounterExamplePredicate("", PathType.INFINITE, 2, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate("", PathType.INFINITE, 2, + secondArgumentValues); + + // create an operator + sinceOperator = new CounterExampleSince(PathType.INFINITE, 2, + firstArgument, secondArgument); + + // check result values + values = sinceOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + firstHighlightedPositions = sinceOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = sinceOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 0 })); + + // Loop entry = 3 + // create first argument + firstArgument = new CounterExamplePredicate("", PathType.INFINITE, 3, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate("", PathType.INFINITE, 3, + secondArgumentValues); + + // create an operator + sinceOperator = new CounterExampleSince(PathType.INFINITE, 3, + firstArgument, secondArgument); + + // check result values + values = sinceOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + firstHighlightedPositions = sinceOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = sinceOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 0 })); + } + + /* + * f-FFTT, g-TFFF, f S g-TFFF + */ + @Test + public void testSinceFalseDefinitionOnInfinitePath1() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // Loop entry = 0 + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.INFINITE, 0, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.INFINITE, 0, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator sinceOperator = new CounterExampleSince( + PathType.INFINITE, 0, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = sinceOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = sinceOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = sinceOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(3).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1 })); + + // Loop entry = 1 + // create first argument + firstArgument = new CounterExamplePredicate("", PathType.INFINITE, 1, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate("", PathType.INFINITE, 1, + secondArgumentValues); + + // create an operator + sinceOperator = new CounterExampleSince(PathType.INFINITE, 1, + firstArgument, secondArgument); + + // check result values + values = sinceOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + firstHighlightedPositions = sinceOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = sinceOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(3).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1 })); + + // Loop entry = 2 + // create first argument + firstArgument = new CounterExamplePredicate("", PathType.INFINITE, 2, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate("", PathType.INFINITE, 2, + secondArgumentValues); + + // create an operator + sinceOperator = new CounterExampleSince(PathType.INFINITE, 2, + firstArgument, secondArgument); + + // check result values + values = sinceOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + firstHighlightedPositions = sinceOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = sinceOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(3).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1 })); + + // Loop entry = 3 + // create first argument + firstArgument = new CounterExamplePredicate("", PathType.INFINITE, 3, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate("", PathType.INFINITE, 3, + secondArgumentValues); + + // create an operator + sinceOperator = new CounterExampleSince(PathType.INFINITE, 3, + firstArgument, secondArgument); + + // check result values + values = sinceOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + firstHighlightedPositions = sinceOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = sinceOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(3).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1 })); + } + + /* + * f-FTTT, g-FFFF, f S g-FFFF + */ + @Test + public void testSinceFalseDefinitionOnInfinitePath2() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // Loop entry = 0 + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.INFINITE, 0, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.INFINITE, 0, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator sinceOperator = new CounterExampleSince( + PathType.INFINITE, 0, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = sinceOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = sinceOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = sinceOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + + // Loop entry = 1 + // create first argument + firstArgument = new CounterExamplePredicate("", PathType.INFINITE, 1, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate("", PathType.INFINITE, 1, + secondArgumentValues); + + // create an operator + sinceOperator = new CounterExampleSince(PathType.INFINITE, 1, + firstArgument, secondArgument); + + // check result values + values = sinceOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + firstHighlightedPositions = sinceOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = sinceOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + + // Loop entry = 2 + // create first argument + firstArgument = new CounterExamplePredicate("", PathType.INFINITE, 2, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate("", PathType.INFINITE, 2, + secondArgumentValues); + + // create an operator + sinceOperator = new CounterExampleSince(PathType.INFINITE, 2, + firstArgument, secondArgument); + + // check result values + values = sinceOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + firstHighlightedPositions = sinceOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = sinceOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + + // Loop entry = 3 + // create first argument + firstArgument = new CounterExamplePredicate("", PathType.INFINITE, 3, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate("", PathType.INFINITE, 3, + secondArgumentValues); + + // create an operator + sinceOperator = new CounterExampleSince(PathType.INFINITE, 3, + firstArgument, secondArgument); + + // check result values + values = sinceOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + firstHighlightedPositions = sinceOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = sinceOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + } + + /* + * f-TTTT, g-FFFF, f S g-FFFF + */ + @Test + public void testSinceFalseDefinitionOnInfinitePath3() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // Loop entry = 0 + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.INFINITE, 0, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.INFINITE, 0, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator sinceOperator = new CounterExampleSince( + PathType.INFINITE, 0, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = sinceOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = sinceOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = sinceOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + assertTrue(secondHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + assertTrue(secondHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + assertTrue(secondHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + + // Loop entry = 1 + // create first argument + firstArgument = new CounterExamplePredicate("", PathType.INFINITE, 1, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate("", PathType.INFINITE, 1, + secondArgumentValues); + + // create an operator + sinceOperator = new CounterExampleSince(PathType.INFINITE, 1, + firstArgument, secondArgument); + + // check result values + values = sinceOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + firstHighlightedPositions = sinceOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = sinceOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + assertTrue(secondHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + assertTrue(secondHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + assertTrue(secondHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + + // Loop entry = 2 + // create first argument + firstArgument = new CounterExamplePredicate("", PathType.INFINITE, 2, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate("", PathType.INFINITE, 2, + secondArgumentValues); + + // create an operator + sinceOperator = new CounterExampleSince(PathType.INFINITE, 2, + firstArgument, secondArgument); + + // check result values + values = sinceOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + firstHighlightedPositions = sinceOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = sinceOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + assertTrue(secondHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + assertTrue(secondHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + assertTrue(secondHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + + // Loop entry = 3 + // create first argument + firstArgument = new CounterExamplePredicate("", PathType.INFINITE, 3, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate("", PathType.INFINITE, 3, + secondArgumentValues); + + // create an operator + sinceOperator = new CounterExampleSince(PathType.INFINITE, 3, + firstArgument, secondArgument); + + // check result values + values = sinceOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + firstHighlightedPositions = sinceOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = sinceOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + assertTrue(secondHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + assertTrue(secondHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + assertTrue(secondHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + } + + /* + * f-FTTT, g-TFFF, f S g-TTTT + */ + @Test + public void testSinceTrueDefinitionOnReducedPath() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.REDUCED, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.REDUCED, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator sinceOperator = new CounterExampleSince( + PathType.REDUCED, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = sinceOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = sinceOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = sinceOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 0 })); + } + + /* + * f-FFTT, g-TFFF, f S g-TFFF + */ + @Test + public void testSinceFalseDefinitionOnReducedPath1() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.REDUCED, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.REDUCED, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator sinceOperator = new CounterExampleSince( + PathType.REDUCED, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = sinceOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = sinceOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = sinceOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(3).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1 })); + } + + /* + * f-FTTT, g-FFFF, f S g-FFFF + */ + @Test + public void testSinceFalseDefinitionOnReducedPath2() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.REDUCED, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.REDUCED, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator sinceOperator = new CounterExampleSince( + PathType.REDUCED, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = sinceOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = sinceOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = sinceOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + } + + /* + * f-TTTT, g-FFFF, f S g-FFFF + */ + @Test + public void testSinceFalseDefinitionOnReducedPath3() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.REDUCED, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.REDUCED, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator sinceOperator = new CounterExampleSince( + PathType.REDUCED, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = sinceOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = sinceOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = sinceOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + assertTrue(secondHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + assertTrue(secondHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + assertTrue(secondHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + } + + /* + * f-UUTU, g-UTUF, f S g-UTTU + */ + @Test + public void testSinceUnknownDefinitionOnReducedPath1() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE, + CounterExampleValueType.UNDEFINED }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.FALSE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.REDUCED, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.REDUCED, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator sinceOperator = new CounterExampleSince( + PathType.REDUCED, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = sinceOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.UNDEFINED); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = sinceOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = sinceOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 0); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2 })); + assertTrue(secondHighlightedPositions.get(3).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1 })); + } + + /* + * f-UFUU, g-UUFF, f S g-UUUU + */ + @Test + public void testSinceUnknownDefinitionOnReducedPath2() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.FALSE, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.REDUCED, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.REDUCED, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator sinceOperator = new CounterExampleSince( + PathType.REDUCED, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = sinceOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(1) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(2) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(3) == CounterExampleValueType.UNDEFINED); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = sinceOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = sinceOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1 })); + assertTrue(secondHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1 })); + assertTrue(secondHighlightedPositions.get(3).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1 })); + } + + /* + * f-UUTU, g-UUUF, f S g-UUUU + */ + @Test + public void testSinceUnknownDefinitionOnReducedPath3() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE, + CounterExampleValueType.UNDEFINED }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.FALSE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.REDUCED, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.REDUCED, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator sinceOperator = new CounterExampleSince( + PathType.REDUCED, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = sinceOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(1) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(2) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(3) == CounterExampleValueType.UNDEFINED); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = sinceOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = sinceOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1 })); + assertTrue(secondHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1 })); + assertTrue(secondHighlightedPositions.get(3).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1 })); + } + + /* + * f-UUUU, g-UUUU, f S g-UUUU + */ + @Test + public void testSinceUnknownDefinitionOnReducedPath4() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.REDUCED, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.REDUCED, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator sinceOperator = new CounterExampleSince( + PathType.REDUCED, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = sinceOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(1) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(2) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(3) == CounterExampleValueType.UNDEFINED); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = sinceOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = sinceOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-TTTT, g-UUUU, f S g-UUUU + */ + @Test + public void testSinceUnknownDefinitionOnReducedPath5() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.REDUCED, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.REDUCED, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator sinceOperator = new CounterExampleSince( + PathType.REDUCED, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = sinceOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(1) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(2) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(3) == CounterExampleValueType.UNDEFINED); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = sinceOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = sinceOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + assertTrue(secondHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + assertTrue(secondHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + assertTrue(secondHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + } + + // FIXME atolstoy + /* + * // f-UUFU, g-TUFU, f S g-TUFU + * + * @Test public void testSinceOnReducedPath() { // create first argument + * values List<CounterExampleValueType> firstArgumentValues = Arrays + * .asList(new CounterExampleValueType[] { + * CounterExampleValueType.UNDEFINED, CounterExampleValueType.UNDEFINED, + * CounterExampleValueType.FALSE, CounterExampleValueType.UNDEFINED }); + * + * // create second argument values List<CounterExampleValueType> + * secondArgumentValues = Arrays .asList(new CounterExampleValueType[] { + * CounterExampleValueType.TRUE, CounterExampleValueType.UNDEFINED, + * CounterExampleValueType.FALSE, CounterExampleValueType.UNDEFINED }); + * + * // create first argument CounterExampleProposition firstArgument = new + * CounterExamplePredicate( PathType.FINITE, firstArgumentValues); + * + * // create second argument CounterExampleProposition secondArgument = new + * CounterExamplePredicate( PathType.FINITE, secondArgumentValues); + * + * // create an operator CounterExampleBinaryOperator sinceOperator = new + * CounterExampleSince( PathType.FINITE, firstArgument, secondArgument); + * + * // check result values List<CounterExampleValueType> values = + * sinceOperator.getValues(); assertTrue(values.size() == + * firstArgumentValues.size()); assertTrue(values.size() == + * secondArgumentValues.size()); assertTrue(values.get(0) == + * CounterExampleValueType.TRUE); assertTrue(values.get(1) == + * CounterExampleValueType.UNDEFINED); assertTrue(values.get(2) == + * CounterExampleValueType.FALSE); assertTrue(values.get(3) == + * CounterExampleValueType.UNDEFINED); + * + * // check highlighted positions List<List<Integer>> + * firstHighlightedPositions = sinceOperator + * .getFirstHighlightedPositions(); List<List<Integer>> + * secondHighlightedPositions = sinceOperator + * .getSecondHighlightedPositions(); + * assertTrue(firstHighlightedPositions.size() == firstArgumentValues + * .size()); assertTrue(secondHighlightedPositions.size() == + * secondArgumentValues .size()); + * + * // State 0 assertTrue(firstHighlightedPositions.get(0).size() == 0); + * assertTrue(secondHighlightedPositions.get(0).size() == 1); + * assertTrue(Arrays.equals( secondHighlightedPositions.get(0).toArray(new + * Integer[0]), new Integer[] { 0 })); + * + * // State 1 assertTrue(firstHighlightedPositions.get(1).size() == 1); + * assertTrue(Arrays.equals( firstHighlightedPositions.get(1).toArray(new + * Integer[0]), new Integer[] { 1 })); + * assertTrue(secondHighlightedPositions.get(1).size() == 1); + * assertTrue(Arrays.equals( secondHighlightedPositions.get(1).toArray(new + * Integer[0]), new Integer[] { 1 })); + * + * // State 2 assertTrue(firstHighlightedPositions.get(2).size() == 1); + * assertTrue(Arrays.equals( firstHighlightedPositions.get(2).toArray(new + * Integer[0]), new Integer[] { 2 })); + * assertTrue(secondHighlightedPositions.get(2).size() == 1); + * assertTrue(Arrays.equals( secondHighlightedPositions.get(2).toArray(new + * Integer[0]), new Integer[] { 2 })); + * + * // State 3 assertTrue(firstHighlightedPositions.get(3).size() == 1); + * assertTrue(Arrays.equals( firstHighlightedPositions.get(3).toArray(new + * Integer[0]), new Integer[] { 3 })); + * assertTrue(secondHighlightedPositions.get(3).size() == 1); + * assertTrue(Arrays.equals( secondHighlightedPositions.get(3).toArray(new + * Integer[0]), new Integer[] { 3 })); } + */ +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleTriggerUnitTest.java b/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleTriggerUnitTest.java new file mode 100644 index 0000000000000000000000000000000000000000..725ab55b9e47ae38c99dc8cefcfe5d371158532f --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleTriggerUnitTest.java @@ -0,0 +1,2613 @@ +package de.prob.core.domainobjects.ltl.unittests; + +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +import de.prob.core.command.LtlCheckingCommand.PathType; +import de.prob.core.domainobjects.ltl.CounterExampleBinaryOperator; +import de.prob.core.domainobjects.ltl.CounterExamplePredicate; +import de.prob.core.domainobjects.ltl.CounterExampleProposition; +import de.prob.core.domainobjects.ltl.CounterExampleTrigger; +import de.prob.core.domainobjects.ltl.CounterExampleValueType; + +/** + * Unit test for a "Trigger" operator. + * + * @author Andriy Tolstoy + * + */ +public class CounterExampleTriggerUnitTest { + /* + * f-TFFF, g-TTTT, f T g-TTTT + */ + @Test + public void testTriggerTrueDefinitionOnFinitePath1() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.FINITE, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.FINITE, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator triggerOperator = new CounterExampleTrigger( + PathType.FINITE, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = triggerOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = triggerOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = triggerOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + } + + /* + * f-FFFF, g-TTTT, f T g-TTTT + */ + @Test + public void testTriggerTrueDefinitionOnFinitePath2() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.FINITE, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.FINITE, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator triggerOperator = new CounterExampleTrigger( + PathType.FINITE, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = triggerOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = triggerOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = triggerOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + assertTrue(secondHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + assertTrue(secondHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + assertTrue(secondHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + } + + /* + * f-TFFF, g-FTTT, f T g-FFFF + */ + @Test + public void testTriggerFalseDefinitionOnFinitePath1() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.FINITE, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.FINITE, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator triggerOperator = new CounterExampleTrigger( + PathType.FINITE, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = triggerOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = triggerOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = triggerOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 0 })); + } + + /* + * f-FFFF, g-FTTT, f T g-FFFF + */ + @Test + public void testTriggerFalseDefinitionOnFinitePath2() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.FINITE, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.FINITE, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator triggerOperator = new CounterExampleTrigger( + PathType.FINITE, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = triggerOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = triggerOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = triggerOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 0 })); + } + + /* + * f-FTTF, g-TTFT, f T g-TTFF + */ + @Test + public void testTriggerOnFinitePath() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.FINITE, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.FINITE, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator triggerOperator = new CounterExampleTrigger( + PathType.FINITE, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = triggerOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = triggerOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = triggerOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 0); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 2 })); + } + + /* + * f-TFFF, g-TTTT, f T g-TTTT + */ + @Test + public void testTriggerTrueDefinitionOnInfinitePath1() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // Loop entry = 0 + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.INFINITE, 0, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.INFINITE, 0, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator triggerOperator = new CounterExampleTrigger( + PathType.INFINITE, 0, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = triggerOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = triggerOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = triggerOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + + // Loop entry = 1 + // create first argument + firstArgument = new CounterExamplePredicate(PathType.INFINITE, 1, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate(PathType.INFINITE, 1, + secondArgumentValues); + + // create an operator + triggerOperator = new CounterExampleTrigger(PathType.INFINITE, 1, + firstArgument, secondArgument); + + // check result values + values = triggerOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + firstHighlightedPositions = triggerOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = triggerOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + + // Loop entry = 2 + // create first argument + firstArgument = new CounterExamplePredicate(PathType.INFINITE, 2, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate(PathType.INFINITE, 2, + secondArgumentValues); + + // create an operator + triggerOperator = new CounterExampleTrigger(PathType.INFINITE, 2, + firstArgument, secondArgument); + + // check result values + values = triggerOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + firstHighlightedPositions = triggerOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = triggerOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + + // Loop entry = 3 + // create first argument + firstArgument = new CounterExamplePredicate("", PathType.INFINITE, 3, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate("", PathType.INFINITE, 3, + secondArgumentValues); + + // create an operator + triggerOperator = new CounterExampleTrigger(PathType.INFINITE, 3, + firstArgument, secondArgument); + + // check result values + values = triggerOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + firstHighlightedPositions = triggerOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = triggerOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + } + + /* + * f-FFFF, g-TTTT, f T g-TTTT + */ + @Test + public void testTriggerTrueDefinitionOnInfinitePath2() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // Loop entry = 0 + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.INFINITE, 0, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.INFINITE, 0, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator triggerOperator = new CounterExampleTrigger( + PathType.INFINITE, 0, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = triggerOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = triggerOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = triggerOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + assertTrue(secondHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + assertTrue(secondHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + assertTrue(secondHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + + // Loop entry = 1 + // create first argument + firstArgument = new CounterExamplePredicate(PathType.INFINITE, 1, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate(PathType.INFINITE, 1, + secondArgumentValues); + + // create an operator + triggerOperator = new CounterExampleTrigger(PathType.INFINITE, 1, + firstArgument, secondArgument); + + // check result values + values = triggerOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + firstHighlightedPositions = triggerOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = triggerOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + assertTrue(secondHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + assertTrue(secondHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + assertTrue(secondHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + + // Loop entry = 2 + // create first argument + firstArgument = new CounterExamplePredicate(PathType.INFINITE, 2, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate(PathType.INFINITE, 2, + secondArgumentValues); + + // create an operator + triggerOperator = new CounterExampleTrigger(PathType.INFINITE, 2, + firstArgument, secondArgument); + + // check result values + values = triggerOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + firstHighlightedPositions = triggerOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = triggerOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + assertTrue(secondHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + assertTrue(secondHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + assertTrue(secondHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + + // Loop entry = 3 + // create first argument + firstArgument = new CounterExamplePredicate("", PathType.INFINITE, 3, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate("", PathType.INFINITE, 3, + secondArgumentValues); + + // create an operator + triggerOperator = new CounterExampleTrigger(PathType.INFINITE, 3, + firstArgument, secondArgument); + + // check result values + values = triggerOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + firstHighlightedPositions = triggerOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = triggerOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + assertTrue(secondHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + assertTrue(secondHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + assertTrue(secondHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + } + + /* + * f-TFFF, g-FTTT, f T g-FFFF + */ + @Test + public void testTriggerFalseDefinitionOnInfinitePath1() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // Loop entry = 0 + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.INFINITE, 0, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.INFINITE, 0, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator triggerOperator = new CounterExampleTrigger( + PathType.INFINITE, 0, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = triggerOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = triggerOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = triggerOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 0 })); + + // Loop entry = 1 + // create first argument + firstArgument = new CounterExamplePredicate(PathType.INFINITE, 1, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate(PathType.INFINITE, 1, + secondArgumentValues); + + // create an operator + triggerOperator = new CounterExampleTrigger(PathType.INFINITE, 1, + firstArgument, secondArgument); + + // check result values + values = triggerOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + firstHighlightedPositions = triggerOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = triggerOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 0 })); + + // Loop entry = 2 + // create first argument + firstArgument = new CounterExamplePredicate(PathType.INFINITE, 2, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate(PathType.INFINITE, 2, + secondArgumentValues); + + // create an operator + triggerOperator = new CounterExampleTrigger(PathType.INFINITE, 2, + firstArgument, secondArgument); + + // check result values + values = triggerOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + firstHighlightedPositions = triggerOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = triggerOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 0 })); + + // Loop entry = 3 + // create first argument + firstArgument = new CounterExamplePredicate("", PathType.INFINITE, 3, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate("", PathType.INFINITE, 3, + secondArgumentValues); + + // create an operator + triggerOperator = new CounterExampleTrigger(PathType.INFINITE, 3, + firstArgument, secondArgument); + + // check result values + values = triggerOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + firstHighlightedPositions = triggerOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = triggerOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 0 })); + } + + /* + * f-FFFF, g-FTTT, f T g-FFFF + */ + @Test + public void testTriggerFalseDefinitionOnInfinitePath2() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // Loop entry = 0 + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.INFINITE, 0, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.INFINITE, 0, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator triggerOperator = new CounterExampleTrigger( + PathType.INFINITE, 0, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = triggerOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = triggerOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = triggerOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 0 })); + + // Loop entry = 1 + // create first argument + firstArgument = new CounterExamplePredicate(PathType.INFINITE, 1, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate(PathType.INFINITE, 1, + secondArgumentValues); + + // create an operator + triggerOperator = new CounterExampleTrigger(PathType.INFINITE, 1, + firstArgument, secondArgument); + + // check result values + values = triggerOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + firstHighlightedPositions = triggerOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = triggerOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 0 })); + + // Loop entry = 2 + // create first argument + firstArgument = new CounterExamplePredicate(PathType.INFINITE, 2, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate(PathType.INFINITE, 2, + secondArgumentValues); + + // create an operator + triggerOperator = new CounterExampleTrigger(PathType.INFINITE, 2, + firstArgument, secondArgument); + + // check result values + values = triggerOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + firstHighlightedPositions = triggerOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = triggerOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 0 })); + + // Loop entry = 3 + // create first argument + firstArgument = new CounterExamplePredicate("", PathType.INFINITE, 3, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate("", PathType.INFINITE, 3, + secondArgumentValues); + + // create an operator + triggerOperator = new CounterExampleTrigger(PathType.INFINITE, 3, + firstArgument, secondArgument); + + // check result values + values = triggerOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + firstHighlightedPositions = triggerOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = triggerOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 0 })); + } + + /* + * f-TFFF, g-TTTT, f T g-TTTT + */ + @Test + public void testTriggerTrueDefinitionOnReducedPath1() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.REDUCED, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.REDUCED, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator triggerOperator = new CounterExampleTrigger( + PathType.REDUCED, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = triggerOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = triggerOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = triggerOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + } + + /* + * f-FFFF, g-TTTT, f T g-TTTT + */ + @Test + public void testTriggerTrueDefinitionOnReducedPath2() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.REDUCED, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.REDUCED, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator triggerOperator = new CounterExampleTrigger( + PathType.REDUCED, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = triggerOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = triggerOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = triggerOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + assertTrue(secondHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + assertTrue(secondHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + assertTrue(secondHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + } + + /* + * f-TFFF, g-FTTT, f T g-FFFF + */ + @Test + public void testTriggerFalseDefinitionOnReducedPath1() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.REDUCED, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.REDUCED, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator triggerOperator = new CounterExampleTrigger( + PathType.REDUCED, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = triggerOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = triggerOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = triggerOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 0 })); + } + + /* + * f-FFFF, g-FTTT, f T g-FFFF + */ + @Test + public void testTriggerFalseDefinitionOnReducedPath2() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.REDUCED, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.REDUCED, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator triggerOperator = new CounterExampleTrigger( + PathType.REDUCED, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = triggerOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = triggerOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = triggerOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 0 })); + } + + /* + * f-UTUF, g-UUTU, f T g-UTTU + */ + @Test + public void testTriggerUnknownDefinitionOnReducedPath1() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE, + CounterExampleValueType.UNDEFINED }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.REDUCED, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.REDUCED, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator triggerOperator = new CounterExampleTrigger( + PathType.REDUCED, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = triggerOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(1) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(2) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(3) == CounterExampleValueType.UNDEFINED); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = triggerOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = triggerOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1 })); + assertTrue(secondHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1 })); + assertTrue(secondHighlightedPositions.get(3).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1 })); + } + + /* + * f-UUUF, g-UFTU, f T g-UFFU + */ + @Test + public void testTriggerUnknownDefinitionOnReducedPath2() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.UNDEFINED }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.REDUCED, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.REDUCED, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator triggerOperator = new CounterExampleTrigger( + PathType.REDUCED, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = triggerOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(3) == CounterExampleValueType.UNDEFINED); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = triggerOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = triggerOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 0); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2 })); + assertTrue(secondHighlightedPositions.get(3).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1 })); + } + + /* + * f-UUUF, g-UUTU, f T g-UUUU + */ + @Test + public void testTriggerUnknownDefinitionOnReducedPath3() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE, + CounterExampleValueType.UNDEFINED }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.REDUCED, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.REDUCED, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator triggerOperator = new CounterExampleTrigger( + PathType.REDUCED, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = triggerOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(1) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(2) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(3) == CounterExampleValueType.UNDEFINED); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = triggerOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = triggerOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1 })); + assertTrue(secondHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1 })); + assertTrue(secondHighlightedPositions.get(3).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1 })); + } + + /* + * f-FFFF, g-UUUU, f T g-UUUU + */ + @Test + public void testTriggerUnknownDefinitionOnReducedPath4() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.REDUCED, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.REDUCED, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator triggerOperator = new CounterExampleTrigger( + PathType.REDUCED, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = triggerOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(1) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(2) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(3) == CounterExampleValueType.UNDEFINED); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = triggerOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = triggerOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + assertTrue(secondHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 0 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + assertTrue(secondHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 1, 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + assertTrue(secondHighlightedPositions.get(3).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2, 1, 0 })); + } + + /* + * f-UUUU, g-UUUU, f T g-UUUU + */ + @Test + public void testTriggerUnknownDefinitionOnReducedPath5() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.REDUCED, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.REDUCED, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator triggerOperator = new CounterExampleTrigger( + PathType.REDUCED, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = triggerOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(1) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(2) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(3) == CounterExampleValueType.UNDEFINED); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = triggerOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = triggerOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-FUTF, g-UUTF, f T g-UUTF + */ + @Test + public void testTriggerOnReducedPath() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + PathType.REDUCED, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + PathType.REDUCED, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator triggerOperator = new CounterExampleTrigger( + PathType.REDUCED, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = triggerOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(1) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = triggerOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = triggerOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 0); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleUntilUnitTest.java b/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleUntilUnitTest.java new file mode 100644 index 0000000000000000000000000000000000000000..dc066a97b026ed1712065cc85fad817cf99a54c1 --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleUntilUnitTest.java @@ -0,0 +1,1602 @@ +package de.prob.core.domainobjects.ltl.unittests; + +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +import de.prob.core.command.LtlCheckingCommand.PathType; +import de.prob.core.domainobjects.ltl.CounterExampleBinaryOperator; +import de.prob.core.domainobjects.ltl.CounterExamplePredicate; +import de.prob.core.domainobjects.ltl.CounterExampleProposition; +import de.prob.core.domainobjects.ltl.CounterExampleUntil; +import de.prob.core.domainobjects.ltl.CounterExampleValueType; + +/** + * Unit test for an "Until" operator. + * + * @author Andriy Tolstoy + * + */ +public class CounterExampleUntilUnitTest { + /* + * f-TTTF, g-FFFT, f U g-TTTT + */ + @Test + public void testUntilOnFinitePathTrueDefinition() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.FINITE, -1, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.FINITE, -1, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator untilOperator = new CounterExampleUntil( + PathType.FINITE, -1, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = untilOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = untilOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = untilOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 0); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-TTTF, g-FFFF, f U g-FFFF + */ + @Test + public void testUntilOnFinitePathFalseDefinition1() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.FINITE, -1, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.FINITE, -1, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator untilOperator = new CounterExampleUntil( + PathType.FINITE, -1, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = untilOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = untilOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = untilOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(0).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2, 3 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(1).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2, 3 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-TTFF, g-FFFT, f U g-FFFT + */ + @Test + public void testUntilOnFinitePathFalseDefinition2() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.FINITE, -1, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.FINITE, -1, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator untilOperator = new CounterExampleUntil( + PathType.FINITE, -1, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = untilOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = untilOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = untilOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(0).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 0); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-TTTT, g-FFFF, f U g-FFFF + */ + @Test + public void testUntilOnFinitePathFalseDefinition3() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.FINITE, -1, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.FINITE, -1, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator untilOperator = new CounterExampleUntil( + PathType.FINITE, -1, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = untilOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = untilOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = untilOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 4); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2, 3 })); + assertTrue(secondHighlightedPositions.get(0).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2, 3 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2, 3 })); + assertTrue(secondHighlightedPositions.get(1).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2, 3 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + assertTrue(secondHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f - TFFT g - FTFF f U g - TTFF + */ + @Test + public void testUntilOnFinitePath() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.FINITE, -1, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.FINITE, -1, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator untilOperator = new CounterExampleUntil( + PathType.FINITE, -1, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = untilOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = untilOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = untilOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 0); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f - TFFT g - FTFF + */ + @Test + public void testUntilOnInfinitePath() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // Loop entry = 0 + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.INFINITE, 0, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.INFINITE, 0, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator untilOperator = new CounterExampleUntil( + PathType.INFINITE, 0, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = untilOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = untilOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = untilOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 0); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 0 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 1 })); + + // Loop entry = 1 + // create first argument + firstArgument = new CounterExamplePredicate("", PathType.INFINITE, 1, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate("", PathType.INFINITE, 1, + secondArgumentValues); + + // create an operator + untilOperator = new CounterExampleUntil(PathType.INFINITE, 1, + firstArgument, secondArgument); + + // check result values + values = untilOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + firstHighlightedPositions = untilOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = untilOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 0); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 1 })); + + // Loop entry = 2 + // create first argument + firstArgument = new CounterExamplePredicate("", PathType.INFINITE, 2, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate("", PathType.INFINITE, 2, + secondArgumentValues); + + // create an operator + untilOperator = new CounterExampleUntil(PathType.INFINITE, 2, + firstArgument, secondArgument); + + // check result values + values = untilOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + firstHighlightedPositions = untilOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = untilOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 0); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(3).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2 })); + + // Loop entry = 3 + // create first argument + firstArgument = new CounterExamplePredicate("", PathType.INFINITE, 3, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate("", PathType.INFINITE, 3, + secondArgumentValues); + + // create an operator + untilOperator = new CounterExampleUntil(PathType.INFINITE, 3, + firstArgument, secondArgument); + + // check result values + values = untilOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + firstHighlightedPositions = untilOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = untilOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 0); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-TTTU, g-UUUT, f U g-TTTT + */ + @Test + public void testUntilOnReducedPathTrueDefinition() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.UNDEFINED }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.REDUCED, -1, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.REDUCED, -1, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator untilOperator = new CounterExampleUntil( + PathType.REDUCED, -1, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = untilOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = untilOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = untilOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 0); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-UUFU, g-FFFT, f U g-FFFT + */ + @Test + public void testUntilOnReducedPathFalseDefinition1() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.FALSE, + CounterExampleValueType.UNDEFINED }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.REDUCED, -1, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.REDUCED, -1, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator untilOperator = new CounterExampleUntil( + PathType.REDUCED, -1, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = untilOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = untilOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = untilOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(0).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 0); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-UUUF, g-FFFF, f U g-FFFF + */ + @Test + public void testUntilOnReducedPathFalseDefinition2() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.REDUCED, -1, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.REDUCED, -1, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator untilOperator = new CounterExampleUntil( + PathType.REDUCED, -1, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = untilOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = untilOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = untilOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(0).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2, 3 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(1).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2, 3 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-UTUU, g-FUTU, f U g-UTTU + */ + @Test + public void testUntilOnReducedPathUnknownDefinition1() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE, + CounterExampleValueType.UNDEFINED }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.REDUCED, -1, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.REDUCED, -1, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator untilOperator = new CounterExampleUntil( + PathType.REDUCED, -1, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = untilOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.UNDEFINED); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = untilOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = untilOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1 })); + assertTrue(secondHighlightedPositions.get(0).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 0); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-UUFU, g-FFUU, f U g-UUUU + */ + @Test + public void testUntilOnReducedPathUnknownDefinition2() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.FALSE, + CounterExampleValueType.UNDEFINED }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.REDUCED, -1, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.REDUCED, -1, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator untilOperator = new CounterExampleUntil( + PathType.REDUCED, -1, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = untilOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(1) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(2) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(3) == CounterExampleValueType.UNDEFINED); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = untilOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = untilOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2 })); + assertTrue(secondHighlightedPositions.get(0).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2 })); + assertTrue(secondHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-UTUU, g-FUUU, f U g-UUUU + */ + @Test + public void testUntilOnReducedPathUnknownDefinition3() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.REDUCED, -1, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.REDUCED, -1, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator untilOperator = new CounterExampleUntil( + PathType.REDUCED, -1, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = untilOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(1) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(2) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(3) == CounterExampleValueType.UNDEFINED); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = untilOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = untilOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2 })); + assertTrue(secondHighlightedPositions.get(0).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2 })); + assertTrue(secondHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-TTTT, g-FFFF, f U g-UUUU + */ + @Test + public void testUntilOnReducedPathUnknownDefinition4() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.REDUCED, -1, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.REDUCED, -1, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator untilOperator = new CounterExampleUntil( + PathType.REDUCED, -1, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = untilOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(1) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(2) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(3) == CounterExampleValueType.UNDEFINED); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = untilOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = untilOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 4); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2, 3 })); + assertTrue(secondHighlightedPositions.get(0).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2, 3 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2, 3 })); + assertTrue(secondHighlightedPositions.get(1).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2, 3 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + assertTrue(secondHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-UTUT, g-FUFU, f U g-UUUU + */ + @Test + public void testUntilOnReducedPathUnknownDefinition5() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.FALSE, + CounterExampleValueType.UNDEFINED }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.REDUCED, -1, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.REDUCED, -1, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator untilOperator = new CounterExampleUntil( + PathType.REDUCED, -1, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = untilOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(1) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(2) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(3) == CounterExampleValueType.UNDEFINED); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = untilOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = untilOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 4); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2, 3 })); + assertTrue(secondHighlightedPositions.get(0).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2, 3 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2, 3 })); + assertTrue(secondHighlightedPositions.get(1).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2, 3 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + assertTrue(secondHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f - UTFU g - FTFF f U g - UTFU + */ + @Test + public void testUntilOnReducedPath() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.UNDEFINED }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.REDUCED, -1, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.REDUCED, -1, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator untilOperator = new CounterExampleUntil( + PathType.REDUCED, -1, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = untilOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.UNDEFINED); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = untilOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = untilOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 0); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleWeakUntilUnitTest.java b/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleWeakUntilUnitTest.java new file mode 100644 index 0000000000000000000000000000000000000000..21c1bc63d12880a3c3cc8487d0e52e76a3fae562 --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleWeakUntilUnitTest.java @@ -0,0 +1,1413 @@ +package de.prob.core.domainobjects.ltl.unittests; + +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +import de.prob.core.command.LtlCheckingCommand.PathType; +import de.prob.core.domainobjects.ltl.CounterExampleBinaryOperator; +import de.prob.core.domainobjects.ltl.CounterExamplePredicate; +import de.prob.core.domainobjects.ltl.CounterExampleProposition; +import de.prob.core.domainobjects.ltl.CounterExampleValueType; +import de.prob.core.domainobjects.ltl.CounterExampleWeakUntil; + +public class CounterExampleWeakUntilUnitTest { + /* + * f-TTTF, g-FFFT, f U g-TTTT + */ + @Test + public void testWeakUntilOnFinitePathTrueDefinition1() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.FINITE, -1, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.FINITE, -1, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator weakUntilOperator = new CounterExampleWeakUntil( + PathType.FINITE, -1, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = weakUntilOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = weakUntilOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = weakUntilOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 0); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-TTTT, g-FFFF, f U g-TTTT + */ + @Test + public void testWeakUntilOnFinitePathTrueDefinition2() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.FINITE, -1, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.FINITE, -1, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator weakUntilOperator = new CounterExampleWeakUntil( + PathType.FINITE, -1, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = weakUntilOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = weakUntilOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = weakUntilOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 4); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2, 3 })); + assertTrue(secondHighlightedPositions.get(0).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2, 3 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2, 3 })); + assertTrue(secondHighlightedPositions.get(1).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2, 3 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + assertTrue(secondHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-TTTF, g-FFFF, f U g-FFFF + */ + @Test + public void testWeakUntilOnFinitePathFalseDefinition1() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.FINITE, -1, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.FINITE, -1, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator weakUntilOperator = new CounterExampleWeakUntil( + PathType.FINITE, -1, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = weakUntilOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = weakUntilOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = weakUntilOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(0).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2, 3 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(1).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2, 3 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-TTFF, g-FFFT, f U g-FFFT + */ + @Test + public void testWeakUntilOnFinitePathFalseDefinition2() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.FINITE, -1, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.FINITE, -1, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator weakUntilOperator = new CounterExampleWeakUntil( + PathType.FINITE, -1, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = weakUntilOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = weakUntilOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = weakUntilOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(0).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 0); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f - FFTT g - TFFF f U g - TFTT + */ + @Test + public void testWeakUntilOnFinitePath() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.FINITE, -1, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.FINITE, -1, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator weakUntilOperator = new CounterExampleWeakUntil( + PathType.FINITE, -1, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = weakUntilOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = weakUntilOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = weakUntilOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + assertTrue(secondHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f - FFTT g - TFFF + */ + @Test + public void testWeakUntilOnInfinitePath() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // Loop entry = 0 + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.INFINITE, 0, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.INFINITE, 0, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator weakUntilOperator = new CounterExampleWeakUntil( + PathType.INFINITE, 0, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = weakUntilOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = weakUntilOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = weakUntilOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 0 })); + + // Loop entry = 1 + // create first argument + firstArgument = new CounterExamplePredicate("", PathType.INFINITE, 1, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate("", PathType.INFINITE, 1, + secondArgumentValues); + + // create an operator + weakUntilOperator = new CounterExampleWeakUntil(PathType.INFINITE, 1, + firstArgument, secondArgument); + + // check result values + values = weakUntilOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + firstHighlightedPositions = weakUntilOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = weakUntilOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(2).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3, 1 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(3).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 1 })); + + // Loop entry = 2 + // create first argument + firstArgument = new CounterExamplePredicate("", PathType.INFINITE, 2, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate("", PathType.INFINITE, 2, + secondArgumentValues); + + // create an operator + weakUntilOperator = new CounterExampleWeakUntil(PathType.INFINITE, 2, + firstArgument, secondArgument); + + // check result values + values = weakUntilOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + firstHighlightedPositions = weakUntilOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = weakUntilOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + assertTrue(secondHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2 })); + assertTrue(secondHighlightedPositions.get(3).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3, 2 })); + + // Loop entry = 3 + // create first argument + firstArgument = new CounterExamplePredicate("", PathType.INFINITE, 3, + firstArgumentValues); + + // create second argument + secondArgument = new CounterExamplePredicate("", PathType.INFINITE, 3, + secondArgumentValues); + + // create an operator + weakUntilOperator = new CounterExampleWeakUntil(PathType.INFINITE, 3, + firstArgument, secondArgument); + + // check result values + values = weakUntilOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + firstHighlightedPositions = weakUntilOperator + .getFirstHighlightedPositions(); + secondHighlightedPositions = weakUntilOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 0); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + assertTrue(secondHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-TTTU, g-UUUT, f U g-TTTT + */ + @Test + public void testWeakUntilTrueDefinitionOnReducedPath() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.UNDEFINED }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.FINITE, -1, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.FINITE, -1, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator weakUntilOperator = new CounterExampleWeakUntil( + PathType.FINITE, -1, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = weakUntilOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.TRUE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.TRUE); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = weakUntilOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = weakUntilOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2 })); + assertTrue(secondHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 3 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 0); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-UTUU, g-FUTU, f U g-UTTU + */ + @Test + public void testUntilOnReducedPathUnknownDefinition1() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE, + CounterExampleValueType.UNDEFINED }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.REDUCED, -1, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.REDUCED, -1, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator weakUntilOperator = new CounterExampleWeakUntil( + PathType.REDUCED, -1, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = weakUntilOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.UNDEFINED); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = weakUntilOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = weakUntilOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1 })); + assertTrue(secondHighlightedPositions.get(0).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 0); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-UUFU, g-FFUU, f U g-UUUU + */ + @Test + public void testUntilOnReducedPathUnknownDefinition2() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.FALSE, + CounterExampleValueType.UNDEFINED }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.REDUCED, -1, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.REDUCED, -1, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator weakUntilOperator = new CounterExampleWeakUntil( + PathType.REDUCED, -1, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = weakUntilOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(1) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(2) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(3) == CounterExampleValueType.UNDEFINED); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = weakUntilOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = weakUntilOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2 })); + assertTrue(secondHighlightedPositions.get(0).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2 })); + assertTrue(secondHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-UTUU, g-FUUU, f U g-UUUU + */ + @Test + public void testUntilOnReducedPathUnknownDefinition3() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.UNDEFINED }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.REDUCED, -1, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.REDUCED, -1, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator weakUntilOperator = new CounterExampleWeakUntil( + PathType.REDUCED, -1, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = weakUntilOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(1) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(2) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(3) == CounterExampleValueType.UNDEFINED); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = weakUntilOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = weakUntilOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2 })); + assertTrue(secondHighlightedPositions.get(0).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2 })); + assertTrue(secondHighlightedPositions.get(1).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-TTTT, g-FFFF, f U g-UUUU + */ + @Test + public void testUntilOnReducedPathUnknownDefinition4() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE, + CounterExampleValueType.TRUE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.REDUCED, -1, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.REDUCED, -1, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator weakUntilOperator = new CounterExampleWeakUntil( + PathType.REDUCED, -1, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = weakUntilOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(1) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(2) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(3) == CounterExampleValueType.UNDEFINED); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = weakUntilOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = weakUntilOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 4); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2, 3 })); + assertTrue(secondHighlightedPositions.get(0).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2, 3 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2, 3 })); + assertTrue(secondHighlightedPositions.get(1).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2, 3 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + assertTrue(secondHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f-UTUT, g-FUFU, f U g-UUUU + */ + @Test + public void testUntilOnReducedPathUnknownDefinition5() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.FALSE, + CounterExampleValueType.UNDEFINED }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.REDUCED, -1, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.REDUCED, -1, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator weakUntilOperator = new CounterExampleWeakUntil( + PathType.REDUCED, -1, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = weakUntilOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(1) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(2) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(3) == CounterExampleValueType.UNDEFINED); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = weakUntilOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = weakUntilOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 4); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2, 3 })); + assertTrue(secondHighlightedPositions.get(0).size() == 4); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1, 2, 3 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 3); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2, 3 })); + assertTrue(secondHighlightedPositions.get(1).size() == 3); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1, 2, 3 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + assertTrue(secondHighlightedPositions.get(2).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2, 3 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } + + /* + * f - UTFU g - FTFF f U g - UTFU + */ + @Test + public void testWeakUntilOnReducedPath() { + // create first argument values + List<CounterExampleValueType> firstArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.UNDEFINED }); + + // create second argument values + List<CounterExampleValueType> secondArgumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.FALSE }); + + // create first argument + CounterExampleProposition firstArgument = new CounterExamplePredicate( + "", PathType.REDUCED, -1, firstArgumentValues); + + // create second argument + CounterExampleProposition secondArgument = new CounterExamplePredicate( + "", PathType.REDUCED, -1, secondArgumentValues); + + // create an operator + CounterExampleBinaryOperator weakUntilOperator = new CounterExampleWeakUntil( + PathType.REDUCED, -1, firstArgument, secondArgument); + + // check result values + List<CounterExampleValueType> values = weakUntilOperator.getValues(); + assertTrue(values.size() == firstArgumentValues.size()); + assertTrue(values.size() == secondArgumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.FALSE); + assertTrue(values.get(3) == CounterExampleValueType.UNDEFINED); + + // check highlighted positions + List<List<Integer>> firstHighlightedPositions = weakUntilOperator + .getFirstHighlightedPositions(); + List<List<Integer>> secondHighlightedPositions = weakUntilOperator + .getSecondHighlightedPositions(); + assertTrue(firstHighlightedPositions.size() == firstArgumentValues + .size()); + assertTrue(secondHighlightedPositions.size() == secondArgumentValues + .size()); + + // State 0 + assertTrue(firstHighlightedPositions.get(0).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0 })); + assertTrue(secondHighlightedPositions.get(0).size() == 2); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(0).toArray(new Integer[0]), + new Integer[] { 0, 1 })); + + // State 1 + assertTrue(firstHighlightedPositions.get(1).size() == 0); + assertTrue(secondHighlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 1 })); + + // State 2 + assertTrue(firstHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + assertTrue(secondHighlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 2 })); + + // State 3 + assertTrue(firstHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + firstHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + assertTrue(secondHighlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + secondHighlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 3 })); + } +} diff --git a/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleYesterdayUnitTest.java b/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleYesterdayUnitTest.java new file mode 100644 index 0000000000000000000000000000000000000000..1e0ce3874100f7e3f03a101682fab3c318d9b37e --- /dev/null +++ b/de.prob.core/src/de/prob/core/domainobjects/ltl/unittests/CounterExampleYesterdayUnitTest.java @@ -0,0 +1,293 @@ +package de.prob.core.domainobjects.ltl.unittests; + +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +import de.prob.core.command.LtlCheckingCommand.PathType; +import de.prob.core.domainobjects.ltl.CounterExamplePredicate; +import de.prob.core.domainobjects.ltl.CounterExampleProposition; +import de.prob.core.domainobjects.ltl.CounterExampleUnaryOperator; +import de.prob.core.domainobjects.ltl.CounterExampleValueType; +import de.prob.core.domainobjects.ltl.CounterExampleYesterday; + +/** + * Unit test for a "Yesterday" operator. + * + * @author Andriy Tolstoy + * + */ +public class CounterExampleYesterdayUnitTest { + + /* + * f-FTFT, Y f-FFTF + */ + @Test + public void testYesterdayOnFinitePath() { + // create argument values + List<CounterExampleValueType> argumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE }); + + // create an argument + CounterExampleProposition argument = new CounterExamplePredicate( + PathType.FINITE, argumentValues); + + // create an operator + CounterExampleUnaryOperator yesterdayOperator = new CounterExampleYesterday( + PathType.FINITE, argument); + + // check result values + List<CounterExampleValueType> values = yesterdayOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> highlightedPositions = yesterdayOperator + .getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + + assertTrue(highlightedPositions.get(0).size() == 0); + + assertTrue(highlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 0 })); + + assertTrue(highlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 2 })); + } + + /* + * f-FTFT, Y f-FFTF + */ + @Test + public void testYesterdayOnInfinitePath() { + // create argument values + List<CounterExampleValueType> argumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE }); + + // Loop entry = 0 + // create an argument + CounterExampleProposition argument = new CounterExamplePredicate( + PathType.INFINITE, 0, argumentValues); + + // create an operator + CounterExampleUnaryOperator yesterdayOperator = new CounterExampleYesterday( + PathType.INFINITE, 0, argument); + + // check result values + List<CounterExampleValueType> values = yesterdayOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> highlightedPositions = yesterdayOperator + .getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + + assertTrue(highlightedPositions.get(0).size() == 0); + + assertTrue(highlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 0 })); + + assertTrue(highlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 2 })); + + // Loop entry = 1 + // create an argument + argument = new CounterExamplePredicate(PathType.INFINITE, 1, argumentValues); + + // create an operator + yesterdayOperator = new CounterExampleYesterday(PathType.INFINITE, 1, + argument); + + // check result values + values = yesterdayOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + highlightedPositions = yesterdayOperator.getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + + assertTrue(highlightedPositions.get(0).size() == 0); + + assertTrue(highlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 0 })); + + assertTrue(highlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 2 })); + + // Loop entry = 2 + // create an argument + argument = new CounterExamplePredicate(PathType.INFINITE, 2, argumentValues); + + // create an operator + yesterdayOperator = new CounterExampleYesterday(PathType.INFINITE, 2, + argument); + + // check result values + values = yesterdayOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + highlightedPositions = yesterdayOperator.getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + + assertTrue(highlightedPositions.get(0).size() == 0); + + assertTrue(highlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 0 })); + + assertTrue(highlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 2 })); + + // Loop entry = 3 + // create an argument + argument = new CounterExamplePredicate(PathType.INFINITE, 3, argumentValues); + + // create an operator + yesterdayOperator = new CounterExampleYesterday(PathType.INFINITE, 3, + argument); + + // check result values + values = yesterdayOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.FALSE); + assertTrue(values.get(2) == CounterExampleValueType.TRUE); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + highlightedPositions = yesterdayOperator.getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + + assertTrue(highlightedPositions.get(0).size() == 0); + + assertTrue(highlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 0 })); + + assertTrue(highlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 2 })); + } + + /* + * f-TUFT, Y f-FTUF + */ + @Test + public void testYesterdayOnReducedPath() { + // create argument values + List<CounterExampleValueType> argumentValues = Arrays + .asList(new CounterExampleValueType[] { + CounterExampleValueType.TRUE, + CounterExampleValueType.UNDEFINED, + CounterExampleValueType.FALSE, + CounterExampleValueType.TRUE }); + + // create an argument + CounterExampleProposition argument = new CounterExamplePredicate( + PathType.REDUCED, argumentValues); + + // create an operator + CounterExampleUnaryOperator yesterdayOperator = new CounterExampleYesterday( + PathType.REDUCED, argument); + + // check result values + List<CounterExampleValueType> values = yesterdayOperator.getValues(); + assertTrue(values.size() == argumentValues.size()); + assertTrue(values.get(0) == CounterExampleValueType.FALSE); + assertTrue(values.get(1) == CounterExampleValueType.TRUE); + assertTrue(values.get(2) == CounterExampleValueType.UNDEFINED); + assertTrue(values.get(3) == CounterExampleValueType.FALSE); + + // check highlighted positions + List<List<Integer>> highlightedPositions = yesterdayOperator + .getHighlightedPositions(); + assertTrue(highlightedPositions.size() == argumentValues.size()); + + assertTrue(highlightedPositions.get(0).size() == 0); + + assertTrue(highlightedPositions.get(1).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(1).toArray(new Integer[0]), + new Integer[] { 0 })); + + assertTrue(highlightedPositions.get(2).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(2).toArray(new Integer[0]), + new Integer[] { 1 })); + + assertTrue(highlightedPositions.get(3).size() == 1); + assertTrue(Arrays.equals( + highlightedPositions.get(3).toArray(new Integer[0]), + new Integer[] { 2 })); + + } +} diff --git a/de.prob.core/src/de/prob/core/internal/Activator.java b/de.prob.core/src/de/prob/core/internal/Activator.java new file mode 100644 index 0000000000000000000000000000000000000000..3165c2d9dcdec8a2e6e9294f4343a0055193b615 --- /dev/null +++ b/de.prob.core/src/de/prob/core/internal/Activator.java @@ -0,0 +1,226 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.internal; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.IExtensionRegistry; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Plugin; +import org.eclipse.core.runtime.jobs.IJobChangeEvent; +import org.eclipse.core.runtime.jobs.IJobChangeListener; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.core.runtime.jobs.JobChangeAdapter; +import org.osgi.framework.BundleContext; + +import de.prob.core.Animator; +import de.prob.core.IAnimationListener; +import de.prob.core.IComputationListener; +import de.prob.core.ILifecycleListener; +import de.prob.core.LimitedLogger; +import de.prob.core.domainobjects.Operation; +import de.prob.core.domainobjects.State; +import de.prob.logging.Logger; + +public final class Activator extends Plugin { + // The plug-in ID + public static final String PLUGIN_ID = "de.prob.core"; + private static final String ANIMATION_EXTENSION_POINT = PLUGIN_ID + + ".animation"; + private static final String COMPUTATION_EXTENSION_POINT = PLUGIN_ID + + ".computation"; + private static final String LIFECYCLE_EXTENSION_POINT = PLUGIN_ID + + ".lifecycle"; + + private final static Set<ILifecycleListener> lifeCycleListeners = initLifeCycleListeners(); + private final static Set<IComputationListener> computationListeners = initComputationListeners(); + private final static Set<IAnimationListener> animationListeners = initAnimationListeners(); + + private static Set<ILifecycleListener> initLifeCycleListeners() { + HashSet<ILifecycleListener> result = new HashSet<ILifecycleListener>(); + final IExtensionRegistry extensionRegistry = Platform + .getExtensionRegistry(); + final IExtensionPoint extensionPoint = extensionRegistry + .getExtensionPoint(LIFECYCLE_EXTENSION_POINT); + for (final IExtension extension : extensionPoint.getExtensions()) { + for (final IConfigurationElement configurationElement : extension + .getConfigurationElements()) { + result.add(new LifeCycleListenerProxy(configurationElement)); + } + } + return result; + } + + private static Set<IComputationListener> initComputationListeners() { + HashSet<IComputationListener> result = new HashSet<IComputationListener>(); + final IExtensionRegistry extensionRegistry = Platform + .getExtensionRegistry(); + final IExtensionPoint extensionPoint = extensionRegistry + .getExtensionPoint(COMPUTATION_EXTENSION_POINT); + for (final IExtension extension : extensionPoint.getExtensions()) { + for (final IConfigurationElement configurationElement : extension + .getConfigurationElements()) { + result.add(new ComputationListenerProxy(configurationElement)); + } + } + return result; + } + + private static Set<IAnimationListener> initAnimationListeners() { + HashSet<IAnimationListener> result = new HashSet<IAnimationListener>(); + final IExtensionRegistry extensionRegistry = Platform + .getExtensionRegistry(); + final IExtensionPoint extensionPoint = extensionRegistry + .getExtensionPoint(ANIMATION_EXTENSION_POINT); + for (final IExtension extension : extensionPoint.getExtensions()) { + for (final IConfigurationElement configurationElement : extension + .getConfigurationElements()) { + result.add(new AnimationListenerProxy(configurationElement)); + } + } + return result; + } + + public static void reset() { + synchronized (lifeCycleListeners) { + final LimitedLogger logger = LimitedLogger.getLogger(); + logger.log("lifecycle", "start announcing reset", null); + for (final ILifecycleListener l : lifeCycleListeners) { + try { + l.reset(); + } catch (final RuntimeException e) { + final String message = "Runtime Exception thrown in bad behaving listener class " + + l.getClass() + " while sending reset event"; + Logger.notifyUser(message, e); + } + } + logger.log("lifecycle", "finished announcing reset", null); + } + } + + public static void computedState(final State state) { + synchronized (computationListeners) { + final String stateId = state == null ? null : state.getId(); + final LimitedLogger logger = LimitedLogger.getLogger(); + logger.log("lifecycle", "start announcing computed state " + + stateId, null); + for (final IComputationListener l : computationListeners) { + try { + l.computedState(state); + } catch (final RuntimeException e) { + final String message = "Runtime Exception thrown in bad behaving listener class " + + l.getClass() + + " while sending computation event."; + Logger.notifyUser(message, e); + } + } + logger.log("lifecycle", "finished announcing computed state " + + stateId, null); + } + } + + public static void currentStateChanged(final State currentState, + final Operation operation) { + synchronized (animationListeners) { + final String stateId = currentState == null ? null : currentState + .getId(); + final LimitedLogger logger = LimitedLogger.getLogger(); + logger.log("lifecycle", + "start announcing current state " + stateId, null); + for (final IAnimationListener l : animationListeners) { + try { + l.currentStateChanged(currentState, operation); + } catch (final RuntimeException e) { + final String message = "Runtime Exception thrown in bad behaving listener class " + + l.getClass() + + " while sending state change event"; + Logger.notifyUser(message, e); + } + } + logger.log("lifecycle", "finished announcing current state " + + stateId, null); + } + } + + // The shared instance + private static Activator plugin = null; + + private final Collection<Job> jobs = new ArrayList<Job>(); + private final IJobChangeListener jobFinishedListener = new JobFinishedListener(); + + /** + * The constructor + */ + public Activator() { + super(); + setInstance(this); + } + + private static void setInstance(final Activator p) { + plugin = p; + } + + @Override + public void stop(final BundleContext context) throws Exception { // NOPMD + // by Jens Bendisposto on 7/20/07 12:19 PM + // Method is declared in org.eclipse.core.runtime.Plugin + + cancelAllJobs(); + final Animator animator = Animator.getAnimator(); + if (animator != null) { + animator.sendUserInterruptSignal(); + animator.shutdown(); + } + + plugin = null; + super.stop(context); + } + + private void cancelAllJobs() { + synchronized (jobs) { + for (final Job job : jobs) { + job.cancel(); + } + } + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + if (plugin == null) { + new Activator(); + } + return plugin; + } + + public void registerJob(final Job job) { + synchronized (jobs) { + jobs.add(job); + job.addJobChangeListener(jobFinishedListener); + } + } + + private class JobFinishedListener extends JobChangeAdapter { + @Override + public void done(final IJobChangeEvent event) { + super.done(event); + synchronized (jobs) { + jobs.remove(event.getJob()); + } + } + } + +} diff --git a/de.prob.core/src/de/prob/core/internal/AnimationListenerProxy.java b/de.prob.core/src/de/prob/core/internal/AnimationListenerProxy.java new file mode 100644 index 0000000000000000000000000000000000000000..341150b1a7464b663cfff382b75301728a9b763a --- /dev/null +++ b/de.prob.core/src/de/prob/core/internal/AnimationListenerProxy.java @@ -0,0 +1,49 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.internal; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; + +import de.prob.core.IAnimationListener; +import de.prob.core.domainobjects.Operation; +import de.prob.core.domainobjects.State; +import de.prob.logging.Logger; + +public class AnimationListenerProxy implements IAnimationListener { + + private final IConfigurationElement config; + private IAnimationListener instance; + + public AnimationListenerProxy(final IConfigurationElement config) { + this.config = config; + } + + public void currentStateChanged(final State currentState, + final Operation operation) { + if (instance == null) { + instance = init(); + } + if (instance != null) { + instance.currentStateChanged(currentState, operation); + } + + } + + private IAnimationListener init() { + try { + return (IAnimationListener) config + .createExecutableExtension("class"); + } catch (CoreException e) { + Logger.notifyUser("A Listener could not be instatiated. Class is: " + + config.getAttribute("class"), e); + e.printStackTrace(); + } + return null; + } + +} diff --git a/de.prob.core/src/de/prob/core/internal/AnimatorImpl.java b/de.prob.core/src/de/prob/core/internal/AnimatorImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..36f836b0690414819d8bef12b2579da59e68cfd7 --- /dev/null +++ b/de.prob.core/src/de/prob/core/internal/AnimatorImpl.java @@ -0,0 +1,213 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.internal; + +import java.io.File; +import java.util.List; +import java.util.Map; + +import de.prob.cli.CliException; +import de.prob.core.IServerConnection; +import de.prob.core.ITrace; +import de.prob.core.LanguageDependendAnimationPart; +import de.prob.core.ProblemHandler; +import de.prob.core.command.CommandException; +import de.prob.core.command.ComposedCommand; +import de.prob.core.command.GetErrorsCommand; +import de.prob.core.command.IComposableCommand; +import de.prob.core.domainobjects.History; +import de.prob.core.domainobjects.HistoryItem; +import de.prob.core.domainobjects.MachineDescription; +import de.prob.core.domainobjects.RandomSeed; +import de.prob.core.domainobjects.State; +import de.prob.core.sablecc.node.Start; +import de.prob.exceptions.ProBException; +import de.prob.logging.Logger; +import de.prob.parser.BindingGenerator; +import de.prob.prolog.output.PrologTermStringOutput; +import de.prob.prolog.term.PrologTerm; + +/** + * @author Jens Bendisposto + * + */ + +public class AnimatorImpl { + + private final History history = new History(); + + private IServerConnection connector; + + private RandomSeed seed; + + private MachineDescription description; + + private final File file; + + private LanguageDependendAnimationPart langdep; + + public AnimatorImpl(final IServerConnection serverConnection, + final File file) { + this.file = file; + setConnector(serverConnection); + } + + public synchronized void shutdownImplementation() { + if (connector != null) { + connector.shutdown(); + } + connector = null; + history.reset(); + description = null; + } + + private void checkConnector(final String command) throws CliException { + if (connector == null) { + final String message = "The connection to the ProB instance has not been established. Tried to execute " + + command; + ProblemHandler.raiseCliException(message); + } + } + + public State getCurrentStateImpl() { + HistoryItem item = history.getCurrent(); + return item == null ? null : item.getState(); + } + + public synchronized Start sendCommandImpl(final String command) + throws ProBException { + String input = connector.sendCommand(command); + return parseResult(input); + } + + private Start parseResult(final String input) throws CliException, + ResultParserException { + if (input == null) + return null; + else + return ProBResultParser.parse(input); + } + + public History getHistoryImpl() { + return history; + } + + private synchronized void setConnector( + final IServerConnection serverConnection) { + this.connector = serverConnection; + try { + connector.startup(file); + } catch (CliException e) { + // The user has been notified by the underlying implementation, so + // we only invalidate the connector + connector = null; + } + } + + public boolean isRunning() { + return true; + } + + public synchronized final ITrace getTraceImpl() { + if (connector instanceof ServerTraceConnection) { + ServerTraceConnection conn = (ServerTraceConnection) connector; + conn.preferenceToTrace("seed: " + getSeed().toString()); + return conn.getTrace(); + } + return null; + } + + public void setSeed(final RandomSeed seed) { + this.seed = seed; + } + + public RandomSeed getSeed() { + return seed; + } + + public synchronized void setMachineDescription( + final MachineDescription machineDescription) { + this.description = machineDescription; + } + + public synchronized MachineDescription getMachineDescription() { + return this.description; + } + + public boolean isMachineLoaded() { + return this.description != null; + } + + public synchronized String getDebuggingKey() { + return connector == null ? null : connector.getDebuggingKey(); + } + + public void execute(final IComposableCommand command) throws ProBException { + checkConnector(command.getClass().getName()); + + final GetErrorsCommand getErrors = new GetErrorsCommand(); + final ComposedCommand cmds = new ComposedCommand(command, getErrors); + SimplifiedROMap<String, PrologTerm> bindings = null; + List<String> errors = null; + try { + bindings = sendCommand(cmds); + cmds.processResult(bindings); + errors = getErrors.getErrors(); + } catch (RuntimeException e) { + Logger.notifyUser(e.getLocalizedMessage(), e); + } finally { + if (errors == null) { + if (bindings == null) { + // the exception occurred while sending the commands + // launch another query to get errors + bindings = sendCommand(getErrors); + getErrors.processResult(bindings); + } else { + // we cannot call getErrors.processResult directly because + // the wrapping ComposedCommand may have mapped the bindings + cmds.reprocessResult(getErrors, bindings); + } + errors = getErrors.getErrors(); + } + if (errors != null && !errors.isEmpty()) { + ProblemHandler.raisePrologException(errors); + } + } + } + + private SimplifiedROMap<String, PrologTerm> sendCommand( + final IComposableCommand command) throws ProBException, + CommandException { + + PrologTermStringOutput pto = new PrologTermStringOutput(); + command.writeCommand(pto); + final String query = pto.fullstop().toString(); + final Start ast = sendCommandImpl(query); + Map<String, PrologTerm> bindings; + try { + bindings = BindingGenerator + .createBindingMustNotFail(query, ast); + } catch (de.prob.parser.ResultParserException e) { + CommandException commandException = new CommandException(e.getLocalizedMessage(), e); + commandException.notifyUserOnce(); + throw commandException; + } + return new SimplifiedROMap<String, PrologTerm>(bindings); + } + + public LanguageDependendAnimationPart getLangdep() { + return langdep; + } + + public void setLangdep(final LanguageDependendAnimationPart langdep) { + this.langdep = langdep; + } + + public void sendUserInterruptSignal() { + connector.sendUserInterruptSignal(); + } +} diff --git a/de.prob.core/src/de/prob/core/internal/ComputationListenerProxy.java b/de.prob.core/src/de/prob/core/internal/ComputationListenerProxy.java new file mode 100644 index 0000000000000000000000000000000000000000..41ce640df888d7ddcc55b52b9146b2146d4a6573 --- /dev/null +++ b/de.prob.core/src/de/prob/core/internal/ComputationListenerProxy.java @@ -0,0 +1,47 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.internal; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; + +import de.prob.core.IComputationListener; +import de.prob.core.domainobjects.State; +import de.prob.logging.Logger; + +public class ComputationListenerProxy implements IComputationListener { + + private final IConfigurationElement config; + private IComputationListener instance; + + public ComputationListenerProxy(final IConfigurationElement config) { + this.config = config; + } + + public void computedState(final State state) { + if (instance == null) { + instance = init(); + } + if (instance != null) { + instance.computedState(state); + } + + } + + private IComputationListener init() { + try { + return (IComputationListener) config + .createExecutableExtension("class"); + } catch (CoreException e) { + Logger.notifyUser("A Listener could not be instatiated. Class is: " + + config.getAttribute("class"), e); + e.printStackTrace(); + } + return null; + } + +} diff --git a/de.prob.core/src/de/prob/core/internal/LifeCycleListenerProxy.java b/de.prob.core/src/de/prob/core/internal/LifeCycleListenerProxy.java new file mode 100644 index 0000000000000000000000000000000000000000..bdc8753fc4fcde9f113c2bf544ba8bec9c491169 --- /dev/null +++ b/de.prob.core/src/de/prob/core/internal/LifeCycleListenerProxy.java @@ -0,0 +1,44 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.internal; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; + +import de.prob.core.ILifecycleListener; +import de.prob.logging.Logger; + +public class LifeCycleListenerProxy implements ILifecycleListener { + + private ILifecycleListener instance; + private final IConfigurationElement config; + + public LifeCycleListenerProxy(final IConfigurationElement config) { + this.config = config; + } + + public void reset() { + if (instance == null) { + instance = init(); + } + if (instance != null) { + instance.reset(); + } + } + + private ILifecycleListener init() { + try { + return (ILifecycleListener) config + .createExecutableExtension("class"); + } catch (CoreException e) { + Logger.notifyUser("A Listener could not be instatiated. Class is: " + + config.getAttribute("class"), e); + e.printStackTrace(); + } + return null; + } +} diff --git a/de.prob.core/src/de/prob/core/internal/Message.java b/de.prob.core/src/de/prob/core/internal/Message.java new file mode 100644 index 0000000000000000000000000000000000000000..7172c5fd7333a9f3679f681fe48d90eaa0426689 --- /dev/null +++ b/de.prob.core/src/de/prob/core/internal/Message.java @@ -0,0 +1,32 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.internal; + +public class Message { + + public static enum Type { + QUERY, ANSWER, LOG, PREFERENCE + }; + + private final Type type; + + private final String message; + + public Message(final Type type, final String message) { + this.message = message; + this.type = type; + } + + public String getMessage() { + return message; + } + + public Type getType() { + return type; + } + +} diff --git a/de.prob.core/src/de/prob/core/internal/ProBResultParser.java b/de.prob.core/src/de/prob/core/internal/ProBResultParser.java new file mode 100644 index 0000000000000000000000000000000000000000..85eb4960e745ef475fc138e34932bdfd5fdf114b --- /dev/null +++ b/de.prob.core/src/de/prob/core/internal/ProBResultParser.java @@ -0,0 +1,61 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.internal; + +import java.io.IOException; +import java.io.PushbackReader; +import java.io.StringReader; + +import de.prob.core.ProblemHandler; +import de.prob.core.sablecc.lexer.Lexer; +import de.prob.core.sablecc.lexer.LexerException; +import de.prob.core.sablecc.node.Start; +import de.prob.core.sablecc.parser.Parser; +import de.prob.core.sablecc.parser.ParserException; +import de.prob.exceptions.ProBAssertionFailed; +import de.prob.logging.Logger; + +public final class ProBResultParser { + + private ProBResultParser() { + throw new UnsupportedOperationException( + "not intended for instantiation"); + } + + public static Start parse(final String prologAnswer) + throws ResultParserException, ProBAssertionFailed { + + Logger.assertProB("prologAnswer.length() != 0", + prologAnswer.length() != 0); + + final PushbackReader codeReader = new PushbackReader(new StringReader( + prologAnswer), prologAnswer.length()); + final Lexer lexer = new Lexer(codeReader); + final Parser parser = new Parser(lexer); + Start parseResult = null; + try { + parseResult = parser.parse(); + } catch (final ParserException e) { + String message = "Internal Error while parsing ProB Answer. This ist most likly a bug in the Resultparser. String was: '" + + prologAnswer + + "'. Last Token was '" + + e.getToken() + + "': " + e.getLocalizedMessage(); + ProblemHandler.handleResultPareserException(message, e); + } catch (final LexerException e) { + String message = "Internal Error while parsing ProB Answer. This ist most likly a bug in the Resultparser String was: '" + + prologAnswer + "': " + e.getLocalizedMessage(); + ProblemHandler.handleResultPareserException(message, e); + } catch (final IOException e) { + String message = "Internal Error while parsing ProB Answer. This ist most likly a bug in the Resultparser String was: " + + prologAnswer + "': " + e.getLocalizedMessage(); + ProblemHandler.handleResultPareserException(message, e); + } + + return parseResult; + } +} \ No newline at end of file diff --git a/de.prob.core/src/de/prob/core/internal/ResultParserException.java b/de.prob.core/src/de/prob/core/internal/ResultParserException.java new file mode 100644 index 0000000000000000000000000000000000000000..5b3b0aa5b1701a441ec386a256c173d5795b60b3 --- /dev/null +++ b/de.prob.core/src/de/prob/core/internal/ResultParserException.java @@ -0,0 +1,18 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.internal; + +import de.prob.exceptions.ProBException; + +public class ResultParserException extends ProBException { + private static final long serialVersionUID = 4607280354438003272L; + + public ResultParserException(final String message, final Throwable t) { + super(message, t, true); + } + +} diff --git a/de.prob.core/src/de/prob/core/internal/ServerConnection.java b/de.prob.core/src/de/prob/core/internal/ServerConnection.java new file mode 100644 index 0000000000000000000000000000000000000000..cef750564c6692b9aa11649345043cccf51cc005 --- /dev/null +++ b/de.prob.core/src/de/prob/core/internal/ServerConnection.java @@ -0,0 +1,212 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.internal; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.IOException; +import java.io.PrintStream; +import java.net.InetAddress; +import java.net.Socket; + +import de.prob.cli.CliException; +import de.prob.cli.CliStarter; +import de.prob.core.IServerConnection; +import de.prob.core.ProblemHandler; +import de.prob.exceptions.ProBException; +import de.prob.logging.Logger; + +public class ServerConnection implements IServerConnection { + + private Socket socket = null; + private BufferedInputStream inputStream = null; + private PrintStream outputStream = null; + + private CliStarter cli = null; + + private String lastCommand; + + private volatile boolean shutdown = true; + + // private static final ScheduledExecutorService exec = new + // ScheduledThreadPoolExecutor( + // 1); + + private void startcli(final File file) throws CliException { + cli = new CliStarter(file); + } + + /* + * (non-Javadoc) + * + * @see de.prob.core.IServerConnection#getLastCommand() + */ + public String getLastCommand() { + return lastCommand; + } + + public String getDebuggingKey() { + return cli == null ? null : cli.getDebuggingKey(); + } + + private void establishConnection(final int port) throws CliException { + try { + socket = new Socket(InetAddress.getByName(null), port); + inputStream = new BufferedInputStream(socket.getInputStream()); + outputStream = new PrintStream(socket.getOutputStream()); + } catch (final IOException e) { + if (socket != null) { + try { + socket.close(); + } catch (final IOException e2) { + Logger.info(e.getLocalizedMessage()); + } finally { + socket = null; + inputStream = null; + outputStream = null; + } + } + ProblemHandler.handleCliException( + "Opening connection to ProB server failed", e); + } + } + + public String sendCommand(final String commandString) throws ProBException { + if (shutdown) { + final String message = "probcli is currently shutting down"; + ProblemHandler.raiseCliException(message); + } + checkState(); + sendQuery(commandString); + return getAnswer(); + } + + private void sendQuery(final String commandString) throws ProBException { + lastCommand = commandString; + Logger.assertProB("commandString.trim().endsWith(\".\")", commandString + .trim().endsWith(".")); + + outputStream.println(commandString); + + outputStream.flush(); + } + + private String getAnswer() throws ProBException { + String input = null; + try { + input = readAnswer(); + if (input == null) + throw new IOException("ProB binary returned nothing - it might have crashed"); + } catch (final IOException e) { + shutdown(); + String message = "Exception while reading from socket"; + ProblemHandler.handleCliException(message, e); + } + return input; + } + + // private String timedRun(final Callable<String> r, final long timeOut, + // final TimeUnit unit) throws InterruptedException, ProBException { + // String s = null; + // Future<String> task = exec.submit(r); + // try { + // s = task.get(timeOut, unit); + // } catch (TimeoutException e) { + // final String message = "Timeout while waiting for ProB's answer"; + // ProblemHandler.handleCliException(message, e); + // } catch (ExecutionException e) { + // final String message = e.getCause().getLocalizedMessage(); + // ProblemHandler.handleCliException(message, e.getCause()); + // } finally { + // task.cancel(true); + // } + // return s; + // } + + protected String readAnswer() throws IOException { + final StringBuilder result = new StringBuilder(); + final byte[] buffer = new byte[1024]; + boolean done = false; + + while (!done) { + /* + * It might be necessary to check for inputStream.available() > 0. + * Or add some kind of timer to prevent the thread blocks forever. + * See task#102 + */ + int count = inputStream.read(buffer); + + if (count > 0) { + final byte length = 1; + + // check for end of transmission (i.e. last byte is 1) + if (buffer[count - length] == 1) { + done = true; + count--; // remove end of transmission marker + } + + // trim white spaces and append + // instead of removing the last byte trim is used, because on + // windows prob uses \r\n as new line. + result.append((new String(buffer, 0, count)).trim()); + } else { + done = true; + } + } + + return result.length() > 0 ? result.toString() : null; + } + + public void startup(final File file) throws CliException { + if (shutdown) { + startcli(file); + establishConnection(cli.getPort()); + shutdown = false; + } else { + // This should never happen + final String message = "Tried to start a server that is already running"; + Logger.notifyUserWithoutBugreport(message); + } + } + + public void shutdown() { + if (!shutdown) { + if (socket != null) { + try { + socket.close(); + } catch (final IOException e) { + Logger.info(e.getLocalizedMessage()); + } + } + + socket = null; + inputStream = null; + outputStream = null; + + cli.shutdown(); + cli = null; + shutdown = true; + } + } + + private void checkState() throws CliException { + if (inputStream == null || outputStream == null) { + ProblemHandler.raiseCliException("Stream to ProB server not ready"); + } + } + + public int getCliPortNumber() { + return cli.getPort(); + } + + @Override + public void sendUserInterruptSignal() { + if (cli != null) { + cli.sendUserInterruptReference(); + } + } +} diff --git a/de.prob.core/src/de/prob/core/internal/ServerTraceConnection.java b/de.prob.core/src/de/prob/core/internal/ServerTraceConnection.java new file mode 100644 index 0000000000000000000000000000000000000000..4eaea64c06a770f77a8b0a52a75df0ac010367b4 --- /dev/null +++ b/de.prob.core/src/de/prob/core/internal/ServerTraceConnection.java @@ -0,0 +1,124 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.internal; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; + +import org.eclipse.core.runtime.ILogListener; +import org.eclipse.core.runtime.IStatus; + +import de.prob.cli.CliException; +import de.prob.core.ITrace; +import de.prob.core.internal.Message.Type; +import de.prob.exceptions.ProBException; +import de.prob.logging.Logger; + +public class ServerTraceConnection extends ServerConnection implements + ILogListener { + + private static final int TRACE_SIZE_LIMIT = 100; + + private Trace trace; + + @Override + public void startup(final File file) throws CliException { + super.startup(file); + trace = new Trace(TRACE_SIZE_LIMIT); + logToTrace("ServerTraceConnection.startup(): " + getCurrentTime()); + Logger.addListener(this); + } + + @Override + public void shutdown() { + super.shutdown(); + logToTrace("ServerTraceConnection.shutdown(): " + getCurrentTime()); + } + + @Override + public String sendCommand(final String commandString) throws ProBException { + sendMessage(commandString); + return super.sendCommand(commandString); + } + + @Override + protected String readAnswer() throws IOException { + String answer = super.readAnswer(); + receiveMessage(answer); + return answer; + + } + + private void sendMessage(final String content) { + trace.addMessage(Type.QUERY, content); + } + + private void receiveMessage(final String content) { + trace.addMessage(Type.ANSWER, content); + } + + private final String getCurrentTime() { + SimpleDateFormat date = new SimpleDateFormat( + "yyyy.MM.dd ' - ' HH:mm:ss"); + Long timemillis = System.currentTimeMillis(); + + return "Time: " + Long.toString(timemillis) + " - " + + date.format(timemillis); + } + + /** + * Adds a {@link Message} with the Type = LOG to the actual Tracing + * {@link ITrace} + * + * @param String + * message + */ + public final void logToTrace(final String message) { + trace.addMessage(Type.LOG, message); + } + + /** + * Adds a {@link Message} with the Type = PREFERENCE to the actual Tracing + * {@link ITrace} + * + * @param String + * message + */ + public final void preferenceToTrace(final String message) { + trace.addMessageOnTop(Type.PREFERENCE, message); + } + + /** + * + * @return {@link ITrace}, containing all Logs, Queries and Answers that + * passed this ServerTraceConnection + */ + + public final ITrace getTrace() { + logToTrace(getCurrentTime()); + return trace; + } + + /** + * Adds a Error-Log-Message to the trace + */ + public void logging(final IStatus status, final String plugin) { + if (status.getSeverity() == IStatus.ERROR) { + StringBuffer message = new StringBuffer(); + message.append(status.getMessage()); + + if (status.getException() != null) { + message.append("\n"); + message.append(status.getException().getLocalizedMessage()); + } + logToTrace(message.toString()); + + } + + } +} diff --git a/de.prob.core/src/de/prob/core/internal/SimplifiedROMap.java b/de.prob.core/src/de/prob/core/internal/SimplifiedROMap.java new file mode 100644 index 0000000000000000000000000000000000000000..4fab4610a338dd222de919d0eb14e38d977da2a4 --- /dev/null +++ b/de.prob.core/src/de/prob/core/internal/SimplifiedROMap.java @@ -0,0 +1,41 @@ +/** + * + */ +package de.prob.core.internal; + +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import de.prob.parser.ISimplifiedROMap; + +/** + * The default implementation of {@link SimplifiedROMap}, which is just a + * wrapper around a {@link Map}. + * + * @author plagge + */ +public class SimplifiedROMap<K, V> implements ISimplifiedROMap<K, V> { + private final Map<K, V> map; + + public SimplifiedROMap(final Map<K, V> map) { + this.map = map; + } + + public V get(final K key) { + return map.get(key); + } + + @Override + public String toString() { + StringBuffer sb = new StringBuffer(); + Set<Entry<K, V>> entrySet = map.entrySet(); + for (Entry<K, V> entry : entrySet) { + sb.append(entry.getKey()); + sb.append("->"); + sb.append(entry.getValue()); + sb.append(" "); + } + return sb.toString(); + } +} diff --git a/de.prob.core/src/de/prob/core/internal/Trace.java b/de.prob.core/src/de/prob/core/internal/Trace.java new file mode 100644 index 0000000000000000000000000000000000000000..1fa86cdfe0149f4b626f89ec205980da7c1f552c --- /dev/null +++ b/de.prob.core/src/de/prob/core/internal/Trace.java @@ -0,0 +1,170 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.internal; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +import de.prob.core.ITrace; +import de.prob.core.internal.Message.Type; + +/** + * TODO: Maybe a part of the trace should be dumped to a file, to prevent a high + * memory consumption. + */ +public class Trace implements ITrace { + + private final LinkedList<Message> list = new LinkedList<Message>(); + private Integer maximum; + + public Trace() { + this(null); + } + + public Trace(final int maximum) { + this(Integer.valueOf(maximum)); + } + + private Trace(final Integer maximum) { + this.maximum = maximum; + } + + /** + * @return the List of logged messages as unmodifiable List of Strings + */ + public final List<Message> getTraceAsList() { + return Collections.unmodifiableList(list); + } + + /** + * @return the List of logged messages as a String + */ + public final String getTraceAsString() { + StringBuffer buffer = new StringBuffer(); + + for (Message message : list) { + buffer.append(starterString(message.getType())); + buffer.append(message.getMessage()); + buffer.append(stopperString(message.getType())); + } + return buffer.toString(); + } + + public final void addMessage(final Type type, final String message) { + list.add(new Message(type, message)); + limit(); + } + + public final void addMessageOnTop(final Type type, final String message) { + list.add(1, new Message(type, message)); + limit(); + } + + private final String starterString(final Type type) { + return "@START " + type + "\n"; + } + + private final String stopperString(final Type type) { + return "\n@END " + type + "\n"; + } + + public static final ITrace traceFromStream(final InputStream stream) { + final Trace trace = new Trace(); + BufferedReader reader = null; + try { + reader = new BufferedReader(new InputStreamReader(stream)); + iterateOverLines(trace, reader); + } catch (IOException e) { + System.out.println(trace.getClass().getName() + + ": IOException at Filehandling"); + e.printStackTrace(); + } finally { + if (reader != null) { + try { + reader.close(); + } catch (IOException e) { + // IGNORE + } + } + } + return trace; + } + + private static void iterateOverLines(final Trace trace, + final BufferedReader reader) throws IOException { + StringBuffer buffer = new StringBuffer(); + + String line = reader.readLine(); + while (null != line) { + final boolean restartBuffer = collect(line, trace, buffer); + if (restartBuffer) { + buffer = new StringBuffer(); + } + line = reader.readLine(); + } + } + + private static final boolean collect(final String line, final Trace trace, + final StringBuffer buffer) { + final boolean restartBuffer; + if (line.startsWith("@START")) { + restartBuffer = true; + } else { + restartBuffer = false; + Type type; + if (line.startsWith("@END ")) { + final String typeString = line.substring(5); + try { + type = Type.valueOf(typeString); + } catch (IllegalArgumentException e) { + // the string does not represent one of our types + type = null; + } + } else { + type = null; + } + if (type != null) { + trace.addMessage(type, buffer.toString()); + } else { + buffer.append(line); + } + } + return restartBuffer; + } + + public int size() { + return list == null ? 0 : list.size(); + } + + @Override + public void setMaximum(final Integer max) { + if (max != null && max < 0) + throw new IllegalArgumentException("Non-negative maximum expected"); + maximum = max; + limit(); + } + + private void limit() { + if (maximum != null && list != null) { + final int toRemove = list.size() - maximum; + for (int i = 0; i < toRemove; i++) { + list.removeFirst(); + } + } + } + + @Override + public Integer getMaximum() { + return maximum; + } + +} diff --git a/de.prob.core/src/de/prob/core/internal/TraceConnectionProvider.java b/de.prob.core/src/de/prob/core/internal/TraceConnectionProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..25676a1c2e5c326ce925fd8d9d0b4ab849fbc5a4 --- /dev/null +++ b/de.prob.core/src/de/prob/core/internal/TraceConnectionProvider.java @@ -0,0 +1,26 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.internal; + +import de.prob.core.IConnectionProvider; +import de.prob.core.IServerConnection; + +/** + * Provides a new {@link ServerTraceConnection} + */ +public class TraceConnectionProvider implements IConnectionProvider { + + /** + * + * @return new {@link ServerTraceConnection} + */ + public final IServerConnection getISeverConnection() { + ServerTraceConnection conn = new ServerTraceConnection(); + return conn; + } + +} diff --git a/de.prob.core/src/de/prob/core/langdep/EventBAnimatorPart.java b/de.prob.core/src/de/prob/core/langdep/EventBAnimatorPart.java new file mode 100644 index 0000000000000000000000000000000000000000..6a91648f7f008b0cdc7d4c651554e0f9fcba1314 --- /dev/null +++ b/de.prob.core/src/de/prob/core/langdep/EventBAnimatorPart.java @@ -0,0 +1,281 @@ +/** + * + */ +package de.prob.core.langdep; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import org.apache.commons.lang.ObjectUtils; +import org.eventb.core.IEventBRoot; +import org.eventb.core.IMachineRoot; +import org.eventb.core.ISCEvent; +import org.eventb.core.ISCIdentifierElement; +import org.eventb.core.ISCMachineRoot; +import org.eventb.core.ISCParameter; +import org.eventb.core.ISCVariable; +import org.eventb.core.ast.ASTProblem; +import org.eventb.core.ast.Expression; +import org.eventb.core.ast.Formula; +import org.eventb.core.ast.FormulaFactory; +import org.eventb.core.ast.IParseResult; +import org.eventb.core.ast.ITypeCheckResult; +import org.eventb.core.ast.ITypeEnvironment; +import org.eventb.core.ast.LanguageVersion; +import org.eventb.core.ast.Predicate; +import org.eventb.core.ast.Type; +import org.rodinp.core.IRodinFile; +import org.rodinp.core.RodinDBException; + +import de.be4.classicalb.core.parser.analysis.prolog.ASTProlog; +import de.be4.classicalb.core.parser.node.Node; +import de.prob.core.Animator; +import de.prob.core.LanguageDependendAnimationPart; +import de.prob.core.command.LoadEventBModelCommand; +import de.prob.eventb.translator.ExpressionVisitor; +import de.prob.eventb.translator.FormulaTranslator; +import de.prob.eventb.translator.PredicateVisitor; +import de.prob.exceptions.ProBException; +import de.prob.parserbase.ProBParseException; +import de.prob.prolog.output.IPrologTermOutput; + +/** + * @author plagge + * + */ +public class EventBAnimatorPart implements LanguageDependendAnimationPart { + private static final String EXPR_WRAPPER = "bexpr"; + private static final String PRED_WRAPPER = "bpred"; + private static final String TRANS_WRAPPER = "btrans"; + + private final IEventBRoot root; + + public EventBAnimatorPart(final IEventBRoot root) { + this.root = root; + } + + public void parseExpression(final IPrologTermOutput pto, + final String expression1, final boolean wrap) + throws ProBParseException { + final String expression = FormulaTranslator.translate( + expression1); + final FormulaFactory ff = FormulaFactory.getDefault(); + final IParseResult parseResult = ff.parseExpression(expression, + LanguageVersion.LATEST, null); + checkParseResult(parseResult); + final Expression ee = parseResult.getParsedExpression(); + typeCheck(ff, ee); + final ExpressionVisitor visitor = new ExpressionVisitor( + new LinkedList<String>()); + ee.accept(visitor); + toPrologTerm(pto, visitor.getExpression(), wrap, EXPR_WRAPPER); + } + + public void parsePredicate(final IPrologTermOutput pto, + final String predicate1, final boolean wrap) + throws ProBParseException { + final String predicate = FormulaTranslator.translate( + predicate1); + final FormulaFactory ff = FormulaFactory.getDefault(); + final IParseResult parseResult = ff.parsePredicate(predicate, + LanguageVersion.LATEST, null); + checkParseResult(parseResult); + final Predicate pp = parseResult.getParsedPredicate(); + typeCheck(ff, pp); + final PredicateVisitor visitor = new PredicateVisitor( + new LinkedList<String>()); + pp.accept(visitor); + toPrologTerm(pto, visitor.getPredicate(), wrap, PRED_WRAPPER); + } + + private void toPrologTerm(final IPrologTermOutput pto, + final Node formulaNode, final boolean wrap, final String wrapper) + throws ProBParseException { + if (wrap) { + pto.openTerm(wrapper); + } + final ASTProlog prolog = new ASTProlog(pto, null); + formulaNode.apply(prolog); + if (wrap) { + pto.closeTerm(); + } + } + + private void typeCheck(final FormulaFactory ff, final Formula<?> pp) + throws ProBParseException { + typeCheck(pp, getTypeEnvironment(ff)); + } + + private void typeCheck(final Formula<?> pp, + final ITypeEnvironment typeEnvironment) throws ProBParseException { + final ITypeCheckResult tcr = pp.typeCheck(typeEnvironment); + if (tcr.hasProblem()) { + final List<ASTProblem> problems = tcr.getProblems(); + final ASTProblem problem = problems.iterator().next(); + throw new ProBParseException(problem.toString()); + } + final ITypeEnvironment inferred = tcr.getInferredEnvironment(); + if (!inferred.isEmpty()) { + final Set<String> names = inferred.getNames(); + throw new ProBParseException("unknown identifier: " + + names.toString()); + } + } + + private ITypeEnvironment getTypeEnvironment(final FormulaFactory ff) + throws ProBParseException { + final ITypeEnvironment typeEnv; + try { + typeEnv = root.getSCMachineRoot().getTypeEnvironment(ff); + } catch (RodinDBException e) { + throw rodin2parseException(e); + } + return typeEnv; + } + + private void checkParseResult(final IParseResult parseResult) + throws ProBParseException { + if (parseResult.hasProblem()) + throw new ProBParseException(parseResult.getProblems().toString()); + } + + public void reload(final Animator animator) throws ProBException { + LoadEventBModelCommand.load(animator, root); + } + + public void parseTransitionPredicate(final IPrologTermOutput pto, + final String transPredicate, final boolean wrap) + throws ProBParseException, UnsupportedOperationException { + if (root instanceof IMachineRoot) { + final String event; + final String predicate; + int sepIndex = transPredicate.indexOf("|"); + if (sepIndex < 0) { + event = transPredicate.trim(); + predicate = null; + } else { + event = transPredicate.substring(0, sepIndex).trim(); + predicate = transPredicate.substring(sepIndex + 1); + } + parseTransition(pto, wrap, event, predicate); + } else + throw new UnsupportedOperationException( + "predicates on transitions are only supported when animating machines"); + } + + private void parseTransition(final IPrologTermOutput pto, + final boolean wrap, final String eventName, + final String predicateString) throws ProBParseException { + final ISCEvent event = getEvent(eventName); + final Predicate predicate = predicateString == null ? null + : parseTransPredicate(predicateString, event); + printTransPred(pto, wrap, eventName, predicate); + } + + private ISCEvent getEvent(final String eventName) throws ProBParseException { + final ISCMachineRoot machine = ((IMachineRoot) root).getSCMachineRoot(); + try { + for (final ISCEvent event : machine.getSCEvents()) { + if (ObjectUtils.equals(event.getLabel(), eventName)) + return event; + } + throw new ProBParseException("unknown event " + eventName); + } catch (RodinDBException e) { + throw rodin2parseException(e); + } + } + + private Predicate parseTransPredicate(final String predicateString, + final ISCEvent event) throws ProBParseException { + final String utf8String = FormulaTranslator.translate( + predicateString); + final FormulaFactory ff = FormulaFactory.getDefault(); + final IParseResult parseResult = ff.parsePredicate(utf8String, + LanguageVersion.LATEST, null); + checkParseResult(parseResult); + final Predicate predicate = parseResult.getParsedPredicate(); + final ITypeEnvironment typeEnv = getTypeEnvironment(ff).clone(); + addEventParameters(event, ff, typeEnv, new ArrayList<String>()); + final ISCMachineRoot machine = ((IMachineRoot) root).getSCMachineRoot(); + addPostStateVariables(machine, ff, typeEnv, new ArrayList<String>()); + typeCheck(predicate, typeEnv); + return predicate; + } + + private void addPostStateVariables(final ISCMachineRoot machine, + final FormulaFactory ff, final ITypeEnvironment typeEnv, + final ArrayList<String> allVariables) throws ProBParseException { + try { + final ISCVariable[] variables = machine.getSCVariables(); + addAllIdentifiers(ff, typeEnv, allVariables, variables, "'"); + for (final IRodinFile refMachine : machine.getAbstractSCMachines()) { + ISCMachineRoot absMachine = (ISCMachineRoot) refMachine + .getRoot(); + addPostStateVariables(absMachine, ff, typeEnv, allVariables); + } + } catch (RodinDBException e) { + throw rodin2parseException(e); + } + } + + private void addEventParameters(final ISCEvent event, + final FormulaFactory ff, final ITypeEnvironment typeEnv, + final Collection<String> allParameters) throws ProBParseException { + try { + ISCParameter[] params = event.getSCParameters(); + addAllIdentifiers(ff, typeEnv, allParameters, params, ""); + // TODO: The Prolog side does not handle abstract parameters yet + // As soon that is solved, the following code can be enabled + // for (final ISCEvent absEvent : event.getAbstractSCEvents()) { + // addEventParameters(absEvent, ff, typeEnv, allParameters); + // } + } catch (RodinDBException e) { + throw rodin2parseException(e); + } + } + + private void addAllIdentifiers(final FormulaFactory ff, + final ITypeEnvironment typeEnv, + final Collection<String> allParameters, + final ISCIdentifierElement[] ids, final String postfix) + throws RodinDBException { + for (final ISCIdentifierElement identifier : ids) { + final String name = identifier.getIdentifierString() + postfix; + if (!allParameters.contains(name)) { + final Type type = identifier.getType(ff); + typeEnv.addName(name, type); + allParameters.add(name); + } + } + } + + private ProBParseException rodin2parseException(final RodinDBException e) { + return new ProBParseException( + "Error in the underlying Rodin Database: " + + e.getLocalizedMessage()); + } + + private void printTransPred(final IPrologTermOutput pto, + final boolean wrap, final String eventName, + final Predicate predicate) { + if (wrap) { + pto.openTerm(TRANS_WRAPPER); + } + pto.openTerm("event"); + pto.printAtom(eventName); + if (predicate != null) { + final PredicateVisitor visitor = new PredicateVisitor( + new LinkedList<String>()); + predicate.accept(visitor); + final ASTProlog prolog = new ASTProlog(pto, null); + visitor.getPredicate().apply(prolog); + } + pto.closeTerm(); + if (wrap) { + pto.closeTerm(); + } + } +} diff --git a/de.prob.core/src/de/prob/core/prolog/TypedIdentifierGenerator.java b/de.prob.core/src/de/prob/core/prolog/TypedIdentifierGenerator.java new file mode 100644 index 0000000000000000000000000000000000000000..1beb714f1be0f6bea5d9ecb6437c6c2331013f8f --- /dev/null +++ b/de.prob.core/src/de/prob/core/prolog/TypedIdentifierGenerator.java @@ -0,0 +1,251 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.prolog; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import de.prob.core.types.BaseProbType; +import de.prob.core.types.CoupleProbType; +import de.prob.core.types.FreetypeProbType; +import de.prob.core.types.GivenSetProbType; +import de.prob.core.types.OperationProbType; +import de.prob.core.types.ProbDataType; +import de.prob.core.types.RecordProbType; +import de.prob.core.types.SequenceDataType; +import de.prob.core.types.SetProbType; +import de.prob.core.types.TypedIdentifier; +import de.prob.prolog.term.CompoundPrologTerm; +import de.prob.prolog.term.ListPrologTerm; +import de.prob.prolog.term.PrologTerm; + +/** + * Generates a typed identifier from a Prolog term. + * + * @author plagge + * + */ +public class TypedIdentifierGenerator { + private static final Map<String, Handler> handlers = initHandlers(); + + public static TypedIdentifier[] extract(final ListPrologTerm list) { + TypedIdentifier[] result = new TypedIdentifier[list.size()]; + for (int i = 0; i < list.size(); i++) { + PrologTerm element = list.get(i); + if (element.isTerm()) { + result[i] = extract((CompoundPrologTerm) element); + } else + throw expectationFailed("list of compound terms", element); + } + return result; + } + + public static TypedIdentifier extract(final CompoundPrologTerm term) { + final TypedIdentifier typedIdentifier; + if (term.hasFunctor("b", 3)) { + final String name = getIdentifier(term.getArgument(1)); + final ProbDataType type = extractType(term.getArgument(2)); + final String[] sections = extractSections(term.getArgument(3)); + typedIdentifier = new TypedIdentifier(name, type, sections); + } else + throw expectationFailed("b/3", term); + return typedIdentifier; + } + + private static String[] extractSections(final PrologTerm term) { + if (term.isList()) { + String[] sections = null; + for (PrologTerm arg : ((ListPrologTerm) term)) { + if (arg.hasFunctor("occurrences", 1)) { + PrologTerm psections = ((CompoundPrologTerm) arg) + .getArgument(1); + if (psections.isList()) { + sections = extractSectionsFromList((ListPrologTerm) psections); + } else + throw expectationFailed("list of sections", psections); + } + } + return sections; + } else + throw expectationFailed("list of identifier informations", term); + } + + private static String[] extractSectionsFromList( + final ListPrologTerm psections) { + String[] sections = new String[psections.size()]; + for (int i = 0; i < psections.size(); i++) { + PrologTerm term = psections.get(i); + if (term.isAtom()) { + sections[i] = ((CompoundPrologTerm) term).getFunctor(); + } + } + return sections; + } + + /** + * Generates a single Prob data type from a Prolog term like ProB sends + * them. + * + * @param aterm + * the prolog term representing the type, never <code>null</code> + * @return the prolog type, never <code>null</code> + * @throws IllegalArgumentException + * if the prolog term cannot be handled. + */ + public static ProbDataType extractType(final PrologTerm aterm) { + ProbDataType type; + if (aterm.isTerm()) { + CompoundPrologTerm term = (CompoundPrologTerm) aterm; + String functor = term.getFunctor(); + String lookup = functor + "/" + term.getArity(); + Handler handler = handlers.get(lookup); + if (handler != null) { + type = handler.handle(term); + } else + throw new IllegalArgumentException("unknown type handler for " + + lookup); + } else + throw expectationFailed("compound term", aterm); + return type; + } + + private static String getIdentifier(final PrologTerm term) { + final String name; + if (term.hasFunctor("identifier", 1)) { + final PrologTerm arg1 = ((CompoundPrologTerm) term).getArgument(1); + name = arg1.isAtom() ? PrologTerm.atomicString(arg1) : arg1 + .toString(); + } else + throw expectationFailed("identifier/1", term); + return name; + } + + private static IllegalArgumentException expectationFailed( + final String expected, final PrologTerm term) { + return new IllegalArgumentException("expected " + expected + + ", but was: " + term.toString()); + } + + private static Map<String, Handler> initHandlers() { + Map<String, Handler> handlers = new HashMap<String, Handler>(); + handlers.put("integer/0", new BasicHandler(BaseProbType.INTEGER)); + handlers.put("string/0", new BasicHandler(BaseProbType.STRING)); + handlers.put("boolean/0", new BasicHandler(BaseProbType.BOOL)); + handlers.put("pred/0", new BasicHandler(BaseProbType.PREDICATE)); + handlers.put("subst/0", new BasicHandler(BaseProbType.SUBSTITUTION)); + handlers.put("any/0", new BasicHandler(BaseProbType.ANY)); + handlers.put("set/1", new SetHandler()); + handlers.put("seq/1", new SeqHandler()); + handlers.put("global/1", new GivenSetHandler()); + handlers.put("couple/2", new CoupleHandler()); + handlers.put("op/2", new OperationHandler()); + handlers.put("freetype/1", new FreetypeHandler()); + handlers.put("record/1", new RecordHandler()); + return Collections.unmodifiableMap(handlers); + } + + private interface Handler { + ProbDataType handle(CompoundPrologTerm term); + } + + private static class BasicHandler implements Handler { + private final ProbDataType type; + + public BasicHandler(final ProbDataType type) { + super(); + this.type = type; + } + + public ProbDataType handle(final CompoundPrologTerm term) { + return type; + } + + } + + private static class SetHandler implements Handler { + public ProbDataType handle(final CompoundPrologTerm term) { + return new SetProbType(extractType(term.getArgument(1))); + } + } + + private static class SeqHandler implements Handler { + public ProbDataType handle(final CompoundPrologTerm term) { + return new SequenceDataType(extractType(term.getArgument(1))); + } + } + + private static class GivenSetHandler implements Handler { + public ProbDataType handle(final CompoundPrologTerm term) { + return new GivenSetProbType(getString(term.getArgument(1))); + } + } + + private static class CoupleHandler implements Handler { + public ProbDataType handle(final CompoundPrologTerm term) { + return new CoupleProbType(extractType(term.getArgument(1)), + extractType(term.getArgument(2))); + } + } + + private static class OperationHandler implements Handler { + public ProbDataType handle(final CompoundPrologTerm term) { + ProbDataType[] results = createList(term.getArgument(1)); + ProbDataType[] params = createList(term.getArgument(2)); + return new OperationProbType(results, params); + } + } + + private static class FreetypeHandler implements Handler { + public ProbDataType handle(final CompoundPrologTerm term) { + return new FreetypeProbType(getString(term.getArgument(1))); + } + } + + private static class RecordHandler implements Handler { + public ProbDataType handle(final CompoundPrologTerm term) { + if (term.getArgument(1) instanceof ListPrologTerm) { + ListPrologTerm list = (ListPrologTerm) term.getArgument(1); + Map<String, ProbDataType> fields = new HashMap<String, ProbDataType>(); + for (int i = 0; i < list.size(); i++) { + PrologTerm field = list.get(i); + if (field.hasFunctor("field", 2)) { + final CompoundPrologTerm cfield = (CompoundPrologTerm) field; + final ProbDataType ftype = extractType(cfield + .getArgument(2)); + fields.put(getString(cfield.getArgument(1)), ftype); + } else + throw new IllegalArgumentException( + "expected field/2, but was: " + + field.toString()); + } + return new RecordProbType(fields); + } else + throw new IllegalArgumentException( + "expected field list, but was: " + term.toString()); + } + } + + private static String getString(final PrologTerm term) { + return term.isAtom() ? ((CompoundPrologTerm) term).getFunctor() : term + .toString(); + } + + private static ProbDataType[] createList(final PrologTerm term) { + ProbDataType[] result; + if (term instanceof ListPrologTerm) { + ListPrologTerm list = (ListPrologTerm) term; + result = new ProbDataType[list.size()]; + for (int i = 0; i < list.size(); i++) { + result[i] = extractType(list.get(i)); + } + } else + throw new IllegalArgumentException("expected list, but was: " + + term.toString()); + return result; + } +} diff --git a/de.prob.core/src/de/prob/core/translator/ITranslator.java b/de.prob.core/src/de/prob/core/translator/ITranslator.java new file mode 100644 index 0000000000000000000000000000000000000000..019fbc2d27e8edd0701ebf9c38bf354848317b13 --- /dev/null +++ b/de.prob.core/src/de/prob/core/translator/ITranslator.java @@ -0,0 +1,11 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.translator; + +public interface ITranslator { + +} \ No newline at end of file diff --git a/de.prob.core/src/de/prob/core/translator/TranslationFailedException.java b/de.prob.core/src/de/prob/core/translator/TranslationFailedException.java new file mode 100644 index 0000000000000000000000000000000000000000..bb5a1fb6e8b3b20d2032f27880866b171dbffd1a --- /dev/null +++ b/de.prob.core/src/de/prob/core/translator/TranslationFailedException.java @@ -0,0 +1,25 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.translator; + +import de.prob.exceptions.ProBException; + +public class TranslationFailedException extends ProBException { + + private static final long serialVersionUID = 591728225914801177L; + + public TranslationFailedException(final Exception e) { + super(e); + } + + public TranslationFailedException(final String component, + final String details) { + super("Translation of " + component + " failed\n" + details); + notifyUserOnce(); + } + +} diff --git a/de.prob.core/src/de/prob/core/types/BaseProbType.java b/de.prob.core/src/de/prob/core/types/BaseProbType.java new file mode 100644 index 0000000000000000000000000000000000000000..ead5001d15f4615ba9b4b270252110c362c1934d --- /dev/null +++ b/de.prob.core/src/de/prob/core/types/BaseProbType.java @@ -0,0 +1,57 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.types; + +/** + * The basic data types like INTEGER, BOOL and STRING. These are a singleton + * types. (well, actually they are multitons) + * + * @author plagge + */ +public class BaseProbType extends ProbDataType { + public final static BaseProbType INTEGER = new BaseProbType("INTEGER"); + public final static BaseProbType BOOL = new BaseProbType("BOOLEAN"); + public final static BaseProbType STRING = new BaseProbType("STRING"); + public final static BaseProbType ANY = new BaseProbType("?"); + public final static BaseProbType PREDICATE = new BaseProbType("predicate"); + public final static BaseProbType SUBSTITUTION = new BaseProbType( + "substitution"); + + private final String type; + + private BaseProbType(final String type) { + super(); + this.type = type; + } + + public int getOperatorPriority() { + return 1000; + } + + public void prettyprint(final StringBuilder builder) { + builder.append(type); + } + + @Override + public boolean equals(final Object other) { + boolean isEqual; + if (other == this) { + isEqual = true; + } else if (other != null && other instanceof BaseProbType) { + isEqual = type.equals(((BaseProbType) other).type); + } else { + isEqual = false; + } + return isEqual; + } + + @Override + public int hashCode() { + return type.hashCode() * 37 + 10; + } + +} diff --git a/de.prob.core/src/de/prob/core/types/CoupleProbType.java b/de.prob.core/src/de/prob/core/types/CoupleProbType.java new file mode 100644 index 0000000000000000000000000000000000000000..0f41568ba222cf655ce6992db1b9fa02ea7381ba --- /dev/null +++ b/de.prob.core/src/de/prob/core/types/CoupleProbType.java @@ -0,0 +1,59 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +/** + * + */ +package de.prob.core.types; + +/** + * The ProB data type couple(A,B) + * + * @author plagge + */ +public class CoupleProbType extends ProbDataType { + private final ProbDataType left, right; + + public CoupleProbType(final ProbDataType left, final ProbDataType right) { + super(); + if (left == null || right == null) { + throw new IllegalArgumentException( + "Subtypes of couple data type must not be null"); + } + this.left = left; + this.right = right; + } + + public int getOperatorPriority() { + return 190; + } + + public void prettyprint(final StringBuilder builder) { + printWithParenthesis(builder, left, getOperatorPriority()); + builder.append('*'); + printWithParenthesis(builder, right, getOperatorPriority() + 1); + } + + @Override + public boolean equals(final Object other) { + boolean isEqual; + if (other == this) { + isEqual = true; + } else if (other != null && other instanceof CoupleProbType) { + CoupleProbType ocouple = (CoupleProbType) other; + isEqual = left.equals(ocouple.left) && right.equals(ocouple.right); + } else { + isEqual = false; + } + return isEqual; + } + + @Override + public int hashCode() { + return ((left.hashCode() * 13 + right.hashCode()) * 17 + 8); + } + +} diff --git a/de.prob.core/src/de/prob/core/types/FreetypeProbType.java b/de.prob.core/src/de/prob/core/types/FreetypeProbType.java new file mode 100644 index 0000000000000000000000000000000000000000..fe2d3d008e8c1f371da05c504fd120df1a83997f --- /dev/null +++ b/de.prob.core/src/de/prob/core/types/FreetypeProbType.java @@ -0,0 +1,72 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +/** + * + */ +package de.prob.core.types; + +/** + * Representation of a ProB data type free type + * + * @author plagge + */ +public class FreetypeProbType extends ProbDataType { + private final String identifier; + + public FreetypeProbType(final String identifier) { + super(); + if (identifier == null) { + throw new IllegalArgumentException( + "Freetype identifier must not be null"); + } + this.identifier = identifier; + } + + public int getOperatorPriority() { + return 500; + } + + public void prettyprint(final StringBuilder builder) { + // builder.append("freetype("); + builder.append(identifier); + // builder.append(':'); + // boolean first = true; + // for (Map.Entry<String, ProbDataType> entry : constructors.entrySet()) { + // if (!first) { + // builder.append(','); + // } + // builder.append(entry.getKey()); + // if (entry.getValue() != null) { + // builder.append('('); + // entry.getValue().prettyprint(builder); + // builder.append(')'); + // } + // first = false; + // } + // builder.append(')'); + } + + @Override + public boolean equals(final Object other) { + boolean isEqual; + if (other == this) { + isEqual = true; + } else if (other != null && other instanceof FreetypeProbType) { + FreetypeProbType fother = (FreetypeProbType) other; + isEqual = identifier.equals(fother.identifier); + } else { + isEqual = false; + } + return isEqual; + } + + @Override + public int hashCode() { + return identifier.hashCode() * 11 + 14; + // return (identifier.hashCode() * 11 + constructors.hashCode()) * 7 + 4; + } +} diff --git a/de.prob.core/src/de/prob/core/types/GivenSetProbType.java b/de.prob.core/src/de/prob/core/types/GivenSetProbType.java new file mode 100644 index 0000000000000000000000000000000000000000..cf8aefc445e51bf7d39b54fc52a693e7d8b65c12 --- /dev/null +++ b/de.prob.core/src/de/prob/core/types/GivenSetProbType.java @@ -0,0 +1,51 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.types; + +/** + * Represents a Prob given set (like in the SETS section of a machine) + * + * @author plagge + */ +public class GivenSetProbType extends ProbDataType { + private final String name; + + public GivenSetProbType(final String name) { + super(); + if (name == null) { + throw new IllegalArgumentException( + "Name of given set must not be null"); + } + this.name = name; + } + + public int getOperatorPriority() { + return 1000; + } + + public void prettyprint(final StringBuilder builder) { + builder.append(name); + } + + @Override + public boolean equals(final Object other) { + boolean isEqual; + if (other == this) { + isEqual = true; + } else if (other != null && other instanceof GivenSetProbType) { + isEqual = name.equals(((GivenSetProbType) other).name); + } else { + isEqual = false; + } + return isEqual; + } + + @Override + public int hashCode() { + return name.hashCode() * 13 + 4; + } +} diff --git a/de.prob.core/src/de/prob/core/types/OperationProbType.java b/de.prob.core/src/de/prob/core/types/OperationProbType.java new file mode 100644 index 0000000000000000000000000000000000000000..cdb6e7653ffeecf1684f7868784df28acce9a668 --- /dev/null +++ b/de.prob.core/src/de/prob/core/types/OperationProbType.java @@ -0,0 +1,99 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +/** + * + */ +package de.prob.core.types; + +import java.util.Arrays; + +/** + * The representation of a ProB operation type + * + * @author plagge + */ +public class OperationProbType extends ProbDataType { + private final ProbDataType[] results, parameters; + + public OperationProbType(final ProbDataType[] results, + final ProbDataType[] parameters) { + super(); + checkValidTypeList(results, "result"); + checkValidTypeList(parameters, "parameter"); + this.results = new ProbDataType[results.length]; + this.parameters = new ProbDataType[parameters.length]; + System.arraycopy(results, 0, this.results, 0, results.length); + System.arraycopy(parameters, 0, this.parameters, 0, parameters.length); + } + + private static void checkValidTypeList(final ProbDataType[] list, + final String name) { + if (list == null) { + throw new IllegalArgumentException(name + + " list of operation type must not be null"); + } + for (ProbDataType elem : list) { + if (elem == null) { + throw new IllegalArgumentException(name + + " list of operation type contains null type"); + } + } + } + + public int getOperatorPriority() { + return results.length == 0 ? 500 : 150; + } + + public void prettyprint(final StringBuilder builder) { + if (results.length > 0) { + printTypeList(builder, results); + builder.append("<--"); + } + builder.append("op("); + printTypeList(builder, parameters); + builder.append(")"); + } + + private static void printTypeList(final StringBuilder builder, + final ProbDataType[] list) { + if (list.length > 0) { + if (list.length == 1) { + list[0].prettyprint(builder); + } else { + boolean first = true; + for (ProbDataType elem : list) { + if (!first) { + builder.append(','); + } + printWithParenthesis(builder, elem, 116); + first = false; + } + } + } + } + + @Override + public boolean equals(final Object other) { + boolean isEqual; + if (other == this) { + isEqual = true; + } else if (other != null && other instanceof OperationProbType) { + OperationProbType opother = (OperationProbType) other; + isEqual = Arrays.equals(results, opother.results) + && Arrays.equals(parameters, opother.parameters); + } else { + isEqual = false; + } + return isEqual; + } + + @Override + public int hashCode() { + return (Arrays.hashCode(results) * 13 + Arrays.hashCode(parameters)) * 17 + 8; + } + +} diff --git a/de.prob.core/src/de/prob/core/types/PrettyPrintable.java b/de.prob.core/src/de/prob/core/types/PrettyPrintable.java new file mode 100644 index 0000000000000000000000000000000000000000..60e586a66d43fa49af06d1f9c4e9c7e4711037d4 --- /dev/null +++ b/de.prob.core/src/de/prob/core/types/PrettyPrintable.java @@ -0,0 +1,30 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.types; + +/** + * An object of a syntax tree (or similiar) that can be pretty-printed. It + * should be able to return the binding priority of the operation that has been + * used inside. + * + * @author plagge + */ +public interface PrettyPrintable { + /** + * Pretty-prints the object + * + * @param builder + * a {@link StringBuilder} that must not be <code>null</code> + */ + void prettyprint(StringBuilder builder); + + /** + * @return the Priority of the binding in the expression, the higher the + * priority, the stronger the binding + */ + int getOperatorPriority(); +} diff --git a/de.prob.core/src/de/prob/core/types/ProbDataType.java b/de.prob.core/src/de/prob/core/types/ProbDataType.java new file mode 100644 index 0000000000000000000000000000000000000000..f824a71c40d328c88e588b63b7551c938fe85c66 --- /dev/null +++ b/de.prob.core/src/de/prob/core/types/ProbDataType.java @@ -0,0 +1,34 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.core.types; + +/** + * Represents a data type like it is used inside ProB. This is the abstract base + * class for the different type implementations. + * + * @author plagge + */ +public abstract class ProbDataType implements PrettyPrintable { + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + prettyprint(sb); + return sb.toString(); + } + + protected final static void printWithParenthesis(StringBuilder builder, + PrettyPrintable toPrint, int minPrio) { + final boolean useParenthesis = toPrint.getOperatorPriority() < minPrio; + if (useParenthesis) { + builder.append('('); + } + toPrint.prettyprint(builder); + if (useParenthesis) { + builder.append(')'); + } + } +} diff --git a/de.prob.core/src/de/prob/core/types/RecordProbType.java b/de.prob.core/src/de/prob/core/types/RecordProbType.java new file mode 100644 index 0000000000000000000000000000000000000000..86357b70e901d0285eed1167a58b8e4bc4c419d8 --- /dev/null +++ b/de.prob.core/src/de/prob/core/types/RecordProbType.java @@ -0,0 +1,82 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +/** + * + */ +package de.prob.core.types; + +import java.util.Map; +import java.util.SortedMap; +import java.util.TreeMap; + +/** + * Representation of the ProB data type record(...) a.k.a. struct(...) + * + * @author plagge + */ +public class RecordProbType extends ProbDataType { + private final SortedMap<String, ProbDataType> fields; + + public RecordProbType(final Map<String, ProbDataType> fields) { + super(); + if (fields == null) { + throw new IllegalArgumentException("fields must not be null"); + } + if (fields.containsValue(null)) { + String invalidField = getNullField(fields); + throw new IllegalArgumentException("field " + invalidField + + " has null type"); + } + this.fields = new TreeMap<String, ProbDataType>(fields); + } + + private static String getNullField(final Map<String, ProbDataType> fields) { + for (Map.Entry<String, ProbDataType> entry : fields.entrySet()) { + if (entry.getValue() == null) { + return entry.getKey(); + } + } + throw new IllegalStateException("no null field found"); + } + + public int getOperatorPriority() { + return 500; + } + + public void prettyprint(final StringBuilder builder) { + builder.append("struct("); + boolean first = true; + for (Map.Entry<String, ProbDataType> entry : fields.entrySet()) { + if (!first) { + builder.append(','); + } + builder.append(entry.getKey()); + builder.append(':'); + printWithParenthesis(builder, entry.getValue(), 81); + first = false; + } + builder.append(')'); + } + + @Override + public boolean equals(final Object other) { + boolean isEqual; + if (other == this) { + isEqual = true; + } else if (other != null && other instanceof RecordProbType) { + isEqual = fields.equals(((RecordProbType) other).fields); + } else { + isEqual = false; + } + return isEqual; + } + + @Override + public int hashCode() { + return fields.hashCode() * 17 + 2; + } +} diff --git a/de.prob.core/src/de/prob/core/types/SequenceDataType.java b/de.prob.core/src/de/prob/core/types/SequenceDataType.java new file mode 100644 index 0000000000000000000000000000000000000000..4fc208017b5a2c9abafed910d9d7816b3438cd87 --- /dev/null +++ b/de.prob.core/src/de/prob/core/types/SequenceDataType.java @@ -0,0 +1,23 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +/** + * + */ +package de.prob.core.types; + +/** + * The ProB data type seq(...) + * + * @author plagge + */ +public class SequenceDataType extends SetLikeProbType { + private static final String SEQ = "seq"; + + public SequenceDataType(ProbDataType innerType) { + super(SEQ, innerType); + } +} diff --git a/de.prob.core/src/de/prob/core/types/SetLikeProbType.java b/de.prob.core/src/de/prob/core/types/SetLikeProbType.java new file mode 100644 index 0000000000000000000000000000000000000000..a45063c770efc577502725bdeb6f28a6441a4a7b --- /dev/null +++ b/de.prob.core/src/de/prob/core/types/SetLikeProbType.java @@ -0,0 +1,66 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +/** + * + */ +package de.prob.core.types; + +/** + * The base class for ProB data types like set(...) or seq(...). + * + * @author plagge + */ +public abstract class SetLikeProbType extends ProbDataType { + private final String variant; + private final ProbDataType innerType; + + protected SetLikeProbType(final String variant, final ProbDataType innerType) { + super(); + if (innerType == null) { + throw new IllegalArgumentException("Inner type to " + variant + + " constructor must not be null"); + } + this.variant = variant; + this.innerType = innerType; + } + + public int getOperatorPriority() { + return 500; + } + + public void prettyprint(final StringBuilder builder) { + builder.append(variant); + builder.append('('); + innerType.prettyprint(builder); + builder.append(')'); + } + + public ProbDataType getInnerType() { + return innerType; + } + + @Override + public boolean equals(final Object other) { + boolean isEqual; + if (other == this) { + isEqual = true; + } else if (other != null && other instanceof SetLikeProbType) { + SetLikeProbType setlikeother = (SetLikeProbType) other; + isEqual = variant == setlikeother.variant + && innerType.equals(setlikeother.innerType); + } else { + isEqual = false; + } + return isEqual; + } + + @Override + public int hashCode() { + return innerType.hashCode() * 17 + variant.hashCode(); + } + +} diff --git a/de.prob.core/src/de/prob/core/types/SetProbType.java b/de.prob.core/src/de/prob/core/types/SetProbType.java new file mode 100644 index 0000000000000000000000000000000000000000..1628179bb77176526e7ae8c14324d471f73ab793 --- /dev/null +++ b/de.prob.core/src/de/prob/core/types/SetProbType.java @@ -0,0 +1,23 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +/** + * + */ +package de.prob.core.types; + +/** + * The ProB data type POW(...) + * + * @author plagge + */ +public class SetProbType extends SetLikeProbType { + private static final String POW = "POW"; + + public SetProbType(ProbDataType innerType) { + super(POW, innerType); + } +} diff --git a/de.prob.core/src/de/prob/core/types/TypedIdentifier.java b/de.prob.core/src/de/prob/core/types/TypedIdentifier.java new file mode 100644 index 0000000000000000000000000000000000000000..aa1bcc20c39253f26470d7f0667136401e74b277 --- /dev/null +++ b/de.prob.core/src/de/prob/core/types/TypedIdentifier.java @@ -0,0 +1,91 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +/** + * + */ +package de.prob.core.types; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + +/** + * An ProB identifier together with its type + * + * @author plagge + */ +public class TypedIdentifier { + private final String name; + private final ProbDataType type; + private final Collection<String> sections; + + /** + * Creates a typed identifier + * + * @param name + * its name, never <code>null</code> + * @param type + * its type, never <code>null</code> + */ + public TypedIdentifier(final String name, final ProbDataType type, + final String[] sections) { + super(); + if (name == null || type == null) + throw new IllegalArgumentException( + "Name and type of a typed identifier must not be null"); + this.name = name; + this.type = type; + if (sections == null) { + this.sections = Collections.emptyList(); + } else { + this.sections = Collections.unmodifiableCollection(Arrays + .asList(sections)); + } + } + + /** + * @return Name of the identifier, never <code>null</code> + */ + public String getName() { + return name; + } + + /** + * + * @return the type of the identifier, never <code>null</code> + */ + public ProbDataType getType() { + return type; + } + + /** + * @return the list of sections (contextes or models) where this identifier + * occurs + */ + public Collection<String> getSections() { + return sections; + } + + @Override + public boolean equals(final Object other) { + boolean isEqual; + if (this == other) { + isEqual = true; + } else if (other != null && other instanceof TypedIdentifier) { + TypedIdentifier ti = (TypedIdentifier) other; + return name.equals(ti.name) && type.equals(ti.type); + } else { + isEqual = false; + } + return isEqual; + } + + @Override + public int hashCode() { + return (name.hashCode() * 23 + type.hashCode()) * 11 + 24; + } +} diff --git a/de.prob.core/src/de/prob/eventb/translator/AbstractComponentTranslator.java b/de.prob.core/src/de/prob/eventb/translator/AbstractComponentTranslator.java new file mode 100644 index 0000000000000000000000000000000000000000..25be5558b80be28bb96fd42eca4530acf9614932 --- /dev/null +++ b/de.prob.core/src/de/prob/eventb/translator/AbstractComponentTranslator.java @@ -0,0 +1,25 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.eventb.translator; + +import java.util.Collections; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.rodinp.core.IInternalElement; + +import de.be4.classicalb.core.parser.node.Node; + +public abstract class AbstractComponentTranslator { + + protected final Map<Node, IInternalElement> labelMapping = new ConcurrentHashMap<Node, IInternalElement>(); + + public Map<Node, IInternalElement> getLabelMapping() { + return Collections.unmodifiableMap(labelMapping); + } + +} \ No newline at end of file diff --git a/de.prob.core/src/de/prob/eventb/translator/AssignmentVisitor.java b/de.prob.core/src/de/prob/eventb/translator/AssignmentVisitor.java new file mode 100644 index 0000000000000000000000000000000000000000..a27ce9ff66b0540666ecd3534a393ca494b514da --- /dev/null +++ b/de.prob.core/src/de/prob/eventb/translator/AssignmentVisitor.java @@ -0,0 +1,124 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.eventb.translator; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +import org.eventb.core.ast.BecomesEqualTo; +import org.eventb.core.ast.BecomesMemberOf; +import org.eventb.core.ast.BecomesSuchThat; +import org.eventb.core.ast.Expression; +import org.eventb.core.ast.FreeIdentifier; +import org.eventb.core.ast.ISimpleVisitor; +import org.eventb.core.ast.Predicate; + +import de.be4.classicalb.core.parser.node.AAssignSubstitution; +import de.be4.classicalb.core.parser.node.ABecomesElementOfSubstitution; +import de.be4.classicalb.core.parser.node.ABecomesSuchSubstitution; +import de.be4.classicalb.core.parser.node.AIdentifierExpression; +import de.be4.classicalb.core.parser.node.PExpression; +import de.be4.classicalb.core.parser.node.PSubstitution; +import de.be4.classicalb.core.parser.node.TIdentifierLiteral; +import de.prob.eventb.translator.internal.SimpleVisitorAdapter; + +public class AssignmentVisitor extends SimpleVisitorAdapter implements + ISimpleVisitor { + + private PSubstitution sub; + private boolean substitutonSet = false; + + public PSubstitution getSubstitution() { + return sub; + } + + public void setSub(final PSubstitution sub) { + if (substitutonSet) { + throw new AssertionError("The Visitor must not be used twice!"); + } + substitutonSet = true; + this.sub = sub; + } + + @Override + public void visitBecomesEqualTo(final BecomesEqualTo assignment) { + final FreeIdentifier[] identifiers = assignment + .getAssignedIdentifiers(); + final Expression[] expressions = assignment.getExpressions(); + final AAssignSubstitution assignSubstitution = new AAssignSubstitution(); + assignSubstitution + .setLhsExpression(createListOfIdentifiers(identifiers)); + assignSubstitution + .setRhsExpressions(createListOfExpressions(expressions)); + setSub(assignSubstitution); + } + + private List<PExpression> createListOfExpressions( + final Expression[] expressions) { + final List<PExpression> list = new ArrayList<PExpression>(); + for (Expression e : expressions) { + final ExpressionVisitor visitor = new ExpressionVisitor( + new LinkedList<String>()); + e.accept(visitor); + list.add(visitor.getExpression()); + } + return list; + } + + private List<PExpression> createListOfIdentifiers( + final FreeIdentifier[] identifiers) { + final List<PExpression> res = new ArrayList<PExpression>( + identifiers.length); + for (FreeIdentifier freeIdentifier : identifiers) { + final List<TIdentifierLiteral> list = Arrays + .asList(new TIdentifierLiteral[] { new TIdentifierLiteral( + freeIdentifier.getName()) }); + final AIdentifierExpression expression = new AIdentifierExpression(); + expression.setIdentifier(list); + res.add(expression); + } + return res; + } + + @Override + public void visitBecomesMemberOf(final BecomesMemberOf assignment) { + final ABecomesElementOfSubstitution becomesElementOfSubstitution = new ABecomesElementOfSubstitution(); + final FreeIdentifier[] identifiers = assignment + .getAssignedIdentifiers(); + final Expression set = assignment.getSet(); + + final ExpressionVisitor visitor = new ExpressionVisitor( + new LinkedList<String>()); + set.accept(visitor); + + becomesElementOfSubstitution + .setIdentifiers(createListOfIdentifiers(identifiers)); + becomesElementOfSubstitution.setSet(visitor.getExpression()); + setSub(becomesElementOfSubstitution); + } + + @Override + public void visitBecomesSuchThat(final BecomesSuchThat assignment) { + final FreeIdentifier[] identifiers = assignment + .getAssignedIdentifiers(); + LinkedList<String> list = new LinkedList<String>(); + for (FreeIdentifier f : identifiers) { + list.addFirst(f.getName() + "'"); + } + final Predicate predicate = assignment.getCondition(); + final PredicateVisitor visitor = new PredicateVisitor(list); + predicate.accept(visitor); + final ABecomesSuchSubstitution becomesSuchSubstitution = new ABecomesSuchSubstitution(); + becomesSuchSubstitution + .setIdentifiers(createListOfIdentifiers(identifiers)); + becomesSuchSubstitution.setPredicate(visitor.getPredicate()); + setSub(becomesSuchSubstitution); + + } +} diff --git a/de.prob.core/src/de/prob/eventb/translator/ContextTranslator.java b/de.prob.core/src/de/prob/eventb/translator/ContextTranslator.java new file mode 100644 index 0000000000000000000000000000000000000000..f255824128ce8947bcc0dbf36454b616147fddd1 --- /dev/null +++ b/de.prob.core/src/de/prob/eventb/translator/ContextTranslator.java @@ -0,0 +1,248 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.eventb.translator; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.runtime.Assert; +import org.eventb.core.IContextRoot; +import org.eventb.core.IExtendsContext; +import org.eventb.core.ISCAxiom; +import org.eventb.core.ISCCarrierSet; +import org.eventb.core.ISCConstant; +import org.eventb.core.ISCContext; +import org.eventb.core.ISCContextRoot; +import org.eventb.core.ISCExtendsContext; +import org.eventb.core.ISCInternalContext; +import org.eventb.core.ISCMachineRoot; +import org.eventb.core.ast.FormulaFactory; +import org.eventb.core.ast.ITypeEnvironment; +import org.rodinp.core.IRodinFile; +import org.rodinp.core.RodinDBException; + +import de.be4.classicalb.core.parser.node.AAxiomsContextClause; +import de.be4.classicalb.core.parser.node.AConstantsContextClause; +import de.be4.classicalb.core.parser.node.ADeferredSet; +import de.be4.classicalb.core.parser.node.AEventBContextParseUnit; +import de.be4.classicalb.core.parser.node.AExtendsContextClause; +import de.be4.classicalb.core.parser.node.AIdentifierExpression; +import de.be4.classicalb.core.parser.node.ASetsContextClause; +import de.be4.classicalb.core.parser.node.ATheoremsContextClause; +import de.be4.classicalb.core.parser.node.PContextClause; +import de.be4.classicalb.core.parser.node.PExpression; +import de.be4.classicalb.core.parser.node.PPredicate; +import de.be4.classicalb.core.parser.node.PSet; +import de.be4.classicalb.core.parser.node.TIdentifierLiteral; +import de.prob.core.translator.TranslationFailedException; + +public final class ContextTranslator extends AbstractComponentTranslator { + + private final ISCContext context; + private final AEventBContextParseUnit model = new AEventBContextParseUnit(); + private final Map<String, ISCContext> depContext = new HashMap<String, ISCContext>(); + private final FormulaFactory ff; + + // Confined in the thread calling the factory method + private ITypeEnvironment te; + + public static ContextTranslator create(final ISCContext context) + throws TranslationFailedException { + ContextTranslator contextTranslator = new ContextTranslator(context); + try { + contextTranslator.translate(); + } catch (RodinDBException e) { + final String message = "A Rodin exception occured during translation process. Possible cause: building aborted or still in progress. Please wait until building has finished before starting ProB. If this does not help, perform a clean and start ProB after building has finished. Original Exception: "; + throw new TranslationFailedException(context.getComponentName(), + message + e.getLocalizedMessage()); + } + return contextTranslator; + } + + /** + * Translates a Rodin EventB Context into the ProB AST. Note, that this + * constructor might throw an RodinDBException, if the file is corrupted + * (i.e. the model is inconsistent with its underlying resource or it + * contains errors) + * + * @param context + * @throws RodinDBException + */ + private ContextTranslator(final ISCContext context) { + this.context = context; + ff = FormulaFactory.getDefault(); + } + + private void translate() throws RodinDBException { + if (context instanceof ISCContextRoot) { + ISCContextRoot context_root = (ISCContextRoot) context; + Assert.isTrue(context_root.getRodinFile().isConsistent()); + te = context_root.getTypeEnvironment(ff); + } else if (context instanceof ISCInternalContext) { + ISCInternalContext context_internal = (ISCInternalContext) context; + ISCMachineRoot machine_root = (ISCMachineRoot) context_internal + .getRoot(); + Assert.isTrue(machine_root.getRodinFile().isConsistent()); + te = machine_root.getTypeEnvironment(ff); + } + translateContext(); + + } + + public AEventBContextParseUnit getContextAST() { + return model; + } + + public Map<String, ISCContext> getContextDependencies() { + return depContext; + } + + private void translateContext() throws RodinDBException { + model.setName(new TIdentifierLiteral(context.getComponentName())); + + final List<PContextClause> clauses = new ArrayList<PContextClause>(); + clauses.add(processExtends()); + clauses.add(processConstants()); + clauses.add(processAxioms()); + clauses.add(processTheorems()); + clauses.add(processSets()); + model.setContextClauses(clauses); + } + + private AExtendsContextClause processExtends() throws RodinDBException { + + if (context instanceof ISCContextRoot) + return processExtendsForContextRoot(); + else if (context instanceof ISCInternalContext) + return processExtendsForInternalContext(); + else { + // should not be reachable + Assert.isTrue(false); + return null; + } + } + + private AExtendsContextClause processExtendsForInternalContext() + throws RodinDBException { + ISCInternalContext icontext = (ISCInternalContext) context; + IExtendsContext[] extendsClauses = icontext + .getChildrenOfType(IExtendsContext.ELEMENT_TYPE); + + try { + extendsClauses = getSeenContexts(icontext); + } catch (RodinDBException e) { + // Use the default value + } + + final List<TIdentifierLiteral> extendsList = new ArrayList<TIdentifierLiteral>( + extendsClauses.length); + + for (final IExtendsContext extendsContext : extendsClauses) { + final String name = extendsContext.getAbstractSCContext() + .getComponentName(); + extendsList.add(new TIdentifierLiteral(name)); + } + + return new AExtendsContextClause(extendsList); + } + + private IExtendsContext[] getSeenContexts(ISCInternalContext icontext) + throws RodinDBException { + IExtendsContext[] extendsClauses; + String fname = icontext.getComponentName(); + IRodinFile file = icontext.getRodinProject().getRodinFile( + fname + ".buc"); + IContextRoot root = (IContextRoot) file.getRoot(); + extendsClauses = root.getExtendsClauses(); + return extendsClauses; + } + + private AExtendsContextClause processExtendsForContextRoot() + throws RodinDBException { + ISCExtendsContext[] extendsClauses = null; + ISCContextRoot rcontext = (ISCContextRoot) context; + + extendsClauses = rcontext.getSCExtendsClauses(); + + final List<TIdentifierLiteral> extendsList = new ArrayList<TIdentifierLiteral>( + extendsClauses.length); + + for (final ISCExtendsContext extendsContext : extendsClauses) { + ISCContextRoot root = (ISCContextRoot) extendsContext + .getAbstractSCContext().getRoot(); + final String name = extendsContext.getAbstractSCContext() + .getComponentName(); + extendsList.add(new TIdentifierLiteral(name)); + depContext.put(name, root); + } + return new AExtendsContextClause(extendsList); + } + + private ASetsContextClause processSets() throws RodinDBException { + final ISCCarrierSet[] carrierSets = context.getSCCarrierSets(); + final List<PSet> setList = new ArrayList<PSet>(carrierSets.length); + for (final ISCCarrierSet carrierSet : carrierSets) { + final ADeferredSet deferredSet = new ADeferredSet( + Arrays.asList(new TIdentifierLiteral[] { new TIdentifierLiteral( + carrierSet.getIdentifierString()) })); + setList.add(deferredSet); + } + return new ASetsContextClause(setList); + } + + private AConstantsContextClause processConstants() throws RodinDBException { + final ISCConstant[] constants = context.getSCConstants(); + final List<PExpression> list = new ArrayList<PExpression>( + constants.length); + for (final ISCConstant constant : constants) { + list.add(new AIdentifierExpression(Arrays + .asList(new TIdentifierLiteral[] { new TIdentifierLiteral( + constant.getIdentifierString()) }))); + } + + final AConstantsContextClause constantsContextClause = new AConstantsContextClause(); + constantsContextClause.setIdentifiers(list); + return constantsContextClause; + } + + private ATheoremsContextClause processTheorems() throws RodinDBException { + final ISCAxiom[] axioms = context.getSCAxioms(); + final ATheoremsContextClause theoremsContextClause = new ATheoremsContextClause(); + theoremsContextClause.setPredicates(extractPredicates(axioms, true)); + return theoremsContextClause; + } + + private AAxiomsContextClause processAxioms() throws RodinDBException { + final ISCAxiom[] axioms = context.getSCAxioms(); + final AAxiomsContextClause axiomsContextClause = new AAxiomsContextClause(); + axiomsContextClause.setPredicates(extractPredicates(axioms, false)); + return axiomsContextClause; + } + + private List<PPredicate> extractPredicates(final ISCAxiom[] predicates, + final boolean theorems) throws RodinDBException { + final List<PPredicate> list = new ArrayList<PPredicate>( + predicates.length); + for (final ISCAxiom element : predicates) { + if (element.isTheorem() != theorems) { + continue; + } + final PredicateVisitor visitor = new PredicateVisitor( + new LinkedList<String>()); + element.getPredicate(ff, te).accept(visitor); + final PPredicate predicate = visitor.getPredicate(); + list.add(predicate); + labelMapping.put(predicate, element); + } + return list; + } + +} diff --git a/de.prob.core/src/de/prob/eventb/translator/ExpressionVisitor.java b/de.prob.core/src/de/prob/eventb/translator/ExpressionVisitor.java new file mode 100644 index 0000000000000000000000000000000000000000..fdf995104cc7703f52fb91ea69900f855db45812 --- /dev/null +++ b/de.prob.core/src/de/prob/eventb/translator/ExpressionVisitor.java @@ -0,0 +1,708 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.eventb.translator; // NOPMD +// high coupling is ok, we only use the AST nodes + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +import org.eventb.core.ast.AssociativeExpression; +import org.eventb.core.ast.AtomicExpression; +import org.eventb.core.ast.BinaryExpression; +import org.eventb.core.ast.BoolExpression; +import org.eventb.core.ast.BoundIdentDecl; +import org.eventb.core.ast.BoundIdentifier; +import org.eventb.core.ast.Expression; +import org.eventb.core.ast.Formula; +import org.eventb.core.ast.FreeIdentifier; +import org.eventb.core.ast.ISimpleVisitor; +import org.eventb.core.ast.IntegerLiteral; +import org.eventb.core.ast.Predicate; +import org.eventb.core.ast.QuantifiedExpression; +import org.eventb.core.ast.SetExtension; +import org.eventb.core.ast.UnaryExpression; + +import de.be4.classicalb.core.parser.node.AAddExpression; +import de.be4.classicalb.core.parser.node.ABoolSetExpression; +import de.be4.classicalb.core.parser.node.ACardExpression; +import de.be4.classicalb.core.parser.node.ACartesianProductExpression; +import de.be4.classicalb.core.parser.node.ACompositionExpression; +import de.be4.classicalb.core.parser.node.AConvertBoolExpression; +import de.be4.classicalb.core.parser.node.ACoupleExpression; +import de.be4.classicalb.core.parser.node.ADirectProductExpression; +import de.be4.classicalb.core.parser.node.ADivExpression; +import de.be4.classicalb.core.parser.node.ADomainExpression; +import de.be4.classicalb.core.parser.node.ADomainRestrictionExpression; +import de.be4.classicalb.core.parser.node.ADomainSubtractionExpression; +import de.be4.classicalb.core.parser.node.AEmptySetExpression; +import de.be4.classicalb.core.parser.node.AEventBComprehensionSetExpression; +import de.be4.classicalb.core.parser.node.AEventBFirstProjectionExpression; +import de.be4.classicalb.core.parser.node.AEventBFirstProjectionV2Expression; +import de.be4.classicalb.core.parser.node.AEventBIdentityExpression; +import de.be4.classicalb.core.parser.node.AEventBSecondProjectionExpression; +import de.be4.classicalb.core.parser.node.AEventBSecondProjectionV2Expression; +import de.be4.classicalb.core.parser.node.AFalseExpression; +import de.be4.classicalb.core.parser.node.AFunctionExpression; +import de.be4.classicalb.core.parser.node.AGeneralIntersectionExpression; +import de.be4.classicalb.core.parser.node.AGeneralUnionExpression; +import de.be4.classicalb.core.parser.node.AIdentifierExpression; +import de.be4.classicalb.core.parser.node.AIdentityExpression; +import de.be4.classicalb.core.parser.node.AImageExpression; +import de.be4.classicalb.core.parser.node.AIntegerExpression; +import de.be4.classicalb.core.parser.node.AIntegerSetExpression; +import de.be4.classicalb.core.parser.node.AIntersectionExpression; +import de.be4.classicalb.core.parser.node.AIntervalExpression; +import de.be4.classicalb.core.parser.node.AMaxExpression; +import de.be4.classicalb.core.parser.node.AMinExpression; +import de.be4.classicalb.core.parser.node.AMinusExpression; +import de.be4.classicalb.core.parser.node.AModuloExpression; +import de.be4.classicalb.core.parser.node.AMultiplicationExpression; +import de.be4.classicalb.core.parser.node.ANatural1SetExpression; +import de.be4.classicalb.core.parser.node.ANaturalSetExpression; +import de.be4.classicalb.core.parser.node.AOverwriteExpression; +import de.be4.classicalb.core.parser.node.AParallelProductExpression; +import de.be4.classicalb.core.parser.node.APartialFunctionExpression; +import de.be4.classicalb.core.parser.node.APartialInjectionExpression; +import de.be4.classicalb.core.parser.node.APartialSurjectionExpression; +import de.be4.classicalb.core.parser.node.APow1SubsetExpression; +import de.be4.classicalb.core.parser.node.APowSubsetExpression; +import de.be4.classicalb.core.parser.node.APowerOfExpression; +import de.be4.classicalb.core.parser.node.APredecessorExpression; +import de.be4.classicalb.core.parser.node.AQuantifiedIntersectionExpression; +import de.be4.classicalb.core.parser.node.AQuantifiedUnionExpression; +import de.be4.classicalb.core.parser.node.ARangeExpression; +import de.be4.classicalb.core.parser.node.ARangeRestrictionExpression; +import de.be4.classicalb.core.parser.node.ARangeSubtractionExpression; +import de.be4.classicalb.core.parser.node.ARelationsExpression; +import de.be4.classicalb.core.parser.node.AReverseExpression; +import de.be4.classicalb.core.parser.node.ARingExpression; +import de.be4.classicalb.core.parser.node.ASetExtensionExpression; +import de.be4.classicalb.core.parser.node.ASetSubtractionExpression; +import de.be4.classicalb.core.parser.node.ASuccessorExpression; +import de.be4.classicalb.core.parser.node.ASurjectionRelationExpression; +import de.be4.classicalb.core.parser.node.ATotalBijectionExpression; +import de.be4.classicalb.core.parser.node.ATotalFunctionExpression; +import de.be4.classicalb.core.parser.node.ATotalInjectionExpression; +import de.be4.classicalb.core.parser.node.ATotalRelationExpression; +import de.be4.classicalb.core.parser.node.ATotalSurjectionExpression; +import de.be4.classicalb.core.parser.node.ATotalSurjectionRelationExpression; +import de.be4.classicalb.core.parser.node.ATrueExpression; +import de.be4.classicalb.core.parser.node.AUnaryExpression; +import de.be4.classicalb.core.parser.node.AUnionExpression; +import de.be4.classicalb.core.parser.node.PExpression; +import de.be4.classicalb.core.parser.node.PPredicate; +import de.be4.classicalb.core.parser.node.TIdentifierLiteral; +import de.be4.classicalb.core.parser.node.TIntegerLiteral; +import de.prob.eventb.translator.internal.SimpleVisitorAdapter; + +// Complexity is actually quite low for a visitor ;-) +public class ExpressionVisitor extends SimpleVisitorAdapter implements // NOPMD + // by bendisposto + ISimpleVisitor { + + private PExpression e; + private final LinkedList<String> bounds; // NOPMD bendisposto + // we need some abilities of the linked list, using List is not an option + private boolean expressionSet = false; + + @SuppressWarnings("unused") + private ExpressionVisitor() { // we want to prevent clients from calling + // the default constructor + super(); + throw new AssertionError("Do not call this constructor"); + } + + public ExpressionVisitor(final LinkedList<String> bounds) { // NOPMD + super(); + this.bounds = bounds; + } + + public PExpression getExpression() { + return e; + } + + public void setExpression(final PExpression e) { + if (expressionSet) { + throw new AssertionError("The Visitor must not be used twice!"); + } + expressionSet = true; + this.e = e; + } + + @Override + public void visitQuantifiedExpression(final QuantifiedExpression expression) { + // QUNION, QINTER, CSET + final int tag = expression.getTag(); + + final List<ExpressionVisitor> ev = new LinkedList<ExpressionVisitor>(); + + final BoundIdentDecl[] decls = expression.getBoundIdentDecls(); + for (final BoundIdentDecl boundIdentDecl : decls) { + final ExpressionVisitor visitor = new ExpressionVisitor(bounds); + boundIdentDecl.accept(visitor); + ev.add(visitor); + bounds.addFirst(boundIdentDecl.getName()); + } + + // Collect Subtrees in a list. + final LinkedList<PExpression> list = new LinkedList<PExpression>(); + for (final ExpressionVisitor visitor : ev) { + list.add(visitor.getExpression()); + } + + // Process internal Expression and Predcate + final Predicate predicate = expression.getPredicate(); + final PredicateVisitor predicateVisitor = new PredicateVisitor(bounds); + predicate.accept(predicateVisitor); + + final PPredicate pr = predicateVisitor.getPredicate(); + + final ExpressionVisitor expressionVisitor = new ExpressionVisitor( + bounds); + expression.getExpression().accept(expressionVisitor); + + final PExpression ex = expressionVisitor.getExpression(); + + switch (tag) { + case Formula.QUNION: + final AQuantifiedUnionExpression quantifiedUnionExpression = new AQuantifiedUnionExpression(); + quantifiedUnionExpression.setExpression(ex); + quantifiedUnionExpression.setPredicates(pr); + quantifiedUnionExpression.setIdentifiers(list); + setExpression(quantifiedUnionExpression); + break; + case Formula.QINTER: + final AQuantifiedIntersectionExpression quantifiedIntersectionExpression = new AQuantifiedIntersectionExpression(); + quantifiedIntersectionExpression.setExpression(ex); + quantifiedIntersectionExpression.setPredicates(pr); + quantifiedIntersectionExpression.setIdentifiers(list); + setExpression(quantifiedIntersectionExpression); + break; + case Formula.CSET: + final AEventBComprehensionSetExpression comprehensionSetExpression = new AEventBComprehensionSetExpression(); + comprehensionSetExpression.setExpression(ex); + comprehensionSetExpression.setPredicates(pr); + comprehensionSetExpression.setIdentifiers(list); + setExpression(comprehensionSetExpression); + break; + default: + break; + } + + for (int i = 0; i < decls.length; i++) { + bounds.remove(0); + } + } + + @Override + public void visitAssociativeExpression( + final AssociativeExpression expression) { + // BUNION, BINTER, BCOMP, FCOMP, OVR, PLUS, MUL + final Expression[] children = expression.getChildren(); + + final LinkedList<ExpressionVisitor> ev = new LinkedList<ExpressionVisitor>(); + + for (final Expression ex : children) { + final ExpressionVisitor e = new ExpressionVisitor(bounds); + ev.add(e); + ex.accept(e); + } + + final int tag = expression.getTag(); + switch (tag) { + case Formula.BUNION: + setExpression(recurseBUNION(ev)); + break; + case Formula.BINTER: + setExpression(recurseBINTER(ev)); + break; + case Formula.BCOMP: + setExpression(recurseBCOMP(ev)); + break; + case Formula.FCOMP: + setExpression(recurseFCOMP(ev)); + break; + case Formula.OVR: + setExpression(recurseOVR(ev)); + break; + case Formula.PLUS: + setExpression(recursePLUS(ev)); + break; + case Formula.MUL: + setExpression(recurseMUL(ev)); + break; + + default: + break; + } + super.visitAssociativeExpression(expression); + } + + private PExpression recurseFCOMP(final List<ExpressionVisitor> list) { + final ACompositionExpression r = new ACompositionExpression(); + if (list.size() == 2) { + r.setLeft(list.get(0).getExpression()); + r.setRight(list.get(1).getExpression()); + } else { + r.setLeft(list.get(0).getExpression()); + r.setRight(recurseFCOMP(list.subList(1, list.size()))); + } + return r; + } + + private PExpression recurseOVR(final List<ExpressionVisitor> list) { + final AOverwriteExpression r = new AOverwriteExpression(); + if (list.size() == 2) { + r.setLeft(list.get(0).getExpression()); + r.setRight(list.get(1).getExpression()); + } else { + r.setLeft(list.get(0).getExpression()); + r.setRight(recurseOVR(list.subList(1, list.size()))); + } + return r; + } + + private PExpression recursePLUS(final List<ExpressionVisitor> list) { + final AAddExpression r = new AAddExpression(); + if (list.size() == 2) { + r.setLeft(list.get(0).getExpression()); + r.setRight(list.get(1).getExpression()); + } else { + r.setLeft(list.get(0).getExpression()); + r.setRight(recursePLUS(list.subList(1, list.size()))); + } + return r; + } + + private PExpression recurseMUL(final List<ExpressionVisitor> list) { + final AMultiplicationExpression r = new AMultiplicationExpression(); + if (list.size() == 2) { + r.setLeft(list.get(0).getExpression()); + r.setRight(list.get(1).getExpression()); + } else { + r.setLeft(list.get(0).getExpression()); + r.setRight(recurseMUL(list.subList(1, list.size()))); + } + return r; + } + + private PExpression recurseBUNION(final List<ExpressionVisitor> list) { + final AUnionExpression r = new AUnionExpression(); + if (list.size() == 2) { + r.setLeft(list.get(0).getExpression()); + r.setRight(list.get(1).getExpression()); + } else { + r.setLeft(list.get(0).getExpression()); + r.setRight(recurseBUNION(list.subList(1, list.size()))); + } + return r; + } + + private PExpression recurseBINTER(final List<ExpressionVisitor> list) { + final AIntersectionExpression r = new AIntersectionExpression(); + if (list.size() == 2) { + r.setLeft(list.get(0).getExpression()); + r.setRight(list.get(1).getExpression()); + } else { + r.setLeft(list.get(0).getExpression()); + r.setRight(recurseBINTER(list.subList(1, list.size()))); + } + return r; + } + + private PExpression recurseBCOMP(final List<ExpressionVisitor> list) { + final ARingExpression r = new ARingExpression(); + if (list.size() == 2) { + r.setLeft(list.get(0).getExpression()); + r.setRight(list.get(1).getExpression()); + } else { + r.setLeft(list.get(0).getExpression()); + r.setRight(recurseBCOMP(list.subList(1, list.size()))); + } + return r; + } + + @Override + // this long method is far easier to read than smaller ones + public void visitBinaryExpression(final BinaryExpression expression) { // NOPMD + final int tag = expression.getTag(); + final ExpressionVisitor visitorLeft = new ExpressionVisitor(bounds); + final ExpressionVisitor visitorRight = new ExpressionVisitor(bounds); + expression.getLeft().accept(visitorLeft); + expression.getRight().accept(visitorRight); + final PExpression exL = visitorLeft.getExpression(); + final PExpression exR = visitorRight.getExpression(); + + switch (tag) { + case Formula.MAPSTO: + final ACoupleExpression coupleExpression = new ACoupleExpression(); + coupleExpression.setList(Arrays + .asList(new PExpression[] { exL, exR })); + setExpression(coupleExpression); + break; + case Formula.REL: + final ARelationsExpression relationsExpression = new ARelationsExpression(); + relationsExpression.setLeft(exL); + relationsExpression.setRight(exR); + setExpression(relationsExpression); + break; + case Formula.TREL: + final ATotalRelationExpression totalRelationExpression = new ATotalRelationExpression(); + totalRelationExpression.setLeft(exL); + totalRelationExpression.setRight(exR); + setExpression(totalRelationExpression); + break; + case Formula.SREL: + final ASurjectionRelationExpression surjectionRelationExpression = new ASurjectionRelationExpression(); + surjectionRelationExpression.setLeft(exL); + surjectionRelationExpression.setRight(exR); + setExpression(surjectionRelationExpression); + break; + case Formula.STREL: + final ATotalSurjectionRelationExpression totalSurjectionRelationExpression = new ATotalSurjectionRelationExpression(); + totalSurjectionRelationExpression.setLeft(exL); + totalSurjectionRelationExpression.setRight(exR); + setExpression(totalSurjectionRelationExpression); + break; + case Formula.PFUN: + final APartialFunctionExpression partialFunctionExpression = new APartialFunctionExpression(); + partialFunctionExpression.setLeft(exL); + partialFunctionExpression.setRight(exR); + setExpression(partialFunctionExpression); + break; + case Formula.TFUN: + final ATotalFunctionExpression totalFunctionExpression = new ATotalFunctionExpression(); + totalFunctionExpression.setLeft(exL); + totalFunctionExpression.setRight(exR); + setExpression(totalFunctionExpression); + break; + case Formula.PINJ: + final APartialInjectionExpression partialInjectionExpression = new APartialInjectionExpression(); + partialInjectionExpression.setLeft(exL); + partialInjectionExpression.setRight(exR); + setExpression(partialInjectionExpression); + break; + case Formula.TINJ: + final ATotalInjectionExpression totalInjectionExpression = new ATotalInjectionExpression(); + totalInjectionExpression.setLeft(exL); + totalInjectionExpression.setRight(exR); + setExpression(totalInjectionExpression); + break; + case Formula.PSUR: + final APartialSurjectionExpression partialSurjectionExpression = new APartialSurjectionExpression(); + partialSurjectionExpression.setLeft(exL); + partialSurjectionExpression.setRight(exR); + setExpression(partialSurjectionExpression); + break; + case Formula.TSUR: + final ATotalSurjectionExpression totalSurjectionExpression = new ATotalSurjectionExpression(); + totalSurjectionExpression.setLeft(exL); + totalSurjectionExpression.setRight(exR); + setExpression(totalSurjectionExpression); + break; + case Formula.TBIJ: + final ATotalBijectionExpression totalBijectionExpression = new ATotalBijectionExpression(); + totalBijectionExpression.setLeft(exL); + totalBijectionExpression.setRight(exR); + setExpression(totalBijectionExpression); + break; + case Formula.SETMINUS: + final ASetSubtractionExpression setSubtractionExpression = new ASetSubtractionExpression(); + setSubtractionExpression.setLeft(exL); + setSubtractionExpression.setRight(exR); + setExpression(setSubtractionExpression); + break; + case Formula.CPROD: + final ACartesianProductExpression mulExpression = new ACartesianProductExpression(); + mulExpression.setLeft(exL); + mulExpression.setRight(exR); + setExpression(mulExpression); + break; + case Formula.DPROD: + final ADirectProductExpression directProductExpression = new ADirectProductExpression(); + directProductExpression.setLeft(exL); + directProductExpression.setRight(exR); + setExpression(directProductExpression); + break; + case Formula.PPROD: + final AParallelProductExpression parallelProductExpression = new AParallelProductExpression(); + parallelProductExpression.setLeft(exL); + parallelProductExpression.setRight(exR); + setExpression(parallelProductExpression); + break; + case Formula.DOMRES: + final ADomainRestrictionExpression domainRestrictionExpression = new ADomainRestrictionExpression(); + domainRestrictionExpression.setLeft(exL); + domainRestrictionExpression.setRight(exR); + setExpression(domainRestrictionExpression); + break; + case Formula.DOMSUB: + final ADomainSubtractionExpression domainSubtractionExpression = new ADomainSubtractionExpression(); + domainSubtractionExpression.setLeft(exL); + domainSubtractionExpression.setRight(exR); + setExpression(domainSubtractionExpression); + break; + case Formula.RANRES: + final ARangeRestrictionExpression rangeRestrictionExpression = new ARangeRestrictionExpression(); + rangeRestrictionExpression.setLeft(exL); + rangeRestrictionExpression.setRight(exR); + setExpression(rangeRestrictionExpression); + break; + case Formula.RANSUB: + final ARangeSubtractionExpression rangeSubtractionExpression = new ARangeSubtractionExpression(); + rangeSubtractionExpression.setLeft(exL); + rangeSubtractionExpression.setRight(exR); + setExpression(rangeSubtractionExpression); + break; + case Formula.UPTO: + final AIntervalExpression intervalExpression = new AIntervalExpression(); + intervalExpression.setLeftBorder(exL); + intervalExpression.setRightBorder(exR); + setExpression(intervalExpression); + break; + case Formula.MINUS: + final AMinusExpression minusExpression = new AMinusExpression(); + minusExpression.setLeft(exL); + minusExpression.setRight(exR); + setExpression(minusExpression); + break; + case Formula.DIV: + final ADivExpression divExpression = new ADivExpression(); + divExpression.setLeft(exL); + divExpression.setRight(exR); + setExpression(divExpression); + break; + case Formula.MOD: + final AModuloExpression moduloExpression = new AModuloExpression(); + moduloExpression.setLeft(exL); + moduloExpression.setRight(exR); + setExpression(moduloExpression); + break; + case Formula.EXPN: + final APowerOfExpression powerOfExpression = new APowerOfExpression(); + powerOfExpression.setLeft(exL); + powerOfExpression.setRight(exR); + setExpression(powerOfExpression); + break; + case Formula.FUNIMAGE: + final AFunctionExpression functionExpression = new AFunctionExpression(); + functionExpression.setIdentifier(exL); + functionExpression.setParameters(Arrays + .asList(new PExpression[] { exR })); + setExpression(functionExpression); + break; + case Formula.RELIMAGE: + final AImageExpression imageExpression = new AImageExpression(); + imageExpression.setLeft(exL); + imageExpression.setRight(exR); + setExpression(imageExpression); + break; + default: + throw new AssertionError("Uncovered Expression"); + } + + } + + @Override + public void visitAtomicExpression(final AtomicExpression expression) { // NOPMD + // by + // bendisposto + final int tag = expression.getTag(); + + switch (tag) { + case Formula.INTEGER: + setExpression(new AIntegerSetExpression()); + break; + case Formula.NATURAL: + setExpression(new ANaturalSetExpression()); + break; + case Formula.NATURAL1: + setExpression(new ANatural1SetExpression()); + break; + case Formula.BOOL: + setExpression(new ABoolSetExpression()); + break; + case Formula.TRUE: + setExpression(new ATrueExpression()); + break; + case Formula.FALSE: + setExpression(new AFalseExpression()); + break; + case Formula.EMPTYSET: + setExpression(new AEmptySetExpression()); + break; + case Formula.KPRED: + setExpression(new APredecessorExpression()); + break; + case Formula.KSUCC: + setExpression(new ASuccessorExpression()); + break; + case Formula.KPRJ1_GEN: // see task#215 + setExpression(new AEventBFirstProjectionV2Expression()); + break; + case Formula.KPRJ2_GEN: + setExpression(new AEventBSecondProjectionV2Expression()); + break; + case Formula.KID_GEN: + setExpression(new AEventBIdentityExpression()); + break; + default: + throw new AssertionError("Uncovered Expression " + expression); + } + } + + @Override + public void visitBoolExpression(final BoolExpression expression) { + final AConvertBoolExpression convertBoolExpression = new AConvertBoolExpression(); + final PredicateVisitor visitor = new PredicateVisitor(bounds); + expression.getPredicate().accept(visitor); + convertBoolExpression.setPredicate(visitor.getPredicate()); + setExpression(convertBoolExpression); + } + + @Override + public void visitBoundIdentDecl(final BoundIdentDecl boundIdentDecl) { + final List<TIdentifierLiteral> list = Arrays + .asList(new TIdentifierLiteral[] { new TIdentifierLiteral( + boundIdentDecl.getName()) }); + final AIdentifierExpression expression = new AIdentifierExpression(); + expression.setIdentifier(list); + setExpression(expression); + } + + @Override + public void visitBoundIdentifier(final BoundIdentifier identifierExpression) { + final List<TIdentifierLiteral> list = Arrays + .asList(new TIdentifierLiteral[] { new TIdentifierLiteral( + bounds.get(identifierExpression.getBoundIndex())) }); + final AIdentifierExpression expression = new AIdentifierExpression(); + expression.setIdentifier(list); + setExpression(expression); + } + + @Override + public void visitFreeIdentifier(final FreeIdentifier identifierExpression) { + final List<TIdentifierLiteral> list = Arrays + .asList(new TIdentifierLiteral[] { new TIdentifierLiteral( + identifierExpression.getName()) }); + final AIdentifierExpression expression = new AIdentifierExpression(); + expression.setIdentifier(list); + setExpression(expression); + } + + @Override + public void visitIntegerLiteral(final IntegerLiteral expression) { + final BigInteger value = expression.getValue(); + final AIntegerExpression integerExpression = new AIntegerExpression(); + integerExpression.setLiteral(new TIntegerLiteral(value.toString())); + setExpression(integerExpression); + } + + @Override + public void visitSetExtension(final SetExtension expression) { + final Expression[] members = expression.getMembers(); + final ASetExtensionExpression setExtensionExpression = new ASetExtensionExpression(); + final List<PExpression> list = new ArrayList<PExpression>(); + for (final Expression e : members) { + final ExpressionVisitor visitor = new ExpressionVisitor(bounds); + e.accept(visitor); + list.add(visitor.getExpression()); + } + setExtensionExpression.setExpressions(list); + setExpression(setExtensionExpression); + } + + @SuppressWarnings("deprecation") + @Override + public void visitUnaryExpression(final UnaryExpression expression) { // NOPMD + // by + // bendisposto + final int tag = expression.getTag(); + final ExpressionVisitor visitor = new ExpressionVisitor(bounds); + expression.getChild().accept(visitor); + final PExpression exp = visitor.getExpression(); + + switch (tag) { + case Formula.KCARD: + final ACardExpression cardExpression = new ACardExpression(); + cardExpression.setExpression(exp); + setExpression(cardExpression); + break; + case Formula.POW: + final APowSubsetExpression powExpression = new APowSubsetExpression(); + powExpression.setExpression(exp); + setExpression(powExpression); + break; + case Formula.POW1: + final APow1SubsetExpression pow1Expression = new APow1SubsetExpression(); + pow1Expression.setExpression(exp); + setExpression(pow1Expression); + break; + case Formula.KUNION: + final AGeneralUnionExpression unionExpression = new AGeneralUnionExpression(); + unionExpression.setExpression(exp); + setExpression(unionExpression); + break; + case Formula.KINTER: + final AGeneralIntersectionExpression interExpression = new AGeneralIntersectionExpression(); + interExpression.setExpression(exp); + setExpression(interExpression); + break; + case Formula.KDOM: + final ADomainExpression domainExpression = new ADomainExpression(); + domainExpression.setExpression(exp); + setExpression(domainExpression); + break; + case Formula.KRAN: + final ARangeExpression rangeExpression = new ARangeExpression(); + rangeExpression.setExpression(exp); + setExpression(rangeExpression); + break; + case Formula.KPRJ1: + final AEventBFirstProjectionExpression firstProjectionExpression = new AEventBFirstProjectionExpression(); + firstProjectionExpression.setExpression(exp); + setExpression(firstProjectionExpression); + break; + case Formula.KPRJ2: + final AEventBSecondProjectionExpression secondProjectionExpression = new AEventBSecondProjectionExpression(); + secondProjectionExpression.setExpression(exp); + setExpression(secondProjectionExpression); + break; + case Formula.KID: + final AIdentityExpression identityExpression = new AIdentityExpression(); + identityExpression.setExpression(exp); + setExpression(identityExpression); + break; + case Formula.KMIN: + final AMinExpression minExpression = new AMinExpression(); + minExpression.setExpression(exp); + setExpression(minExpression); + break; + case Formula.KMAX: + final AMaxExpression maxExpression = new AMaxExpression(); + maxExpression.setExpression(exp); + setExpression(maxExpression); + break; + case Formula.CONVERSE: + final AReverseExpression reverseExpression = new AReverseExpression(); + reverseExpression.setExpression(exp); + setExpression(reverseExpression); + break; + case Formula.UNMINUS: + final AUnaryExpression unaryExpression = new AUnaryExpression(); + unaryExpression.setExpression(exp); + setExpression(unaryExpression); + break; + + default: + throw new AssertionError("Uncovered Expression"); + } + } +} diff --git a/de.prob.core/src/de/prob/eventb/translator/FormulaTranslator.java b/de.prob.core/src/de/prob/eventb/translator/FormulaTranslator.java new file mode 100644 index 0000000000000000000000000000000000000000..5fb9850e26646494cc0c1fce173edcf5b8332529 --- /dev/null +++ b/de.prob.core/src/de/prob/eventb/translator/FormulaTranslator.java @@ -0,0 +1,11 @@ +package de.prob.eventb.translator; + +import de.prob.unicode.UnicodeTranslator; + +public class FormulaTranslator { + + public static String translate(String input) { + return UnicodeTranslator.toUnicode(input); + } + +} diff --git a/de.prob.core/src/de/prob/eventb/translator/PredicateVisitor.java b/de.prob.core/src/de/prob/eventb/translator/PredicateVisitor.java new file mode 100644 index 0000000000000000000000000000000000000000..9ebdb79eae5f81a8caad9fdc7d3a63870775eca8 --- /dev/null +++ b/de.prob.core/src/de/prob/eventb/translator/PredicateVisitor.java @@ -0,0 +1,406 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.eventb.translator; // NOPMD +// High number of imports because it depends on AST + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +import org.eventb.core.ast.AssociativePredicate; +import org.eventb.core.ast.BinaryPredicate; +import org.eventb.core.ast.BoundIdentDecl; +import org.eventb.core.ast.Expression; +import org.eventb.core.ast.Formula; +import org.eventb.core.ast.ISimpleVisitor; +import org.eventb.core.ast.LiteralPredicate; +import org.eventb.core.ast.MultiplePredicate; +import org.eventb.core.ast.Predicate; +import org.eventb.core.ast.QuantifiedPredicate; +import org.eventb.core.ast.RelationalPredicate; +import org.eventb.core.ast.SimplePredicate; +import org.eventb.core.ast.UnaryPredicate; + +import de.be4.classicalb.core.parser.node.ABelongPredicate; +import de.be4.classicalb.core.parser.node.AConjunctPredicate; +import de.be4.classicalb.core.parser.node.ADisjunctPredicate; +import de.be4.classicalb.core.parser.node.AEqualPredicate; +import de.be4.classicalb.core.parser.node.AEquivalencePredicate; +import de.be4.classicalb.core.parser.node.AExistentialQuantificationPredicate; +import de.be4.classicalb.core.parser.node.AFalsePredicate; +import de.be4.classicalb.core.parser.node.AFinitePredicate; +import de.be4.classicalb.core.parser.node.AGreaterEqualPredicate; +import de.be4.classicalb.core.parser.node.AGreaterPredicate; +import de.be4.classicalb.core.parser.node.AImplicationPredicate; +import de.be4.classicalb.core.parser.node.AIncludePredicate; +import de.be4.classicalb.core.parser.node.AIncludeStrictlyPredicate; +import de.be4.classicalb.core.parser.node.ALessEqualPredicate; +import de.be4.classicalb.core.parser.node.ALessPredicate; +import de.be4.classicalb.core.parser.node.ANegationPredicate; +import de.be4.classicalb.core.parser.node.ANotBelongPredicate; +import de.be4.classicalb.core.parser.node.ANotIncludePredicate; +import de.be4.classicalb.core.parser.node.ANotIncludeStrictlyPredicate; +import de.be4.classicalb.core.parser.node.APartitionPredicate; +import de.be4.classicalb.core.parser.node.ATruePredicate; +import de.be4.classicalb.core.parser.node.AUnequalPredicate; +import de.be4.classicalb.core.parser.node.AUniversalQuantificationPredicate; +import de.be4.classicalb.core.parser.node.PExpression; +import de.be4.classicalb.core.parser.node.PPredicate; +import de.prob.eventb.translator.internal.SimpleVisitorAdapter; + +public class PredicateVisitor extends SimpleVisitorAdapter implements // NOPMD + ISimpleVisitor { + + private static final String UNCOVERED_PREDICATE = "Uncovered Predicate"; + + private PPredicate p; + + private final LinkedList<String> bounds; // NOPMD + // we need properties of linked lists, List is not an option + + private boolean predicateSet = false; + + public PPredicate getPredicate() { + return p; + } + + public void setPredicate(final PPredicate p) { + synchronized (bounds) { + if (predicateSet) { + throw new AssertionError("The Visitor must not be used twice!"); + } + predicateSet = true; + this.p = p; + } + } + + public PredicateVisitor(final LinkedList<String> bounds) { + super(); + if (bounds == null) { + this.bounds = new LinkedList<String>(); + } else { + this.bounds = bounds; + } + } + + public PredicateVisitor() { + this(null); + } + + @Override + public void visitQuantifiedPredicate(final QuantifiedPredicate predicate) { + final int tag = predicate.getTag(); + + // Add quantified identifiers to bound list and recursively create + // subtrees representing the identifiers + final List<ExpressionVisitor> ev = new LinkedList<ExpressionVisitor>(); + final BoundIdentDecl[] decls = predicate.getBoundIdentDecls(); + for (final BoundIdentDecl boundIdentDecl : decls) { + final ExpressionVisitor visitor = new ExpressionVisitor(bounds); + boundIdentDecl.accept(visitor); + ev.add(visitor); + bounds.addFirst(boundIdentDecl.getName()); + } + + // Collect Subtrees in a list + final LinkedList<PExpression> list = new LinkedList<PExpression>(); + for (final ExpressionVisitor visitor : ev) { + list.add(visitor.getExpression()); + } + + // Recursively analyze the predicate (important, bounds are already set) + final PredicateVisitor predicateVisitor = new PredicateVisitor(bounds); + predicate.getPredicate().accept(predicateVisitor); + + switch (tag) { + case Formula.EXISTS: + final AExistentialQuantificationPredicate existentialQuantificationPredicate = new AExistentialQuantificationPredicate(); + existentialQuantificationPredicate.setIdentifiers(list); + existentialQuantificationPredicate.setPredicate(predicateVisitor + .getPredicate()); + setPredicate(existentialQuantificationPredicate); + break; + case Formula.FORALL: + final AUniversalQuantificationPredicate universalQuantificationPredicate = new AUniversalQuantificationPredicate(); + universalQuantificationPredicate.setIdentifiers(list); + PPredicate pred = predicateVisitor.getPredicate(); + if (!(pred instanceof AImplicationPredicate)) { + pred = new AImplicationPredicate(new ATruePredicate(), pred); + } + universalQuantificationPredicate.setImplication(pred); + setPredicate(universalQuantificationPredicate); + break; + + default: + throw new AssertionError(UNCOVERED_PREDICATE); + } + // remove quantified identifiers from bound list (leaving scope) + for (int i = 0; i < decls.length; i++) { + bounds.removeFirst(); + } + + } + + @Override + public void visitAssociativePredicate(final AssociativePredicate predicate) { + // {LAND, LOR, LEQV} + final int tag = predicate.getTag(); + final Predicate[] children = predicate.getChildren(); + if (children.length < 2) { + throw new AssertionError( + "Predicate must have at least 2 subpredicates."); + } + + final LinkedList<PredicateVisitor> pv = new LinkedList<PredicateVisitor>(); + + for (final Predicate pr : children) { + final PredicateVisitor p = new PredicateVisitor(bounds); + pv.add(p); + pr.accept(p); + } + + switch (tag) { + case Formula.LOR: + setPredicate(recurseOR(pv)); + break; + + case Formula.LAND: + setPredicate(recurseAND(pv)); + break; + case Formula.LEQV: + setPredicate(recurseEQV(pv)); + break; + + default: + throw new AssertionError(UNCOVERED_PREDICATE); + } + + } + + private PPredicate recurseOR(final List<PredicateVisitor> list) { + final ADisjunctPredicate r = new ADisjunctPredicate(); + if (list.size() == 2) { + r.setLeft(list.get(0).getPredicate()); + r.setRight(list.get(1).getPredicate()); + } else { + r.setLeft(list.get(0).getPredicate()); + r.setRight(recurseOR(list.subList(1, list.size()))); + } + return r; + } + + private PPredicate recurseAND(final List<PredicateVisitor> list) { + final AConjunctPredicate r = new AConjunctPredicate(); + if (list.size() == 2) { + r.setLeft(list.get(0).getPredicate()); + r.setRight(list.get(1).getPredicate()); + } else { + r.setLeft(list.get(0).getPredicate()); + r.setRight(recurseAND(list.subList(1, list.size()))); + } + return r; + } + + private PPredicate recurseEQV(final List<PredicateVisitor> list) { + final AEquivalencePredicate r = new AEquivalencePredicate(); + if (list.size() == 2) { + r.setLeft(list.get(0).getPredicate()); + r.setRight(list.get(1).getPredicate()); + } else { + r.setLeft(list.get(0).getPredicate()); + r.setRight(recurseEQV(list.subList(1, list.size()))); + } + return r; + } + + @Override + public void visitBinaryPredicate(final BinaryPredicate predicate) { + final int tag = predicate.getTag(); + + final PredicateVisitor subLeft = new PredicateVisitor(bounds); + predicate.getLeft().accept(subLeft); + final PredicateVisitor subRight = new PredicateVisitor(bounds); + predicate.getRight().accept(subRight); + + switch (tag) { + case Formula.LIMP: + final AImplicationPredicate limp = new AImplicationPredicate(); + limp.setLeft(subLeft.getPredicate()); + limp.setRight(subRight.getPredicate()); + setPredicate(limp); + break; + case Formula.LEQV: + final AEquivalencePredicate leqv = new AEquivalencePredicate(); + leqv.setLeft(subLeft.getPredicate()); + leqv.setRight(subRight.getPredicate()); + setPredicate(leqv); + break; + default: + throw new AssertionError(UNCOVERED_PREDICATE); + } + } + + @Override + public void visitLiteralPredicate(final LiteralPredicate predicate) { + final int tag = predicate.getTag(); + switch (tag) { + case Formula.BTRUE: + setPredicate(new ATruePredicate()); + break; + case Formula.BFALSE: + setPredicate(new AFalsePredicate()); + break; + + default: + throw new AssertionError(UNCOVERED_PREDICATE); + } + } + + @Override + public void visitRelationalPredicate(final RelationalPredicate predicate) { // NOPMD + // High complexity is ok + // EQUAL, NOTEQUAL, LT, LE, GT, GE, IN, NOTIN, SUBSET, + // NOTSUBSET, SUBSETEQ, NOTSUBSETEQ + final ExpressionVisitor subLeft = new ExpressionVisitor(bounds); + predicate.getLeft().accept(subLeft); + final ExpressionVisitor subRight = new ExpressionVisitor(bounds); + predicate.getRight().accept(subRight); + + final int tag = predicate.getTag(); + + switch (tag) { + case Formula.EQUAL: + final AEqualPredicate equalPredicate = new AEqualPredicate(); + equalPredicate.setLeft(subLeft.getExpression()); + equalPredicate.setRight(subRight.getExpression()); + setPredicate(equalPredicate); + break; + case Formula.NOTEQUAL: + final AUnequalPredicate unequalPredicate = new AUnequalPredicate(); + unequalPredicate.setLeft(subLeft.getExpression()); + unequalPredicate.setRight(subRight.getExpression()); + setPredicate(unequalPredicate); + break; + + case Formula.LT: + final ALessPredicate ltPredicate = new ALessPredicate(); + ltPredicate.setLeft(subLeft.getExpression()); + ltPredicate.setRight(subRight.getExpression()); + setPredicate(ltPredicate); + break; + case Formula.LE: + final ALessEqualPredicate lePredicate = new ALessEqualPredicate(); + lePredicate.setLeft(subLeft.getExpression()); + lePredicate.setRight(subRight.getExpression()); + setPredicate(lePredicate); + break; + case Formula.GT: + final AGreaterPredicate gtPredicate = new AGreaterPredicate(); + gtPredicate.setLeft(subLeft.getExpression()); + gtPredicate.setRight(subRight.getExpression()); + setPredicate(gtPredicate); + break; + case Formula.GE: + final AGreaterEqualPredicate gePredicate = new AGreaterEqualPredicate(); + gePredicate.setLeft(subLeft.getExpression()); + gePredicate.setRight(subRight.getExpression()); + setPredicate(gePredicate); + break; + + case Formula.IN: + final ABelongPredicate inPredicate = new ABelongPredicate(); + inPredicate.setLeft(subLeft.getExpression()); + inPredicate.setRight(subRight.getExpression()); + setPredicate(inPredicate); + break; + case Formula.NOTIN: + final ANotBelongPredicate ninPredicate = new ANotBelongPredicate(); + ninPredicate.setLeft(subLeft.getExpression()); + ninPredicate.setRight(subRight.getExpression()); + setPredicate(ninPredicate); + break; + case Formula.SUBSET: + final AIncludeStrictlyPredicate strictSubsetPredicate = new AIncludeStrictlyPredicate(); + strictSubsetPredicate.setLeft(subLeft.getExpression()); + strictSubsetPredicate.setRight(subRight.getExpression()); + setPredicate(strictSubsetPredicate); + break; + case Formula.NOTSUBSET: + final ANotIncludeStrictlyPredicate notStrictSubsetPredicate = new ANotIncludeStrictlyPredicate(); + notStrictSubsetPredicate.setLeft(subLeft.getExpression()); + notStrictSubsetPredicate.setRight(subRight.getExpression()); + setPredicate(notStrictSubsetPredicate); + break; + case Formula.SUBSETEQ: + final AIncludePredicate subsetPredicate = new AIncludePredicate(); + subsetPredicate.setLeft(subLeft.getExpression()); + subsetPredicate.setRight(subRight.getExpression()); + setPredicate(subsetPredicate); + break; + case Formula.NOTSUBSETEQ: + final ANotIncludePredicate notSubsetPredicate = new ANotIncludePredicate(); + notSubsetPredicate.setLeft(subLeft.getExpression()); + notSubsetPredicate.setRight(subRight.getExpression()); + setPredicate(notSubsetPredicate); + break; + + default: + throw new AssertionError(UNCOVERED_PREDICATE); + } + + } + + @Override + public void visitSimplePredicate(final SimplePredicate predicate) { + if (predicate.getTag() != Formula.KFINITE) { + throw new AssertionError(UNCOVERED_PREDICATE); + } + final AFinitePredicate finite = new AFinitePredicate(); + final ExpressionVisitor subEx = new ExpressionVisitor(bounds); + predicate.getExpression().accept(subEx); + finite.setSet(subEx.getExpression()); + setPredicate(finite); + } + + @Override + public void visitUnaryPredicate(final UnaryPredicate predicate) { + if (predicate.getTag() != Formula.NOT) { + throw new AssertionError(UNCOVERED_PREDICATE); + } + final ANegationPredicate negationPredicate = new ANegationPredicate(); + final PredicateVisitor sub = new PredicateVisitor(bounds); + predicate.getChild().accept(sub); + negationPredicate.setPredicate(sub.getPredicate()); + setPredicate(negationPredicate); + } + + @Override + public void visitMultiplePredicate(final MultiplePredicate predicate) { + final Expression[] subs = predicate.getChildren(); + final List<PExpression> expressions = new ArrayList<PExpression>( + subs.length); + for (Expression e : subs) { + final ExpressionVisitor sub = new ExpressionVisitor(bounds); + e.accept(sub); + expressions.add(sub.getExpression()); + } + + final PPredicate result; + if (predicate.getTag() == Formula.KPARTITION) { + if (expressions.size() > 0) { + PExpression set = expressions.remove(0); + result = new APartitionPredicate(set, expressions); + } else { + throw new AssertionError("to few arguments for PARTITION"); + } + } else { + throw new AssertionError(UNCOVERED_PREDICATE); + } + setPredicate(result); + } + +} diff --git a/de.prob.core/src/de/prob/eventb/translator/TranslatorFactory.java b/de.prob.core/src/de/prob/eventb/translator/TranslatorFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..0e9a5d1af765473e700a8e24a4306f0caa3d2441 --- /dev/null +++ b/de.prob.core/src/de/prob/eventb/translator/TranslatorFactory.java @@ -0,0 +1,61 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.eventb.translator; + +import java.io.PrintWriter; + +import org.eventb.core.IContextRoot; +import org.eventb.core.IEventBRoot; +import org.eventb.core.IMachineRoot; +import org.eventb.core.ISCContextRoot; +import org.eventb.core.ISCMachineRoot; + +import de.prob.core.translator.ITranslator; +import de.prob.core.translator.TranslationFailedException; +import de.prob.eventb.translator.internal.EventBContextTranslator; +import de.prob.eventb.translator.internal.EventBMachineTranslator; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.output.PrologTermOutput; + +public class TranslatorFactory { + + /** + * Use this Factory to obtain an instance of {@link ITranslator}. + * + * @param root + * IEventBRoot (either machine or context) + * @return {@link ITranslator} instance + * @throws TranslationFailedException + */ + public static void translate(final IEventBRoot root, + final IPrologTermOutput pto) throws TranslationFailedException { + if (root instanceof IMachineRoot) { + final ISCMachineRoot scRoot = ((IMachineRoot) root) + .getSCMachineRoot(); + EventBMachineTranslator.create(scRoot, pto); + + } else if (root instanceof IContextRoot) { + final ISCContextRoot scRoot = ((IContextRoot) root) + .getSCContextRoot(); + EventBContextTranslator.create(scRoot, pto); + } else { + throw new TranslationFailedException(root.getComponentName(), + "Cannot translate anything else than IMachineRoot or IContextRoot. Type was: " + + root.getClass()); + } + } + + public static void translate(final IEventBRoot root, + final PrintWriter writer) throws TranslationFailedException { + IPrologTermOutput pto = new PrologTermOutput(writer, false); + pto.openTerm("package"); + TranslatorFactory.translate(root, pto); + pto.closeTerm(); + pto.fullstop().flush(); + } + +} diff --git a/de.prob.core/src/de/prob/eventb/translator/flow/Event.java b/de.prob.core/src/de/prob/eventb/translator/flow/Event.java new file mode 100644 index 0000000000000000000000000000000000000000..0f96e1ff2cb5d164f910ee71cc4fac8069d11ed0 --- /dev/null +++ b/de.prob.core/src/de/prob/eventb/translator/flow/Event.java @@ -0,0 +1,248 @@ +package de.prob.eventb.translator.flow; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.BitSet; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.eventb.core.ISCAction; +import org.eventb.core.ISCEvent; +import org.eventb.core.ISCGuard; +import org.eventb.core.ISCParameter; +import org.eventb.core.ast.Assignment; +import org.eventb.core.ast.AssociativePredicate; +import org.eventb.core.ast.BecomesEqualTo; +import org.eventb.core.ast.BoundIdentDecl; +import org.eventb.core.ast.FormulaFactory; +import org.eventb.core.ast.FreeIdentifier; +import org.eventb.core.ast.ITypeEnvironment; +import org.eventb.core.ast.Predicate; +import org.eventb.core.ast.QuantifiedPredicate; +import org.rodinp.core.RodinDBException; + +public class Event { + + private final String name; + private final ITypeEnvironment localTypeEnv; + private final Map<FreeIdentifier, Integer> variables; + private final BitSet reads; + private final BitSet writes; + private final List<Assignment> assignements; + private final Predicate guards; + private final FlowAnalysis analysis; + private FreeIdentifier[] freeIdentifiers; + private BoundIdentDecl[] boundIdentifiers; + + private Event() { + throw new UnsupportedOperationException( + "Use Factory Method create(ISCEvent) to get an instance"); + } + + @Override + public String toString() { + return name; + } + + private Event(final ISCEvent evt, final FlowAnalysis analysis) + throws RodinDBException { + this.analysis = analysis; + this.name = evt.getLabel(); + this.localTypeEnv = generateLocalTypeEnvironment(evt, analysis); + this.variables = analysis.getVariables(); + + ISCParameter[] parameters = evt.getSCParameters(); + + freeIdentifiers = new FreeIdentifier[parameters.length]; + boundIdentifiers = new BoundIdentDecl[parameters.length]; + for (int k = 0; k < parameters.length; k++) { + freeIdentifiers[k] = parameters[k].getIdentifier(analysis.FF); + boundIdentifiers[k] = analysis.FF.makeBoundIdentDecl( + freeIdentifiers[k].getName(), null, + freeIdentifiers[k].getType()); + } + + this.guards = getGuard(analysis, evt); + this.reads = createReadSet(guards); + + this.assignements = getAssignments(analysis, + Arrays.asList(evt.getSCActions())); + this.writes = createWriteSet(assignements); + } + + private Predicate getGuard(final FlowAnalysis analysis, ISCEvent event) + throws RodinDBException { + ISCParameter[] parameters = event.getSCParameters(); + ISCGuard[] guards = event.getSCGuards(); + + FormulaFactory factory = analysis.FF; + + ITypeEnvironment typenv = factory.makeTypeEnvironment(); + typenv.addAll(analysis.getTypeEnvironment()); + typenv.addAll(freeIdentifiers); + + Predicate[] gPreds = new Predicate[guards.length]; + for (int k = 0; k < guards.length; k++) { + gPreds[k] = guards[k].getPredicate(factory, typenv); + } + + if (guards.length == 0) + return factory.makeLiteralPredicate(Predicate.BTRUE, null); + Predicate conjPred = guards.length == 1 ? gPreds[0] : factory + .makeAssociativePredicate(Predicate.LAND, gPreds, null); + Predicate predicate = parameters.length == 0 ? conjPred : factory + .makeQuantifiedPredicate(Predicate.EXISTS, boundIdentifiers, + conjPred.bindTheseIdents( + Arrays.asList(freeIdentifiers), factory), null); + return predicate; + + } + + public List<Assignment> getAssignements() { + return assignements; + } + + private List<Assignment> getAssignments(final FlowAnalysis analysis, + final List<ISCAction> actions) throws RodinDBException { + List<Assignment> assignements = new ArrayList<Assignment>(); + for (ISCAction action : actions) { + assignements.add(action.getAssignment(analysis.FF, localTypeEnv)); + } + return Collections.unmodifiableList(assignements); + } + + public boolean effects(final Event e) { + return writes.intersects(e.getReads()); + } + + public BitSet getReads() { + return reads; + } + + public BitSet getWrites() { + return writes; + } + + private BitSet createWriteSet(final List<Assignment> actions) + throws RodinDBException { + BitSet writeset = new BitSet(); + for (Assignment assignment : actions) { + FreeIdentifier[] identifiers = assignment.getAssignedIdentifiers(); + for (FreeIdentifier identifier : identifiers) { + Integer nr = variables.get(identifier); + writeset.set(nr); + } + } + return writeset; + } + + private BitSet createReadSet(final Predicate predicate) + throws RodinDBException { + BitSet result = new BitSet(); + result.or(calculateReadSet(predicate)); + return result; + } + + private BitSet calculateReadSet(final Predicate predicate) { + BitSet readset = new BitSet(); + FreeIdentifier[] identifiers = predicate + .getSyntacticallyFreeIdentifiers(); + for (FreeIdentifier identifier : identifiers) { + Integer nr = variables.get(identifier); + if (nr != null) { + readset.set(nr); + } + } + return readset; + } + + private ITypeEnvironment generateLocalTypeEnvironment(final ISCEvent evt, + final FlowAnalysis analysis) throws RodinDBException { + final ITypeEnvironment globalTypeEnvironment = analysis + .getTypeEnvironment(); + final ITypeEnvironment typeEnvironment = evt.getTypeEnvironment( + globalTypeEnvironment, analysis.FF); + typeEnvironment.addAll(globalTypeEnvironment); + return typeEnvironment; + } + + public static Event create(final ISCEvent evt, final FlowAnalysis analysis) + throws RodinDBException { + Event event = new Event(evt, analysis); + return event; + } + + public Predicate getSubstGuards(final Event other) { + Predicate p = this.guards; + for (Assignment assignment : other.assignements) { + List<BecomesEqualTo> deterministic = new ArrayList<BecomesEqualTo>(); + if (assignment instanceof BecomesEqualTo) { + deterministic.add((BecomesEqualTo) assignment); + } else { + // FIXME We need to deal with non deterministic assignments + // here + } + p = p.applyAssignments(deterministic, analysis.FF); + } + + return p; + } + + @Override + public boolean equals(final Object obj) { + if (obj instanceof Event) { + Event other = (Event) obj; + return this.name.equals(other.name); + } + return false; + } + + @Override + public int hashCode() { + return name.hashCode(); + } + + public Predicate getGuardsAfterAssignment() { + List<Predicate> result = new ArrayList<Predicate>(); + Predicate[] grd = unpackPredicates(guards); + for (Predicate g : grd) { + BitSet readSet = calculateReadSet(g); + if (!readSet.intersects(writes)) { + result.add(g); + } + } + + return packPredicates(result); + } + + private Predicate[] unpackPredicates(Predicate guards) { + Predicate g; + Predicate[] preds; + if (guards instanceof QuantifiedPredicate) { + QuantifiedPredicate qp = (QuantifiedPredicate) guards; + g = qp.getPredicate(); + } else { + g = guards; + } + + if (g instanceof AssociativePredicate) { + AssociativePredicate ass = (AssociativePredicate) g; + preds = ass.getChildren(); + } else { + preds = new Predicate[] { g }; + } + return preds; + } + + private Predicate packPredicates(List<Predicate> preds) { + FormulaFactory factory = analysis.FF; + Predicate conjPred = preds.size() == 1 ? preds.get(0) : factory + .makeAssociativePredicate(Predicate.LAND, preds, null); + Predicate predicate = freeIdentifiers.length == 0 ? conjPred : factory + .makeQuantifiedPredicate(Predicate.EXISTS, boundIdentifiers, + conjPred, null); + return predicate; + } + +} diff --git a/de.prob.core/src/de/prob/eventb/translator/flow/EventTuple.java b/de.prob.core/src/de/prob/eventb/translator/flow/EventTuple.java new file mode 100644 index 0000000000000000000000000000000000000000..23027566328017cdfa8fa6a89c1c1d78e09895a6 --- /dev/null +++ b/de.prob.core/src/de/prob/eventb/translator/flow/EventTuple.java @@ -0,0 +1,45 @@ +package de.prob.eventb.translator.flow; + +public class EventTuple implements Comparable<EventTuple> { + + private final Event first; + private final Event second; + + public EventTuple(final Event first, final Event second) { + this.first = first; + this.second = second; + } + + public Event getFirst() { + return first; + } + + public Event getSecond() { + return second; + } + + @Override + public String toString() { + return "(" + first.toString() + "," + second.toString() + ")"; + } + + public int compareTo(final EventTuple o) { + return this.toString().compareTo(o.toString()); + } + + @Override + public boolean equals(final Object obj) { + if (obj instanceof EventTuple) { + EventTuple other = (EventTuple) obj; + return getFirst().equals(other.getFirst()) + && getSecond().equals(other.getSecond()); + } + return false; + } + + @Override + public int hashCode() { + return first.hashCode() + 71 * second.hashCode(); + } + +} diff --git a/de.prob.core/src/de/prob/eventb/translator/flow/FlowAnalysis.java b/de.prob.core/src/de/prob/eventb/translator/flow/FlowAnalysis.java new file mode 100644 index 0000000000000000000000000000000000000000..7ea22f902921913d4ab43b3c0e652dd2ecfa5396 --- /dev/null +++ b/de.prob.core/src/de/prob/eventb/translator/flow/FlowAnalysis.java @@ -0,0 +1,125 @@ +package de.prob.eventb.translator.flow; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eventb.core.ISCEvent; +import org.eventb.core.ISCMachineRoot; +import org.eventb.core.ISCVariable; +import org.eventb.core.ast.FormulaFactory; +import org.eventb.core.ast.FreeIdentifier; +import org.eventb.core.ast.ITypeEnvironment; +import org.eventb.core.ast.Predicate; +import org.rodinp.core.RodinDBException; + +import de.be4.classicalb.core.parser.analysis.prolog.ASTProlog; +import de.be4.classicalb.core.parser.analysis.prolog.ClassicalPositionPrinter; +import de.be4.classicalb.core.parser.analysis.prolog.NodeIdAssignment; +import de.be4.classicalb.core.parser.node.PPredicate; +import de.prob.eventb.translator.PredicateVisitor; +import de.prob.prolog.output.IPrologTermOutput; + +public class FlowAnalysis { + + public final FormulaFactory FF = FormulaFactory.getDefault(); + private final ITypeEnvironment typeEnvironment; + private final Map<FreeIdentifier, Integer> identifiers; + private final List<Event> events; + private final Map<EventTuple, WeakestPrecondition> edges; + private final List<EventTuple> noEffect; + + public void printGraph(final IPrologTermOutput pout) { + + final Set<EventTuple> entries = edges.keySet(); + EventTuple[] tuples = entries.toArray(new EventTuple[entries.size()]); + Arrays.sort(tuples); + for (EventTuple eventTuple : tuples) { + pout.openTerm("wp").printAtom(eventTuple.getFirst().toString()) + .printAtom(eventTuple.getSecond().toString()); + final WeakestPrecondition weakestPrecondition = edges + .get(eventTuple); + + weakestPrecondition.getSyntaxTree(pout); + pout.closeTerm(); + } + for (Event evt : events) { + final ASTProlog prolog = new ASTProlog(pout, + new ClassicalPositionPrinter(new NodeIdAssignment())); + pout.openTerm("nonchanging_guard"); + pout.printAtom(evt.toString()); + pout.openList(); + final Predicate predicate = evt.getGuardsAfterAssignment(); + PredicateVisitor pv = new PredicateVisitor(new LinkedList<String>()); + predicate.accept(pv); + PPredicate p = pv.getPredicate(); + p.apply(prolog); + pout.closeList(); + pout.closeTerm(); + } + + } + + public FlowAnalysis(final ISCMachineRoot model) throws RodinDBException { + this.typeEnvironment = model.getTypeEnvironment(FF); + this.identifiers = enumerateVariables(model.getSCVariables()); + this.events = createEvents(model); + noEffect = new ArrayList<EventTuple>(); + this.edges = calculateInputGraph(noEffect); + } + + private Map<EventTuple, WeakestPrecondition> calculateInputGraph( + final List<EventTuple> noEffect) { + Map<EventTuple, WeakestPrecondition> wps = new HashMap<EventTuple, WeakestPrecondition>(); + for (Event e : events) { + for (Event f : events) { + EventTuple tuple = new EventTuple(e, f); + if (e.effects(f)) { + WeakestPrecondition weakestPrecondition = WeakestPrecondition + .create(tuple); + wps.put(tuple, weakestPrecondition); + } else { + noEffect.add(tuple); + } + } + } + return Collections.unmodifiableMap(wps); + } + + private ArrayList<Event> createEvents(final ISCMachineRoot model) + throws RodinDBException { + ISCEvent[] revents = model.getSCEvents(); + final ArrayList<Event> arrayList = new ArrayList<Event>(revents.length); + + for (ISCEvent e1 : revents) { + Event event = Event.create(e1, this); + arrayList.add(event); + } + return arrayList; + } + + public Map<FreeIdentifier, Integer> getVariables() throws RodinDBException { + return identifiers; + } + + public ITypeEnvironment getTypeEnvironment() { + return typeEnvironment; + } + + private Map<FreeIdentifier, Integer> enumerateVariables( + final ISCVariable[] variables) throws RodinDBException { + Map<FreeIdentifier, Integer> varNumber = new HashMap<FreeIdentifier, Integer>(); + int count = 0; + for (ISCVariable variable : variables) { + varNumber.put(variable.getIdentifier(FF), count++); + } + final Map<FreeIdentifier, Integer> result = Collections + .unmodifiableMap(varNumber); + return result; + } +} diff --git a/de.prob.core/src/de/prob/eventb/translator/flow/ReverseTranslate.java b/de.prob.core/src/de/prob/eventb/translator/flow/ReverseTranslate.java new file mode 100644 index 0000000000000000000000000000000000000000..1522e2019ae119e1a473da13041d0a5a97a51080 --- /dev/null +++ b/de.prob.core/src/de/prob/eventb/translator/flow/ReverseTranslate.java @@ -0,0 +1,71 @@ +package de.prob.eventb.translator.flow; + +import java.util.HashMap; + +public class ReverseTranslate { + + public static class Symbol { + + public final String combo; + public final String unicode; + + public Symbol(final String string, final String string2) { + this.combo = string; + this.unicode = string2; + } + + } + + static Symbol[] x = new Symbol[] { new Symbol("|>>", "\u2a65"), + new Symbol("|>", "\u25b7"), new Symbol("\\/", "\u222a"), + new Symbol("/\\", "\u2229"), new Symbol("|->", "\u21a6"), + new Symbol("-->", "\u2192"), new Symbol("/<<:", "\u2284"), + new Symbol("/<:", "\u2288"), new Symbol("/:", "\u2209"), + new Symbol("<=>", "\u21d4"), new Symbol("=>", "\u21d2"), + new Symbol("&", "\u2227"), new Symbol("!", "\u2200"), + new Symbol("#", "\u2203"), new Symbol("/=", "\u2260"), + new Symbol("<=", "\u2264"), new Symbol(">=", "\u2265"), + new Symbol("<<:", "\u2282"), new Symbol("<:", "\u2286"), + new Symbol("<<->>", "\ue102"), new Symbol("<<->", "\ue100"), + new Symbol("<->>", "\ue101"), new Symbol("<->", "\u2194"), + new Symbol(">->>", "\u2916"), new Symbol("+->", "\u21f8"), + new Symbol(">+>", "\u2914"), new Symbol(">->", "\u21a3"), + new Symbol("+>>", "\u2900"), new Symbol("->>", "\u21a0"), + new Symbol("{}", "\u2205"), new Symbol("\\", "\u2216"), + new Symbol("**", "\u00d7"), new Symbol("<+", "\ue103"), + new Symbol("><", "\u2297"), new Symbol("||", "\u2225"), + new Symbol("~", "\u223c"), new Symbol("<<|", "\u2a64"), + new Symbol("<|", "\u25c1"), new Symbol("%", "\u03bb"), + new Symbol("..", "\u2025"), new Symbol(".", "\u00b7"), + new Symbol("-", "\u2212"), new Symbol("*", "\u2217"), + new Symbol("/", "\u00f7"), new Symbol(":=", "\u2254"), + new Symbol("::", ":\u2208"), new Symbol(":|", ":\u2223"), + new Symbol(":", "\u2208"), new Symbol("|", "\u2223"), + new Symbol("NAT", "\u2115"), new Symbol("POW", "\u2119"), + new Symbol("INT", "\u2124"), new Symbol("INTER", "\u22c2"), + new Symbol("UNION", "\u22c3"), new Symbol("or", "\u2228"), + new Symbol("not", "\u00ac"), new Symbol("true", "\u22a4"), + new Symbol("false", "\u22a5"), new Symbol("circ", "\u2218"), + new Symbol("oftype", "\u2982") }; + private static final HashMap<String, String> translationMap = new HashMap<String, String>(); + + static { + for (Symbol symbol : x) { + translationMap.put(symbol.unicode, symbol.combo); + } + } + + public static String reverseTranslate(final String input) { + StringBuffer result = new StringBuffer(); + for (int i = 0; i < input.length(); i++) { + String s = "" + input.charAt(i); + final String replacement = translationMap.get(s); + if (replacement != null) { + result.append(replacement); + } else { + result.append(s); + } + } + return result.toString(); + } +} diff --git a/de.prob.core/src/de/prob/eventb/translator/flow/WeakestPrecondition.java b/de.prob.core/src/de/prob/eventb/translator/flow/WeakestPrecondition.java new file mode 100644 index 0000000000000000000000000000000000000000..2f5ccfda4539ad374e4145cd6dbd5770b3ce0cdb --- /dev/null +++ b/de.prob.core/src/de/prob/eventb/translator/flow/WeakestPrecondition.java @@ -0,0 +1,58 @@ +package de.prob.eventb.translator.flow; + +import java.util.LinkedList; + +import org.eventb.core.ast.Predicate; + +import de.be4.classicalb.core.parser.analysis.prolog.ASTProlog; +import de.be4.classicalb.core.parser.analysis.prolog.ClassicalPositionPrinter; +import de.be4.classicalb.core.parser.analysis.prolog.NodeIdAssignment; +import de.be4.classicalb.core.parser.node.PPredicate; +import de.prob.eventb.translator.PredicateVisitor; +import de.prob.prolog.output.IPrologTermOutput; + +public class WeakestPrecondition { + + private final Event first; + private final Event second; + private Predicate wps; + + private WeakestPrecondition() { + throw new UnsupportedOperationException( + "Use Factory Method create(EventTuple) to get an instance"); + } + + private WeakestPrecondition(final EventTuple tuple) { + first = tuple.getFirst(); + second = tuple.getSecond(); + wps = second.getSubstGuards(first); + } + + public Predicate getPredicates() { + return wps; + } + + public static WeakestPrecondition create(final EventTuple tuple) { + WeakestPrecondition weakestPrecondition = new WeakestPrecondition(tuple); + return weakestPrecondition; + } + + @Override + public String toString() { + return "['" + wps + "']"; + } + + public void getSyntaxTree(final IPrologTermOutput pout) { + final ASTProlog prolog = new ASTProlog(pout, + new ClassicalPositionPrinter(new NodeIdAssignment())); + pout.openList(); + // pout.openTerm("entry"); + // pout.printAtom(ReverseTranslate.reverseTranslate(p.toString())); + PredicateVisitor pv = new PredicateVisitor(new LinkedList<String>()); + wps.accept(pv); + PPredicate predicate = pv.getPredicate(); + predicate.apply(prolog); + // pout.closeTerm(); + pout.closeList(); + } +} diff --git a/de.prob.core/src/de/prob/eventb/translator/internal/DischargedProof.java b/de.prob.core/src/de/prob/eventb/translator/internal/DischargedProof.java new file mode 100644 index 0000000000000000000000000000000000000000..fb26c2d76db70579408323f7c020cb1154280976 --- /dev/null +++ b/de.prob.core/src/de/prob/eventb/translator/internal/DischargedProof.java @@ -0,0 +1,27 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +/** + * + */ +package de.prob.eventb.translator.internal; + +import org.eventb.core.IEvent; +import org.eventb.core.IInvariant; +import org.eventb.core.IMachineRoot; + +public class DischargedProof { + public final IInvariant invariant; + public final IEvent event; + public final IMachineRoot machine; + + public DischargedProof(final IMachineRoot root, final IInvariant inv, + final IEvent evt) { + machine = root; + invariant = inv; + event = evt; + } +} \ No newline at end of file diff --git a/de.prob.core/src/de/prob/eventb/translator/internal/EventBContextTranslator.java b/de.prob.core/src/de/prob/eventb/translator/internal/EventBContextTranslator.java new file mode 100644 index 0000000000000000000000000000000000000000..00bcb019eb44f2cf08dca58f4df5a3e706f83d9a --- /dev/null +++ b/de.prob.core/src/de/prob/eventb/translator/internal/EventBContextTranslator.java @@ -0,0 +1,88 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.eventb.translator.internal; + +import java.util.ArrayList; +import java.util.List; + +import org.eventb.core.ISCContext; +import org.eventb.core.ISCContextRoot; +import org.eventb.core.ISCExtendsContext; +import org.eventb.core.ISCInternalContext; +import org.rodinp.core.RodinDBException; + +import de.prob.core.translator.TranslationFailedException; +import de.prob.eventb.translator.ContextTranslator; +import de.prob.prolog.output.IPrologTermOutput; + +public final class EventBContextTranslator extends EventBTranslator { + + private final ISCContext context; + + public static void create(final ISCContextRoot context, + final IPrologTermOutput pto) throws TranslationFailedException { + EventBContextTranslator translator = new EventBContextTranslator( + context); + translator.constructTranslation(pto); + } + + public static void create(final ISCInternalContext context, + final IPrologTermOutput pto) throws TranslationFailedException { + EventBContextTranslator translator = new EventBContextTranslator( + context); + translator.constructTranslation(pto); + } + + // ############################################################################################ + + private EventBContextTranslator(final ISCInternalContext context) { + super(context); + this.context = context; + } + + private EventBContextTranslator(final ISCContextRoot context) { + super(context); + this.context = context; + } + + private void constructTranslation(final IPrologTermOutput pto) + throws TranslationFailedException { + List<ContextTranslator> translators = new ArrayList<ContextTranslator>(); + translators.add(ContextTranslator.create(context)); + if (context instanceof ISCContextRoot) { + ISCContextRoot root = (ISCContextRoot) context; + collectContexts(translators, new ArrayList<String>(), root); + } + printProlog(new ArrayList<ModelTranslator>(), translators, pto); + } + + private void collectContexts(final List<ContextTranslator> translatorMap, + final List<String> processed, final ISCContextRoot context) + throws TranslationFailedException { + String name = context.getElementName(); + if (!processed.contains(name)) { + processed.add(name); + translatorMap.add(ContextTranslator.create(context)); + ISCExtendsContext[] clauses; + try { + clauses = context.getSCExtendsClauses(); + for (ISCExtendsContext extendsContext : clauses) { + ISCContextRoot element = extendsContext + .getAbstractSCContext(); + collectContexts(translatorMap, processed, element); + } + } catch (RodinDBException e) { + throw new TranslationFailedException(e); + } + } + } + + @Override + protected void printFlowInformation(final IPrologTermOutput pout) { + } + +} diff --git a/de.prob.core/src/de/prob/eventb/translator/internal/EventBMachineTranslator.java b/de.prob.core/src/de/prob/eventb/translator/internal/EventBMachineTranslator.java new file mode 100644 index 0000000000000000000000000000000000000000..b6ee12f4e13e3fbabecdd6b9ea25020a3f8b907f --- /dev/null +++ b/de.prob.core/src/de/prob/eventb/translator/internal/EventBMachineTranslator.java @@ -0,0 +1,140 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.eventb.translator.internal; + +import java.util.ArrayList; +import java.util.List; + +import org.eventb.core.ISCInternalContext; +import org.eventb.core.ISCMachineRoot; +import org.rodinp.core.IRodinFile; +import org.rodinp.core.RodinDBException; + +import de.prob.core.translator.TranslationFailedException; +import de.prob.eventb.translator.ContextTranslator; +import de.prob.eventb.translator.flow.FlowAnalysis; +import de.prob.logging.Logger; +import de.prob.prolog.output.IPrologTermOutput; + +public final class EventBMachineTranslator extends EventBTranslator { + + private final ISCMachineRoot machine; + + /* + * (non-Javadoc) + * + * @see de.prob.core.translator.ITranslator#getPrologTerm() + */ + // public String getPrologTerm() { + // return term; + // } + + public static void create(final ISCMachineRoot machine, + final IPrologTermOutput pto) throws TranslationFailedException { + EventBMachineTranslator translator = new EventBMachineTranslator( + machine); + translator.constructTranslation(pto); + } + + // ############################################################################################ + + private EventBMachineTranslator(final ISCMachineRoot machine) { + super(machine); + this.machine = machine; + } + + private void constructTranslation(final IPrologTermOutput pto) + throws TranslationFailedException { + // ISCMachineRoot currentMachine = machine; + // + // ModelTranslator root = ModelTranslator.create(currentMachine); + // + // final List<ModelTranslator> mchTranslators = + // getModelTranslators(root); + // final List<ContextTranslator> ctxTranslators = + // getContextTranslators(root + // .getContextDependencies()); + // + // term = printProlog(mchTranslators, ctxTranslators); + + List<ISCMachineRoot> roots = collectRefinementChain(); + final List<ModelTranslator> mchTranslators = getModelTranslators(roots); + final List<ContextTranslator> ctxTranslators = getContextTranslators(roots); + printProlog(mchTranslators, ctxTranslators, pto); + } + + private List<ISCMachineRoot> collectRefinementChain() + throws TranslationFailedException { + List<ISCMachineRoot> roots = new ArrayList<ISCMachineRoot>(); + + try { + buildRefinementChain(machine, roots); + } catch (RodinDBException e) { + throw new TranslationFailedException(e); + } + return roots; + } + + private void buildRefinementChain(final ISCMachineRoot element, + final List<ISCMachineRoot> list) throws RodinDBException { + list.add(element); + IRodinFile[] abst = element.getAbstractSCMachines(); + for (IRodinFile rodinFile : abst) { + buildRefinementChain((ISCMachineRoot) rodinFile.getRoot(), list); + } + } + + private List<ModelTranslator> getModelTranslators( + final List<ISCMachineRoot> roots) throws TranslationFailedException { + final List<ModelTranslator> mchTranslators = new ArrayList<ModelTranslator>(); + for (ISCMachineRoot iscMachineRoot : roots) { + mchTranslators.add(ModelTranslator.create(iscMachineRoot)); + } + return mchTranslators; + } + + private List<ContextTranslator> getContextTranslators( + final List<ISCMachineRoot> models) + throws TranslationFailedException { + final List<ContextTranslator> translators = new ArrayList<ContextTranslator>(); + final List<String> processed = new ArrayList<String>(); + for (ISCMachineRoot m : models) { + ISCInternalContext[] seenContexts; + try { + seenContexts = m.getSCSeenContexts(); + for (ISCInternalContext seenContext : seenContexts) { + collectContexts(translators, processed, seenContext); + } + } catch (RodinDBException e) { + throw new TranslationFailedException(e); + } + } + return translators; + } + + private void collectContexts(final List<ContextTranslator> translatorMap, + final List<String> processed, final ISCInternalContext context) + throws TranslationFailedException { + String name = context.getElementName(); + if (!processed.contains(name)) { + processed.add(name); + translatorMap.add(ContextTranslator.create(context)); + } + } + + @Override + protected void printFlowInformation(final IPrologTermOutput pout) { + try { + FlowAnalysis flowAnalysis = new FlowAnalysis(this.machine); + flowAnalysis.printGraph(pout); + } catch (Exception e) { + final String message = "Error while constructing Flow Information: " + + e.getLocalizedMessage(); + Logger.notifyUser(message, e); + } + } +} diff --git a/de.prob.core/src/de/prob/eventb/translator/internal/EventBTranslator.java b/de.prob.core/src/de/prob/eventb/translator/internal/EventBTranslator.java new file mode 100644 index 0000000000000000000000000000000000000000..6f0abac0ea06db6494470811d7d5270f98826171 --- /dev/null +++ b/de.prob.core/src/de/prob/eventb/translator/internal/EventBTranslator.java @@ -0,0 +1,136 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.eventb.translator.internal; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Map; + +import org.eclipse.core.runtime.Assert; +import org.eventb.core.IEventBProject; +import org.eventb.core.IEventBRoot; +import org.eventb.core.ISCInternalContext; +import org.eventb.core.ISCMachineRoot; +import org.rodinp.core.IInternalElement; +import org.rodinp.core.RodinDBException; + +import de.be4.classicalb.core.parser.analysis.prolog.ASTProlog; +import de.be4.classicalb.core.parser.node.AEventBContextParseUnit; +import de.be4.classicalb.core.parser.node.AEventBModelParseUnit; +import de.be4.classicalb.core.parser.node.Node; +import de.prob.core.translator.ITranslator; +import de.prob.core.translator.TranslationFailedException; +import de.prob.eventb.translator.AbstractComponentTranslator; +import de.prob.eventb.translator.ContextTranslator; +import de.prob.prolog.output.IPrologTermOutput; + +public abstract class EventBTranslator implements ITranslator { + protected final IEventBProject project; + private final String name; + + protected EventBTranslator(final IEventBRoot root) { + this.project = root.getEventBProject(); + this.name = root.getComponentName(); + } + + // another constructor to cater for ISCInternalContext (which is not a root + // element) + protected EventBTranslator(final ISCInternalContext ctx) { + Assert.isTrue(ctx.getRoot() instanceof ISCMachineRoot); + this.project = ((ISCMachineRoot) ctx.getRoot()).getEventBProject(); + this.name = ctx.getComponentName(); + } + + private LabelPositionPrinter createPrinter( + final Collection<AbstractComponentTranslator> translators) + throws TranslationFailedException { + LabelPositionPrinter printer = new LabelPositionPrinter(); + for (AbstractComponentTranslator t : translators) { + final Map<Node, IInternalElement> labelMapping = t + .getLabelMapping(); + printer.addNodes(labelMapping); + } + return printer; + } + + private void printContexts( + final Collection<ContextTranslator> contextTranslators, + final IPrologTermOutput pout, final ASTProlog prolog) { + pout.openList(); + for (final ContextTranslator contextTranslator : contextTranslators) { + final AEventBContextParseUnit contextAST = contextTranslator + .getContextAST(); + contextAST.apply(prolog); + } + pout.closeList(); + } + + private void printModels( + final Collection<ModelTranslator> refinementChainTranslators, + final IPrologTermOutput pout, final ASTProlog prolog) { + pout.openList(); + + for (final ModelTranslator modelTranslator : refinementChainTranslators) { + final AEventBModelParseUnit modelAST = modelTranslator + .getModelAST(); + modelAST.apply(prolog); + } + pout.closeList(); + } + + private void printProofInformation( + final Collection<ModelTranslator> refinementChainTranslators, + final IPrologTermOutput pout) throws TranslationFailedException { + for (ModelTranslator modelTranslator : refinementChainTranslators) { + for (DischargedProof proof : modelTranslator.getProofs()) { + pout.openTerm("discharged"); + pout.printAtom(proof.machine.getRodinFile().getBareName()); + try { + final String label = proof.event.getLabel(); + final String elementName = proof.invariant.getLabel(); + pout.printAtom(label); + pout.printAtom(elementName); + } catch (RodinDBException e) { + final String details = "Translation error while getting information about discharged proof obligations"; + throw new TranslationFailedException(name, details); + } + + pout.closeTerm(); + } + } + if (System.getProperty("flow") != null) printFlowInformation(pout); + } + + protected abstract void printFlowInformation(final IPrologTermOutput pout); + + private ASTProlog createAstVisitor( + final Collection<ModelTranslator> refinementChainTranslators, + final Collection<ContextTranslator> contextTranslators, + final IPrologTermOutput pout) throws TranslationFailedException { + Collection<AbstractComponentTranslator> translators = new ArrayList<AbstractComponentTranslator>(); + translators.addAll(refinementChainTranslators); + translators.addAll(contextTranslators); + return new ASTProlog(pout, createPrinter(translators)); + } + + protected void printProlog( + final Collection<ModelTranslator> refinementChainTranslators, + final Collection<ContextTranslator> contextTranslators, + final IPrologTermOutput pout) throws TranslationFailedException { + final ASTProlog prolog = createAstVisitor(refinementChainTranslators, + contextTranslators, pout); + + pout.openTerm("load_event_b_project"); + printModels(refinementChainTranslators, pout, prolog); + printContexts(contextTranslators, pout, prolog); + pout.openList(); + printProofInformation(refinementChainTranslators, pout); + pout.closeList(); + pout.printVariable("_Error"); + pout.closeTerm(); + } +} diff --git a/de.prob.core/src/de/prob/eventb/translator/internal/LabelPositionPrinter.java b/de.prob.core/src/de/prob/eventb/translator/internal/LabelPositionPrinter.java new file mode 100644 index 0000000000000000000000000000000000000000..49aa39a67a5ce3c76325e3e26787f217a40aa83e --- /dev/null +++ b/de.prob.core/src/de/prob/eventb/translator/internal/LabelPositionPrinter.java @@ -0,0 +1,115 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +/** + * + */ +package de.prob.eventb.translator.internal; + +import java.util.Map; +import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; + +import org.eventb.core.ILabeledElement; +import org.eventb.core.ITraceableElement; +import org.rodinp.core.IInternalElement; +import org.rodinp.core.IRodinElement; +import org.rodinp.core.RodinDBException; + +import de.be4.classicalb.core.parser.analysis.prolog.PositionPrinter; +import de.be4.classicalb.core.parser.node.Node; +import de.prob.core.translator.TranslationFailedException; +import de.prob.prolog.output.IPrologTermOutput; + +/** + * This PositionPrinter stores and prints the labels and internal node name + * + * @author plagge + * + */ +public class LabelPositionPrinter implements PositionPrinter { + private IPrologTermOutput pout; + + private final Map<Node, NodeInfo> nodeInfos = new ConcurrentHashMap<Node, NodeInfo>(); + + public void addNode(final Node node, final IInternalElement element) + throws TranslationFailedException { + final String label, source; + try { + if (element instanceof ITraceableElement) { + // get name of unchecked element + IRodinElement traceableSource; + traceableSource = ((ITraceableElement) element).getSource(); + + source = traceableSource.getElementName(); + } else { + source = null; + } + if (element instanceof ILabeledElement) { + label = ((ILabeledElement) element).getLabel(); + } else { + label = null; + } + addNode(node, label, source); + } catch (RodinDBException e) { + final String message = "A Rodin exception occured during translation process, you can try to fix that by cleaning the project. Original Exception: "; + throw new TranslationFailedException(element.getElementName(), + message + e.getLocalizedMessage()); + } + } + + public void addNodes(final Map<Node, IInternalElement> nodeMapping) + throws TranslationFailedException { + for (Entry<Node, IInternalElement> item : nodeMapping.entrySet()) { + final Node key = item.getKey(); + final IInternalElement value = item.getValue(); + addNode(key, value); + } + } + + private void addNode(final Node node, final String label, + final String elementName) { + if (label != null || elementName != null) { + nodeInfos.put(node, new NodeInfo(label, elementName)); + } + } + + public void printPosition(final Node node) { + final NodeInfo info = nodeInfos.get(node); + if (info == null) { + pout.printAtom("none"); + } else { + pout.openTerm("rodinpos"); + if (info.label == null) { + pout.emptyList(); + } else { + pout.printAtom(info.label); + } + if (info.elementName == null) { + pout.emptyList(); + } else { + pout.printAtom(info.elementName); + } + pout.closeTerm(); + } + } + + public void setPrologTermOutput(final IPrologTermOutput pout) { + this.pout = pout; + } + + private static class NodeInfo { + private final String label; + private final String elementName; + + public NodeInfo(final String label, final String elementName) { + super(); + this.label = label; + this.elementName = elementName; + } + } + +} diff --git a/de.prob.core/src/de/prob/eventb/translator/internal/LabelStore.java b/de.prob.core/src/de/prob/eventb/translator/internal/LabelStore.java new file mode 100644 index 0000000000000000000000000000000000000000..99e6f0ccecbc22fcefa5b7490293db651275300e --- /dev/null +++ b/de.prob.core/src/de/prob/eventb/translator/internal/LabelStore.java @@ -0,0 +1,51 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.eventb.translator.internal; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.eclipse.core.runtime.Assert; + +import de.be4.classicalb.core.parser.node.PPredicate; + +public final class LabelStore { + + private final Map<PPredicate, String> node2label = new ConcurrentHashMap<PPredicate, String>(); + private final Map<String, PPredicate> label2node = new ConcurrentHashMap<String, PPredicate>(); + + /** + * Returns the AST Node for a given label. + * + * @param label + * (must not be null) + * @return AST root node of the corresponding subtree + */ + public PPredicate getNode(final String label) { + Assert.isNotNull(label); + return label2node.get(label); + } + + /** + * Returns the label for a given AST Node. + * + * @param node + * (must not be null) + * @return Label for a give subtree (if there is one, otherwise it returns + * null) + */ + public String getLabel(final PPredicate node) { + Assert.isNotNull(node); + return node2label.get(node); + } + + public synchronized void put(final String label, final PPredicate node) { + label2node.put(label, node); + node2label.put(node, label); + } + +} diff --git a/de.prob.core/src/de/prob/eventb/translator/internal/ModelTranslator.java b/de.prob.core/src/de/prob/eventb/translator/internal/ModelTranslator.java new file mode 100644 index 0000000000000000000000000000000000000000..da2420757d7e21218a8db087ee1f8f1f6f8f9b1e --- /dev/null +++ b/de.prob.core/src/de/prob/eventb/translator/internal/ModelTranslator.java @@ -0,0 +1,528 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, Heinrich + * Heine Universitaet Duesseldorf This software is licenced under EPL 1.0 + * (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.eventb.translator.internal; // NOPMD by bendisposto +// High coupling to the ast is ok + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +import org.apache.commons.lang.StringUtils; +import org.eventb.core.IConvergenceElement.Convergence; +import org.eventb.core.IEvent; +import org.eventb.core.IInvariant; +import org.eventb.core.IMachineRoot; +import org.eventb.core.IPOSequent; +import org.eventb.core.IPOSource; +import org.eventb.core.IPSRoot; +import org.eventb.core.IPSStatus; +import org.eventb.core.ISCAction; +import org.eventb.core.ISCEvent; +import org.eventb.core.ISCGuard; +import org.eventb.core.ISCInternalContext; +import org.eventb.core.ISCInvariant; +import org.eventb.core.ISCMachineRoot; +import org.eventb.core.ISCParameter; +import org.eventb.core.ISCPredicateElement; +import org.eventb.core.ISCRefinesEvent; +import org.eventb.core.ISCRefinesMachine; +import org.eventb.core.ISCVariable; +import org.eventb.core.ISCVariant; +import org.eventb.core.ISCWitness; +import org.eventb.core.ITraceableElement; +import org.eventb.core.ast.FormulaFactory; +import org.eventb.core.ast.ITypeEnvironment; +import org.eventb.core.ast.Predicate; +import org.eventb.core.seqprover.IConfidence; +import org.rodinp.core.IRodinElement; +import org.rodinp.core.IRodinFile; +import org.rodinp.core.RodinDBException; + +import de.be4.classicalb.core.parser.node.AAnticipatedEventstatus; +import de.be4.classicalb.core.parser.node.AConvergentEventstatus; +import de.be4.classicalb.core.parser.node.AEvent; +import de.be4.classicalb.core.parser.node.AEventBModelParseUnit; +import de.be4.classicalb.core.parser.node.AEventsModelClause; +import de.be4.classicalb.core.parser.node.AIdentifierExpression; +import de.be4.classicalb.core.parser.node.AInvariantModelClause; +import de.be4.classicalb.core.parser.node.AOrdinaryEventstatus; +import de.be4.classicalb.core.parser.node.ARefinesModelClause; +import de.be4.classicalb.core.parser.node.ASeesModelClause; +import de.be4.classicalb.core.parser.node.ATheoremsModelClause; +import de.be4.classicalb.core.parser.node.AVariablesModelClause; +import de.be4.classicalb.core.parser.node.AVariantModelClause; +import de.be4.classicalb.core.parser.node.AWitness; +import de.be4.classicalb.core.parser.node.PEvent; +import de.be4.classicalb.core.parser.node.PEventstatus; +import de.be4.classicalb.core.parser.node.PExpression; +import de.be4.classicalb.core.parser.node.PModelClause; +import de.be4.classicalb.core.parser.node.PPredicate; +import de.be4.classicalb.core.parser.node.PSubstitution; +import de.be4.classicalb.core.parser.node.PWitness; +import de.be4.classicalb.core.parser.node.TIdentifierLiteral; +import de.prob.core.translator.TranslationFailedException; +import de.prob.eventb.translator.AbstractComponentTranslator; +import de.prob.eventb.translator.AssignmentVisitor; +import de.prob.eventb.translator.ExpressionVisitor; +import de.prob.eventb.translator.PredicateVisitor; +import de.prob.logging.Logger; + +public class ModelTranslator extends AbstractComponentTranslator { + + private final ISCMachineRoot machine; + private final AEventBModelParseUnit model = new AEventBModelParseUnit(); + private final FormulaFactory ff = FormulaFactory.getDefault();; + private final IMachineRoot origin; + private final List<DischargedProof> proofs = new ArrayList<DischargedProof>(); + // private final List<String> depContext = new ArrayList<String>(); + + // Confined in the thread calling the factory method + private ITypeEnvironment te; + private String refines; + private boolean broken = false; + + // ############################################################################################################################################################### + // Public Interface + + public static ModelTranslator create(final ISCMachineRoot model) + throws TranslationFailedException { + ModelTranslator modelTranslator = new ModelTranslator(model); + try { + modelTranslator.translate(); + } catch (RodinDBException re) { + final String message = "Rodin Database Exception: \n" + + re.getLocalizedMessage(); + throw new TranslationFailedException(modelTranslator.getClass() + .toString(), message); + } catch (RuntimeException e) { + // spurious runtime exceptions were thrown, especially if older + // EventB= Projects were used without cleaning the project + final String message = "Possible cause: building aborted or still in progress. Please wait until building has finished before starting ProB. If this does not help, perform a clean and start ProB after building has finished.\nException was: " + + e.getClass().getSimpleName() + + "\n" + + e.getLocalizedMessage(); + throw new TranslationFailedException(modelTranslator.getClass() + .toString(), message); + } + return modelTranslator; + } + + public List<DischargedProof> getProofs() { + return Collections.unmodifiableList(proofs); + } + + public AEventBModelParseUnit getModelAST() { + if (broken) { + final String message = "The machine contains Rodin Problems. Please fix it before animating"; + Logger.notifyUserWithoutBugreport(message); + return model; + } + return model; + } + + // public List<String> getContextDependencies() { + // return depContext; + // } + + public String getRefinementDependency() { + return refines; + } + + // ############################################################################################################################################################### + // Implementation + + private ModelTranslator(final ISCMachineRoot currentMachine) { + this.machine = currentMachine; + origin = machine.getMachineRoot(); + } + + private void translate() throws RodinDBException, + TranslationFailedException { + + final String message = "machine.getRodinFile().isConsistent() [Note: Maybe you can fix this Rodin problem by refreshing and rebuilding the project]"; + Logger.assertProB(message, machine.getRodinFile().isConsistent()); + + broken = !machine.isAccurate(); // isAccurate() is not transitive, we + // need to collect the information also + // for the events + te = machine.getTypeEnvironment(ff); + + translateMachine(); + + // Check for fully discharged Invariants and Events + collectProofInfo(); + } + + private void collectProofInfo() throws RodinDBException { + + IPSRoot proofStatus = machine.getPSRoot(); + IPSStatus[] statuses = proofStatus.getStatuses(); + + List<String> bugs = new LinkedList<String>(); + + for (IPSStatus status : statuses) { + final int confidence = status.getConfidence(); + boolean broken = status.isBroken(); + if (!broken && confidence == IConfidence.DISCHARGED_MAX) { + IPOSequent sequent = status.getPOSequent(); + IPOSource[] sources = sequent.getSources(); + + IEvent evt = null; + IInvariant inv = null; + + for (IPOSource source : sources) { + + IRodinElement srcElement = source.getSource(); + if (!srcElement.exists()) { + bugs.add(status.getElementName()); + break; + } + + if (srcElement instanceof IEvent) { + IEvent tmp = (IEvent) srcElement; + if (((IMachineRoot) tmp.getParent()).equals(origin)) { + evt = tmp; + } + } + if (srcElement instanceof IInvariant) { + IInvariant tmp = (IInvariant) srcElement; + if (((IMachineRoot) tmp.getParent()).equals(origin)) { + inv = tmp; + } + + } + } + if (evt != null && inv != null) { + proofs.add(new DischargedProof(origin, inv, evt)); + } + } + } + + if (!bugs.isEmpty()) { + String message = "Translation incomplete due to a Bug in Rodin. This does not affect correctness of the Animation/Model Checking but can decrease its performance. Skipped discharged information about: " + + StringUtils.join(bugs, ","); + Logger.notifyUser(message); + } + + } + + private void translateMachine() throws RodinDBException, + TranslationFailedException { + model.setName(new TIdentifierLiteral(machine.getRodinFile() + .getBareName())); + + final List<PModelClause> clauses = new ArrayList<PModelClause>(); + + clauses.add(processContexts()); + final ARefinesModelClause ref = processRefines(); + if (ref != null) { + clauses.add(ref); + } + clauses.add(processVariables()); + clauses.add(processInvariants()); + clauses.add(processTheorems()); + final AVariantModelClause var = processVariant(); + if (var != null) { + clauses.add(var); + } + clauses.add(processEvents()); + + model.setModelClauses(clauses); + } + + private AVariantModelClause processVariant() throws RodinDBException, + TranslationFailedException { + final ISCVariant[] variant = machine.getSCVariants(); + final AVariantModelClause var; + if (variant.length == 1) { + final ExpressionVisitor visitor = new ExpressionVisitor( + new LinkedList<String>()); + variant[0].getExpression(ff, te).accept(visitor); + var = new AVariantModelClause(visitor.getExpression()); + } else if (variant.length == 0) { + var = null; + } else + throw new TranslationFailedException(machine.getComponentName(), + "expected at most one variant, but there were " + + variant.length); + return var; + } + + private ARefinesModelClause processRefines() throws RodinDBException, + TranslationFailedException { + final ISCRefinesMachine[] refinesClauses = machine + .getSCRefinesClauses(); + final ARefinesModelClause ref; + if (refinesClauses.length == 1) { + final String name = refinesClauses[0].getAbstractSCMachine() + .getBareName(); + ref = new ARefinesModelClause(new TIdentifierLiteral(name)); + refines = name; + } else if (refinesClauses.length == 0) { + ref = null; + refines = null; + } else + throw new TranslationFailedException(machine.getComponentName(), + "expected at most one refined machine, but there were " + + refinesClauses.length); + return ref; + } + + private ASeesModelClause processContexts() throws RodinDBException { + final ISCInternalContext[] seenContexts = machine.getSCSeenContexts(); + final List<TIdentifierLiteral> contexts = new ArrayList<TIdentifierLiteral>( + seenContexts.length); + for (final ISCInternalContext context : seenContexts) { + final String componentName = context.getComponentName(); + // depContext.add(componentName); + contexts.add(new TIdentifierLiteral(componentName)); + } + return new ASeesModelClause(contexts); + } + + private AEventsModelClause processEvents() + throws TranslationFailedException, RodinDBException { + final AEventsModelClause clause = new AEventsModelClause(); + final ISCEvent[] events = machine.getSCEvents(); + final List<PEvent> eventsList = new ArrayList<PEvent>(events.length); + for (final ISCEvent revent : events) { + + broken = broken || !revent.isAccurate(); + + ITypeEnvironment localEnv = revent.getTypeEnvironment(te, ff); + localEnv.addAll(te); + + ISCVariable[] variables = machine.getSCVariables(); + for (ISCVariable variable : variables) { + if (variable.isAbstract() || variable.isConcrete()) { + localEnv.add(variable.getIdentifier(ff).withPrime(ff)); + } + } + + final AEvent event = new AEvent(); + // Name + event.setEventName(new TIdentifierLiteral(revent.getLabel())); + labelMapping.put(event, revent); + + List<PPredicate> guards = new ArrayList<PPredicate>(); + List<PPredicate> theorems = new ArrayList<PPredicate>(); + + event.setStatus(extractEventStatus(revent)); + event.setRefines(extractRefinedEvents(revent)); + event.setVariables(extractParameters(revent)); + extractGuards(revent, localEnv, guards, theorems); + event.setGuards(guards); + event.setTheorems(theorems); + event.setWitness(extractWitnesses(revent, localEnv)); + event.setAssignments(extractActions(revent, localEnv)); + eventsList.add(event); + } + clause.setEvent(eventsList); + return clause; + } + + private PEventstatus extractEventStatus(final ISCEvent revent) + throws TranslationFailedException, RodinDBException { + Convergence convergence = revent.getConvergence(); + PEventstatus status; + switch (convergence) { + case ORDINARY: + status = new AOrdinaryEventstatus(); + break; + case ANTICIPATED: + status = new AAnticipatedEventstatus(); + break; + case CONVERGENT: + status = new AConvergentEventstatus(); + break; + default: + throw new TranslationFailedException(machine.getComponentName(), + "unexpected convergent status " + convergence); + } + return status; + } + + private List<TIdentifierLiteral> extractRefinedEvents(final ISCEvent revent) + throws RodinDBException { + final ISCRefinesEvent[] refinesClauses = revent.getSCRefinesClauses(); + final List<TIdentifierLiteral> refines = new ArrayList<TIdentifierLiteral>( + refinesClauses.length); + for (final ISCRefinesEvent refinesEvent : refinesClauses) { + final String label = refinesEvent.getAbstractSCEvent().getLabel(); + refines.add(new TIdentifierLiteral(label)); + } + return refines; + } + + private List<PExpression> extractParameters(final ISCEvent revent) + throws RodinDBException { + final ISCParameter[] parameters = revent.getSCParameters(); + final List<PExpression> parametersList = new ArrayList<PExpression>( + parameters.length); + for (final ISCParameter parameter : parameters) { + final AIdentifierExpression id = new AIdentifierExpression( + Arrays.asList(new TIdentifierLiteral[] { new TIdentifierLiteral( + parameter.getIdentifierString()) })); + parametersList.add(id); + labelMapping.put(id, parameter); + } + return parametersList; + } + + private void extractGuards(final ISCEvent revent, + final ITypeEnvironment localEnv, final List<PPredicate> guardsList, + final List<PPredicate> theoremsList) throws RodinDBException { + final ISCGuard[] guards = revent.getSCGuards(); + for (final ISCGuard guard : guards) { + final PredicateVisitor visitor = new PredicateVisitor( + new LinkedList<String>()); + final Predicate guardPredicate = guard.getPredicate(ff, localEnv); + // System.out.println("GUARD: " + guard.getLabel() + " -> " + // + guardPredicate); + guardPredicate.accept(visitor); + final PPredicate predicate = visitor.getPredicate(); + if (guard.isTheorem()) { + theoremsList.add(predicate); + } else { + guardsList.add(predicate); + } + labelMapping.put(predicate, guard); + } + } + + private AVariablesModelClause processVariables() throws RodinDBException { + final ISCVariable[] variables = machine.getSCVariables(); + final AVariablesModelClause variablesModelClause = new AVariablesModelClause(); + + final List<PExpression> list = new ArrayList<PExpression>( + variables.length); + for (final ISCVariable variable : variables) { + if (variable.isConcrete()) { + final TIdentifierLiteral literal = new TIdentifierLiteral( + variable.getIdentifierString()); + final AIdentifierExpression id = new AIdentifierExpression( + Arrays.asList(new TIdentifierLiteral[] { literal })); + list.add(id); + } + } + variablesModelClause.setIdentifiers(list); + return variablesModelClause; + } + + private List<PWitness> extractWitnesses(final ISCEvent revent, + final ITypeEnvironment localEnv) throws RodinDBException { + final ISCWitness[] witnesses = revent.getSCWitnesses(); + final List<PWitness> witnessList = new ArrayList<PWitness>( + witnesses.length); + for (final ISCWitness witness : witnesses) { + final PredicateVisitor visitor = new PredicateVisitor( + new LinkedList<String>()); + final Predicate pp = witness.getPredicate(ff, localEnv); + pp.accept(visitor); + final PPredicate predicate = visitor.getPredicate(); + final TIdentifierLiteral label = new TIdentifierLiteral( + witness.getLabel()); + witnessList.add(new AWitness(label, predicate)); + labelMapping.put(predicate, witness); + } + return witnessList; + } + + private List<PSubstitution> extractActions(final ISCEvent revent, + final ITypeEnvironment localEnv) throws RodinDBException { + final ISCAction[] actions = revent.getSCActions(); + final List<PSubstitution> actionList = new ArrayList<PSubstitution>(); + for (final ISCAction action : actions) { + final AssignmentVisitor visitor = new AssignmentVisitor(); + action.getAssignment(ff, localEnv).accept(visitor); + final PSubstitution substitution = visitor.getSubstitution(); + actionList.add(substitution); + labelMapping.put(substitution, action); + } + return actionList; + } + + private AInvariantModelClause processInvariants() throws RodinDBException { + final AInvariantModelClause invariantModelClause = new AInvariantModelClause(); + invariantModelClause.setPredicates(getPredicateList( + machine.getSCInvariants(), false)); + return invariantModelClause; + } + + private ATheoremsModelClause processTheorems() throws RodinDBException { + final ATheoremsModelClause theoremsModelClause = new ATheoremsModelClause(); + theoremsModelClause.setPredicates(getPredicateList( + machine.getSCInvariants(), true)); + return theoremsModelClause; + } + + /** + * Generates a list of classical B predicates from a list of invariants or + * theorems Note: Aside from {@link ISCPredicateElement}, each element must + * additionally implement {@link ITraceableElement}, such as + * {@link ISCInvariant} does. + * + * @param predicates + * Array of static checked predicated taken from the invariants + * @param theorems + * true, if the returned list should only contain theorems, + * false, if all theorems shall be filtered out + * @return + * @throws RodinDBException + */ + private List<PPredicate> getPredicateList(final ISCInvariant[] predicates, + final boolean theorems) throws RodinDBException { + final List<PPredicate> list = new ArrayList<PPredicate>( + predicates.length); + for (final ISCInvariant evPredicate : predicates) { + // skip, if we want invariants and this is a theorem or vice versa + if (evPredicate.isTheorem() != theorems) { + continue; + } + // only use predicates that are defined in the current refinement + // level, not in an abstract machine + if (!isDefinedInAbstraction(evPredicate)) { + final PredicateVisitor visitor = new PredicateVisitor( + new LinkedList<String>()); + evPredicate.getPredicate(ff, te).accept(visitor); + final PPredicate predicate = visitor.getPredicate(); + list.add(predicate); + labelMapping.put(predicate, evPredicate); + } + } + return list; + } + + private boolean isDefinedInAbstraction(final ITraceableElement element) + throws RodinDBException { + final IRodinElement parentsource = element.getSource().getParent(); + final boolean result; + + if (parentsource instanceof IMachineRoot) { + IMachineRoot src = (IMachineRoot) parentsource; + + // do a finer level check + String srcName = src.getRodinFile().getBareName(); + + // is the source one of the refined machines? + for (IRodinFile abstr : machine.getAbstractSCMachines()) + if (abstr.getBareName().equals(srcName)) + return true; + + result = false; + + // result = !machine.getRodinFile().getBareName() + // .equals(src.getRodinFile().getBareName()); + } else { + result = false; + } + return result; + } + +} diff --git a/de.prob.core/src/de/prob/eventb/translator/internal/SimpleVisitorAdapter.java b/de.prob.core/src/de/prob/eventb/translator/internal/SimpleVisitorAdapter.java new file mode 100644 index 0000000000000000000000000000000000000000..b6b186285f102b1336e76d5686360313ec31dfef --- /dev/null +++ b/de.prob.core/src/de/prob/eventb/translator/internal/SimpleVisitorAdapter.java @@ -0,0 +1,157 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.eventb.translator.internal; + +import org.eventb.core.ast.AssociativeExpression; +import org.eventb.core.ast.AssociativePredicate; +import org.eventb.core.ast.AtomicExpression; +import org.eventb.core.ast.BecomesEqualTo; +import org.eventb.core.ast.BecomesMemberOf; +import org.eventb.core.ast.BecomesSuchThat; +import org.eventb.core.ast.BinaryExpression; +import org.eventb.core.ast.BinaryPredicate; +import org.eventb.core.ast.BoolExpression; +import org.eventb.core.ast.BoundIdentDecl; +import org.eventb.core.ast.BoundIdentifier; +import org.eventb.core.ast.ExtendedExpression; +import org.eventb.core.ast.ExtendedPredicate; +import org.eventb.core.ast.FreeIdentifier; +import org.eventb.core.ast.ISimpleVisitor; +import org.eventb.core.ast.IntegerLiteral; +import org.eventb.core.ast.LiteralPredicate; +import org.eventb.core.ast.MultiplePredicate; +import org.eventb.core.ast.QuantifiedExpression; +import org.eventb.core.ast.QuantifiedPredicate; +import org.eventb.core.ast.RelationalPredicate; +import org.eventb.core.ast.SetExtension; +import org.eventb.core.ast.SimplePredicate; +import org.eventb.core.ast.UnaryExpression; +import org.eventb.core.ast.UnaryPredicate; + +public class SimpleVisitorAdapter implements ISimpleVisitor { + + public void visitAssociativeExpression( + final AssociativeExpression expression) { + // Default implementation does nothing + } + + public void visitAssociativePredicate(final AssociativePredicate predicate) { + // Default implementation does nothing + + } + + public void visitAtomicExpression(final AtomicExpression expression) { + // Default implementation does nothing + + } + + public void visitBecomesEqualTo(final BecomesEqualTo assignment) { + + // Default implementation does nothing + } + + public void visitBecomesMemberOf(final BecomesMemberOf assignment) { + // Default implementation does nothing + + } + + public void visitBecomesSuchThat(final BecomesSuchThat assignment) { + // Default implementation does nothing + + } + + public void visitBinaryExpression(final BinaryExpression expression) { + + // Default implementation does nothing + } + + public void visitBinaryPredicate(final BinaryPredicate predicate) { + // Default implementation does nothing + + } + + public void visitBoolExpression(final BoolExpression expression) { + // Default implementation does nothing + + } + + public void visitBoundIdentDecl(final BoundIdentDecl boundIdentDecl) { + // Default implementation does nothing + + } + + public void visitBoundIdentifier(final BoundIdentifier identifierExpression) { + // Default implementation does nothing + + } + + public void visitFreeIdentifier(final FreeIdentifier identifierExpression) { + // Default implementation does nothing + + } + + public void visitIntegerLiteral(final IntegerLiteral expression) { + // Default implementation does nothing + + } + + public void visitLiteralPredicate(final LiteralPredicate predicate) { + // Default implementation does nothing + + } + + public void visitQuantifiedExpression(final QuantifiedExpression expression) { + // Default implementation does nothing + + } + + public void visitQuantifiedPredicate(final QuantifiedPredicate predicate) { + // Default implementation does nothing + + } + + public void visitRelationalPredicate(final RelationalPredicate predicate) { + // Default implementation does nothing + + } + + public void visitSetExtension(final SetExtension expression) { + // Default implementation does nothing + + } + + public void visitSimplePredicate(final SimplePredicate predicate) { + // Default implementation does nothing + + } + + public void visitUnaryExpression(final UnaryExpression expression) { + // Default implementation does nothing + + } + + public void visitUnaryPredicate(final UnaryPredicate predicate) { + // Default implementation does nothing + + } + + public void visitMultiplePredicate(final MultiplePredicate predicate) { + // Default implementation does nothing + + } + + @Override + public void visitExtendedExpression(final ExtendedExpression expression) { + // Default implementation does nothing + } + + @Override + public void visitExtendedPredicate(final ExtendedPredicate predicate) { + // Default implementation does nothing + } + +} diff --git a/de.prob.core/src/de/prob/exceptions/ProBAssertionFailed.java b/de.prob.core/src/de/prob/exceptions/ProBAssertionFailed.java new file mode 100644 index 0000000000000000000000000000000000000000..1694e18b9f73e50283137cfce9158601758efa3a --- /dev/null +++ b/de.prob.core/src/de/prob/exceptions/ProBAssertionFailed.java @@ -0,0 +1,17 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.exceptions; + +public class ProBAssertionFailed extends RuntimeException { + + private static final long serialVersionUID = -7604689708047639171L; + + public ProBAssertionFailed(final String assertion) { + super(assertion); + } + +} diff --git a/de.prob.core/src/de/prob/exceptions/ProBException.java b/de.prob.core/src/de/prob/exceptions/ProBException.java new file mode 100644 index 0000000000000000000000000000000000000000..0b31e6a42d165a7c308460cf5f7881f898307383 --- /dev/null +++ b/de.prob.core/src/de/prob/exceptions/ProBException.java @@ -0,0 +1,47 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.exceptions; + +import de.prob.logging.Logger; + +public abstract class ProBException extends Exception { + + private static final long serialVersionUID = -1797280394427366051L; + + protected boolean handled; + + public boolean isHandled() { + return handled; + } + + public ProBException(final String exception) { + this(exception, null, false); + } + + public ProBException(final Throwable e) { + this(e.getLocalizedMessage(), e, true); + } + + public ProBException(final String message, final Throwable e, + final boolean b) { + super(message, e); + this.handled = b; + } + + public ProBException(final String message, final boolean b) { + super(message); + this.handled = b; + } + + public final void notifyUserOnce() { + if (!handled) { + handled = true; + Logger.notifyUser(this.getMessage(), this); + } + } + +} diff --git a/de.prob.core/src/de/prob/logging/Logger.java b/de.prob.core/src/de/prob/logging/Logger.java new file mode 100644 index 0000000000000000000000000000000000000000..8780aa3023a0cd5596b3b27bcbaf5dc30151347c --- /dev/null +++ b/de.prob.core/src/de/prob/logging/Logger.java @@ -0,0 +1,152 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.logging; + +import org.eclipse.core.runtime.ILogListener; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; + +import de.prob.cli.CliException; +import de.prob.core.internal.Activator; +import de.prob.exceptions.ProBAssertionFailed; +import de.prob.parser.BindingGenerator; + +/** + * Logging class, use this to notify the user about errors. It also allows to + * register new Log-Listeners + * + * @author Jens Bendisposto + * + */ +public final class Logger { + + public static final int DEBUG = 0; + public static final int INFO = 1; + public static final int WARNING = 2; + public static final int BUGREPORT = 4; + public static final int NOBUGREPORT = 8; + + /** + * Registers a new {@link ILogListener}. The listener's + * {@link ILogListener#logging(IStatus, String)} method is called, if + * something is written to the plug-in log + * + * @param listener + */ + public static void addListener(final ILogListener listener) { + Activator.getDefault().getLog().addLogListener(listener); + } + + /** + * Notifies the User about a fatal problem by adding a + * {@link Logger#FATALERROR} to the log. This method takes a message + * describing the problem as well as an exception. + * <p> + * Note: Use this only if you don't want to throw an exception. If you want + * to throw a {@link CliException}, use + * {@link #handleCliException(String, Throwable)} or + * {@link #createException(String)} instead + * + * @param message + * Description of the problem. + * + * @param throwable + * Causing exception + */ + public static void notifyUser(final String message, + final Throwable throwable) { + log(IStatus.ERROR, BUGREPORT, message, throwable); + } + + public static void notifyUser(final String message) { + notifyUser(message, null); + } + + public static void notifyUserWithoutBugreport(final String message, + final Throwable throwable) { + log(IStatus.ERROR, NOBUGREPORT, message, throwable); + } + + public static void notifyUserWithoutBugreport(final String message) { + notifyUserWithoutBugreport(message, null); + } + + /** + * Check a property. The method notifies the user and throws an exception if + * the assertion fails. <br> + * <b>Examples:</b><br>{@code Logger.assertProB(this.getClass(),"x != null", x + * != null); } <br> + * {@code Logger.assertProB(this.getClass(),"x should not be null", x != null); } + * <br> + * <b>Note:</b> If you check PrologTerm objects for their type, you should + * rather use the static getXXX methods from {@link BindingGenerator} + * located in the de.prob.core package + * + * @param clazz + * The calling class. This is to help locating the problem + * @param assertion + * The Property as a string, this helps to find out, what is + * going wrong, this can contain arbitrary text to help. It is + * recommended to include the property itself + * @param property + * a boolean value, typically you want to use a boolean + * expression + * @throws CliException + */ + public static void assertProB(final String assertion, final boolean property) + throws ProBAssertionFailed { + if (!property) { + + StackTraceElement caller = Thread.currentThread().getStackTrace()[2]; + + notifyUser("ProB Assertion '" + assertion + "' failed in Class: " + + caller.getClassName() + "\n Please submit a bugreport"); + + throw new ProBAssertionFailed(assertion); + } + } + + /** + * Failed assertion. The method notifies the user and throws an exception. <br> + * <b>Examples:</b><br>{@code if (!file.exists()) String message = + * "Called open on nonexisting file " + file; + * Logger.assertProB(EditorPlugin.class, message); } + * + * @param clazz + * The calling class. This is to help locating the problem + * @param assertion + * The Property as a string, this helps to find out, what is + * going wrong, this can contain arbitrary text to help. It is + * recommended to include the property itself + * @throws CliException + */ + public static void assertFail(final String assertion) + throws ProBAssertionFailed { + assertProB(assertion, false); + } + + public static void log(final int severity, final int code, + final String message, final Throwable exception) { + final IStatus status = new Status(severity, Activator.PLUGIN_ID, code, + message, exception); + log(status); + } + + public static void info(final String message) { + final IStatus status = new Status(IStatus.INFO, Activator.PLUGIN_ID, + IStatus.OK, message, null); + log(status); + } + + private Logger() { + // Not intended for instantiation + } + + private static void log(final IStatus status) { + Activator.getDefault().getLog().log(status); + } +} diff --git a/de.prob.core/src/de/prob/sap/commands/FindTestPathCommand.java b/de.prob.core/src/de/prob/sap/commands/FindTestPathCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..c6ddc772953bbe65a18c35be465c8c549c5b5acf --- /dev/null +++ b/de.prob.core/src/de/prob/sap/commands/FindTestPathCommand.java @@ -0,0 +1,132 @@ +/** + * + */ +package de.prob.sap.commands; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.eventb.core.ast.Predicate; + +import de.prob.core.command.CommandException; +import de.prob.core.command.IComposableCommand; +import de.prob.core.domainobjects.Operation; +import de.prob.parser.ISimplifiedROMap; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.CompoundPrologTerm; +import de.prob.prolog.term.ListPrologTerm; +import de.prob.prolog.term.PrologTerm; +import de.prob.sap.util.FormulaUtils; + +/** + * This is a command that takes a list of events and a predicate over a final + * state and ask ProB to find a concrete path (with concrete states and + * parameter values). + * + * If ProB finds a value, the result can be accessed via {@link #getTrace()} + * + * @author plagge + */ +public class FindTestPathCommand implements IComposableCommand { + private final String COMMAND = "sap_find_test_path"; + private final String TRACE_VAR = "Trace"; + + private final List<String> events; + private final Predicate endPredicate; + private final int timeout; + + public enum TestPathStatus { + FOUND, NOT_FOUND, TIMEOUT, INTERRUPTED + }; + + private List<Operation> trace; + private TestPathStatus status; + + /** + * @param events + * a list of event names, never <code>null</code> + * @param endPredicate + * the predicate that constrains the last reached state. + * @param timeout + * how many milliseconds the operation should run maximally (0 if + * no time out is needed) + */ + public FindTestPathCommand(final List<String> events, + final Predicate endPredicate, final int timeout) { + this.events = Collections.unmodifiableList(events); + this.endPredicate = endPredicate; + this.timeout = timeout <= 0 ? 0 : timeout; + } + + /** + * @param events + * a list of event names, never <code>null</code> + * @param endPredicate + * the predicate that constrains the last reached state. + */ + public FindTestPathCommand(final List<String> events, + final Predicate endPredicate) { + this(events, endPredicate, 0); + } + + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + final TestPathStatus status; + final List<Operation> trace; + + final PrologTerm answer = bindings.get(TRACE_VAR); + if (answer.hasFunctor("timeout", 0)) { + status = TestPathStatus.TIMEOUT; + trace = null; + } else if (answer.hasFunctor("interrupt", 0)) { + status = TestPathStatus.INTERRUPTED; + trace = null; + } else if (answer.isList()) { + List<PrologTerm> pTrace = (ListPrologTerm) answer; + if (pTrace.isEmpty()) { + status = TestPathStatus.NOT_FOUND; + trace = null; + } else { + status = TestPathStatus.FOUND; + trace = new ArrayList<Operation>(pTrace.size()); + for (final PrologTerm opTerm : pTrace) { + final CompoundPrologTerm cpt = (CompoundPrologTerm) opTerm; + trace.add(Operation.fromPrologTerm(cpt)); + } + } + } else { + throw new CommandException("Unexpected Prolog answer: " + answer); + } + + this.status = status; + this.trace = trace; + } + + public void writeCommand(final IPrologTermOutput pto) { + pto.openTerm(COMMAND); + pto.openList(); + for (final String event : events) { + pto.printAtom(event); + } + pto.closeList(); + FormulaUtils.printPredicate(endPredicate, pto); + pto.printNumber(timeout); + pto.printVariable(TRACE_VAR); + pto.closeTerm(); + } + + /** + * Returns the found trace if one was found. + * + * @return a list of events or <code>null</code> if non was found. + */ + public List<Operation> getTrace() { + return trace; + } + + public TestPathStatus getStatus() { + return status; + } +} diff --git a/de.prob.core/src/de/prob/sap/commands/GenerateLocalTestcasesCommand.java b/de.prob.core/src/de/prob/sap/commands/GenerateLocalTestcasesCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..8d5d92358fd835a438dd28cebd1ae54d89d8c967 --- /dev/null +++ b/de.prob.core/src/de/prob/sap/commands/GenerateLocalTestcasesCommand.java @@ -0,0 +1,58 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.sap.commands; + +import de.prob.core.Animator; +import de.prob.core.command.CommandException; +import de.prob.core.command.IComposableCommand; +import de.prob.exceptions.ProBException; +import de.prob.parser.ISimplifiedROMap; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.IntegerPrologTerm; +import de.prob.prolog.term.PrologTerm; + +public class GenerateLocalTestcasesCommand implements IComposableCommand { + + private final String global; + private final String local; + private final int maxNodes; + private LocalTestcasesResult result; + + public GenerateLocalTestcasesCommand(final String global, + final String local, final int maxNodes) { + this.global = global; + this.local = local; + this.maxNodes = maxNodes; + } + + public static LocalTestcasesResult generateTestcases( + final String globalFilename, final String localFilename, + final int maxNodes) throws ProBException { + final GenerateLocalTestcasesCommand command = new GenerateLocalTestcasesCommand( + globalFilename, localFilename, maxNodes); + Animator.getAnimator().execute(command); + return command.result; + } + + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + final int sat = ((IntegerPrologTerm) bindings.get("SAT")).getValue() + .intValue(); + final int unsat = ((IntegerPrologTerm) bindings.get("UNSAT")) + .getValue().intValue(); + result = new LocalTestcasesResult(sat, unsat); + + } + + public void writeCommand(final IPrologTermOutput pto) { + pto.openTerm("sap_generate_testcases").printAtom(global) + .printAtom(local).printNumber(maxNodes).printVariable("SAT") + .printVariable("UNSAT").closeTerm(); + } + +} diff --git a/de.prob.core/src/de/prob/sap/commands/GenerateTestcaseCommand.java b/de.prob.core/src/de/prob/sap/commands/GenerateTestcaseCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..8bb990195a453a78303b22e37c38e1af3e3abcd6 --- /dev/null +++ b/de.prob.core/src/de/prob/sap/commands/GenerateTestcaseCommand.java @@ -0,0 +1,173 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.sap.commands; + +import java.util.ArrayList; +import java.util.Collection; + +import org.eventb.core.IMachineRoot; +import org.eventb.core.ast.FormulaFactory; +import org.eventb.core.ast.IParseResult; +import org.eventb.core.ast.ITypeCheckResult; +import org.eventb.core.ast.ITypeEnvironment; +import org.eventb.core.ast.LanguageVersion; +import org.eventb.core.ast.Predicate; +import org.eventb.core.basis.MachineRoot; +import org.rodinp.core.RodinDBException; + +import de.prob.core.Animator; +import de.prob.core.command.CommandException; +import de.prob.core.command.IComposableCommand; +import de.prob.core.command.LoadEventBModelCommand; +import de.prob.exceptions.ProBException; +import de.prob.parser.ISimplifiedROMap; +import de.prob.prolog.output.IPrologTermOutput; +import de.prob.prolog.term.IntegerPrologTerm; +import de.prob.prolog.term.ListPrologTerm; +import de.prob.prolog.term.PrologTerm; +import de.prob.sap.exceptions.ParseProblemException; +import de.prob.sap.util.FormulaUtils; + +/** + * A command to generate test cases for the choreography model. + * + * @author plagge + */ +public class GenerateTestcaseCommand implements IComposableCommand { + + private static final String UNCOVERED_EVENTS = "UncoveredEvents"; + private static final String NUMBER_TESTCASES = "NrTestcases"; + + private final Collection<String> operationNames; + private final Predicate targetPredicate; + private final int maxDepth; + private final int maxNodes; + private final String filename; + + private GlobalTestcaseResult result; + + public GenerateTestcaseCommand(final Collection<String> operationNames, + final Predicate targetPredicate, final int maxDepth, + final int maxNodes, final String filename) { + this.operationNames = operationNames; + this.targetPredicate = targetPredicate; + this.maxDepth = maxDepth; + this.maxNodes = maxNodes; + this.filename = filename; + } + + /** + * Like {@link #generateTestcases(Collection, Predicate, int, int, String)}, + * but the predicate is given as a string that will be parsed before + * generating tests. A reference to {@link MachineRoot} is needed to parse + * and type-check the predicate. + * + * @see #generateTestcases(Collection, Predicate, int, int, String) + */ + public static GlobalTestcaseResult generateTestcases( + final IMachineRoot machineRoot, + final Collection<String> operationNames, + final String targetPredicate, final int maxDepth, + final int maxNodes, final String filename) throws RodinDBException, + ProBException { + final Predicate predicate = parsePredicate(machineRoot, targetPredicate); + return generateTestcases(operationNames, predicate, maxDepth, maxNodes, + filename); + } + + /** + * Generate test cases and write them into an XML file. A machine should + * have been already loaded by the animator (see + * {@link LoadEventBModelCommand}). Each generated test case covers one of + * the specified events and ends in a state that satisfies the given + * predicate. + * + * @param events + * a list of event names for which test cases should be generated + * @param predicate + * a predicate that describes a valid end state where a test case + * might stop + * @param maxDepth + * the maximum length of the test cases + * @param maxNodes + * the maximum number of new states that will be explored while + * searching for test cases. + * @param filename + * the file name of the XML file that will be generated and + * contain the generated test cases, never <code>null</code>. + * @return an object to summarize the test case generation + * @throws ProBException + */ + private static GlobalTestcaseResult generateTestcases( + final Collection<String> events, final Predicate predicate, + final int maxDepth, final int maxNodes, final String filename) + throws ProBException { + final Animator animator = Animator.getAnimator(); + GenerateTestcaseCommand command = new GenerateTestcaseCommand(events, + predicate, maxDepth, maxNodes, filename); + animator.execute(command); + return command.result; + } + + private static Predicate parsePredicate(final IMachineRoot machineRoot, + final String targetPredicate) throws ParseProblemException, + RodinDBException { + final FormulaFactory formfact = FormulaFactory.getDefault(); + final IParseResult parsedPredicate = formfact.parsePredicate( + targetPredicate, LanguageVersion.LATEST, null); + if (parsedPredicate.hasProblem()) + throw new ParseProblemException(parsedPredicate.getProblems()); + final Predicate predicate = parsedPredicate.getParsedPredicate(); + + final ITypeEnvironment typeEnv = machineRoot.getSCMachineRoot() + .getTypeEnvironment(formfact); + final ITypeCheckResult tcr = predicate.typeCheck(typeEnv); + if (tcr.hasProblem()) + throw new ParseProblemException(tcr.getProblems()); + return predicate; + } + + public void processResult( + final ISimplifiedROMap<String, PrologTerm> bindings) + throws CommandException { + final IntegerPrologTerm pNumberTests = (IntegerPrologTerm) bindings + .get(NUMBER_TESTCASES); + final int numberOfTests = pNumberTests.getValue().intValue(); + + final ListPrologTerm pEvents = (ListPrologTerm) bindings + .get(UNCOVERED_EVENTS); + Collection<String> uncovered = new ArrayList<String>(pEvents.size()); + for (PrologTerm term : pEvents) { + final String event = PrologTerm.atomicString(term); + uncovered.add(event); + } + + result = new GlobalTestcaseResult(numberOfTests, uncovered); + } + + public void writeCommand(final IPrologTermOutput pto) { + pto.openTerm("sap_generate_testcases"); + + // print operation names + pto.openList(); + for (String op : operationNames) { + pto.printAtom(op); + } + pto.closeList(); + + // print the predicate + FormulaUtils.printPredicate(targetPredicate, pto); + + // print limits + pto.printNumber(maxDepth).printNumber(maxNodes).printAtom(filename); + // print variables for return values + pto.printVariable(NUMBER_TESTCASES).printVariable(UNCOVERED_EVENTS); + + pto.closeTerm(); + } + +} diff --git a/de.prob.core/src/de/prob/sap/commands/GlobalTestcaseResult.java b/de.prob.core/src/de/prob/sap/commands/GlobalTestcaseResult.java new file mode 100644 index 0000000000000000000000000000000000000000..89b28cced7bee505c922988c0b150a1445254c55 --- /dev/null +++ b/de.prob.core/src/de/prob/sap/commands/GlobalTestcaseResult.java @@ -0,0 +1,40 @@ +/** + * + */ +package de.prob.sap.commands; + +import java.util.Collection; +import java.util.Collections; + +/** + * Instances of this class are created by the {@link GenerateTestcaseCommand} + * and contains a few properties about the generated test cases. + * + * @author plagge + */ +public class GlobalTestcaseResult { + private final int numberOfTestcases; + private final Collection<String> uncoveredEvents; + + public GlobalTestcaseResult(int numberOfTestcases, + Collection<String> uncoveredEvents) { + this.numberOfTestcases = numberOfTestcases; + this.uncoveredEvents = Collections + .unmodifiableCollection(uncoveredEvents); + } + + /** + * @return the number of test cases that have been generated + */ + public int getNumberOfTestcases() { + return numberOfTestcases; + } + + /** + * @return the list of events that weren't covered by any test cases, never + * <code>null</code>. + */ + public Collection<String> getUncoveredEvents() { + return uncoveredEvents; + } +} \ No newline at end of file diff --git a/de.prob.core/src/de/prob/sap/commands/LocalTestcasesResult.java b/de.prob.core/src/de/prob/sap/commands/LocalTestcasesResult.java new file mode 100644 index 0000000000000000000000000000000000000000..90e6c6280ae1298ef683a7c6312a9b86e9037eab --- /dev/null +++ b/de.prob.core/src/de/prob/sap/commands/LocalTestcasesResult.java @@ -0,0 +1,43 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +/** + * + */ +package de.prob.sap.commands; + +/** + * Instances of this class summarizes the generation of local test cases. (test + * cases in the partner model) + * + * @author plagge + */ +public class LocalTestcasesResult { + private final int sat; + private final int unsat; + + public LocalTestcasesResult(final int sat, final int unsat) { + this.sat = sat; + this.unsat = unsat; + } + + /** + * @return the number of global test cases for which local test cases have + * been successfully generated. + */ + public int getSat() { + return sat; + } + + /** + * @return the number of global test cases for which no local test case have + * been found. + */ + public int getUnsat() { + return unsat; + } + +} \ No newline at end of file diff --git a/de.prob.core/src/de/prob/sap/exceptions/ParseProblemException.java b/de.prob.core/src/de/prob/sap/exceptions/ParseProblemException.java new file mode 100644 index 0000000000000000000000000000000000000000..14cfc3f41c798c9af27f4a411e6b970c7178ed23 --- /dev/null +++ b/de.prob.core/src/de/prob/sap/exceptions/ParseProblemException.java @@ -0,0 +1,30 @@ +/** + * + */ +package de.prob.sap.exceptions; + +import java.util.Collection; +import java.util.Collections; + +import org.eventb.core.ast.ASTProblem; + +/** + * This exception is thrown if an expression or predicate had parser problems + * (a.k.a. errors). + * + * @author plagge + */ +public class ParseProblemException extends ProbSapException { + private static final long serialVersionUID = 1315549744488826055L; + + private final Collection<ASTProblem> problems; + + public ParseProblemException(Collection<ASTProblem> problems) { + super("Parse problems"); + this.problems = Collections.unmodifiableCollection(problems); + } + + public Collection<ASTProblem> getProblems() { + return problems; + } +} diff --git a/de.prob.core/src/de/prob/sap/exceptions/ProbSapException.java b/de.prob.core/src/de/prob/sap/exceptions/ProbSapException.java new file mode 100644 index 0000000000000000000000000000000000000000..5c0761a6f56c2365b3348937729bf95d6d3fa74a --- /dev/null +++ b/de.prob.core/src/de/prob/sap/exceptions/ProbSapException.java @@ -0,0 +1,20 @@ +/** + * + */ +package de.prob.sap.exceptions; + +import de.prob.exceptions.ProBException; + +/** + * This class represents exceptions that are specific to the ProB-SAP plugin. + * + * @author plagge + */ +public class ProbSapException extends ProBException { + private static final long serialVersionUID = -3950873334778622083L; + + public ProbSapException(String exception) { + super(exception); + } + +} diff --git a/de.prob.core/src/de/prob/sap/util/FormulaUtils.java b/de.prob.core/src/de/prob/sap/util/FormulaUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..551c1292dbe3744e6213b60f4e5b037f41c3790d --- /dev/null +++ b/de.prob.core/src/de/prob/sap/util/FormulaUtils.java @@ -0,0 +1,37 @@ +/** + * + */ +package de.prob.sap.util; + +import java.util.LinkedList; + +import org.eventb.core.ast.Predicate; + +import de.be4.classicalb.core.parser.analysis.prolog.ASTProlog; +import de.be4.classicalb.core.parser.node.PPredicate; +import de.prob.eventb.translator.PredicateVisitor; +import de.prob.prolog.output.IPrologTermOutput; + +/** + * Some helper methods for handling formulas + * + * @author plagge + */ +public final class FormulaUtils { + + /** + * Write a Event-B predicate to a Prolog output + * + * @param predicate + * @param pto + */ + static public void printPredicate(final Predicate predicate, + final IPrologTermOutput pto) { + final PredicateVisitor visitor = new PredicateVisitor( + new LinkedList<String>()); + predicate.accept(visitor); + final PPredicate probPredicate = visitor.getPredicate(); + final ASTProlog prolog = new ASTProlog(pto, null); + probPredicate.apply(prolog); + } +} diff --git a/de.prob.plugin/.classpath b/de.prob.plugin/.classpath new file mode 100644 index 0000000000000000000000000000000000000000..ad32c83a7885b8953a938b41df3b4fd4fe1aae01 --- /dev/null +++ b/de.prob.plugin/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="src" path="src"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/de.prob.plugin/.project b/de.prob.plugin/.project new file mode 100644 index 0000000000000000000000000000000000000000..a00f814cf6f9966a13b8f02e7e113d88f0085dcd --- /dev/null +++ b/de.prob.plugin/.project @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>de.prob.plugin</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/de.prob.plugin/META-INF/MANIFEST.MF b/de.prob.plugin/META-INF/MANIFEST.MF new file mode 100644 index 0000000000000000000000000000000000000000..71b57f2b25a1227fdc36cc3d2f8263cc70c477f4 --- /dev/null +++ b/de.prob.plugin/META-INF/MANIFEST.MF @@ -0,0 +1,8 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: ProB Rodin2 UI Bindings +Bundle-SymbolicName: de.prob.plugin;singleton:=true +Bundle-Version: 2.1.0 +Fragment-Host: de.prob.ui;bundle-version="[7.1.0,7.2)" +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Bundle-Vendor: HHU Düsseldorf STUPS Group diff --git a/de.prob.plugin/build.properties b/de.prob.plugin/build.properties new file mode 100644 index 0000000000000000000000000000000000000000..e3023e14e9992e9d7e6a1a62b122da44d179c756 --- /dev/null +++ b/de.prob.plugin/build.properties @@ -0,0 +1,5 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + fragment.xml diff --git a/de.prob.plugin/fragment.xml b/de.prob.plugin/fragment.xml new file mode 100644 index 0000000000000000000000000000000000000000..9b58895d54d1fe0a9e7e6b205020e7b7df57dd87 --- /dev/null +++ b/de.prob.plugin/fragment.xml @@ -0,0 +1,63 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?eclipse version="3.4"?> +<fragment> + <extension + point="org.eclipse.ui.perspectives"> + <perspective + class="de.prob.ui.PerspectiveFactory" + icon="icons/prob.png" + id="de.prob.ui.perspective" + name="ProB"> + </perspective> + </extension> + <!-- <extension + point="org.eclipse.ui.splashHandlers"> + <splashHandler + class="de.prob.plugin.Splash" + id="de.prob.plugin.splash"> + </splashHandler> + <splashHandlerProductBinding + productId="org.rodinp.platform.product" + splashId="de.prob.plugin.splash"> + </splashHandlerProductBinding> + </extension> --> + + <extension + point="org.eclipse.ui.menus"> + <menuContribution + locationURI="menu:org.eclipse.ui.main.menu"> + <menu + id="prob" + label="ProB" + mnemonic="P"> + <menu + id="contact" + label="Contact" + mnemonic="C"> + <separator + name="bugs"> + </separator> + <separator + name="contact"> + </separator> + </menu> + <menu + id="analyze" + label="Analyze"> + <separator + name="analyze"> + </separator> + </menu> + </menu> + </menuContribution> + <menuContribution + locationURI="toolbar:org.eclipse.ui.main.toolbar"> + <toolbar + id="probtoolbar"> + </toolbar> + </menuContribution> + </extension> + + + +</fragment> diff --git a/de.prob.plugin/icons/prob.png b/de.prob.plugin/icons/prob.png new file mode 100644 index 0000000000000000000000000000000000000000..36d5d6278be2e2226de7b9d4d0fc9da720e47f1b Binary files /dev/null and b/de.prob.plugin/icons/prob.png differ diff --git a/de.prob.plugin/src/de/prob/plugin/Splash.java b/de.prob.plugin/src/de/prob/plugin/Splash.java new file mode 100644 index 0000000000000000000000000000000000000000..623339aa3a8329414fda46e755ca40191b71cdff --- /dev/null +++ b/de.prob.plugin/src/de/prob/plugin/Splash.java @@ -0,0 +1,35 @@ +package de.prob.plugin; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.splash.AbstractSplashHandler; + +import de.prob.ui.ProbUiPlugin; + +public class Splash extends AbstractSplashHandler { + + @Override + public void init(final Shell splash) { + super.init(splash); + + final Image overlay = ProbUiPlugin.getDefault().getImageRegistry().get( + ProbUiPlugin.OVERLAY); + + // FillLayout layout = new FillLayout(); + // + // getSplash().setLayout(layout); + + // Force shell to inherit the splash background + getSplash().setBackgroundMode(SWT.INHERIT_DEFAULT); + + Label transparentIdeaLabel = new Label(getSplash(), SWT.NONE); + transparentIdeaLabel.setImage(overlay); + + transparentIdeaLabel.setBounds(10, 220, 90, 35); + + splash.layout(true); + + } +} diff --git a/de.prob.standalone.feature/.project b/de.prob.standalone.feature/.project new file mode 100644 index 0000000000000000000000000000000000000000..dfb1d0474fedfec4168094a86142642225c66beb --- /dev/null +++ b/de.prob.standalone.feature/.project @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>de.prob.standalone.feature</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.pde.FeatureBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.FeatureNature</nature> + </natures> +</projectDescription> diff --git a/de.prob.standalone.feature/ProB_standalone.product b/de.prob.standalone.feature/ProB_standalone.product new file mode 100644 index 0000000000000000000000000000000000000000..c36b6c0a78098e06da8645bc04796ae3bb1492ac --- /dev/null +++ b/de.prob.standalone.feature/ProB_standalone.product @@ -0,0 +1,196 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?pde version="3.5"?> + +<product name="ProB" uid="de.prob.product" id="de.prob.standalone.prob" application="de.prob.standalone.application" version="1.0.0" useFeatures="false" includeLaunchers="true"> + + <aboutInfo> + <image path="/de.prob.standalone/icons/icon16.png"/> + <text> + ProB: An Animator and Model Checker for B +----------------------------------------- + +(C) 2000-2010 Michael Leuschel (and many others; see below) +All rights reserved. +ProB can now be used freely for commercial, non-commercial +and academic use. +For availability of commercial support, please contact the author +(http://www.stups.uni-duesseldorf.de/~leuschel). +No re-distribution allowed. Use of ProB's nauty +library for symmetry reduction implies further +restrictions (no applications with nontrivial military +significance, see http://cs.anu.edu.au/~bdm/nauty/). + +ProB comes with ABSOLUTELY NO WARRANTY OF ANY KIND ! +This software is distributed in the hope that it will be useful +but WITHOUT ANY WARRANTY. The author(s) do not accept responsibility +to anyone for the consequences of using it or for whether it serves +any particular purpose or works at all. No warranty is made about +the software or its performance. + +For updates and news check: + http://www.stups.uni-duesseldorf.de/ProB/ + +ProB uses state-of-the-art Prolog technology (co-routining, finite +domain constraint solvers,...) to achieve symbolic debugging, +constraint-based and temporal-logic based model checking. +The tool was partly being developed within the EPSRC grants iMoc and ABCD +and the EU grant ASAP. Further development within RODIN has been carried out. +Future developments within DEPLOY and GEPAVAS are being undertaken. + +Development, Copyright and Intellectual Property Rights: +B-Kernel & Model Checker: + Michael Leuschel, Daniel Plagge, Jens Bendisposto +Java Interface: + Jens Bendisposto, Daniel Plagge, Michael Leuschel +B Parser: + Fabian Fritz +B Typechecker: + Daniel Plagge +Event-B Translator: + Jens Bendipsoto, Daniel Plagge +ProZ, LTL model checker: + Daniel Plagge, Michael Leuschel +ProCSP: + Michael Leuschel, Marc Fontaine +Parser for CSP-M: + Marc Fontaine +Nauty interface for ProB: + Corinna Spermann, Michael Leuschel +Symmetry Hash Markers + Michael Leuschel, Thierry Massart +ProMLA + Dennis Winter, Michael Leuschel + +Other Developers: + Michael Butler, Carla Ferreira, + Stephane Lo-Presti, Li Luo, Leonid Mikhailov, + Ed Turner, Phil Turner + + +Fuzz Parser and Type Checker for Z: + Mike Spivey + (see http://spivey.oriel.ox.ac.uk/mike/fuzz) +Nauty library for symmetry reduction: + Copyright (1984-2007) Brendan McKay + http://cs.anu.edu.au/~bdm/nauty/ + +Known limitations: +================== + - Unsupported features: + the closure operator (but closure1 is supported), tuple notation + without parentheses a,b,c (use (a,b,c) instead), relational + composition needs to be put inside parantheses, the VALUES clause, ... + (see ProB Summary in About menu for which features are supported) + - Atelier B's tree operations are not supported + - Preconditions of operations are not automatically propagated down + to operations in refinements and implementations + - Refinement checker treats PRE as SELECT + - ... possibly more ... + +Notes: +====== + - To visualize state space graphs: dot from AT&T's GraphViz package has to be installed + +See the FAQ.txt file for troubleshooting and frequently asked questions. + </text> + </aboutInfo> + + <configIni use="default"> + </configIni> + + <launcherArgs> + <programArgs>-consoleLog</programArgs> + <vmArgsMac>-XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts</vmArgsMac> + </launcherArgs> + + <windowImages i16="/de.prob.standalone/icons/icon16.png" i32="/de.prob.standalone/icons/icon32.png" i48="/de.prob.standalone/icons/icon48png" i64="/de.prob.standalone/icons/icon64.png" i128="/de.prob.standalone/icons/icon128.png"/> + + <splash + location="de.prob.standalone" + startupProgressRect="15,370,670,20" + startupMessageRect="20,350,670,20" + startupForegroundColor="FFFFFF" /> + <launcher name="ProB"> + <macosx icon="/de.prob.standalone/icons/ProB_Icon.icns"/> + <solaris/> + <win useIco="false"> + <bmp/> + </win> + </launcher> + + <vm> + </vm> + + <plugins> + <plugin id="com.ibm.icu"/> + <plugin id="de.bmotionstudio.gef.editor"/> + <plugin id="de.prob.core"/> + <plugin id="de.prob.standalone"/> + <plugin id="de.prob.ui"/> + <plugin id="org.eclipse.compare"/> + <plugin id="org.eclipse.compare.core"/> + <plugin id="org.eclipse.core.commands"/> + <plugin id="org.eclipse.core.contenttype"/> + <plugin id="org.eclipse.core.databinding"/> + <plugin id="org.eclipse.core.databinding.beans"/> + <plugin id="org.eclipse.core.databinding.observable"/> + <plugin id="org.eclipse.core.databinding.property"/> + <plugin id="org.eclipse.core.expressions"/> + <plugin id="org.eclipse.core.filebuffers"/> + <plugin id="org.eclipse.core.filesystem"/> + <plugin id="org.eclipse.core.filesystem.win32.x86" fragment="true"/> + <plugin id="org.eclipse.core.jobs"/> + <plugin id="org.eclipse.core.net"/> + <plugin id="org.eclipse.core.net.win32.x86" fragment="true"/> + <plugin id="org.eclipse.core.resources"/> + <plugin id="org.eclipse.core.resources.win32.x86" fragment="true"/> + <plugin id="org.eclipse.core.runtime"/> + <plugin id="org.eclipse.core.runtime.compatibility.registry" fragment="true"/> + <plugin id="org.eclipse.draw2d"/> + <plugin id="org.eclipse.equinox.app"/> + <plugin id="org.eclipse.equinox.common"/> + <plugin id="org.eclipse.equinox.p2.core"/> + <plugin id="org.eclipse.equinox.p2.engine"/> + <plugin id="org.eclipse.equinox.p2.metadata"/> + <plugin id="org.eclipse.equinox.p2.metadata.repository"/> + <plugin id="org.eclipse.equinox.p2.repository"/> + <plugin id="org.eclipse.equinox.preferences"/> + <plugin id="org.eclipse.equinox.registry"/> + <plugin id="org.eclipse.equinox.security"/> + <plugin id="org.eclipse.equinox.security.win32.x86" fragment="true"/> + <plugin id="org.eclipse.gef"/> + <plugin id="org.eclipse.help"/> + <plugin id="org.eclipse.jface"/> + <plugin id="org.eclipse.jface.databinding"/> + <plugin id="org.eclipse.jface.text"/> + <plugin id="org.eclipse.ltk.core.refactoring"/> + <plugin id="org.eclipse.ltk.ui.refactoring"/> + <plugin id="org.eclipse.osgi"/> + <plugin id="org.eclipse.swt"/> + <plugin id="org.eclipse.swt.win32.win32.x86" fragment="true"/> + <plugin id="org.eclipse.team.core"/> + <plugin id="org.eclipse.team.ui"/> + <plugin id="org.eclipse.text"/> + <plugin id="org.eclipse.ui"/> + <plugin id="org.eclipse.ui.editors"/> + <plugin id="org.eclipse.ui.forms"/> + <plugin id="org.eclipse.ui.ide"/> + <plugin id="org.eclipse.ui.ide.application"/> + <plugin id="org.eclipse.ui.intro"/> + <plugin id="org.eclipse.ui.navigator"/> + <plugin id="org.eclipse.ui.navigator.resources"/> + <plugin id="org.eclipse.ui.views"/> + <plugin id="org.eclipse.ui.views.properties.tabbed"/> + <plugin id="org.eclipse.ui.win32" fragment="true"/> + <plugin id="org.eclipse.ui.workbench"/> + <plugin id="org.eclipse.ui.workbench.texteditor"/> + <plugin id="org.eventb.core"/> + <plugin id="org.eventb.core.ast"/> + <plugin id="org.eventb.core.seqprover"/> + <plugin id="org.hamcrest.core"/> + <plugin id="org.junit"/> + <plugin id="org.rodinp.core"/> + </plugins> + + +</product> diff --git a/de.prob.standalone.feature/build.properties b/de.prob.standalone.feature/build.properties new file mode 100644 index 0000000000000000000000000000000000000000..0686ff45e5e8cb3e522d88e4b1a97739fe026fbe --- /dev/null +++ b/de.prob.standalone.feature/build.properties @@ -0,0 +1,2 @@ +bin.includes = feature.xml,\ + plugin_customization.ini diff --git a/de.prob.standalone.feature/compile.de.prob.standalone.feature.xml b/de.prob.standalone.feature/compile.de.prob.standalone.feature.xml new file mode 100644 index 0000000000000000000000000000000000000000..daee3bc9f0f1ce06d5988cc5358a6d7b36040fee --- /dev/null +++ b/de.prob.standalone.feature/compile.de.prob.standalone.feature.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project name="Compile de.prob.standalone.feature" default="main"> + <target name="main"> + <ant antfile="build.xml" dir="../de.prob.standalone" target="build.jars"/> + </target> +</project> diff --git a/de.prob.standalone.feature/feature.xml b/de.prob.standalone.feature/feature.xml new file mode 100644 index 0000000000000000000000000000000000000000..708ea7e1eee60ffd9dd21dba499f719943b872b4 --- /dev/null +++ b/de.prob.standalone.feature/feature.xml @@ -0,0 +1,70 @@ +<?xml version="1.0" encoding="UTF-8"?> +<feature + id="de.prob.standalone.feature" + label="Feature" + version="1.0.0"> + + <description url="http://www.example.com/description"> + [Enter Feature Description here.] + </description> + + <copyright url="http://www.example.com/copyright"> + [Enter Copyright Description here.] + </copyright> + + <license url="http://www.example.com/license"> + [Enter License Description here.] + </license> + + <requires> + <import plugin="org.eclipse.core.runtime" version="3.5.0" match="compatible"/> + <import plugin="org.rodinp.core" version="1.3.1"/> + <import plugin="org.eventb.core" version="2.1.0"/> + <import plugin="org.eclipse.jface" version="3.6.0" match="compatible"/> + <import plugin="org.eclipse.ui" version="3.6.0" match="compatible"/> + <import plugin="de.prob.ui" version="4.1.0" match="greaterOrEqual"/> + <import plugin="de.prob.core" version="9.1.1" match="greaterOrEqual"/> + <import plugin="org.rodinp.core" version="1.2.0" match="greaterOrEqual"/> + <import plugin="org.eventb.core" version="1.2.0" match="greaterOrEqual"/> + <import plugin="org.eclipse.ui.navigator" version="3.4.1" match="greaterOrEqual"/> + <import plugin="org.eclipse.ui.ide" version="3.5.1" match="greaterOrEqual"/> + <import plugin="org.eclipse.ui.ide.application" version="1.0.101" match="greaterOrEqual"/> + <import plugin="org.eclipse.ui.navigator.resources" version="3.4.1" match="greaterOrEqual"/> + <import plugin="org.eclipse.ui.intro"/> + <import plugin="org.eclipse.ui" version="3.5.0" match="compatible"/> + <import plugin="org.eclipse.core.resources" version="3.5.0" match="compatible"/> + <import plugin="org.eclipse.ui.ide" version="3.5.0" match="compatible"/> + <import plugin="de.prob.core" version="9.1.0" match="equivalent"/> + <import plugin="org.eclipse.core.expressions" version="3.4.101" match="compatible"/> + <import plugin="org.eclipse.gef" version="3.5.0" match="compatible"/> + </requires> + + <plugin + id="de.prob.core" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="de.prob.standalone" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="de.prob.ui" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="fr.systerel.explorer" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + +</feature> diff --git a/de.prob.standalone.feature/plugin_customization.ini b/de.prob.standalone.feature/plugin_customization.ini new file mode 100644 index 0000000000000000000000000000000000000000..333fab9da760c08792618efc88d4a4c7a17b2fc3 --- /dev/null +++ b/de.prob.standalone.feature/plugin_customization.ini @@ -0,0 +1 @@ +org.eclipse.ui/SHOW_PROGRESS_ON_STARTUP = true diff --git a/de.prob.standalone/.classpath b/de.prob.standalone/.classpath new file mode 100644 index 0000000000000000000000000000000000000000..64c5e31b7a264082f4c1dfdabb8097de820e66ce --- /dev/null +++ b/de.prob.standalone/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="src" path="src"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/de.prob.standalone/.project b/de.prob.standalone/.project new file mode 100644 index 0000000000000000000000000000000000000000..8a55a27275d8cec9e3c1b8f96043686b8ced081d --- /dev/null +++ b/de.prob.standalone/.project @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>de.prob.standalone</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>edu.umd.cs.findbugs.plugin.eclipse.findbugsBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + <nature>edu.umd.cs.findbugs.plugin.eclipse.findbugsNature</nature> + </natures> +</projectDescription> diff --git a/de.prob.standalone/META-INF/MANIFEST.MF b/de.prob.standalone/META-INF/MANIFEST.MF new file mode 100644 index 0000000000000000000000000000000000000000..3431a4a5416fe32673cc78d07f48ef05f2342607 --- /dev/null +++ b/de.prob.standalone/META-INF/MANIFEST.MF @@ -0,0 +1,20 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Standalone +Bundle-SymbolicName: de.prob.standalone; singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: de.prob.standalone.Activator +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + de.prob.ui;bundle-version="4.1.0", + de.prob.core;bundle-version="9.1.1", + de.bmotionstudio.gef.editor;bundle-version="5.2.0", + org.rodinp.core;bundle-version="1.2.0", + org.eventb.core;bundle-version="1.2.0", + org.eclipse.ui.navigator;bundle-version="3.4.1", + org.eclipse.ui.navigator.resources;bundle-version="3.4.1", + org.eclipse.ui.ide;bundle-version="3.5.1", + org.eclipse.ui.ide.application;bundle-version="1.0.101", + org.eclipse.ui.intro +Bundle-ActivationPolicy: lazy +Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/de.prob.standalone/ProB_Icon.icns b/de.prob.standalone/ProB_Icon.icns new file mode 100644 index 0000000000000000000000000000000000000000..e38eee5f0c9b4263a624da709936f9d583031a40 Binary files /dev/null and b/de.prob.standalone/ProB_Icon.icns differ diff --git a/de.prob.standalone/ProB_Icon.ico b/de.prob.standalone/ProB_Icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..43c5ec23183b1145406ed3569dfad17777a11ab1 Binary files /dev/null and b/de.prob.standalone/ProB_Icon.ico differ diff --git a/de.prob.standalone/about.png b/de.prob.standalone/about.png new file mode 100644 index 0000000000000000000000000000000000000000..d6d53856b529427146b51efb31032b2471a8b03e Binary files /dev/null and b/de.prob.standalone/about.png differ diff --git a/de.prob.standalone/about2.png b/de.prob.standalone/about2.png new file mode 100644 index 0000000000000000000000000000000000000000..443b1749877c5ef270087cb9fcc529f96e20759d Binary files /dev/null and b/de.prob.standalone/about2.png differ diff --git a/de.prob.standalone/build.properties b/de.prob.standalone/build.properties new file mode 100644 index 0000000000000000000000000000000000000000..9507d4bf2b9fa036a87ec0571ceb405bf23ba558 --- /dev/null +++ b/de.prob.standalone/build.properties @@ -0,0 +1,11 @@ +output.. = bin/ +bin.includes = plugin.xml,\ + META-INF/,\ + .,\ + plugin_customization.ini,\ + ProB_Icon.icns,\ + ProB_Icon.ico,\ + about2.png,\ + icons/,\ + images/ +source.. = src/ diff --git a/de.prob.standalone/icons/bms/bms16.png b/de.prob.standalone/icons/bms/bms16.png new file mode 100644 index 0000000000000000000000000000000000000000..2bcb148a75ce4d1f5d9257033306b5b12b5d295d Binary files /dev/null and b/de.prob.standalone/icons/bms/bms16.png differ diff --git a/de.prob.standalone/icons/bms/bmsrun16.png b/de.prob.standalone/icons/bms/bmsrun16.png new file mode 100644 index 0000000000000000000000000000000000000000..f5808d2dfd5b042b5584ce1c81aa40835ebc8055 Binary files /dev/null and b/de.prob.standalone/icons/bms/bmsrun16.png differ diff --git a/de.prob.standalone/icons/eventb/ctx_obj.png b/de.prob.standalone/icons/eventb/ctx_obj.png new file mode 100644 index 0000000000000000000000000000000000000000..af167c8a022244cf4147b055312695e126ce4767 Binary files /dev/null and b/de.prob.standalone/icons/eventb/ctx_obj.png differ diff --git a/de.prob.standalone/icons/eventb/mch_obj.png b/de.prob.standalone/icons/eventb/mch_obj.png new file mode 100644 index 0000000000000000000000000000000000000000..6f5732dd3b51d5f23003998426c7e2a09a21a9e4 Binary files /dev/null and b/de.prob.standalone/icons/eventb/mch_obj.png differ diff --git a/de.prob.standalone/icons/icon128.png b/de.prob.standalone/icons/icon128.png new file mode 100644 index 0000000000000000000000000000000000000000..73e6d9972adbb904a4168de17a5b8894e4caac51 Binary files /dev/null and b/de.prob.standalone/icons/icon128.png differ diff --git a/de.prob.standalone/icons/icon16.png b/de.prob.standalone/icons/icon16.png new file mode 100644 index 0000000000000000000000000000000000000000..3ef45c9caad56d296de50951e47c3916a8795e01 Binary files /dev/null and b/de.prob.standalone/icons/icon16.png differ diff --git a/de.prob.standalone/icons/icon32.png b/de.prob.standalone/icons/icon32.png new file mode 100644 index 0000000000000000000000000000000000000000..e469b83835904d8075e5f1c8f85a5c5cc2bba6eb Binary files /dev/null and b/de.prob.standalone/icons/icon32.png differ diff --git a/de.prob.standalone/icons/icon48.png b/de.prob.standalone/icons/icon48.png new file mode 100644 index 0000000000000000000000000000000000000000..17eb3bef1e11cf8c8719bbab957bf61daf52e707 Binary files /dev/null and b/de.prob.standalone/icons/icon48.png differ diff --git a/de.prob.standalone/icons/icon64.png b/de.prob.standalone/icons/icon64.png new file mode 100644 index 0000000000000000000000000000000000000000..a59d642a3f0bf92344c5f9221eb2a4dc41794e8a Binary files /dev/null and b/de.prob.standalone/icons/icon64.png differ diff --git a/de.prob.standalone/images/close.gif b/de.prob.standalone/images/close.gif new file mode 100644 index 0000000000000000000000000000000000000000..880993e3491a7bb1ac402167ae70beeccc259b28 Binary files /dev/null and b/de.prob.standalone/images/close.gif differ diff --git a/de.prob.standalone/images/closeSelected.gif b/de.prob.standalone/images/closeSelected.gif new file mode 100644 index 0000000000000000000000000000000000000000..0fcc0ccda5cfd28ba2282bc08766d3caafb9a855 Binary files /dev/null and b/de.prob.standalone/images/closeSelected.gif differ diff --git a/de.prob.standalone/images/close_blue.gif b/de.prob.standalone/images/close_blue.gif new file mode 100644 index 0000000000000000000000000000000000000000..729f334d59aeb51c7c7dfedb73a58fffe6eff5d5 Binary files /dev/null and b/de.prob.standalone/images/close_blue.gif differ diff --git a/de.prob.standalone/plugin.xml b/de.prob.standalone/plugin.xml new file mode 100644 index 0000000000000000000000000000000000000000..5011fc7bd78081d08fc601b0dfbd99c1858390ae --- /dev/null +++ b/de.prob.standalone/plugin.xml @@ -0,0 +1,485 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?eclipse version="3.4"?> +<plugin> + + + <extension + point="org.eclipse.ui.menus"> + <menuContribution + locationURI="menu:org.eclipse.ui.main.menu?before=help"> + <menu + id="contact" + label="Contact" + mnemonic="C"> + </menu> + </menuContribution> + <menuContribution + locationURI="toolbar:org.eclipse.ui.main.toolbar"> + <toolbar + id="probtoolbar"> + </toolbar> + </menuContribution> + <menuContribution + locationURI="popup:de.prob.standalone.navigatorview"> + <separator + name="de.prob.ui.separator2" + visible="true"> + </separator> + <command + commandId="de.prob.ui.starteventbanimation" + icon="icons/icon16.png" + label="Start Animation / Model Checking" + style="push"> + <visibleWhen> + <with + variable="selection"> + <iterate + operator="or"> + <and> + <instanceof + value="org.eclipse.core.resources.IResource"> + </instanceof> + <or> + <test + forcePluginActivation="true" + property="org.eclipse.core.resources.extension" + value="bum"> + </test> + <test + forcePluginActivation="true" + property="org.eclipse.core.resources.extension" + value="buc"> + </test> + </or> + </and> + </iterate> + </with> + </visibleWhen> + </command> + <command + commandId="de.prob.command.startClassicalBAnimation" + icon="icons/icon16.png" + label="Start Animation / Model Checking" + style="push"> + <visibleWhen> + <with + variable="selection"> + <iterate + operator="or"> + <and> + <instanceof + value="org.eclipse.core.resources.IResource"> + </instanceof> + <test + forcePluginActivation="true" + property="org.eclipse.core.resources.extension" + value="mch"> + </test> + </and> + </iterate> + </with> + </visibleWhen> + </command> + <command + commandId="de.bmotionstudio.command.startVisualizationFromFile" + icon="icons/bms/bmsrun16.png" + label="Start Visualization" + style="push"> + <visibleWhen> + <with + variable="selection"> + <iterate + operator="or"> + <and> + <instanceof + value="org.eclipse.core.resources.IResource"> + </instanceof> + <test + forcePluginActivation="true" + property="org.eclipse.core.resources.extension" + value="bmso"> + </test> + </and> + </iterate> + </with> + </visibleWhen> + </command> + <separator + name="de.prob.ui.separator1" + visible="true"> + </separator> + </menuContribution> + <menuContribution + locationURI="menu:file"> + <command + commandId="org.eclipse.ui.newWizard" + label="New" + style="push"> + </command> + <separator + name="de.prob.standalone.separator1" + visible="true"> + </separator> + <command + commandId="org.eclipse.ui.file.save" + label="Save" + style="push"> + </command> + <command + commandId="org.eclipse.ui.file.saveAll" + label="Save All" + style="push"> + </command> + <separator + name="de.prob.standalone.separator2" + visible="true"> + </separator> + <command + commandId="org.eclipse.ui.file.close" + label="Close" + style="push"> + </command> + <command + commandId="org.eclipse.ui.file.closeAll" + label="Close All" + style="push"> + </command> + <separator + name="de.prob.standalone.separator3" + visible="true"> + </separator> + <command + commandId="org.eclipse.ui.file.refresh" + label="Refresh" + style="push"> + </command> + </menuContribution> + </extension> + + + + + <extension + id="application" + point="org.eclipse.core.runtime.applications"> + <application> + <run + class="de.prob.standalone.Application"> + </run> + </application> + </extension> + <extension + point="org.eclipse.ui.perspectives"> + <perspective + class="de.prob.standalone.internal.AnimationPerspective" + icon="icons/icon16.png" + id="de.prob.ui.perspective" + name="Animation"> + </perspective> + <perspective + class="de.prob.standalone.internal.VisualizationEditPerspective" + icon="icons/bms/bms16.png" + id="de.bmotionstudio.perspective.edit" + name="Visualization"> + </perspective> + <perspective + class="de.prob.standalone.internal.VisualizationRunPerspective" + icon="icons/bms/bmsrun16.png" + id="de.bmotionstudio.perspective.run" + name="Visualization"> + </perspective> + </extension> + <!-- <extension + point="org.eclipse.ui.actionSets"> + <actionSet + label="ProB Demo Action Set" + visible="true" + id="demoActionSet"> + <menu + label="File" + id="sampleMenu"> + <separator + name="fileGroup"> + </separator> + </menu> + <action + label="Open File" + class="de.prob.standalone.actions.OpenFileAction" + tooltip="Open a file" + menubarPath="sampleMenu/fileGroup" + id="openFileAction"> + </action> + <action + label="Open Event-B Model" + class="de.prob.standalone.actions.OpenEventBFileAction" + tooltip="Open an Event-B Model" + menubarPath="sampleMenu/fileGroup" + id="openFileAction"> + </action> + </actionSet> + </extension> + + --> + <extension + id="prob" + point="org.eclipse.core.runtime.products"> + <product + application="de.prob.standalone.application" + name="ProB"> + <property + name="appName" + value="ProB"> + </property> + <property + name="preferenceCustomization" + value="plugin_customization.ini"> + </property> + <property + name="aboutImage" + value="icons/icon16.png"> + </property> + <property + name="aboutText" + value="ProB: An Animator and Model Checker for B
-----------------------------------------

(C) 2000-2010 Michael Leuschel (and many others; see below)
All rights reserved.
ProB can now be used freely for commercial, non-commercial
and academic use.
For availability of commercial support, please contact the author
(http://www.stups.uni-duesseldorf.de/~leuschel).
No re-distribution allowed. Use of ProB's nauty
library for symmetry reduction implies further
restrictions (no applications with nontrivial military
significance, see http://cs.anu.edu.au/~bdm/nauty/).

ProB comes with ABSOLUTELY NO WARRANTY OF ANY KIND !
This software is distributed in the hope that it will be useful
but WITHOUT ANY WARRANTY. The author(s) do not accept responsibility
to anyone for the consequences of using it or for whether it serves
any particular purpose or works at all. No warranty is made about
the software or its performance.

For updates and news check:
 http://www.stups.uni-duesseldorf.de/ProB/

ProB uses state-of-the-art Prolog technology (co-routining, finite
domain constraint solvers,...) to achieve symbolic debugging,
constraint-based and temporal-logic based model checking.
The tool was partly being developed within the EPSRC grants iMoc and ABCD
and the EU grant ASAP. Further development within RODIN has been carried out.
Future developments within DEPLOY and GEPAVAS are being undertaken.

Development, Copyright and Intellectual Property Rights:
B-Kernel & Model Checker:
 Michael Leuschel, Daniel Plagge, Jens Bendisposto
Java Interface:
 Jens Bendisposto, Daniel Plagge, Michael Leuschel
B Parser:
 Fabian Fritz
B Typechecker:
 Daniel Plagge
Event-B Translator:
 Jens Bendipsoto, Daniel Plagge
ProZ, LTL model checker:
 Daniel Plagge, Michael Leuschel
ProCSP:
 Michael Leuschel, Marc Fontaine
Parser for CSP-M:
 Marc Fontaine
Nauty interface for ProB:
 Corinna Spermann, Michael Leuschel
Symmetry Hash Markers
 Michael Leuschel, Thierry Massart
ProMLA
 Dennis Winter, Michael Leuschel

Other Developers:
 Michael Butler, Carla Ferreira,
 Stephane Lo-Presti, Li Luo, Leonid Mikhailov,
 Ed Turner, Phil Turner
 

Fuzz Parser and Type Checker for Z:
 Mike Spivey
 (see http://spivey.oriel.ox.ac.uk/mike/fuzz)
Nauty library for symmetry reduction:
 Copyright (1984-2007) Brendan McKay
 http://cs.anu.edu.au/~bdm/nauty/

Known limitations:
==================
 - Unsupported features: 
 the closure operator (but closure1 is supported), tuple notation
 without parentheses a,b,c (use (a,b,c) instead), relational
 composition needs to be put inside parantheses, the VALUES clause, ...
 (see ProB Summary in About menu for which features are supported)
 - Atelier B's tree operations are not supported
 - Preconditions of operations are not automatically propagated down
 to operations in refinements and implementations
 - Refinement checker treats PRE as SELECT
 - ... possibly more ...

Notes:
======
 - To visualize state space graphs: dot from AT&T's GraphViz package has to be installed

See the FAQ.txt file for troubleshooting and frequently asked questions."> + </property> + <property + name="windowImages" + value="icons/icon16.png,icons/icon32.png,icons/icon48png,icons/icon64.png,icons/icon128.png"> + </property> + <property + name="startupForegroundColor" + value="FFFFFF"> + </property> + <property + name="startupMessageRect" + value="20,350,670,20"> + </property> + <property + name="startupProgressRect" + value="15,370,670,20"> + </property> + </product> + </extension> + <extension + point="org.eclipse.ui.presentationFactories"> + <factory + class="de.prob.standalone.presentation.PresentationFactory" + id="de.prob.standalone.presentation" + name="ProB Presentation"> + </factory> + </extension> + + + <extension + point="org.eclipse.ui.activities"> + <activity id="hiddenActivity" name="Hide Eclipse UI "/> + <activityPatternBinding + activityId="hiddenActivity" + isEqualityPattern="false" + pattern="org\.eclipse\.ui\.project\..*"> + </activityPatternBinding> +</extension> + <extension + point="org.eclipse.ui.views"> + <view + allowMultiple="false" + class="org.eclipse.ui.navigator.CommonNavigator" + id="de.prob.standalone.navigatorview" + name="Navigation" + restorable="true"> + </view> + </extension> + <extension + point="org.eclipse.ui.navigator.viewer"> + <viewer + viewerId="de.prob.standalone.navigatorview"> + </viewer> + <viewerContentBinding + viewerId="de.prob.standalone.navigatorview"> + <includes> + <contentExtension + pattern="org.eclipse.ui.navigator.resourceContent"> + </contentExtension> + <contentExtension + pattern="org.eclipse.ui.navigator.resources.filters.*"> + </contentExtension> + <contentExtension + pattern="de.prob.standalone.commonFilter.*"> + </contentExtension> + <contentExtension + pattern="de.prob.standalone.navigatorContent.*"> + </contentExtension> + </includes> + </viewerContentBinding> + <viewerActionBinding + viewerId="de.prob.standalone.navigatorview"> + <includes> + <actionExtension + pattern="org.eclipse.ui.navigator.resources.*"> + </actionExtension></includes> + </viewerActionBinding> + </extension> + <extension + point="org.eclipse.ui.navigator.navigatorContent"> + <navigatorContent + activeByDefault="true" + contentProvider="de.prob.standalone.internal.FormalModelContentProvider" + id="de.prob.standalone.navigatorContent.formalModelContent" + labelProvider="de.prob.standalone.internal.FormalModelLabelProvider" + name="Formal Model Content" + priority="normal"> + <triggerPoints> + <or> + <and> + <instanceof + value="org.eclipse.core.resources.IResource"> + </instanceof> + <test + forcePluginActivation="true" + property="org.eclipse.core.resources.extension" + value="bum"> + </test> + </and> + <and> + <instanceof + value="org.eclipse.core.resources.IResource"> + </instanceof> + <test + forcePluginActivation="true" + property="org.eclipse.core.resources.extension" + value="buc"> + </test> + </and> + <and> + <instanceof + value="org.eclipse.core.resources.IResource"> + </instanceof> + <test + forcePluginActivation="true" + property="org.eclipse.core.resources.extension" + value="mch"> + </test> + </and> + <and> + <instanceof + value="org.eclipse.core.resources.IResource"> + </instanceof> + <test + forcePluginActivation="true" + property="org.eclipse.core.resources.extension" + value="bmso"> + </test> + </and> + </or> + </triggerPoints> + </navigatorContent> + <commonFilter + activeByDefault="true" + id="de.prob.standalone.commonFilter.probFileFilter" + name="ProB File Filter"> + <filterExpression> + <or> + <instanceof + value="org.eclipse.core.resources.IFolder"> + </instanceof> + <and> + <instanceof + value="org.eclipse.core.resources.IFile"> + </instanceof> + <not> + <and> + <instanceof + value="org.eclipse.core.resources.IFile"> + </instanceof> + <test + forcePluginActivation="true" + property="org.eclipse.core.resources.extension" + value="buc"> + </test> + </and> + </not> + <not> + <and> + <instanceof + value="org.eclipse.core.resources.IFile"> + </instanceof> + <test + forcePluginActivation="true" + property="org.eclipse.core.resources.extension" + value="bum"> + </test> + </and> + </not> + <not> + <and> + <instanceof + value="org.eclipse.core.resources.IFile"> + </instanceof> + <test + forcePluginActivation="true" + property="org.eclipse.core.resources.extension" + value="bmso"> + </test> + </and> + </not> + <not> + <and> + <instanceof + value="org.eclipse.core.resources.IFile"> + </instanceof> + <test + forcePluginActivation="true" + property="org.eclipse.core.resources.extension" + value="mch"> + </test> + </and> + </not> + </and> + </or> + </filterExpression> + </commonFilter> + </extension> + <extension + point="org.eclipse.ui.commands"> + <command + id="de.prob.command.startClassicalBAnimation" + name="Classical-B Animate / Model Check"> + </command> + </extension> + <extension + point="org.eclipse.ui.handlers"> + <handler + commandId="de.prob.command.startClassicalBAnimation"> + <class + class="de.prob.standalone.handler.StartClassicalBAnimationHandler"> + </class> + <enabledWhen> + <with + variable="selection"> + <iterate + operator="or"> + <and> + <instanceof + value="org.eclipse.core.resources.IResource"> + </instanceof> + <test + forcePluginActivation="true" + property="org.eclipse.core.resources.extension" + value="mch"> + </test> + </and> + </iterate> + </with> + </enabledWhen> + </handler> + </extension> + <extension + point="de.bmotionstudio.gef.editor.language"> + <language + id="ClassicalB" + service="de.prob.standalone.internal.ClassicalBLanguageService"> + </language> + </extension> + + +</plugin> diff --git a/de.prob.standalone/plugin_customization.ini b/de.prob.standalone/plugin_customization.ini new file mode 100644 index 0000000000000000000000000000000000000000..f1bb9046a1f1e1862fea9b1d55e3790a8cc549d2 --- /dev/null +++ b/de.prob.standalone/plugin_customization.ini @@ -0,0 +1,12 @@ +org.eclipse.ui/defaultPerspectiveId=de.prob.standalone.perspective + +# new-style tabs by default +org.eclipse.ui/SHOW_TRADITIONAL_STYLE_TABS=false + +# put the perspective switcher on the top right +org.eclipse.ui/DOCK_PERSPECTIVE_BAR=topRight + +# show progress on startup +org.eclipse.ui/SHOW_PROGRESS_ON_STARTUP=true + +org.eclipse.ui/presentationFactoryId=de.prob.standalone.presentation diff --git a/de.prob.standalone/splash.bmp b/de.prob.standalone/splash.bmp new file mode 100644 index 0000000000000000000000000000000000000000..f3e5a2a34948431f458853896f27c0023bd72691 Binary files /dev/null and b/de.prob.standalone/splash.bmp differ diff --git a/de.prob.standalone/src/de/prob/standalone/Activator.java b/de.prob.standalone/src/de/prob/standalone/Activator.java new file mode 100644 index 0000000000000000000000000000000000000000..916f4f0b3ce87e32a6a892c950991630a7e3b4bb --- /dev/null +++ b/de.prob.standalone/src/de/prob/standalone/Activator.java @@ -0,0 +1,61 @@ +package de.prob.standalone; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +public class Activator extends AbstractUIPlugin { + + // The plug-in ID + public static final String PLUGIN_ID = "de.prob.standalone"; + + // The shared instance + private static Activator plugin; + + /** + * The constructor + */ + public Activator() { + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return plugin; + } + + /** + * Returns an image descriptor for the image file at the given + * plug-in relative path + * + * @param path the path + * @return the image descriptor + */ + public static ImageDescriptor getImageDescriptor(String path) { + return imageDescriptorFromPlugin(PLUGIN_ID, path); + } +} diff --git a/de.prob.standalone/src/de/prob/standalone/Application.java b/de.prob.standalone/src/de/prob/standalone/Application.java new file mode 100644 index 0000000000000000000000000000000000000000..10d6e99665d3d00e9b08634f8f73c21ff5b3193e --- /dev/null +++ b/de.prob.standalone/src/de/prob/standalone/Application.java @@ -0,0 +1,46 @@ +package de.prob.standalone; + +import org.eclipse.equinox.app.IApplication; +import org.eclipse.equinox.app.IApplicationContext; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.PlatformUI; + +/** + * This class controls all aspects of the application's execution + */ +public class Application implements IApplication { + + /* (non-Javadoc) + * @see org.eclipse.equinox.app.IApplication#start(org.eclipse.equinox.app.IApplicationContext) + */ + public Object start(IApplicationContext context) throws Exception { + Display display = PlatformUI.createDisplay(); + try { + int returnCode = PlatformUI.createAndRunWorkbench(display, new ApplicationWorkbenchAdvisor()); + if (returnCode == PlatformUI.RETURN_RESTART) + return IApplication.EXIT_RESTART; + else + return IApplication.EXIT_OK; + } finally { + display.dispose(); + } + + } + + /* (non-Javadoc) + * @see org.eclipse.equinox.app.IApplication#stop() + */ + public void stop() { + final IWorkbench workbench = PlatformUI.getWorkbench(); + if (workbench == null) + return; + final Display display = workbench.getDisplay(); + display.syncExec(new Runnable() { + public void run() { + if (!display.isDisposed()) + workbench.close(); + } + }); + } +} diff --git a/de.prob.standalone/src/de/prob/standalone/ApplicationActionBarAdvisor.java b/de.prob.standalone/src/de/prob/standalone/ApplicationActionBarAdvisor.java new file mode 100644 index 0000000000000000000000000000000000000000..a2b43be501cfe1c6828ab8577930ec6d798421cc --- /dev/null +++ b/de.prob.standalone/src/de/prob/standalone/ApplicationActionBarAdvisor.java @@ -0,0 +1,128 @@ +package de.prob.standalone; + +import org.eclipse.jface.action.ActionContributionItem; +import org.eclipse.jface.action.GroupMarker; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.util.Util; +import org.eclipse.ui.IWorkbenchActionConstants; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.actions.ActionFactory; +import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; +import org.eclipse.ui.application.ActionBarAdvisor; +import org.eclipse.ui.application.IActionBarConfigurer; + +public class ApplicationActionBarAdvisor extends ActionBarAdvisor { + + private IWorkbenchAction helpContentsAction; + private IWorkbenchAction helpSearchAction; + private IWorkbenchAction dynamicHelpAction; + private IWorkbenchAction aboutAction; + private IWorkbenchAction openPreferencesAction; + private IWorkbenchAction deleteAction; + private IWorkbenchAction copyAction; + private IWorkbenchAction pasteAction; + + public ApplicationActionBarAdvisor(final IActionBarConfigurer configurer) { + super(configurer); + } + + @Override + protected void makeActions(final IWorkbenchWindow window) { + helpContentsAction = ActionFactory.HELP_CONTENTS.create(window); + register(helpContentsAction); + + helpSearchAction = ActionFactory.HELP_SEARCH.create(window); + register(helpSearchAction); + + dynamicHelpAction = ActionFactory.DYNAMIC_HELP.create(window); + register(dynamicHelpAction); + + aboutAction = ActionFactory.ABOUT.create(window); + // aboutAction + // .setImageDescriptor(IDEInternalWorkbenchImages + // .getImageDescriptor(IDEInternalWorkbenchImages.IMG_OBJS_DEFAULT_PROD)); + register(aboutAction); + + openPreferencesAction = ActionFactory.PREFERENCES.create(window); + register(openPreferencesAction); + + deleteAction = ActionFactory.DELETE.create(window); + register(deleteAction); + + copyAction = ActionFactory.COPY.create(window); + register(copyAction); + pasteAction = ActionFactory.PASTE.create(window); + register(pasteAction); + + } + + @Override + protected void fillMenuBar(final IMenuManager menuBar) { + menuBar.add(createFileMenu()); + menuBar.add(createHelpMenu()); + } + + private MenuManager createFileMenu() { + MenuManager menu = new MenuManager("File", + IWorkbenchActionConstants.M_FILE); + menu.add(new GroupMarker(IWorkbenchActionConstants.FILE_START)); + return menu; + } + + private MenuManager createHelpMenu() { + MenuManager menu = new MenuManager("Help", + IWorkbenchActionConstants.M_HELP); + addSeparatorOrGroupMarker(menu, "group.intro"); //$NON-NLS-1$ + // FIXME Intro? + + // See if a welcome or intro page is specified + // if (introAction != null) { + // menu.add(introAction); + // } else if (quickStartAction != null) { + // menu.add(quickStartAction); + // } + menu.add(new GroupMarker("group.intro.ext")); //$NON-NLS-1$ + addSeparatorOrGroupMarker(menu, "group.main"); //$NON-NLS-1$ + menu.add(helpContentsAction); + menu.add(helpSearchAction); + menu.add(dynamicHelpAction); + addSeparatorOrGroupMarker(menu, "group.assist"); //$NON-NLS-1$ + // See if a tips and tricks page is specified + // if (tipsAndTricksAction != null) { + // menu.add(tipsAndTricksAction); + // } + // HELP_START should really be the first item, but it was after + // quickStartAction and tipsAndTricksAction in 2.1. + menu.add(new GroupMarker(IWorkbenchActionConstants.HELP_START)); + menu.add(new GroupMarker("group.main.ext")); //$NON-NLS-1$ + addSeparatorOrGroupMarker(menu, "group.tutorials"); //$NON-NLS-1$ + addSeparatorOrGroupMarker(menu, "group.tools"); //$NON-NLS-1$ + addSeparatorOrGroupMarker(menu, "group.updates"); //$NON-NLS-1$ + menu.add(new GroupMarker(IWorkbenchActionConstants.HELP_END)); + addSeparatorOrGroupMarker(menu, IWorkbenchActionConstants.MB_ADDITIONS); + // about should always be at the bottom + menu.add(new Separator("group.about")); //$NON-NLS-1$ + + ActionContributionItem aboutItem = new ActionContributionItem( + aboutAction); + aboutItem.setVisible(!Util.isMac()); + menu.add(aboutItem); + menu.add(new GroupMarker("group.about.ext")); //$NON-NLS-1$ + return menu; + } + + private void addSeparatorOrGroupMarker(final MenuManager menu, + final String groupId) { + // String prefId = "useSeparator." + menu.getId() + "." + groupId; //$NON-NLS-1$ //$NON-NLS-2$ + boolean addExtraSeparators = true; + // IDEWorkbenchPlugin.getDefault().getPreferenceStore().getBoolean(prefId); + if (addExtraSeparators) { + menu.add(new Separator(groupId)); + } else { + menu.add(new GroupMarker(groupId)); + } + } + +} diff --git a/de.prob.standalone/src/de/prob/standalone/ApplicationWorkbenchAdvisor.java b/de.prob.standalone/src/de/prob/standalone/ApplicationWorkbenchAdvisor.java new file mode 100644 index 0000000000000000000000000000000000000000..0a47a299361fc2f541bbfc71b0e4f8b253ca8882 --- /dev/null +++ b/de.prob.standalone/src/de/prob/standalone/ApplicationWorkbenchAdvisor.java @@ -0,0 +1,76 @@ +package de.prob.standalone; + +import java.net.URL; + +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.application.IWorkbenchConfigurer; +import org.eclipse.ui.application.IWorkbenchWindowConfigurer; +import org.eclipse.ui.application.WorkbenchAdvisor; +import org.eclipse.ui.application.WorkbenchWindowAdvisor; +import org.eclipse.ui.ide.IDE; +import org.osgi.framework.Bundle; + +public class ApplicationWorkbenchAdvisor extends WorkbenchAdvisor { + + private static final String PERSPECTIVE_ID = "de.prob.ui.perspective"; + + @Override + public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor( + final IWorkbenchWindowConfigurer configurer) { + return new ApplicationWorkbenchWindowAdvisor(configurer); + } + + @Override + public String getInitialWindowPerspectiveId() { + return PERSPECTIVE_ID; + } + + @Override + public void initialize(final IWorkbenchConfigurer configurer) { + super.initialize(configurer); + // configurer.setSaveAndRestore(true); + declareWorkbenchImages(); + } + + /* + * Comment from Lukas: Copied from IDEWorkbenchAdvisor.class in order to + * show folder images. + */ + private void declareWorkbenchImages() { + final String ICONS_PATH = "$nl$/icons/full/";//$NON-NLS-1$ + final String PATH_ELOCALTOOL = ICONS_PATH + "elcl16/"; // Enabled //$NON-NLS-1$ + final String PATH_OBJECT = ICONS_PATH + "obj16/"; // Model object //$NON-NLS-1$ + Bundle ideBundle = Platform.getBundle("org.eclipse.ui.ide"); + declareWorkbenchImage(ideBundle, IDE.SharedImages.IMG_OBJ_PROJECT, + PATH_OBJECT + "prj_obj.gif", true); //$NON-NLS-1$ + declareWorkbenchImage(ideBundle, + IDE.SharedImages.IMG_OBJ_PROJECT_CLOSED, PATH_OBJECT + + "cprj_obj.gif", true); //$NON-NLS-1$ + declareWorkbenchImage(ideBundle, IDE.SharedImages.IMG_OPEN_MARKER, + PATH_ELOCALTOOL + "gotoobj_tsk.gif", true); //$NON-NLS-1$ + } + + private void declareWorkbenchImage(Bundle ideBundle, String symbolicName, + String path, boolean shared) { + URL url = FileLocator.find(ideBundle, new Path(path), null); + ImageDescriptor desc = ImageDescriptor.createFromURL(url); + getWorkbenchConfigurer().declareImage(symbolicName, desc, shared); + } + + @Override + public void preStartup() { + IDE.registerAdapters(); + } + + @Override + public IAdaptable getDefaultPageInput() { + IAdaptable root = ResourcesPlugin.getWorkspace().getRoot(); + return root; + } + +} diff --git a/de.prob.standalone/src/de/prob/standalone/ApplicationWorkbenchWindowAdvisor.java b/de.prob.standalone/src/de/prob/standalone/ApplicationWorkbenchWindowAdvisor.java new file mode 100644 index 0000000000000000000000000000000000000000..c106e8fb2108c29d19fed2da31a04dec66972bc1 --- /dev/null +++ b/de.prob.standalone/src/de/prob/standalone/ApplicationWorkbenchWindowAdvisor.java @@ -0,0 +1,32 @@ +package de.prob.standalone; + +import org.eclipse.swt.graphics.Point; +import org.eclipse.ui.application.ActionBarAdvisor; +import org.eclipse.ui.application.IActionBarConfigurer; +import org.eclipse.ui.application.IWorkbenchWindowConfigurer; +import org.eclipse.ui.application.WorkbenchWindowAdvisor; + +public class ApplicationWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor { + + public ApplicationWorkbenchWindowAdvisor( + final IWorkbenchWindowConfigurer configurer) { + super(configurer); + } + + @Override + public ActionBarAdvisor createActionBarAdvisor( + final IActionBarConfigurer configurer) { + return new ApplicationActionBarAdvisor(configurer); + } + + @Override + public void preWindowOpen() { + IWorkbenchWindowConfigurer configurer = getWindowConfigurer(); + configurer.setInitialSize(new Point(1024, 768)); + configurer.setShowCoolBar(true); + configurer.setShowStatusLine(true); + configurer.setShowPerspectiveBar(true); + configurer.setTitle("ProB 1.0.0"); + } + +} diff --git a/de.prob.standalone/src/de/prob/standalone/OpenFileCommand.java b/de.prob.standalone/src/de/prob/standalone/OpenFileCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..3dfe766f175db587624c9f2cbb2eb52484e72583 --- /dev/null +++ b/de.prob.standalone/src/de/prob/standalone/OpenFileCommand.java @@ -0,0 +1,57 @@ +package de.prob.standalone; +import java.io.File; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.IHandler; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.handlers.HandlerUtil; + +import de.prob.core.Animator; +import de.prob.core.command.ExploreStateCommand; +import de.prob.core.command.StartAnimationCommand; +import de.prob.core.domainobjects.Operation; +import de.prob.core.domainobjects.State; +import de.prob.exceptions.ProBException; + +public class OpenFileCommand extends AbstractHandler implements IHandler { + + public Object execute(final ExecutionEvent event) throws ExecutionException { + IWorkbenchWindow window = HandlerUtil + .getActiveWorkbenchWindowChecked(event); + + FileDialog fileDialog = new FileDialog(window.getShell()); + String filename = fileDialog.open(); + if (filename == null) + return null; + File f = new File(filename); + Animator.killAndLoad(f); + Animator animator = Animator.getAnimator(); + try { + // final String START_COMMAND = new + // PrologTermStringOutput().openTerm( + // "start_animation").closeTerm().fullstop().toString(); + // PrologTermGenerator.toPrologTermMustNotFail(START_COMMAND, + // animator + // .sendCommand(START_COMMAND)); + + StartAnimationCommand.start(animator); + + animator.announceReset(); + + State commandResult = ExploreStateCommand.exploreState(animator, + "root"); + + animator.announceCurrentStateChanged(commandResult, + Operation.NULL_OPERATION); + + } catch (ProBException e) { + e.printStackTrace(); + } + + return null; + } + +} diff --git a/de.prob.standalone/src/de/prob/standalone/actions/OpenEventBFileAction.java b/de.prob.standalone/src/de/prob/standalone/actions/OpenEventBFileAction.java new file mode 100644 index 0000000000000000000000000000000000000000..04479b1f40ee483a914d159131e599812d6c3b62 --- /dev/null +++ b/de.prob.standalone/src/de/prob/standalone/actions/OpenEventBFileAction.java @@ -0,0 +1,182 @@ +package de.prob.standalone.actions; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.channels.FileChannel; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.IWorkbenchWindowActionDelegate; +import org.eventb.core.IEventBRoot; +import org.rodinp.core.IInternalElement; +import org.rodinp.core.IRodinDB; +import org.rodinp.core.IRodinProject; +import org.rodinp.core.RodinCore; + +import de.prob.core.Animator; +import de.prob.core.command.LoadEventBModelCommand; +import de.prob.exceptions.ProBException; + +/** + * Our sample action implements workbench action delegate. The action proxy will + * be created by the workbench and shown in the UI. When the user tries to use + * the action, this delegate will be created and execution will be delegated to + * it. + * + * @see IWorkbenchWindowActionDelegate + */ +public class OpenEventBFileAction implements IWorkbenchWindowActionDelegate { + private IWorkbenchWindow window; + + /** + * The constructor. + */ + public OpenEventBFileAction() { + } + + /** + * The action has been activated. The argument of the method represents the + * 'real' action sitting in the workbench UI. + * + * @see IWorkbenchWindowActionDelegate#run + */ + public void run(final IAction action) { + String filename = getFileDialog(); + String projectName = getProjectName(filename); + // IProject tempProject = + createTempProject(projectName, filename); + load(projectName, filename); + // deleteTempProject(tempProject); + } + + // private void deleteTempProject(final IProject tempProject) { + // try { + // tempProject.delete(true, null); + // } catch (CoreException e) { + // e.printStackTrace(); + // } + // } + + private String getProjectName(final String filename) { + File f = new File(filename); + String projectName = f.getName() + "_tmp_" + System.currentTimeMillis(); + return projectName; + } + + private String getFileName(final String filename) { + File f = new File(filename); + return f.getName(); + } + + private String getParent(final String filename) { + File f = new File(filename); + return f.getParent(); + } + + private void load(final String projectName, final String fileName) { + IRodinDB rodinDB = RodinCore.getRodinDB(); + IRodinProject rodinProject = rodinDB.getRodinProject(projectName); + IInternalElement root = rodinProject + .getRodinFile(getFileName(fileName)).getRoot(); + if (root instanceof IEventBRoot) { + IEventBRoot machineRoot = (IEventBRoot) root; + try { + LoadEventBModelCommand + .load(Animator.getAnimator(), machineRoot); + } catch (ProBException e) { + e.printStackTrace(); + } + } + } + + private IProject createTempProject(final String projectName, + final String filename) { + + IPath location = Platform.getLocation(); + String projectLocation = location.toOSString() + File.separator + + projectName; + + IRodinDB rodinDB = RodinCore.getRodinDB(); + IWorkspaceRoot workspaceRoot = rodinDB.getWorkspaceRoot(); + IProject project = workspaceRoot.getProject(projectName); + try { + project.create(null); + String parent = getParent(filename); + String[] filesToCopy = new File(parent).list(); + for (String string : filesToCopy) { + File src = new File(parent + File.separator + string); + File dst = new File(projectLocation + File.separator + + src.getName()); + copyFile(src, dst); + } + project.open(null); + project.getDescription().setNatureIds( + new String[] { RodinCore.NATURE_ID }); + } catch (Exception e) { + e.printStackTrace(); + } + return project; + } + + private String getFileDialog() { + FileDialog fileDialog = new FileDialog(window.getShell()); + fileDialog.setFilterExtensions(new String[] { "bum" }); + String filename = fileDialog.open(); + return filename; + } + + public void copyFile(final File in, final File out) throws IOException { + FileChannel inChannel = new FileInputStream(in).getChannel(); + FileChannel outChannel = new FileOutputStream(out).getChannel(); + try { + inChannel.transferTo(0, inChannel.size(), outChannel); + } catch (IOException e) { + throw e; + } finally { + if (inChannel != null) { + inChannel.close(); + } + if (outChannel != null) { + outChannel.close(); + } + } + } + + /** + * Selection in the workbench has been changed. We can change the state of + * the 'real' action here if we want, but this can only happen after the + * delegate has been created. + * + * @see IWorkbenchWindowActionDelegate#selectionChanged + */ + public void selectionChanged(final IAction action, + final ISelection selection) { + } + + /** + * We can use this method to dispose of any system resources we previously + * allocated. + * + * @see IWorkbenchWindowActionDelegate#dispose + */ + public void dispose() { + } + + /** + * We will cache window object in order to be able to provide parent shell + * for the message dialog. + * + * @see IWorkbenchWindowActionDelegate#init + */ + public void init(final IWorkbenchWindow window) { + this.window = window; + } +} \ No newline at end of file diff --git a/de.prob.standalone/src/de/prob/standalone/actions/OpenFileAction.java b/de.prob.standalone/src/de/prob/standalone/actions/OpenFileAction.java new file mode 100644 index 0000000000000000000000000000000000000000..7ef900ebfd71c07f669a5881e7d3db1d5bfb0954 --- /dev/null +++ b/de.prob.standalone/src/de/prob/standalone/actions/OpenFileAction.java @@ -0,0 +1,99 @@ +package de.prob.standalone.actions; + +import java.io.File; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.IWorkbenchWindowActionDelegate; + +import de.prob.core.Animator; +import de.prob.core.command.ExploreStateCommand; +import de.prob.core.command.StartAnimationCommand; +import de.prob.core.domainobjects.Operation; +import de.prob.core.domainobjects.State; +import de.prob.exceptions.ProBException; + +/** + * Our sample action implements workbench action delegate. The action proxy will + * be created by the workbench and shown in the UI. When the user tries to use + * the action, this delegate will be created and execution will be delegated to + * it. + * + * @see IWorkbenchWindowActionDelegate + */ +public class OpenFileAction implements IWorkbenchWindowActionDelegate { + private IWorkbenchWindow window; + + /** + * The constructor. + */ + public OpenFileAction() { + } + + /** + * The action has been activated. The argument of the method represents the + * 'real' action sitting in the workbench UI. + * + * @see IWorkbenchWindowActionDelegate#run + */ + public void run(final IAction action) { + FileDialog fileDialog = new FileDialog(window.getShell()); + String filename = fileDialog.open(); + File f = new File(filename); + Animator.killAndLoad(f); + Animator animator = Animator.getAnimator(); + try { + // final String START_COMMAND = new PrologTermStringOutput() + // .openTerm("start_animation").closeTerm().fullstop().toString(); + // PrologTermGenerator.toPrologTermMustNotFail(START_COMMAND, + // animator + // .sendCommand(START_COMMAND)); + + StartAnimationCommand.start(animator); + + animator.announceReset(); + + State commandResult = ExploreStateCommand.exploreState(animator, + "root"); + + animator.announceCurrentStateChanged(commandResult, + Operation.NULL_OPERATION); + + } catch (ProBException e) { + e.printStackTrace(); + } + + } + + /** + * Selection in the workbench has been changed. We can change the state of + * the 'real' action here if we want, but this can only happen after the + * delegate has been created. + * + * @see IWorkbenchWindowActionDelegate#selectionChanged + */ + public void selectionChanged(final IAction action, + final ISelection selection) { + } + + /** + * We can use this method to dispose of any system resources we previously + * allocated. + * + * @see IWorkbenchWindowActionDelegate#dispose + */ + public void dispose() { + } + + /** + * We will cache window object in order to be able to provide parent shell + * for the message dialog. + * + * @see IWorkbenchWindowActionDelegate#init + */ + public void init(final IWorkbenchWindow window) { + this.window = window; + } +} \ No newline at end of file diff --git a/de.prob.standalone/src/de/prob/standalone/handler/StartClassicalBAnimationHandler.java b/de.prob.standalone/src/de/prob/standalone/handler/StartClassicalBAnimationHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..f7384e650e146cc1acc2525286f0c95d471aa4cc --- /dev/null +++ b/de.prob.standalone/src/de/prob/standalone/handler/StartClassicalBAnimationHandler.java @@ -0,0 +1,55 @@ +package de.prob.standalone.handler; + +import java.io.File; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.IHandler; +import org.eclipse.core.resources.IFile; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.handlers.HandlerUtil; + +import de.prob.core.Animator; +import de.prob.core.command.LoadClassicalBModelCommand; +import de.prob.exceptions.ProBException; + +public class StartClassicalBAnimationHandler extends AbstractHandler implements + IHandler { + + private ISelection fSelection; + + public Object execute(final ExecutionEvent event) throws ExecutionException { + + fSelection = HandlerUtil.getCurrentSelection(event); + + if (fSelection instanceof IStructuredSelection) { + final IStructuredSelection ssel = (IStructuredSelection) fSelection; + if (ssel.size() == 1) { + final Object element = ssel.getFirstElement(); + if (element instanceof IFile) { + IFile f = (IFile) element; + String n = f.getName(); + String name = n.substring(0,n.length()-4); + File file = new File(f.getLocationURI()); + try { + LoadClassicalBModelCommand.load(Animator.getAnimator(), file, name); + } catch (ProBException e) { + throw new ExecutionException(e.getLocalizedMessage(),e); + } + } + } + } + + return null; + + } + + public void selectionChanged(final IAction action, + final ISelection selection) { + fSelection = selection; + } + +} diff --git a/de.prob.standalone/src/de/prob/standalone/internal/AnimationPerspective.java b/de.prob.standalone/src/de/prob/standalone/internal/AnimationPerspective.java new file mode 100644 index 0000000000000000000000000000000000000000..4dd54c243a24d6ec1416f770278cc8a8c7914298 --- /dev/null +++ b/de.prob.standalone/src/de/prob/standalone/internal/AnimationPerspective.java @@ -0,0 +1,35 @@ +package de.prob.standalone.internal; + +import org.eclipse.ui.IFolderLayout; +import org.eclipse.ui.IPageLayout; + +import de.prob.ui.PerspectiveFactory; + +public class AnimationPerspective extends PerspectiveFactory { + + public void createInitialLayout(final IPageLayout layout) { + String editorArea = layout.getEditorArea(); + layout.setEditorAreaVisible(false); + + // Place the project explorer to left of editor area. + IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT, + 0.30f, editorArea); + left.addView("de.prob.ui.OperationView"); + + IFolderLayout leftb = layout.createFolder("leftb", IPageLayout.BOTTOM, + 0.50f, "left"); + leftb.addView("de.prob.standalone.navigatorview"); + + // Place the outline to right of editor area. + IFolderLayout right1 = layout.createFolder("right1", IPageLayout.RIGHT, + 0.6f, editorArea); + right1.addView("de.prob.ui.StateView"); + right1.addView("de.prob.ui.ltl.CounterExampleView"); + IFolderLayout right2 = layout.createFolder("right2", IPageLayout.RIGHT, + 0.6f, "right1"); + right2.addView("de.prob.ui.HistoryView"); + right2.addView("de.prob.ui.EventErrorView"); + + } + +} diff --git a/de.prob.standalone/src/de/prob/standalone/internal/ClassicalBLanguageService.java b/de.prob.standalone/src/de/prob/standalone/internal/ClassicalBLanguageService.java new file mode 100644 index 0000000000000000000000000000000000000000..219d2cfac2022b0994ba1783ce043c3281b87bc6 --- /dev/null +++ b/de.prob.standalone/src/de/prob/standalone/internal/ClassicalBLanguageService.java @@ -0,0 +1,33 @@ +package de.prob.standalone.internal; + +import java.io.File; + +import org.eclipse.core.resources.IFile; + +import de.bmotionstudio.gef.editor.ILanguageService; +import de.bmotionstudio.gef.editor.model.Visualization; +import de.prob.core.Animator; +import de.prob.core.command.LoadClassicalBModelCommand; +import de.prob.exceptions.ProBException; + +/** + * @author Lukas Ladenberger + * + */ +public class ClassicalBLanguageService implements ILanguageService { + + public void startProBAnimator(Visualization v) throws ProBException { + IFile f = v.getProjectFile().getProject().getFile(v.getMachineName()); + String n = f.getName(); + String name = n.substring(0, n.length() - 4); + File file = new File(f.getLocationURI()); + LoadClassicalBModelCommand.load(Animator.getAnimator(), file, name); + } + + public boolean isLanguageFile(IFile f) { + if ("mch".equals(f.getFileExtension())) + return true; + return false; + } + +} diff --git a/de.prob.standalone/src/de/prob/standalone/internal/FormalModelContentProvider.java b/de.prob.standalone/src/de/prob/standalone/internal/FormalModelContentProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..027c41ad22447d007135438bad820dfaebe5ddb2 --- /dev/null +++ b/de.prob.standalone/src/de/prob/standalone/internal/FormalModelContentProvider.java @@ -0,0 +1,39 @@ +package de.prob.standalone.internal; + +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; + +public class FormalModelContentProvider implements ITreeContentProvider { + + public Object getParent(final Object element) { + return null; + } + + public boolean hasChildren(final Object element) { + return false; + } + + public Object[] getElements(final Object inputElement) { + return null; + } + + public void dispose() { + // do nothing + } + + public void inputChanged(final Viewer viewer, final Object oldInput, + final Object newInput) { + // do nothing + } + + public Object[] getChildren(Object parentElement) { + return null; + } + +} diff --git a/de.prob.standalone/src/de/prob/standalone/internal/FormalModelLabelProvider.java b/de.prob.standalone/src/de/prob/standalone/internal/FormalModelLabelProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..f28f7dd05660d6c5238265595957f7e5009f5a64 --- /dev/null +++ b/de.prob.standalone/src/de/prob/standalone/internal/FormalModelLabelProvider.java @@ -0,0 +1,59 @@ +package de.prob.standalone.internal; + +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +import org.eclipse.core.resources.IFile; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.swt.graphics.Image; + +import de.prob.standalone.Activator; + +public class FormalModelLabelProvider implements ILabelProvider { + + public Image getImage(final Object element) { + if (element instanceof IFile) { + IFile file = (IFile) element; + if (file.getFileExtension().equals("bum")) { + return Activator.getImageDescriptor("icons/eventb/mch_obj.png") + .createImage(); + } else if (file.getFileExtension().equals("buc")) { + return Activator.getImageDescriptor("icons/eventb/ctx_obj.png") + .createImage(); + } else if (file.getFileExtension().equals("mch")) { + return Activator.getImageDescriptor("icons/icon16.png") + .createImage(); + } + } + return null; + } + + public String getText(final Object element) { + if (element instanceof IFile) { + IFile file = (IFile) element; + return file.getName().replace("." + file.getFileExtension(), ""); + } + return null; + } + + public void addListener(final ILabelProviderListener listener) { + // do nothing + } + + public void dispose() { + // do nothing + } + + public boolean isLabelProperty(final Object element, final String property) { + return false; + } + + public void removeListener(final ILabelProviderListener listener) { + // do nothing + } + +} diff --git a/de.prob.standalone/src/de/prob/standalone/internal/VisualizationEditPerspective.java b/de.prob.standalone/src/de/prob/standalone/internal/VisualizationEditPerspective.java new file mode 100644 index 0000000000000000000000000000000000000000..339ee6632985465b9e071e69d5620a4be43439d7 --- /dev/null +++ b/de.prob.standalone/src/de/prob/standalone/internal/VisualizationEditPerspective.java @@ -0,0 +1,40 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.standalone.internal; + +import org.eclipse.ui.IFolderLayout; +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.IPerspectiveFactory; + +import de.bmotionstudio.gef.editor.library.LibraryView; + +public class VisualizationEditPerspective implements IPerspectiveFactory { + + public void createInitialLayout(final IPageLayout layout) { + + final String editorArea = layout.getEditorArea(); + + // Place the project explorer to left of editor area. + final IFolderLayout left = layout.createFolder("left", + IPageLayout.LEFT, 0.15f, editorArea); + left.addView("de.prob.standalone.navigatorview"); + + // Place the outline to right of editor area. + final IFolderLayout righttop = layout.createFolder("right", + IPageLayout.RIGHT, 0.70f, editorArea); + righttop.addView(IPageLayout.ID_OUTLINE); + // Library View + righttop.addView(LibraryView.ID); + + final IFolderLayout bottom = layout.createFolder("bottom", + IPageLayout.BOTTOM, 0.75f, editorArea); + // Properties view + bottom.addView(IPageLayout.ID_PROP_SHEET); + + } + +} diff --git a/de.prob.standalone/src/de/prob/standalone/internal/VisualizationRunPerspective.java b/de.prob.standalone/src/de/prob/standalone/internal/VisualizationRunPerspective.java new file mode 100644 index 0000000000000000000000000000000000000000..8382d19f360aaf13495867015e229a56d89d6011 --- /dev/null +++ b/de.prob.standalone/src/de/prob/standalone/internal/VisualizationRunPerspective.java @@ -0,0 +1,34 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.standalone.internal; + +import org.eclipse.ui.IFolderLayout; +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.IPerspectiveFactory; + +public class VisualizationRunPerspective implements IPerspectiveFactory { + + public void createInitialLayout(IPageLayout layout) { + + String editorArea = layout.getEditorArea(); + + // ProB Event View (Top-Left) + IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT, + 0.30f, editorArea); + left.addView("de.prob.ui.OperationView"); + + // ProB State View (Bottom) + IFolderLayout bottom = layout.createFolder("bottom", + IPageLayout.BOTTOM, 0.35f, "left"); + bottom.addView("de.prob.ui.StateView"); + bottom.addView("de.prob.ui.HistoryView"); + bottom.addView("de.prob.ui.EventErrorView"); + bottom.addView("de.prob.standalone.navigatorview"); + + } + +} diff --git a/de.prob.standalone/src/de/prob/standalone/presentation/AbstractClosable.java b/de.prob.standalone/src/de/prob/standalone/presentation/AbstractClosable.java new file mode 100644 index 0000000000000000000000000000000000000000..7c6504cf3da2ee31203a3fe05c3cd930eed0ce22 --- /dev/null +++ b/de.prob.standalone/src/de/prob/standalone/presentation/AbstractClosable.java @@ -0,0 +1,138 @@ +/******************************************************************************* + * Copyright (c) 2009 Siemens AG + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Kai Tödter - initial API and implementation + *******************************************************************************/ + +package de.prob.standalone.presentation; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseMoveListener; +import org.eclipse.swt.events.MouseTrackAdapter; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.eclipse.ui.presentations.IPresentablePart; + +import de.prob.standalone.Activator; + +public abstract class AbstractClosable extends Canvas implements PaintListener { + + private static final String PLUGIN = Activator.PLUGIN_ID; + + protected static Image closeUnselectedImage; + + protected static Image closeSelectedImage; + + protected boolean isCloseSelected; + + protected boolean isMouseOver; + + protected IPresentablePart part; + + private final MouseMoveListener mouseMoveListener = new MouseMoveListener() { + public void mouseMove(final MouseEvent e) { + boolean oldState = isCloseSelected; + Rectangle clientArea = getBounds(); + clientArea.x = clientArea.width - 20; + clientArea.width = closeSelectedImage.getBounds().width; + clientArea.y = 2; + clientArea.height = closeSelectedImage.getBounds().height; + if (clientArea.contains(e.x, e.y)) { + isCloseSelected = true; + } else { + isCloseSelected = false; + } + + if (oldState != isCloseSelected) { + redraw(); + } + } + }; + + protected MouseTrackAdapter mouseTrackAdapter = new MouseTrackAdapter() { + @Override + public void mouseEnter(final MouseEvent e) { + isMouseOver = true; + redraw(); + } + + @Override + public void mouseExit(final MouseEvent e) { + isMouseOver = false; + isCloseSelected = false; + redraw(); + } + }; + + static { + ImageDescriptor imageDescriptor = AbstractUIPlugin + .imageDescriptorFromPlugin(PLUGIN, "images/close_blue.gif"); + if (imageDescriptor != null) { + closeUnselectedImage = imageDescriptor.createImage(); + } + imageDescriptor = AbstractUIPlugin.imageDescriptorFromPlugin(PLUGIN, + "images/closeSelected.gif"); + if (imageDescriptor != null) { + closeSelectedImage = imageDescriptor.createImage(); + } + } + + public AbstractClosable(final Composite parent, final int style) { + super(parent, style); + addMouseMoveListener(mouseMoveListener); + addMouseTrackListener(mouseTrackAdapter); + } + + public void setPresentablePart(final IPresentablePart part) { + this.part = part; + setToolTipText(part.getTitleToolTip()); + layout(); + redraw(); + } + + public int getHeight() { + return 21; + } + + public void removePart(final IPresentablePart oldPart) { + if (part == oldPart) { + part = null; + } + } + + protected String shortenText(final GC gc, String text, final int width) { + if (text == null) + return null; + if (gc.textExtent(text, 0).x <= width) + return text; + String elipse = "..."; + int elipseWidth = gc.textExtent(elipse, 0).x; + int textLength = text.length(); + + while (textLength >= 0) { + String s1 = text.substring(0, textLength); + int textWidth = gc.textExtent(s1, 0).x; + + if (textWidth + elipseWidth < width) { + text = s1 + elipse; + break; + } + textLength--; + + } + return text; + } + +} diff --git a/de.prob.standalone/src/de/prob/standalone/presentation/Presentation.java b/de.prob.standalone/src/de/prob/standalone/presentation/Presentation.java new file mode 100644 index 0000000000000000000000000000000000000000..d345140a3b620f3b8e9d4b0326c9a1b95651f483 --- /dev/null +++ b/de.prob.standalone/src/de/prob/standalone/presentation/Presentation.java @@ -0,0 +1,295 @@ +/******************************************************************************* + * Copyright (c) 2009 Siemens AG + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Kai Tödter - initial API and implementation + *******************************************************************************/ + +package de.prob.standalone.presentation; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.ui.IPropertyListener; +import org.eclipse.ui.presentations.IPresentablePart; +import org.eclipse.ui.presentations.IStackPresentationSite; +import org.eclipse.ui.presentations.StackDropResult; +import org.eclipse.ui.presentations.StackPresentation; + +public class Presentation extends StackPresentation { + + private Color borderColor; + + private IPresentablePart current; + + private final PaintListener paintListener = new PaintListener() { + + public void paintControl(final PaintEvent e) { + final Rectangle clientArea = presentationControl.getClientArea(); + // Image img = new Image(e.display, clientArea.width, + // clientArea.height); + // GC gc = new GC(img); + final GC gc = e.gc; + + final int border = 1; + gc.setLineWidth(border); + gc.setForeground(borderColor); + gc.drawRectangle(clientArea.x, clientArea.y, clientArea.width + - border, clientArea.height - border); + + // e.gc.drawImage(img, 0, 0); + // gc.dispose(); + // img.dispose(); + + } + }; + + /** + * Listener attached to all child parts. It responds to changes in part + * properties + */ + private final IPropertyListener partPropertyChangeListener = new IPropertyListener() { + + public void propertyChanged(final Object source, final int property) { + + if (source instanceof IPresentablePart) { + redraw(); + } + } + }; + + private Composite presentationControl; + + private TabContainer tabContainer; + + private Title titleBar; + + private Color toolBarColor; + + public Presentation(final Composite parent, + final IStackPresentationSite site) { + super(site); + // Create a top-level control for the presentation. + presentationControl = new Composite(parent, SWT.NONE); + borderColor = new Color(presentationControl.getDisplay(), 50, 50, 50); + toolBarColor = new Color(presentationControl.getDisplay(), 203, 220, + 235); + + presentationControl.addPaintListener(paintListener); + + titleBar = new Title(presentationControl, SWT.NONE, getSite()); + tabContainer = new TabContainer(presentationControl, SWT.NONE); + + /* + * Add a dispose listener. Important because dispose() may // not always + * be called. + */ + presentationControl.addDisposeListener(new DisposeListener() { + + public void widgetDisposed(final DisposeEvent e) { + presentationDisposed(); + } + }); + + } + + protected Presentation(final IStackPresentationSite stackSite) { + super(stackSite); + // TODO Auto-generated constructor stub + } + + @Override + public void addPart(final IPresentablePart newPart, final Object cookie) { + newPart.addPropertyListener(partPropertyChangeListener); + tabContainer.addPart(newPart, this, getSite()); + } + + @Override + public int computePreferredSize(final boolean width, + final int availableParallel, final int availablePerpendicular, + final int preferredResult) { + if (width) + return Math.max(preferredResult, 100); + else + return tabContainer.getHeight() + titleBar.getHeight(); + } + + @Override + public void dispose() { + presentationDisposed(); + } + + @Override + public StackDropResult dragOver(final Control currentControl, + final Point location) { + // TODO Auto-generated method stub + return null; + } + + /** + * Gets the colorBorder. + * + * @return Returns the colorBorder. + */ + public Color getColorBorder() { + return borderColor; + } + + @Override + public Control getControl() { + return presentationControl; + } + + @Override + public Control[] getTabList(final IPresentablePart part) { + return new Control[] { part.getControl() }; + } + + @Override + public void removePart(final IPresentablePart oldPart) { + oldPart.removePropertyListener(partPropertyChangeListener); + tabContainer.removePart(oldPart); + titleBar.removePart(oldPart); + if (current == oldPart) { + current = null; + } + redraw(); + } + + @Override + public void selectPart(final IPresentablePart toSelect) { + // Ignore redundant selections + if (toSelect == current) + return; + + // If there was an existing part selected, make it invisible + if (current != null) { + current.setVisible(false); + } + // Select the new part + current = toSelect; + + // Make the part visible before setBounds, or the call to setBounds + // may be ignored. + if (current != null) { + current.setVisible(true); + setBounds(presentationControl.getBounds()); + titleBar.setPresentablePart(current); + tabContainer.setPresentablePart(current); + } + } + + @Override + public void setActive(final int newState) { + // TODO Auto-generated method stub + + } + + @Override + public void setBounds(final Rectangle bounds) { + // Set the bounds of the presentation widget + presentationControl.setBounds(bounds); + + final int titlebarHeight = titleBar.getHeight(); + final Rectangle clientArea = presentationControl.getClientArea(); + titleBar.setBounds(clientArea.x + 1, clientArea.y + 1, + clientArea.width - 2, titlebarHeight); + final int tabPaneHeight = tabContainer.getHeight(); + tabContainer.setBounds(clientArea.x, clientArea.y + clientArea.height + - tabPaneHeight, clientArea.width, tabPaneHeight); + if (current != null) { + final Rectangle contentArea = presentationControl.getBounds(); + int toolBarHeight = 0; + final Control toolBar = current.getToolBar(); + if (toolBar != null) { + toolBar.setBackground(toolBarColor); + toolBarHeight = toolBar.getBounds().height; + toolBar.setBounds(contentArea.x + 1, contentArea.y + 1 + + titlebarHeight, contentArea.width - 2, toolBarHeight); + } + contentArea.x += 1; + contentArea.y += titlebarHeight + toolBarHeight; + contentArea.width -= 2; + contentArea.height -= titlebarHeight + tabPaneHeight + + toolBarHeight; + if (tabPaneHeight == 0) { + contentArea.height -= 1; + } + current.setBounds(contentArea); + } + } + + @Override + public void setState(final int state) { + // TODO Auto-generated method stub + + } + + @Override + public void setVisible(final boolean isVisible) { + // Make the presentation widget visible + presentationControl.setVisible(isVisible); + titleBar.setVisible(isVisible); + + // Make the currently visible part visible + if (current != null) { + current.setVisible(isVisible); + + if (isVisible) { + // Restore the bounds of the currently visible part. + // IPartPresentations can be used by multiple + // StackPresentations, + // although only one such presentation is ever visible at a + // time. + // It is possible that some other presentation has changed the + // bounds of the part since it was last visible, so we need to + // update the part's bounds when the presentation becomes + // visible. + + setBounds(presentationControl.getBounds()); + } + } + } + + @Override + public void showPaneMenu() { + // TODO Auto-generated method stub + } + + @Override + public void showSystemMenu() { + // TODO Auto-generated method stub + } + + protected void presentationDisposed() { + // Remove any listeners that were attached to any + // global Eclipse resources. This is necessary in order to prevent + // memory leaks. + borderColor.dispose(); + toolBarColor.dispose(); + presentationControl.removePaintListener(paintListener); + presentationControl.dispose(); + presentationControl = null; + } + + protected void redraw() { + if (presentationControl != null) { + presentationControl.redraw(); + titleBar.redraw(); + tabContainer.redraw(); + } + } +} diff --git a/de.prob.standalone/src/de/prob/standalone/presentation/PresentationFactory.java b/de.prob.standalone/src/de/prob/standalone/presentation/PresentationFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..d83aef3f80794ae43e09482c9095e38df36c0dde --- /dev/null +++ b/de.prob.standalone/src/de/prob/standalone/presentation/PresentationFactory.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2009 Siemens AG + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Kai Tödter - initial API and implementation + *******************************************************************************/ + +package de.prob.standalone.presentation; + +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.presentations.AbstractPresentationFactory; +import org.eclipse.ui.presentations.IStackPresentationSite; +import org.eclipse.ui.presentations.StackPresentation; + +public class PresentationFactory extends AbstractPresentationFactory { + @Override + public StackPresentation createEditorPresentation(final Composite parent, + final IStackPresentationSite site) { + return new Presentation(parent, site); + } + + @Override + public StackPresentation createViewPresentation(final Composite parent, + final IStackPresentationSite site) { + return new Presentation(parent, site); + } + + @Override + public StackPresentation createStandaloneViewPresentation( + final Composite parent, final IStackPresentationSite site, + final boolean showTitle) { + return new Presentation(parent, site); + } +} \ No newline at end of file diff --git a/de.prob.standalone/src/de/prob/standalone/presentation/Tab.java b/de.prob.standalone/src/de/prob/standalone/presentation/Tab.java new file mode 100644 index 0000000000000000000000000000000000000000..f6f8b072ea1af61611340dd3e4194b76e147cafa --- /dev/null +++ b/de.prob.standalone/src/de/prob/standalone/presentation/Tab.java @@ -0,0 +1,192 @@ +/******************************************************************************* + * Copyright (c) 2009 Siemens AG + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Kai Tödter - initial API and implementation + *******************************************************************************/ + +package de.prob.standalone.presentation; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.presentations.IPresentablePart; +import org.eclipse.ui.presentations.IStackPresentationSite; + +public class Tab extends AbstractClosable implements PaintListener { + + private final Presentation presentation; + + private final IStackPresentationSite site; + + protected final Color unselectedTop = new Color(getDisplay(), 250, 250, 250); + + protected final Color unselectedBottom = new Color(getDisplay(), 200, 225, + 255); + + protected final Color selectedTop = new Color(getDisplay(), 250, 230, 150); + + protected final Color selectedBottom = new Color(getDisplay(), 240, 155, 30); + + protected final Color mouseOverTop = new Color(getDisplay(), 255, 248, 223); + + protected final Color mouseOverBottom = new Color(getDisplay(), 255, 225, + 120); + + protected Font font = new Font(getDisplay(), "Default", 10, SWT.NORMAL); + + private boolean isSelected; + + /** + * This listener responds to selection events in all tabs. + */ + private final MouseListener mouseListener = new MouseAdapter() { + @Override + public void mouseDown(final MouseEvent e) { + if (part != null) { + part.setFocus(); + if (isCloseSelected()) { + site.close(new IPresentablePart[] { part }); + } else { + site.selectPart(part); + presentation.selectPart(part); + } + } + } + }; + + public Tab(final Composite parent, final int style, + final Presentation presentation, final IStackPresentationSite site) { + super(parent, style | SWT.NO_BACKGROUND); + this.presentation = presentation; + this.site = site; + + setSected(false); + addPaintListener(this); + addMouseListener(mouseListener); + } + + @Override + public void setPresentablePart(final IPresentablePart part) { + this.part = part; + setToolTipText(part.getTitleToolTip()); + layout(); + redraw(); + } + + public boolean checkPart(final IPresentablePart part) { + return (this.part == part); + } + + public void setSected(final boolean selected) { + isSelected = selected; + } + + /** + * Paint the title bar + */ + public void paintControl(final PaintEvent e) { + Rectangle clientArea = getBounds(); + Image img = new Image(e.display, clientArea.width, clientArea.height); + GC gc = new GC(img); + + gc.setForeground(presentation.getColorBorder()); + gc.drawRectangle(0, 0, clientArea.width - 1, clientArea.height - 1); + + Color colorTop; + Color colorBottom; + + if (isMouseOver) { + if (isSelected) { + colorTop = selectedBottom; + colorBottom = selectedTop; + } else { + colorTop = mouseOverTop; + colorBottom = mouseOverBottom; + } + } else { + if (isSelected) { + colorTop = selectedTop; + colorBottom = selectedBottom; + } else { + colorTop = unselectedTop; + colorBottom = unselectedBottom; + } + } + gc.setForeground(colorTop); + gc.setBackground(colorBottom); + gc.fillGradientRectangle(1, 1, clientArea.width - 2, + clientArea.height - 2, true); + + if (part != null) { + Image partImage = part.getTitleImage(); + gc.drawImage(partImage, 2, 2); + + Color colorText = new Color(getDisplay(), 0, 0, 0); + // gc.setFont(font); + gc.setForeground(colorText); + String dirty = ""; + if (part.isDirty()) { + dirty = "*"; + } + int closeImageOffset = 0; + if (part.isCloseable()) { + closeImageOffset = 20; + } + String text = shortenText(gc, dirty + part.getTitle(), + clientArea.width - 25 - closeImageOffset); + gc.drawText(text, partImage.getBounds().width + 7, 3, true); + } + + if (part.isCloseable()) { + if (isCloseSelected) { + gc.drawImage(closeSelectedImage, clientArea.width - 20, 3); + } else { + gc.drawImage(closeUnselectedImage, clientArea.width - 20, 3); + } + } + + e.gc.drawImage(img, 0, 0); + gc.dispose(); + img.dispose(); + } + + public IPresentablePart getPart() { + return part; + } + + public boolean isCloseSelected() { + return isCloseSelected; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.swt.widgets.Widget#dispose() + */ + @Override + public void dispose() { + unselectedTop.dispose(); + unselectedBottom.dispose(); + selectedTop.dispose(); + selectedBottom.dispose(); + mouseOverTop.dispose(); + mouseOverBottom.dispose(); + font.dispose(); + super.dispose(); + } +} diff --git a/de.prob.standalone/src/de/prob/standalone/presentation/TabContainer.java b/de.prob.standalone/src/de/prob/standalone/presentation/TabContainer.java new file mode 100644 index 0000000000000000000000000000000000000000..b90da981f02d32f7b693e06b6ac4c557a201df10 --- /dev/null +++ b/de.prob.standalone/src/de/prob/standalone/presentation/TabContainer.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright (c) 2009 Siemens AG + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Kai Tödter - initial API and implementation + *******************************************************************************/ + +package de.prob.standalone.presentation; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.presentations.IPresentablePart; +import org.eclipse.ui.presentations.IStackPresentationSite; + +public class TabContainer extends Composite { + + protected List<Tab> tabItems = new ArrayList<Tab>(); + + protected IPresentablePart part; + + protected int style; + + public TabContainer(final Composite parent, final int style) { + super(parent, style); + this.style = style; + } + + public void addPart(final IPresentablePart part, + final Presentation presentation, final IStackPresentationSite site) { + Tab tab = new Tab(this, style, presentation, site); + tab.setPresentablePart(part); + tabItems.add(tab); + redraw(); + } + + public void setPresentablePart(final IPresentablePart part) { + this.part = part; + for (Tab b : tabItems) { + b.setSected(b.checkPart(part)); + } + redraw(); + } + + public int getHeight() { + if (tabItems.size() < 2) + return 0; + return tabItems.size() * tabItems.get(0).getHeight() - tabItems.size() + + 1; + } + + @Override + public void setBounds(final int x, final int y, final int width, + final int height) { + int y2 = 0; + int h = 21; + for (Tab b : tabItems) { + b.setBounds(x, y2, width, h); + y2 += 20; + } + super.setBounds(x, y, width, height); + } + + @Override + public void redraw() { + if (tabItems.size() < 2) + return; + for (Tab b : tabItems) { + b.redraw(); + } + } + + public void removePart(final IPresentablePart oldPart) { + Tab foundTab = null; + for (Tab b : tabItems) { + if (b.getPart() == oldPart) { + foundTab = b; + break; + } + } + if (foundTab != null) { + tabItems.remove(foundTab); + foundTab.dispose(); + } + } +} diff --git a/de.prob.standalone/src/de/prob/standalone/presentation/Title.java b/de.prob.standalone/src/de/prob/standalone/presentation/Title.java new file mode 100644 index 0000000000000000000000000000000000000000..8e11a6c780e2565922891d2dbc495a1f6e8057cb --- /dev/null +++ b/de.prob.standalone/src/de/prob/standalone/presentation/Title.java @@ -0,0 +1,119 @@ +/******************************************************************************* + * Copyright (c) 2009 Siemens AG + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Kai Tödter - initial API and implementation + *******************************************************************************/ + +package de.prob.standalone.presentation; + +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.presentations.IPresentablePart; +import org.eclipse.ui.presentations.IStackPresentationSite; + +public class Title extends AbstractClosable { + private final IStackPresentationSite site; + + Color colorTop = new Color(getDisplay(), 142, 158, 170); + // Color colorTop = new Color(getDisplay(), 135, 135, 135); + + Color colorBottom = new Color(getDisplay(), 13, 63, 110); + + Color colorText = new Color(getDisplay(), 255, 255, 255); + + protected Font font = new Font(getDisplay(), "Default", 10, SWT.BOLD); + + /** + * This listener responds to selection events in all tab buttons. + */ + private final MouseListener mouseListener = new MouseAdapter() { + @Override + public void mouseDown(final MouseEvent e) { + if (part != null) { + part.setFocus(); + if (isCloseSelected) { + site.close(new IPresentablePart[] { part }); + } + } + } + }; + + public Title(final Composite parent, final int style, + final IStackPresentationSite site) { + super(parent, style | SWT.NO_BACKGROUND); + this.site = site; + addPaintListener(this); + addMouseListener(mouseListener); + } + + /** + * Paint the title + */ + public void paintControl(final PaintEvent e) { + Rectangle clientArea = getBounds(); + Image img = new Image(e.display, clientArea.width, clientArea.height); + GC gc = new GC(img); + + gc.setForeground(colorTop); + gc.setBackground(colorBottom); + gc.fillGradientRectangle(0, 0, clientArea.width, clientArea.height, + true); + + if (part != null) { + gc.setFont(JFaceResources.getBannerFont()); + gc.setForeground(colorText); + String dirty = ""; + if (part.isDirty()) { + dirty = "*"; + } + String text = shortenText(gc, dirty + part.getTitle(), + clientArea.width - 30); + gc.drawText(text, 5, 2, true); + + if (part.isCloseable()) { + if (isCloseSelected) { + gc.drawImage(closeSelectedImage, clientArea.width - 20, 2); + } else { + gc + .drawImage(closeUnselectedImage, + clientArea.width - 20, 2); + } + } + } + + e.gc.drawImage(img, 0, 0); + gc.dispose(); + img.dispose(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.swt.widgets.Widget#dispose() + */ + @Override + public void dispose() { + colorTop.dispose(); + colorBottom.dispose(); + colorText.dispose(); + font.dispose(); + super.dispose(); + } + +} diff --git a/de.prob.ui/.classpath b/de.prob.ui/.classpath new file mode 100644 index 0000000000000000000000000000000000000000..88ce79dcd66db4de0f421cd37cdc52dd427558ac --- /dev/null +++ b/de.prob.ui/.classpath @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="src" path="src"/> + <classpathentry exported="true" kind="lib" path="lib/apache_xmlrpc.jar"/> + <classpathentry exported="true" kind="lib" path="lib/ws_commons.jar"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/de.prob.ui/.fbprefs b/de.prob.ui/.fbprefs new file mode 100755 index 0000000000000000000000000000000000000000..82704f5a9c08cac93bebdb001e66ca615d4a8efa --- /dev/null +++ b/de.prob.ui/.fbprefs @@ -0,0 +1,143 @@ +#FindBugs User Preferences +#Thu Sep 04 18:24:06 CEST 2008 +detectorAppendingToAnObjectOutputStream=AppendingToAnObjectOutputStream|true +detectorBCPMethodReturnCheck=BCPMethodReturnCheck|false +detectorBadAppletConstructor=BadAppletConstructor|false +detectorBadResultSetAccess=BadResultSetAccess|true +detectorBadSyntaxForRegularExpression=BadSyntaxForRegularExpression|true +detectorBadUseOfReturnValue=BadUseOfReturnValue|true +detectorBadlyOverriddenAdapter=BadlyOverriddenAdapter|true +detectorBooleanReturnNull=BooleanReturnNull|true +detectorCalledMethods=CalledMethods|true +detectorCheckCalls=CheckCalls|false +detectorCheckImmutableAnnotation=CheckImmutableAnnotation|true +detectorCheckTypeQualifiers=CheckTypeQualifiers|true +detectorCloneIdiom=CloneIdiom|true +detectorComparatorIdiom=ComparatorIdiom|true +detectorConfusedInheritance=ConfusedInheritance|true +detectorConfusionBetweenInheritedAndOuterMethod=ConfusionBetweenInheritedAndOuterMethod|true +detectorCrossSiteScripting=CrossSiteScripting|true +detectorDoInsideDoPrivileged=DoInsideDoPrivileged|true +detectorDontCatchIllegalMonitorStateException=DontCatchIllegalMonitorStateException|true +detectorDontUseEnum=DontUseEnum|true +detectorDroppedException=DroppedException|true +detectorDumbMethodInvocations=DumbMethodInvocations|true +detectorDumbMethods=DumbMethods|true +detectorDuplicateBranches=DuplicateBranches|true +detectorEmptyZipFileEntry=EmptyZipFileEntry|true +detectorEqStringTest=EqStringTest|false +detectorFinalizerNullsFields=FinalizerNullsFields|true +detectorFindBadCast=FindBadCast|false +detectorFindBadCast2=FindBadCast2|true +detectorFindBadEqualsImplementation=FindBadEqualsImplementation|false +detectorFindBadForLoop=FindBadForLoop|true +detectorFindBugsSummaryStats=FindBugsSummaryStats|true +detectorFindCircularDependencies=FindCircularDependencies|false +detectorFindDeadLocalStores=FindDeadLocalStores|true +detectorFindDoubleCheck=FindDoubleCheck|true +detectorFindEmptySynchronizedBlock=FindEmptySynchronizedBlock|true +detectorFindFieldSelfAssignment=FindFieldSelfAssignment|true +detectorFindFinalizeInvocations=FindFinalizeInvocations|true +detectorFindFloatEquality=FindFloatEquality|true +detectorFindFloatMath=FindFloatMath|false +detectorFindHEmismatch=FindHEmismatch|true +detectorFindInconsistentSync2=FindInconsistentSync2|false +detectorFindJSR166LockMonitorenter=FindJSR166LockMonitorenter|true +detectorFindLocalSelfAssignment2=FindLocalSelfAssignment2|true +detectorFindMaskedFields=FindMaskedFields|true +detectorFindMismatchedWaitOrNotify=FindMismatchedWaitOrNotify|true +detectorFindNakedNotify=FindNakedNotify|true +detectorFindNonSerializableStoreIntoSession=FindNonSerializableStoreIntoSession|true +detectorFindNonSerializableValuePassedToWriteObject=FindNonSerializableValuePassedToWriteObject|true +detectorFindNonShortCircuit=FindNonShortCircuit|true +detectorFindNullDeref=FindNullDeref|true +detectorFindOpenStream=FindOpenStream|true +detectorFindPuzzlers=FindPuzzlers|true +detectorFindRefComparison=FindRefComparison|true +detectorFindReturnRef=FindReturnRef|true +detectorFindRunInvocations=FindRunInvocations|true +detectorFindSelfComparison=FindSelfComparison|true +detectorFindSelfComparison2=FindSelfComparison2|true +detectorFindSleepWithLockHeld=FindSleepWithLockHeld|true +detectorFindSpinLoop=FindSpinLoop|true +detectorFindSqlInjection=FindSqlInjection|true +detectorFindTwoLockWait=FindTwoLockWait|true +detectorFindUncalledPrivateMethods=FindUncalledPrivateMethods|true +detectorFindUnconditionalWait=FindUnconditionalWait|true +detectorFindUninitializedGet=FindUninitializedGet|true +detectorFindUnrelatedTypesInGenericContainer=FindUnrelatedTypesInGenericContainer|true +detectorFindUnreleasedLock=FindUnreleasedLock|true +detectorFindUnsatisfiedObligation=FindUnsatisfiedObligation|false +detectorFindUnsyncGet=FindUnsyncGet|true +detectorFindUselessControlFlow=FindUselessControlFlow|true +detectorHugeSharedStringConstants=HugeSharedStringConstants|true +detectorIDivResultCastToDouble=IDivResultCastToDouble|true +detectorIncompatMask=IncompatMask|true +detectorInefficientMemberAccess=InefficientMemberAccess|false +detectorInefficientToArray=InefficientToArray|true +detectorInfiniteLoop=InfiniteLoop|true +detectorInfiniteRecursiveLoop=InfiniteRecursiveLoop|true +detectorInfiniteRecursiveLoop2=InfiniteRecursiveLoop2|false +detectorInheritanceUnsafeGetResource=InheritanceUnsafeGetResource|true +detectorInitializationChain=InitializationChain|true +detectorInstantiateStaticClass=InstantiateStaticClass|true +detectorInvalidJUnitTest=InvalidJUnitTest|true +detectorIteratorIdioms=IteratorIdioms|true +detectorLazyInit=LazyInit|false +detectorLoadOfKnownNullValue=LoadOfKnownNullValue|true +detectorLockedFields=LockedFields|false +detectorMethodReturnCheck=MethodReturnCheck|true +detectorMethods=Methods|true +detectorMultithreadedInstanceAccess=MultithreadedInstanceAccess|true +detectorMutableLock=MutableLock|true +detectorMutableStaticFields=MutableStaticFields|false +detectorNaming=Naming|true +detectorNoteAnnotationRetention=NoteAnnotationRetention|true +detectorNoteCheckReturnValue=NoteCheckReturnValue|true +detectorNoteCheckReturnValueAnnotations=NoteCheckReturnValueAnnotations|true +detectorNoteDirectlyRelevantTypeQualifiers=NoteDirectlyRelevantTypeQualifiers|true +detectorNoteJCIPAnnotation=NoteJCIPAnnotation|true +detectorNoteNonNullAnnotations=NoteNonNullAnnotations|true +detectorNoteNonnullReturnValues=NoteNonnullReturnValues|true +detectorNoteSuppressedWarnings=NoteSuppressedWarnings|true +detectorNoteUnconditionalParamDerefs=NoteUnconditionalParamDerefs|true +detectorNumberConstructor=NumberConstructor|true +detectorOverridingEqualsNotSymmetrical=OverridingEqualsNotSymmetrical|true +detectorPreferZeroLengthArrays=PreferZeroLengthArrays|true +detectorPublicSemaphores=PublicSemaphores|false +detectorQuestionableBooleanAssignment=QuestionableBooleanAssignment|true +detectorReadReturnShouldBeChecked=ReadReturnShouldBeChecked|true +detectorRedundantInterfaces=RedundantInterfaces|true +detectorReflectiveClasses=ReflectiveClasses|true +detectorResolveAllReferences=ResolveAllReferences|false +detectorRuntimeExceptionCapture=RuntimeExceptionCapture|true +detectorSerializableIdiom=SerializableIdiom|true +detectorStartInConstructor=StartInConstructor|true +detectorStaticCalendarDetector=StaticCalendarDetector|true +detectorStringConcatenation=StringConcatenation|true +detectorSuperfluousInstanceOf=SuperfluousInstanceOf|true +detectorSuspiciousThreadInterrupted=SuspiciousThreadInterrupted|true +detectorSwitchFallthrough=SwitchFallthrough|true +detectorSynchronizationOnSharedBuiltinConstant=SynchronizationOnSharedBuiltinConstant|true +detectorSynchronizeAndNullCheckField=SynchronizeAndNullCheckField|true +detectorTestASM=TestASM|false +detectorTestDataflowAnalysis=TestDataflowAnalysis|false +detectorTestingGround=TestingGround|false +detectorTrainFieldStoreTypes=TrainFieldStoreTypes|true +detectorTrainNonNullAnnotations=TrainNonNullAnnotations|true +detectorTrainUnconditionalDerefParams=TrainUnconditionalDerefParams|true +detectorURLProblems=URLProblems|true +detectorUncallableMethodOfAnonymousClass=UncallableMethodOfAnonymousClass|true +detectorUnnecessaryMath=UnnecessaryMath|true +detectorUnreadFields=UnreadFields|true +detectorUseObjectEquals=UseObjectEquals|false +detectorUselessSubclassMethod=UselessSubclassMethod|false +detectorVarArgsProblems=VarArgsProblems|true +detectorVolatileUsage=VolatileUsage|true +detectorWaitInLoop=WaitInLoop|true +detectorWrongMapIterator=WrongMapIterator|true +detectorXMLFactoryBypass=XMLFactoryBypass|true +detector_threshold=2 +effort=default +filter_settings=Medium|BAD_PRACTICE,CORRECTNESS,I18N,MALICIOUS_CODE,MT_CORRECTNESS,PERFORMANCE,SECURITY,STYLE|false +filter_settings_neg=| diff --git a/de.prob.ui/.pmd b/de.prob.ui/.pmd new file mode 100755 index 0000000000000000000000000000000000000000..460a087d2cdcc0a6498e55d6bd1ff5388df8a92e --- /dev/null +++ b/de.prob.ui/.pmd @@ -0,0 +1,951 @@ +<?xml version="1.0" encoding="UTF-8"?> +<pmd> + <useProjectRuleSet>false</useProjectRuleSet> + <ruleSetFile>.ruleset</ruleSetFile> + <excludePatterns> + <excludePattern>.*/sablecc/.*</excludePattern> + </excludePatterns> + <rules> + <rule> + <name>UseCorrectExceptionLogging</name> + <ruleset>Jakarta Commons Logging Rules</ruleset> + </rule> + <rule> + <name>ProperLogger</name> + <ruleset>Jakarta Commons Logging Rules</ruleset> + </rule> + <rule> + <name>AvoidDuplicateLiterals</name> + <ruleset>String and StringBuffer Rules</ruleset> + </rule> + <rule> + <name>StringInstantiation</name> + <ruleset>String and StringBuffer Rules</ruleset> + </rule> + <rule> + <name>StringToString</name> + <ruleset>String and StringBuffer Rules</ruleset> + </rule> + <rule> + <name>InefficientStringBuffering</name> + <ruleset>String and StringBuffer Rules</ruleset> + </rule> + <rule> + <name>UnnecessaryCaseChange</name> + <ruleset>String and StringBuffer Rules</ruleset> + </rule> + <rule> + <name>UseStringBufferLength</name> + <ruleset>String and StringBuffer Rules</ruleset> + </rule> + <rule> + <name>AppendCharacterWithChar</name> + <ruleset>String and StringBuffer Rules</ruleset> + </rule> + <rule> + <name>ConsecutiveLiteralAppends</name> + <ruleset>String and StringBuffer Rules</ruleset> + </rule> + <rule> + <name>UseIndexOfChar</name> + <ruleset>String and StringBuffer Rules</ruleset> + </rule> + <rule> + <name>InefficientEmptyStringCheck</name> + <ruleset>String and StringBuffer Rules</ruleset> + </rule> + <rule> + <name>InsufficientStringBufferDeclaration</name> + <ruleset>String and StringBuffer Rules</ruleset> + </rule> + <rule> + <name>UselessStringValueOf</name> + <ruleset>String and StringBuffer Rules</ruleset> + </rule> + <rule> + <name>StringBufferInstantiationWithChar</name> + <ruleset>String and StringBuffer Rules</ruleset> + </rule> + <rule> + <name>UseEqualsToCompareStrings</name> + <ruleset>String and StringBuffer Rules</ruleset> + </rule> + <rule> + <name>AvoidStringBufferField</name> + <ruleset>String and StringBuffer Rules</ruleset> + </rule> + <rule> + <name>LocalVariableCouldBeFinal</name> + <ruleset>Optimization Rules</ruleset> + </rule> + <rule> + <name>MethodArgumentCouldBeFinal</name> + <ruleset>Optimization Rules</ruleset> + </rule> + <rule> + <name>AvoidInstantiatingObjectsInLoops</name> + <ruleset>Optimization Rules</ruleset> + </rule> + <rule> + <name>UseArrayListInsteadOfVector</name> + <ruleset>Optimization Rules</ruleset> + </rule> + <rule> + <name>SimplifyStartsWith</name> + <ruleset>Optimization Rules</ruleset> + </rule> + <rule> + <name>UseStringBufferForStringAppends</name> + <ruleset>Optimization Rules</ruleset> + </rule> + <rule> + <name>UseArraysAsList</name> + <ruleset>Optimization Rules</ruleset> + </rule> + <rule> + <name>AvoidArrayLoops</name> + <ruleset>Optimization Rules</ruleset> + </rule> + <rule> + <name>UnnecessaryWrapperObjectCreation</name> + <ruleset>Optimization Rules</ruleset> + </rule> + <rule> + <name>AddEmptyString</name> + <ruleset>Optimization Rules</ruleset> + </rule> + <rule> + <name>LooseCoupling</name> + <ruleset>Type Resolution Rules</ruleset> + </rule> + <rule> + <name>CloneMethodMustImplementCloneable</name> + <ruleset>Type Resolution Rules</ruleset> + </rule> + <rule> + <name>UnusedImports</name> + <ruleset>Type Resolution Rules</ruleset> + </rule> + <rule> + <name>SignatureDeclareThrowsException</name> + <ruleset>Type Resolution Rules</ruleset> + </rule> + <rule> + <name>JUnitStaticSuite</name> + <ruleset>JUnit Rules</ruleset> + </rule> + <rule> + <name>JUnitSpelling</name> + <ruleset>JUnit Rules</ruleset> + </rule> + <rule> + <name>JUnitAssertionsShouldIncludeMessage</name> + <ruleset>JUnit Rules</ruleset> + </rule> + <rule> + <name>JUnitTestsShouldIncludeAssert</name> + <ruleset>JUnit Rules</ruleset> + </rule> + <rule> + <name>TestClassWithoutTestCases</name> + <ruleset>JUnit Rules</ruleset> + </rule> + <rule> + <name>UnnecessaryBooleanAssertion</name> + <ruleset>JUnit Rules</ruleset> + </rule> + <rule> + <name>UseAssertEqualsInsteadOfAssertTrue</name> + <ruleset>JUnit Rules</ruleset> + </rule> + <rule> + <name>UseAssertSameInsteadOfAssertTrue</name> + <ruleset>JUnit Rules</ruleset> + </rule> + <rule> + <name>UseAssertNullInsteadOfAssertTrue</name> + <ruleset>JUnit Rules</ruleset> + </rule> + <rule> + <name>SimplifyBooleanAssertion</name> + <ruleset>JUnit Rules</ruleset> + </rule> + <rule> + <name>UseSingleton</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>SimplifyBooleanReturns</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>SimplifyBooleanExpressions</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>SwitchStmtsShouldHaveDefault</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>AvoidDeeplyNestedIfStmts</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>AvoidReassigningParameters</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>SwitchDensity</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>ConstructorCallsOverridableMethod</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>AccessorClassGeneration</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>FinalFieldCouldBeStatic</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>CloseResource</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>NonStaticInitializer</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>DefaultLabelNotLastInSwitchStmt</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>NonCaseLabelInSwitchStatement</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>OptimizableToArrayCall</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>BadComparison</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>EqualsNull</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>ConfusingTernary</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>InstantiationToGetClass</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>IdempotentOperations</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>SimpleDateFormatNeedsLocale</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>ImmutableField</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>UseLocaleWithCaseConversions</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>AvoidProtectedFieldInFinalClass</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>AssignmentToNonFinalStatic</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>MissingStaticMethodInNonInstantiatableClass</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>AvoidSynchronizedAtMethodLevel</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>MissingBreakInSwitch</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>UseNotifyAllInsteadOfNotify</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>AvoidInstanceofChecksInCatchClause</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>AbstractClassWithoutAbstractMethod</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>SimplifyConditional</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>CompareObjectsWithEquals</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>PositionLiteralsFirstInComparisons</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>UnnecessaryLocalBeforeReturn</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>NonThreadSafeSingleton</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>UncommentedEmptyMethod</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>UncommentedEmptyConstructor</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>AvoidConstantsInterface</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>UnsynchronizedStaticDateFormatter</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>PreserveStackTrace</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>UseCollectionIsEmpty</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>ClassWithOnlyPrivateConstructorsShouldBeFinal</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>EmptyMethodInAbstractClassShouldBeAbstract</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>SingularField</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>ReturnEmptyArrayRatherThanNull</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>AbstractClassWithoutAnyMethod</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>TooFewBranchesForASwitchStatement</name> + <ruleset>Design Rules</ruleset> + </rule> + <rule> + <name>IfStmtsMustUseBraces</name> + <ruleset>Braces Rules</ruleset> + </rule> + <rule> + <name>WhileLoopsMustUseBraces</name> + <ruleset>Braces Rules</ruleset> + </rule> + <rule> + <name>IfElseStmtsMustUseBraces</name> + <ruleset>Braces Rules</ruleset> + </rule> + <rule> + <name>ForLoopsMustUseBraces</name> + <ruleset>Braces Rules</ruleset> + </rule> + <rule> + <name>CouplingBetweenObjects</name> + <ruleset>Coupling Rules</ruleset> + </rule> + <rule> + <name>ExcessiveImports</name> + <ruleset>Coupling Rules</ruleset> + </rule> + <rule> + <name>LooseCoupling</name> + <ruleset>Coupling Rules</ruleset> + </rule> + <rule> + <name>EmptyCatchBlock</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>EmptyIfStmt</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>EmptyWhileStmt</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>EmptyTryBlock</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>EmptyFinallyBlock</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>EmptySwitchStatements</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>JumbledIncrementer</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>ForLoopShouldBeWhileLoop</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>UnnecessaryConversionTemporary</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>OverrideBothEqualsAndHashcode</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>DoubleCheckedLocking</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>ReturnFromFinallyBlock</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>EmptySynchronizedBlock</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>UnnecessaryReturn</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>EmptyStaticInitializer</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>UnconditionalIfStatement</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>EmptyStatementNotInLoop</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>BooleanInstantiation</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>UnnecessaryFinalModifier</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>CollapsibleIfStatements</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>UselessOverridingMethod</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>ClassCastExceptionWithToArray</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>AvoidDecimalLiteralsInBigDecimalConstructor</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>UselessOperationOnImmutable</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>MisplacedNullCheck</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>UnusedNullCheckInEquals</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>AvoidThreadGroup</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>BrokenNullCheck</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>BigIntegerInstantiation</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>AvoidUsingOctalValues</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>AvoidUsingHardCodedIP</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>CheckResultSet</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>AvoidMultipleUnaryOperators</name> + <ruleset>Basic Rules</ruleset> + </rule> + <rule> + <name>UnnecessaryConstructor</name> + <ruleset>Controversial Rules</ruleset> + </rule> + <rule> + <name>NullAssignment</name> + <ruleset>Controversial Rules</ruleset> + </rule> + <rule> + <name>OnlyOneReturn</name> + <ruleset>Controversial Rules</ruleset> + </rule> + <rule> + <name>UnusedModifier</name> + <ruleset>Controversial Rules</ruleset> + </rule> + <rule> + <name>AssignmentInOperand</name> + <ruleset>Controversial Rules</ruleset> + </rule> + <rule> + <name>AtLeastOneConstructor</name> + <ruleset>Controversial Rules</ruleset> + </rule> + <rule> + <name>DontImportSun</name> + <ruleset>Controversial Rules</ruleset> + </rule> + <rule> + <name>SuspiciousOctalEscape</name> + <ruleset>Controversial Rules</ruleset> + </rule> + <rule> + <name>CallSuperInConstructor</name> + <ruleset>Controversial Rules</ruleset> + </rule> + <rule> + <name>UnnecessaryParentheses</name> + <ruleset>Controversial Rules</ruleset> + </rule> + <rule> + <name>DefaultPackage</name> + <ruleset>Controversial Rules</ruleset> + </rule> + <rule> + <name>BooleanInversion</name> + <ruleset>Controversial Rules</ruleset> + </rule> + <rule> + <name>DataflowAnomalyAnalysis</name> + <ruleset>Controversial Rules</ruleset> + </rule> + <rule> + <name>AvoidFinalLocalVariable</name> + <ruleset>Controversial Rules</ruleset> + </rule> + <rule> + <name>AvoidUsingShortType</name> + <ruleset>Controversial Rules</ruleset> + </rule> + <rule> + <name>AvoidUsingVolatile</name> + <ruleset>Controversial Rules</ruleset> + </rule> + <rule> + <name>AvoidUsingNativeCode</name> + <ruleset>Controversial Rules</ruleset> + </rule> + <rule> + <name>AvoidAccessibilityAlteration</name> + <ruleset>Controversial Rules</ruleset> + </rule> + <rule> + <name>DoNotCallGarbageCollectionExplicitly</name> + <ruleset>Controversial Rules</ruleset> + </rule> + <rule> + <name>MoreThanOneLogger</name> + <ruleset>Java Logging Rules</ruleset> + </rule> + <rule> + <name>LoggerIsNotStaticFinal</name> + <ruleset>Java Logging Rules</ruleset> + </rule> + <rule> + <name>SystemPrintln</name> + <ruleset>Java Logging Rules</ruleset> + </rule> + <rule> + <name>AvoidPrintStackTrace</name> + <ruleset>Java Logging Rules</ruleset> + </rule> + <rule> + <name>DuplicateImports</name> + <ruleset>Import Statement Rules</ruleset> + </rule> + <rule> + <name>DontImportJavaLang</name> + <ruleset>Import Statement Rules</ruleset> + </rule> + <rule> + <name>UnusedImports</name> + <ruleset>Import Statement Rules</ruleset> + </rule> + <rule> + <name>ImportFromSamePackage</name> + <ruleset>Import Statement Rules</ruleset> + </rule> + <rule> + <name>TooManyStaticImports</name> + <ruleset>Import Statement Rules</ruleset> + </rule> + <rule> + <name>ReplaceVectorWithList</name> + <ruleset>Migration Rules</ruleset> + </rule> + <rule> + <name>ReplaceHashtableWithMap</name> + <ruleset>Migration Rules</ruleset> + </rule> + <rule> + <name>ReplaceEnumerationWithIterator</name> + <ruleset>Migration Rules</ruleset> + </rule> + <rule> + <name>AvoidEnumAsIdentifier</name> + <ruleset>Migration Rules</ruleset> + </rule> + <rule> + <name>AvoidAssertAsIdentifier</name> + <ruleset>Migration Rules</ruleset> + </rule> + <rule> + <name>IntegerInstantiation</name> + <ruleset>Migration Rules</ruleset> + </rule> + <rule> + <name>ByteInstantiation</name> + <ruleset>Migration Rules</ruleset> + </rule> + <rule> + <name>ShortInstantiation</name> + <ruleset>Migration Rules</ruleset> + </rule> + <rule> + <name>LongInstantiation</name> + <ruleset>Migration Rules</ruleset> + </rule> + <rule> + <name>JUnit4TestShouldUseBeforeAnnotation</name> + <ruleset>Migration Rules</ruleset> + </rule> + <rule> + <name>JUnit4TestShouldUseAfterAnnotation</name> + <ruleset>Migration Rules</ruleset> + </rule> + <rule> + <name>JUnit4TestShouldUseTestAnnotation</name> + <ruleset>Migration Rules</ruleset> + </rule> + <rule> + <name>JUnit4SuitesShouldUseSuiteAnnotation</name> + <ruleset>Migration Rules</ruleset> + </rule> + <rule> + <name>JUnitUseExpected</name> + <ruleset>Migration Rules</ruleset> + </rule> + <rule> + <name>ProperCloneImplementation</name> + <ruleset>Clone Implementation Rules</ruleset> + </rule> + <rule> + <name>CloneThrowsCloneNotSupportedException</name> + <ruleset>Clone Implementation Rules</ruleset> + </rule> + <rule> + <name>CloneMethodMustImplementCloneable</name> + <ruleset>Clone Implementation Rules</ruleset> + </rule> + <rule> + <name>AvoidCatchingThrowable</name> + <ruleset>Strict Exception Rules</ruleset> + </rule> + <rule> + <name>SignatureDeclareThrowsException</name> + <ruleset>Strict Exception Rules</ruleset> + </rule> + <rule> + <name>ExceptionAsFlowControl</name> + <ruleset>Strict Exception Rules</ruleset> + </rule> + <rule> + <name>AvoidCatchingNPE</name> + <ruleset>Strict Exception Rules</ruleset> + </rule> + <rule> + <name>AvoidThrowingRawExceptionTypes</name> + <ruleset>Strict Exception Rules</ruleset> + </rule> + <rule> + <name>AvoidThrowingNullPointerException</name> + <ruleset>Strict Exception Rules</ruleset> + </rule> + <rule> + <name>AvoidRethrowingException</name> + <ruleset>Strict Exception Rules</ruleset> + </rule> + <rule> + <name>DoNotExtendJavaLangError</name> + <ruleset>Strict Exception Rules</ruleset> + </rule> + <rule> + <name>DoNotThrowExceptionInFinally</name> + <ruleset>Strict Exception Rules</ruleset> + </rule> + <rule> + <name>MethodReturnsInternalArray</name> + <ruleset>Security Code Guidelines</ruleset> + </rule> + <rule> + <name>ArrayIsStoredDirectly</name> + <ruleset>Security Code Guidelines</ruleset> + </rule> + <rule> + <name>BeanMembersShouldSerialize</name> + <ruleset>JavaBean Rules</ruleset> + </rule> + <rule> + <name>MissingSerialVersionUID</name> + <ruleset>JavaBean Rules</ruleset> + </rule> + <rule> + <name>EmptyFinalizer</name> + <ruleset>Finalizer Rules</ruleset> + </rule> + <rule> + <name>FinalizeOnlyCallsSuperFinalize</name> + <ruleset>Finalizer Rules</ruleset> + </rule> + <rule> + <name>FinalizeOverloaded</name> + <ruleset>Finalizer Rules</ruleset> + </rule> + <rule> + <name>FinalizeDoesNotCallSuperFinalize</name> + <ruleset>Finalizer Rules</ruleset> + </rule> + <rule> + <name>FinalizeShouldBeProtected</name> + <ruleset>Finalizer Rules</ruleset> + </rule> + <rule> + <name>AvoidCallingFinalize</name> + <ruleset>Finalizer Rules</ruleset> + </rule> + <rule> + <name>UseProperClassLoader</name> + <ruleset>J2EE Rules</ruleset> + </rule> + <rule> + <name>MDBAndSessionBeanNamingConvention</name> + <ruleset>J2EE Rules</ruleset> + </rule> + <rule> + <name>RemoteSessionInterfaceNamingConvention</name> + <ruleset>J2EE Rules</ruleset> + </rule> + <rule> + <name>LocalInterfaceSessionNamingConvention</name> + <ruleset>J2EE Rules</ruleset> + </rule> + <rule> + <name>LocalHomeNamingConvention</name> + <ruleset>J2EE Rules</ruleset> + </rule> + <rule> + <name>RemoteInterfaceNamingConvention</name> + <ruleset>J2EE Rules</ruleset> + </rule> + <rule> + <name>DoNotCallSystemExit</name> + <ruleset>J2EE Rules</ruleset> + </rule> + <rule> + <name>StaticEJBFieldShouldBeFinal</name> + <ruleset>J2EE Rules</ruleset> + </rule> + <rule> + <name>DoNotUseThreads</name> + <ruleset>J2EE Rules</ruleset> + </rule> + <rule> + <name>ShortVariable</name> + <ruleset>Naming Rules</ruleset> + </rule> + <rule> + <name>LongVariable</name> + <ruleset>Naming Rules</ruleset> + </rule> + <rule> + <name>ShortMethodName</name> + <ruleset>Naming Rules</ruleset> + </rule> + <rule> + <name>VariableNamingConventions</name> + <ruleset>Naming Rules</ruleset> + </rule> + <rule> + <name>MethodNamingConventions</name> + <ruleset>Naming Rules</ruleset> + </rule> + <rule> + <name>ClassNamingConventions</name> + <ruleset>Naming Rules</ruleset> + </rule> + <rule> + <name>AbstractNaming</name> + <ruleset>Naming Rules</ruleset> + </rule> + <rule> + <name>AvoidDollarSigns</name> + <ruleset>Naming Rules</ruleset> + </rule> + <rule> + <name>MethodWithSameNameAsEnclosingClass</name> + <ruleset>Naming Rules</ruleset> + </rule> + <rule> + <name>SuspiciousHashcodeMethodName</name> + <ruleset>Naming Rules</ruleset> + </rule> + <rule> + <name>SuspiciousConstantFieldName</name> + <ruleset>Naming Rules</ruleset> + </rule> + <rule> + <name>SuspiciousEqualsMethodName</name> + <ruleset>Naming Rules</ruleset> + </rule> + <rule> + <name>AvoidFieldNameMatchingTypeName</name> + <ruleset>Naming Rules</ruleset> + </rule> + <rule> + <name>AvoidFieldNameMatchingMethodName</name> + <ruleset>Naming Rules</ruleset> + </rule> + <rule> + <name>NoPackage</name> + <ruleset>Naming Rules</ruleset> + </rule> + <rule> + <name>PackageCase</name> + <ruleset>Naming Rules</ruleset> + </rule> + <rule> + <name>MisleadingVariableName</name> + <ruleset>Naming Rules</ruleset> + </rule> + <rule> + <name>BooleanGetMethodName</name> + <ruleset>Naming Rules</ruleset> + </rule> + <rule> + <name>NPathComplexity</name> + <ruleset>Code Size Rules</ruleset> + </rule> + <rule> + <name>ExcessiveMethodLength</name> + <ruleset>Code Size Rules</ruleset> + </rule> + <rule> + <name>ExcessiveParameterList</name> + <ruleset>Code Size Rules</ruleset> + </rule> + <rule> + <name>ExcessiveClassLength</name> + <ruleset>Code Size Rules</ruleset> + </rule> + <rule> + <name>CyclomaticComplexity</name> + <ruleset>Code Size Rules</ruleset> + </rule> + <rule> + <name>ExcessivePublicCount</name> + <ruleset>Code Size Rules</ruleset> + </rule> + <rule> + <name>TooManyFields</name> + <ruleset>Code Size Rules</ruleset> + </rule> + <rule> + <name>NcssMethodCount</name> + <ruleset>Code Size Rules</ruleset> + </rule> + <rule> + <name>NcssTypeCount</name> + <ruleset>Code Size Rules</ruleset> + </rule> + <rule> + <name>NcssConstructorCount</name> + <ruleset>Code Size Rules</ruleset> + </rule> + <rule> + <name>TooManyMethods</name> + <ruleset>Code Size Rules</ruleset> + </rule> + <rule> + <name>UnusedPrivateField</name> + <ruleset>Unused Code Rules</ruleset> + </rule> + <rule> + <name>UnusedLocalVariable</name> + <ruleset>Unused Code Rules</ruleset> + </rule> + <rule> + <name>UnusedPrivateMethod</name> + <ruleset>Unused Code Rules</ruleset> + </rule> + <rule> + <name>UnusedFormalParameter</name> + <ruleset>Unused Code Rules</ruleset> + </rule> + </rules> + <includeDerivedFiles>false</includeDerivedFiles> +</pmd> diff --git a/de.prob.ui/.project b/de.prob.ui/.project new file mode 100644 index 0000000000000000000000000000000000000000..5e8ce8b3b55f1d608527f8c37f5edb5e85e0510e --- /dev/null +++ b/de.prob.ui/.project @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>de.prob.ui</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>edu.umd.cs.findbugs.plugin.eclipse.findbugsBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + <nature>edu.umd.cs.findbugs.plugin.eclipse.findbugsNature</nature> + </natures> +</projectDescription> diff --git a/de.prob.ui/META-INF/MANIFEST.MF b/de.prob.ui/META-INF/MANIFEST.MF new file mode 100644 index 0000000000000000000000000000000000000000..f0347aa0492ac4260f66cb0be18ab7907e96574b --- /dev/null +++ b/de.prob.ui/META-INF/MANIFEST.MF @@ -0,0 +1,21 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: ProB Ui Plug-in +Bundle-SymbolicName: de.prob.ui;singleton:=true +Bundle-Version: 7.1.1 +Require-Bundle: org.eclipse.ui;bundle-version="[3.5.0,4.0.0)", + org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", + org.eclipse.core.resources;bundle-version="[3.5.0,4.0.0)", + org.eclipse.ui.ide;bundle-version="[3.5.0,4.0.0)", + de.prob.core;bundle-version="[9.1.0,9.2.0)", + org.eventb.core;bundle-version="[2.1.0,2.4.0)", + org.eclipse.core.expressions;bundle-version="[3.4.101,4.0.0)", + org.eclipse.gef;bundle-version="[3.5.0,4.0.0)" +Bundle-ActivationPolicy: lazy +Bundle-Vendor: HHU Düsseldorf STUPS Group +Bundle-Activator: de.prob.ui.ProbUiPlugin +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Export-Package: de.prob.ui +Bundle-ClassPath: lib/apache_xmlrpc.jar, + lib/ws_commons.jar, + . diff --git a/de.prob.ui/about.ini b/de.prob.ui/about.ini new file mode 100644 index 0000000000000000000000000000000000000000..2bd589b72ecab060e4fa1924080ba910f58a0014 --- /dev/null +++ b/de.prob.ui/about.ini @@ -0,0 +1,3 @@ +# Feature Branding for ProB +aboutText=ProB Model Checker (c) 2009 http://www.stups.uni-duesseldorf.de/ProB +featureImage=icons/prob.png diff --git a/de.prob.ui/about.properties b/de.prob.ui/about.properties new file mode 100644 index 0000000000000000000000000000000000000000..632c9e487fe97a77ae273a5b8d7917c4583722d3 --- /dev/null +++ b/de.prob.ui/about.properties @@ -0,0 +1,18 @@ +############################################################################### +# Copyright (c) 2006-2008 Heinrich-Heine University Dusseldorf. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# http://www.eclipse.org/legal/epl-v10.html +############################################################################### + +aboutText=ProB Plug-In for Rodin\n\ +\n\ +Version: {featureVersion}\n\ +\n\ +Copyright (c) 2005-2008 Heinrich-Heine University Dusseldorf. All rights reserved.\n\ +Visit http://www.stups.uni-duesseldorf.de\n\ +\n\ +This offering is powered by Eclipse technology and includes\n\ +Eclipse plug-ins that can be installed and used with other\n\ +Eclipse (3.3)-based offerings. diff --git a/de.prob.ui/build.properties b/de.prob.ui/build.properties new file mode 100644 index 0000000000000000000000000000000000000000..7bb2e5aa6d67c9fa9f937b447952842643f8bb36 --- /dev/null +++ b/de.prob.ui/build.properties @@ -0,0 +1,8 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml,\ + icons/,\ + lib/apache_xmlrpc.jar,\ + lib/ws_commons.jar diff --git a/de.prob.ui/icons/CBCInvariantCheck.gif b/de.prob.ui/icons/CBCInvariantCheck.gif new file mode 100644 index 0000000000000000000000000000000000000000..69e6e6159803877c2b4908d81eb7889438de0a64 Binary files /dev/null and b/de.prob.ui/icons/CBCInvariantCheck.gif differ diff --git a/de.prob.ui/icons/CBCInvariantCheck.png b/de.prob.ui/icons/CBCInvariantCheck.png new file mode 100644 index 0000000000000000000000000000000000000000..1798872015391544470797ed2156a26dfb42b846 Binary files /dev/null and b/de.prob.ui/icons/CBCInvariantCheck.png differ diff --git a/de.prob.ui/icons/Consistency.png b/de.prob.ui/icons/Consistency.png new file mode 100644 index 0000000000000000000000000000000000000000..7b7377de61aaf5aeb7b2e5ee4161b806cd0b602f Binary files /dev/null and b/de.prob.ui/icons/Consistency.png differ diff --git a/de.prob.ui/icons/DeadlockCheck.png b/de.prob.ui/icons/DeadlockCheck.png new file mode 100644 index 0000000000000000000000000000000000000000..5114d93404010962285ea36e10eba6b05331615f Binary files /dev/null and b/de.prob.ui/icons/DeadlockCheck.png differ diff --git a/de.prob.ui/icons/LTL_Modelcheck.png b/de.prob.ui/icons/LTL_Modelcheck.png new file mode 100644 index 0000000000000000000000000000000000000000..6cb2b32ac8eefe389a4a717991062e4ba683c0ca Binary files /dev/null and b/de.prob.ui/icons/LTL_Modelcheck.png differ diff --git a/de.prob.ui/icons/add_att.gif b/de.prob.ui/icons/add_att.gif new file mode 100644 index 0000000000000000000000000000000000000000..252d7ebcb8c74d6e5de66ef0eb8856622a0e9d89 Binary files /dev/null and b/de.prob.ui/icons/add_att.gif differ diff --git a/de.prob.ui/icons/anim.gif b/de.prob.ui/icons/anim.gif new file mode 100644 index 0000000000000000000000000000000000000000..c2a7d7ea55a6a730bbc4797d03fb74a394be2472 Binary files /dev/null and b/de.prob.ui/icons/anim.gif differ diff --git a/de.prob.ui/icons/back.gif b/de.prob.ui/icons/back.gif new file mode 100644 index 0000000000000000000000000000000000000000..4fb41501036b940c99c8a839d7459c88eb98385c Binary files /dev/null and b/de.prob.ui/icons/back.gif differ diff --git a/de.prob.ui/icons/checked.gif b/de.prob.ui/icons/checked.gif new file mode 100644 index 0000000000000000000000000000000000000000..0b789f79f6605af5e2466ab2995e692402a28b98 Binary files /dev/null and b/de.prob.ui/icons/checked.gif differ diff --git a/de.prob.ui/icons/ctx_obj.gif b/de.prob.ui/icons/ctx_obj.gif new file mode 100644 index 0000000000000000000000000000000000000000..63cabc6b41561a2093300b89f1fc3a7b02026e93 Binary files /dev/null and b/de.prob.ui/icons/ctx_obj.gif differ diff --git a/de.prob.ui/icons/disabled.png b/de.prob.ui/icons/disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..b97907a67a1a8c08f5ada79dc7d8da18ddd05916 Binary files /dev/null and b/de.prob.ui/icons/disabled.png differ diff --git a/de.prob.ui/icons/doubleclick.png b/de.prob.ui/icons/doubleclick.png new file mode 100644 index 0000000000000000000000000000000000000000..142e3a91ae9a4ed207cb3265bfa3579552ff4bff Binary files /dev/null and b/de.prob.ui/icons/doubleclick.png differ diff --git a/de.prob.ui/icons/enabled.png b/de.prob.ui/icons/enabled.png new file mode 100644 index 0000000000000000000000000000000000000000..6c2ec9ada9c20cb6557eee20302b067d40257ea5 Binary files /dev/null and b/de.prob.ui/icons/enabled.png differ diff --git a/de.prob.ui/icons/filter_ps.gif b/de.prob.ui/icons/filter_ps.gif new file mode 100644 index 0000000000000000000000000000000000000000..6fe6f0e10a11203f4297dcdff4288ae6f2698fe7 Binary files /dev/null and b/de.prob.ui/icons/filter_ps.gif differ diff --git a/de.prob.ui/icons/forward.gif b/de.prob.ui/icons/forward.gif new file mode 100644 index 0000000000000000000000000000000000000000..e2f8c3e1feeb0541239db4061812008af2225105 Binary files /dev/null and b/de.prob.ui/icons/forward.gif differ diff --git a/de.prob.ui/icons/mch_obj.gif b/de.prob.ui/icons/mch_obj.gif new file mode 100644 index 0000000000000000000000000000000000000000..62bea01bea245b4feff1d3cd5ad9f7db2857bd62 Binary files /dev/null and b/de.prob.ui/icons/mch_obj.gif differ diff --git a/de.prob.ui/icons/new_prob_mini.png b/de.prob.ui/icons/new_prob_mini.png new file mode 100644 index 0000000000000000000000000000000000000000..36d5d6278be2e2226de7b9d4d0fc9da720e47f1b Binary files /dev/null and b/de.prob.ui/icons/new_prob_mini.png differ diff --git a/de.prob.ui/icons/overlay1.png b/de.prob.ui/icons/overlay1.png new file mode 100644 index 0000000000000000000000000000000000000000..28c7e3fb85018ffeb706ea05d01fc1eead0e8e49 Binary files /dev/null and b/de.prob.ui/icons/overlay1.png differ diff --git a/de.prob.ui/icons/overlay2.png b/de.prob.ui/icons/overlay2.png new file mode 100644 index 0000000000000000000000000000000000000000..3158ff78de35e50d5298eccb89cf5a1e27eedc89 Binary files /dev/null and b/de.prob.ui/icons/overlay2.png differ diff --git a/de.prob.ui/icons/prob.png b/de.prob.ui/icons/prob.png new file mode 100644 index 0000000000000000000000000000000000000000..36d5d6278be2e2226de7b9d4d0fc9da720e47f1b Binary files /dev/null and b/de.prob.ui/icons/prob.png differ diff --git a/de.prob.ui/icons/prob_animation_dialog.png b/de.prob.ui/icons/prob_animation_dialog.png new file mode 100755 index 0000000000000000000000000000000000000000..94771f2a9d619b9e9e485af3d4eda8cef5f00139 Binary files /dev/null and b/de.prob.ui/icons/prob_animation_dialog.png differ diff --git a/de.prob.ui/icons/prob_mini_logo.gif b/de.prob.ui/icons/prob_mini_logo.gif new file mode 100644 index 0000000000000000000000000000000000000000..c6867d469651f80e12a2021e619563e3f2a39b64 Binary files /dev/null and b/de.prob.ui/icons/prob_mini_logo.gif differ diff --git a/de.prob.ui/icons/refresh.gif b/de.prob.ui/icons/refresh.gif new file mode 100644 index 0000000000000000000000000000000000000000..e3831471a6592da14f53b1e7c5a2f7d6a92d9937 Binary files /dev/null and b/de.prob.ui/icons/refresh.gif differ diff --git a/de.prob.ui/icons/resume.gif b/de.prob.ui/icons/resume.gif new file mode 100644 index 0000000000000000000000000000000000000000..16f4e251756e92ed4c271c57c483629b824961e7 Binary files /dev/null and b/de.prob.ui/icons/resume.gif differ diff --git a/de.prob.ui/icons/search_src.gif b/de.prob.ui/icons/search_src.gif new file mode 100644 index 0000000000000000000000000000000000000000..d540a01f4d9eeb9d2951f30cee165c7370e9fc6a Binary files /dev/null and b/de.prob.ui/icons/search_src.gif differ diff --git a/de.prob.ui/icons/splash_overlay.png b/de.prob.ui/icons/splash_overlay.png new file mode 100644 index 0000000000000000000000000000000000000000..39638f0bf2bc9a95ae5944509ee8fb841f5915de Binary files /dev/null and b/de.prob.ui/icons/splash_overlay.png differ diff --git a/de.prob.ui/icons/splash_overlay_x.png b/de.prob.ui/icons/splash_overlay_x.png new file mode 100644 index 0000000000000000000000000000000000000000..e5c9d55b3a4a502bbf9fe781dc4f3a1298f694a0 Binary files /dev/null and b/de.prob.ui/icons/splash_overlay_x.png differ diff --git a/de.prob.ui/icons/star.png b/de.prob.ui/icons/star.png new file mode 100644 index 0000000000000000000000000000000000000000..3e9110f9753f0562ed89e5de37647a5afcd12dca Binary files /dev/null and b/de.prob.ui/icons/star.png differ diff --git a/de.prob.ui/icons/timeout.png b/de.prob.ui/icons/timeout.png new file mode 100644 index 0000000000000000000000000000000000000000..4172b3bc177505521afee2c6fa62bf75f2ffde15 Binary files /dev/null and b/de.prob.ui/icons/timeout.png differ diff --git a/de.prob.ui/icons/unchecked.gif b/de.prob.ui/icons/unchecked.gif new file mode 100644 index 0000000000000000000000000000000000000000..d32dcba09e4c68c6df3d1c22a91080cf08a065fe Binary files /dev/null and b/de.prob.ui/icons/unchecked.gif differ diff --git a/de.prob.ui/lib/apache_xmlrpc.jar b/de.prob.ui/lib/apache_xmlrpc.jar new file mode 100644 index 0000000000000000000000000000000000000000..99231bdeab2aaee659bf3f5a995ee03a7d761cd2 Binary files /dev/null and b/de.prob.ui/lib/apache_xmlrpc.jar differ diff --git a/de.prob.ui/lib/ws_commons.jar b/de.prob.ui/lib/ws_commons.jar new file mode 100644 index 0000000000000000000000000000000000000000..5d97cf53e868e4f277881465c07d98c2ac5e87a7 Binary files /dev/null and b/de.prob.ui/lib/ws_commons.jar differ diff --git a/de.prob.ui/plugin.xml b/de.prob.ui/plugin.xml new file mode 100644 index 0000000000000000000000000000000000000000..418f09996e890110f3a225e78c7734afe6ce9490 --- /dev/null +++ b/de.prob.ui/plugin.xml @@ -0,0 +1,1037 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?eclipse version="3.2"?> +<plugin> + + + <extension + point="org.eclipse.ui.preferencePages"> + <page + class="de.prob.ui.eventb.ClassicPreferences" + id="de.prob.ui.probclassic" + name="ProB Classic" + category="probpreferences"> + </page> + </extension> + +<!-- <extension + point="org.eclipse.ui.actionSets"> + <actionSet + id="probConfigurationActions" + label="ProBConfiguration Action" + visible="true"> + <action + class="de.prob.ui.eventb.ShowProBConfigurations" + icon="icons/new_prob_mini.png" + id="showProBConfigurations" + label="Show ProB Configurations" + style="pulldown" + toolbarPath="org.eclipse.debug.ui.launchActionSet"> + </action> + </actionSet> + </extension> +--> + <extension + point="org.eclipse.ui.views"> + <category + id="de.hhu.stups.prob" + name="ProB"/> + <view + allowMultiple="false" + category="de.hhu.stups.prob" + class="de.prob.ui.operationview.OperationViewPart" + id="de.prob.ui.OperationView" + name="Events"/> + <view + allowMultiple="false" + category="de.hhu.stups.prob" + class="de.prob.ui.stateview.StateViewPart" + id="de.prob.ui.StateView" + name="State"/> + <view + allowMultiple="false" + category="de.hhu.stups.prob" + class="de.prob.ui.errorview.StateErrorView" + id="de.prob.ui.EventErrorView" + name="Event Error View" + restorable="true"> + </view> + <view + allowMultiple="true" + category="de.hhu.stups.prob" + class="de.prob.ui.LimitedLogView" + id="de.prob.ui.TemplogView" + name="ProB Performance Log" + restorable="true"> + </view> + <view + allowMultiple="false" + category="de.hhu.stups.prob" + class="de.prob.ui.historyview.HistoryView" + id="de.prob.ui.HistoryView" + name="History" + restorable="true"> + </view> + <view + category="de.hhu.stups.prob" + class="de.prob.ui.ticket.LogView" + id="de.prob.ui.log" + name="ProB Log View" + restorable="true"> + </view> + <view + category="de.hhu.stups.prob" + class="de.prob.ui.ltl.CounterExampleView" + id="de.prob.ui.ltl.CounterExampleView" + name="Ltl Counter-Example" + restorable="true"> + </view> + </extension> + <extension + point="de.prob.core.animation"> + <listener + class="de.prob.ui.StaticListenerRegistry"> + </listener> + </extension> + <extension + point="de.prob.core.lifecycle"> + <listener + class="de.prob.ui.StaticListenerRegistry"> + </listener> + </extension> + + + <extension + point="org.eclipse.ui.preferencePages"> + <page + class="de.prob.ui.ProBGeneralPreferences" + id="probpreferences" + name="ProB"> + </page> + </extension> + <!-- + <extension + point="org.eclipse.ui.actionSets"> + <actionSet + description="Web Action Set" + id="de.prob.core.ticket.actionSet" + label="Web Action Set" + visible="true"> + <menu + id="probMenu" + label="ProB"> + <separator + name="bugReport"> + </separator> + </menu> + + <action + class="de.prob.ui.ticket.OpenBugReportWebsite" + id="OpenBugReportWebsite" + label="Open Bugreport Website" + menubarPath="probMenu/bugReport"> + </action> + <action + class="de.prob.ui.ticket.NewBugReportAction" + id="NewBugReportAction" + label="Submit Bugreport" + menubarPath="probMenu/bugReport"> + </action> + </actionSet> + </extension> + --> + + <extension + point="org.eclipse.ui.commands"> + <category + description="ProB commands" + id="de.prob.ui.commands.category" + name="ProB"> + </category> + <command + categoryId="de.prob.ui.commands.category" + id="de.prob.ui.openWebsite" + name="Open Website"> + <commandParameter + id="de.prob.ui.openwebsite.url" + name="URL" + optional="false"> + </commandParameter> + </command> + <command + categoryId="de.prob.ui.commands.category" + id="de.prob.ui.bugreport" + name="Submit Bugreport"> + </command> + <command + categoryId="de.prob.ui.commands.category" + id="de.prob.ui.probconfiguration" + name="ProB Configuration Wizard"> + </command> + <command + description="Show a state item in the history view" + id="de.prob.ui.command.showInHistory" + name="ShowInHistory"> + </command> + <command + categoryId="de.prob.ui.commands.category" + id="de.prob.ui.ltl_modelchecking" + name="LTL Modelchecking"> + </command> + <command + categoryId="de.prob.ui.commands.category" + id="de.prob.ui.consistency_checking" + name="Consistencychecking"> + </command> + + + <command + defaultHandler="de.prob.ui.operationview.DoubleClickBehaviorHandler" + id="de.prob.ui.doubleclickbehaviour" + name="Double Click Behaviour"> + <commandParameter + id="org.eclipse.ui.commands.radioStateParameter" + name="State" + optional="false"> + </commandParameter> + <state + class="org.eclipse.ui.handlers.RadioState:NORMAL" + id="org.eclipse.ui.commands.radioState"> + </state> +</command> + <command + id="de.prob.ui.randomoperation" + name="Execute Random Events"> + <commandParameter + id="de.prob.ui.randomoperation.steps" + name="Number of Steps" + optional="false"> + </commandParameter> + </command> + <command + id="de.prob.ui.filtermenu" + name="Filter Operations Menu"> + </command> + <command + id="de.prob.ui.filter_enabled_only" + name="Show only enabled Events"> + <state + class="org.eclipse.ui.handlers.RegistryToggleState:false" + id="org.eclipse.ui.commands.toggleState"> + </state> + </command> + <command + id="de.prob.ui.restart" + name="Restart Animation"> + </command> + <command + id="de.prob.ui.load_shortest_trace" + name="Load shortest Trace"> + </command> + <command + id="de.prob.ui.add_formula" + name="Add new watched formula"> + </command> + <command + id="de.prob.ui.history.back" + name="History Back"> + <commandParameter + id="de.prob.ui.history.pos" + name="Position" + optional="true"> + </commandParameter> + </command> + <command + id="de.prob.ui.history.forward" + name="History Forward"> + <commandParameter + id="de.prob.ui.history.pos" + name="Position" + optional="true"> + </commandParameter> + </command> + <command + id="de.prob.ui.starteventbanimation" + name="Event-B Animate / Model Check"> + </command> + <command + id="de.prob.ui.navigator.context" + name="Project Explorer Context Menu"> + </command> + <command + id="de.prob.ui.create_config" + name="Create Configuration"> + </command> + <command + id="de.prob.ui.classic.export" + name="Export for Classic ProB"> + </command> + <command + id="de.prob.ui.classic.open" + name="Open in Classic ProB"> + </command> + <command + id="de.prob.ui.execute_event" + name="Execute an event"> + <commandParameter + id="de.prob.ui.operation" + name="Operation id" + optional="true"> + </commandParameter> + </command> + <command + id="de.prob.ui.stateview.toggleShowDuplicates" + name="Toggle Show Duplicates"> + <state class="org.eclipse.jface.commands.ToggleState" + id="de.prob.ui.stateview.duplicateFilterState" /> + </command> + <command + id="de.prob.ui.show_parameter_dialog" + name="Show Parameter Dialog"> + </command> + <command + categoryId="de.prob.ui.commands.category" + id="de.prob.ui.deadlock_check" + name="Check for Deadlock Freedom"> + </command> + <command + categoryId="de.prob.ui.commands.category" + id="de.prob.ui.invariant_check" + name="Check for Invariant Preservation"> + </command> + <command + categoryId="de.prob.ui.commands.category" + id="de.prob.ui.opview.checks" + name="Checks"> + </command> + <command + categoryId="de.prob.ui.commands.category" + id="de.prob.ui.exampleanalyzecommand" + name="Example for Analyze Commands"> + </command> + <!-- <command + id="de.prob.ui.startdmc" + name="Start Distributed Modelcheck"> + </command> + --> + <command defaultHandler="de.prob.ui.ltl.CounterExampleViewMenuHandler" + id="de.prob.ui.ltl.counterexampleviewmenuhandler" + name="CounterExampleView Menu Command"> + <commandParameter + id="org.eclipse.ui.commands.radioStateParameter" + name="org.eclipse.ui.commands.radiostateparameter"> + </commandParameter> + <state + class="org.eclipse.ui.handlers.RadioState" + id="org.eclipse.ui.commands.radioState"> + </state> + </command> + <command defaultHandler="de.prob.ui.ltl.CEHistoryHandler" + id="de.prob.ui.ltl.showCounterexampleInHistory" + name="Show counter-example in history"> + </command> + </extension> + <extension + point="org.eclipse.ui.handlers"> + <handler + commandId="de.prob.ui.openWebsite"> + <class + class="de.prob.ui.internal.OpenWebsiteCommand"> + </class> + </handler> + <handler + commandId="de.prob.ui.bugreport"> + <class + class="de.prob.ui.ticket.SubmitBugreportCommand"> + </class> + </handler> + <handler + commandId="de.prob.ui.probconfiguration"> + <class + class="de.prob.ui.internal.ShowProBConfigCommand"> + </class> + </handler> + <handler + commandId="de.prob.ui.command.showInHistory"> + <class + class="de.prob.ui.stateview.ShowInHistoryHandler"> + </class> + </handler> + <handler + commandId="de.prob.ui.ltl_modelchecking"> + <enabledWhen> + <with variable="de.prob.core.model_loaded"> + <equals + value="enabled"> + </equals> + </with> + </enabledWhen> + <class + class="de.prob.ui.ltl.LtlCommand"> + </class> + </handler> + <handler + commandId="de.prob.ui.consistency_checking"> + <enabledWhen> + <with variable="de.prob.core.model_loaded"> + <equals + value="enabled"> + </equals> + </with> + </enabledWhen> + <class + class="de.prob.ui.eventb.ConsistencyCheckCommand"> + </class> + </handler> + <handler + commandId="de.prob.ui.randomoperation"> + <enabledWhen> + <with variable="de.prob.core.model_loaded"> + <equals + value="enabled"> + </equals> + </with> + </enabledWhen> + <class + class="de.prob.ui.operationview.ExecuteRandomHandler"> + </class> + </handler> + <handler + commandId="de.prob.ui.filter_enabled_only"> + <class + class="de.prob.ui.operationview.ShowOnlyEnabledOpsHandler"> + </class> + </handler> + <handler + commandId="de.prob.ui.filtermenu"> + <class + class="de.prob.ui.operationview.NullHandler"> + </class> + + </handler> + <handler + commandId="de.prob.ui.restart"> + <class + class="de.prob.ui.operationview.RestartHandler"> + </class> + <enabledWhen> + <with + variable="de.prob.core.model_loaded"> + <equals + value="enabled"> + </equals> + </with> + </enabledWhen> + </handler> + <handler + commandId="de.prob.ui.load_shortest_trace"> + <enabledWhen> + <with + variable="de.prob.core.model_loaded"> + <equals + value="enabled"> + </equals> + </with> + </enabledWhen> + <class + class="de.prob.ui.stateview.LoadShortestTraceHandler"> + </class> + </handler> + <handler + commandId="de.prob.ui.add_formula"> + <class + class="de.prob.ui.stateview.AddFormulaHandler"> + </class> + <enabledWhen> + <with + variable="de.prob.core.model_loaded"> + <equals + value="enabled"> + </equals> + </with> + </enabledWhen> + </handler> + <handler + commandId="de.prob.ui.history.back"> + <class + class="de.prob.ui.operationview.HistoryBackHandler"> + </class> + <enabledWhen> + <and> + <with + variable="de.prob.core.model_loaded"> + <equals + value="enabled"> + </equals> + </with> + <with + variable="de.prob.core.history.backward_service"> + <equals + value="enabled"> + </equals> + </with> + </and> + </enabledWhen> + </handler> + <handler + commandId="de.prob.ui.history.forward"> + <class + class="de.prob.ui.operationview.HistoryForwardHandler"> + </class> + <enabledWhen> + <and> + <with + variable="de.prob.core.model_loaded"> + <equals + value="enabled"> + </equals> + </with> + <with + variable="de.prob.core.history.forward_service"> + <equals + value="enabled"> + </equals> + </with> + </and> + </enabledWhen> + </handler> + <handler + commandId="de.prob.ui.starteventbanimation"> + <class + class="de.prob.ui.eventb.StartAnimationHandler"> + </class> + <enabledWhen> + <with + variable="selection"> + <iterate + operator="or"> + <or> + <instanceof + value="org.eventb.core.IEventBRoot"> + </instanceof> + <and> + <instanceof + value="org.eclipse.core.resources.IResource"> + </instanceof> + <or> + <test + forcePluginActivation="true" + property="org.eclipse.core.resources.extension" + value="bum"> + </test> + <test + forcePluginActivation="true" + property="org.eclipse.core.resources.extension" + value="buc"> + </test> + </or> + </and> + </or> + </iterate> + </with> + </enabledWhen> + </handler> + <handler + commandId="de.prob.ui.create_config"> + <class + class="de.prob.ui.eventb.CreateConfigurationHandler"> + </class> + <enabledWhen> + <with + variable="selection"> + <iterate + operator="or"> + <instanceof + value="org.eventb.core.IEventBRoot"> + </instanceof> + </iterate> + </with> + </enabledWhen> + </handler> + <handler + commandId="de.prob.ui.classic.export"> + <class + class="de.prob.ui.eventb.ExportClassicHandler"> + </class> + <enabledWhen> + <with + variable="selection"> + <iterate + operator="or"> + <instanceof + value="org.eventb.core.IEventBRoot"> + </instanceof> + </iterate> + </with> + </enabledWhen> + </handler> + <handler + commandId="de.prob.ui.classic.open"> + <class + class="de.prob.ui.eventb.OpenClassicHandler"> + </class> + <enabledWhen> + <with + variable="selection"> + <iterate + operator="or"> + <instanceof + value="org.eventb.core.IEventBRoot"> + </instanceof> + </iterate> + </with> + </enabledWhen> + </handler> + <handler + commandId="de.prob.ui.execute_event"> + <class + class="de.prob.ui.operationview.ExecuteEventHandler"> + </class> + <enabledWhen> + <with + variable="de.prob.core.model_loaded"> + <equals + value="enabled"> + </equals> + </with> + </enabledWhen> + </handler> + <handler + commandId="de.prob.ui.stateview.toggleShowDuplicates"> + <class + class="de.prob.ui.stateview.ToggleShowDuplicatesHandler"> + </class> + <enabledWhen> + <with + variable="de.prob.core.model_loaded"> + <equals + value="enabled"> + </equals> + </with> + </enabledWhen> + </handler> + <handler + commandId="de.prob.ui.show_parameter_dialog"> + <class + class="de.prob.ui.operationview.ShowParameterDialogHandler"> + </class> + </handler> + <handler + commandId="de.prob.ui.deadlock_check"> + <class class="de.prob.ui.deadlock.DeadlockCheckHandler"/> + <enabledWhen> + <with variable="de.prob.core.model_loaded"> + <equals + value="enabled"> + </equals> + </with> + </enabledWhen> + </handler> + <handler + commandId="de.prob.ui.invariant_check"> + <class class="de.prob.ui.invcheck.InvariantCheckHandler"/> + <enabledWhen> + <with variable="de.prob.core.model_loaded"> + <equals + value="enabled"> + </equals> + </with> + </enabledWhen> + </handler> + <handler + commandId="de.prob.ui.opview.checks"> + <class class="de.prob.ui.eventb.ConsistencyCheckCommand" /> + <enabledWhen> + <with variable="de.prob.core.model_loaded"> + <equals + value="enabled"> + </equals> + </with> + </enabledWhen> + + </handler> + <handler + commandId="de.prob.ui.exampleanalyzecommand"> + <class + class="de.prob.ui.internal.InvariantAnalyzeHandler"> + </class> + </handler> +<!-- <handler + commandId="de.prob.ui.startdmc"> + <class + class="de.prob.ui.eventb.StartDistributedModelcheckHandler"> + </class> + <enabledWhen> + <with + variable="selection"> + <iterate + operator="or"> + <instanceof + value="org.eventb.core.IEventBRoot"> + </instanceof> + </iterate> + </with> + </enabledWhen> + </handler> --> + </extension> + <extension + point="org.eclipse.ui.menus"> + <menuContribution + locationURI="menu:contact"> + <command + commandId="de.prob.ui.openWebsite" + label="Open ProB Website" + mnemonic="W" + style="push"> + <parameter + name="de.prob.ui.openwebsite.url" + value="http://www.stups.uni-duesseldorf.de/ProB"> + </parameter> + </command> + <command + commandId="de.prob.ui.openWebsite" + label="Open Bugtracker Website" + mnemonic="W" + style="push"> + <parameter + name="de.prob.ui.openwebsite.url" + value="https://cobra.cs.uni-duesseldorf.de/trac/newticket?type=bug&priority=major&component=Eclipse%20Plugin&keywords=user%20discovered%20bug"> + </parameter> + </command> + <command + commandId="de.prob.ui.bugreport" + label="Submit bugreport" + mnemonic="B" + style="push"> + </command> + </menuContribution> + + <menuContribution + locationURI="toolbar:de.prob.ui.StateView"> + <command + commandId="de.prob.ui.load_shortest_trace" + icon="icons/search_src.gif" + label="Load shortest trace" + style="push"> + </command> + <command + commandId="de.prob.ui.add_formula" + icon="icons/add_att.gif" + label="Add new Formula" + style="push"> + </command> + <command + commandId="de.prob.ui.stateview.toggleShowDuplicates" + icon="icons/filter_ps.gif" + label="Filter Duplicate Variables" + style="toggle"> + </command> + </menuContribution> + <menuContribution + locationURI="popup:de.prob.ui.StateView"> + <command + commandId="de.prob.ui.command.showInHistory" + label="Show item in history" + style="push"> + </command> + </menuContribution> + + <menuContribution + locationURI="toolbar:de.prob.ui.OperationView"> + <command + commandId="de.prob.ui.opview.checks" + label="Checks" + style="pulldown"> + </command> + <command + commandId="de.prob.ui.doubleclickbehaviour" + icon="icons/doubleclick.png" + label="Double Click Behaviour" + style="pulldown"> + </command> + <command + commandId="de.prob.ui.randomoperation" + icon="icons/resume.gif" + label="Execute Random Operations" + style="pulldown"> + </command> + <command + commandId="de.prob.ui.filtermenu" + icon="icons/filter_ps.gif" + label="Filter" + style="pulldown"> + </command> + <command + commandId="de.prob.ui.restart" + icon="icons/refresh.gif" + label="Restart Animation" + style="push"> + </command> + <command + commandId="de.prob.ui.history.back" + icon="icons/back.gif" + label="History Back" + style="pulldown"> + </command> + <command + commandId="de.prob.ui.history.forward" + icon="icons/forward.gif" + label="History Forward" + style="pulldown"> + </command> + </menuContribution> + <menuContribution + locationURI="menu:de.prob.ui.doubleclickbehaviour"> + <command + commandId="de.prob.ui.doubleclickbehaviour" + label="First solution for Parameters" + style="radio"> + <parameter + name="org.eclipse.ui.commands.radioStateParameter" + value="NORMAL"> + </parameter> + </command> + <command + commandId="de.prob.ui.doubleclickbehaviour" + label="Random solution for Parameters" + style="radio"> + <parameter + name="org.eclipse.ui.commands.radioStateParameter" + value="RANDOM"> + </parameter> + </command> + <command + commandId="de.prob.ui.doubleclickbehaviour" + label="Open Dialog" + style="radio"> + <parameter + name="org.eclipse.ui.commands.radioStateParameter" + value="DIALOG"> + </parameter> + </command> + </menuContribution> + <menuContribution + locationURI="menu:de.prob.ui.randomoperation"> + <command + commandId="de.prob.ui.randomoperation" + label="Execute 1 Step" + style="push"> + <parameter + name="de.prob.ui.randomoperation.steps" + value="1"> + </parameter> + </command> + <command + commandId="de.prob.ui.randomoperation" + label="Execute 5 Steps" + style="push"> + <parameter + name="de.prob.ui.randomoperation.steps" + value="5"> + </parameter> + </command> + <command + commandId="de.prob.ui.randomoperation" + label="Execute 10 Steps" + style="push"> + <parameter + name="de.prob.ui.randomoperation.steps" + value="10"> + </parameter> + </command> + <command + commandId="de.prob.ui.randomoperation" + label=" Enter Number of Steps" + style="push"> + <parameter + name="de.prob.ui.randomoperation.steps" + value="-1"> + </parameter> + </command> + </menuContribution> + <menuContribution + locationURI="menu:de.prob.ui.filtermenu"> + <command + commandId="de.prob.ui.filter_enabled_only" + label="Show only enabled Events" + style="toggle"> + </command> + </menuContribution> + <menuContribution + class="de.prob.ui.operationview.HistoryBackwardMenu" + locationURI="menu:de.prob.ui.history.back"> + </menuContribution> + <menuContribution + class="de.prob.ui.operationview.HistoryForwardMenu" + locationURI="menu:de.prob.ui.history.forward"> + </menuContribution> + <menuContribution + locationURI="popup:fr.systerel.explorer.navigator.view"> + <separator + name="de.prob.ui.separator2" + visible="true"> + </separator> + <command + commandId="de.prob.ui.starteventbanimation" + icon="icons/prob.png" + label="Start Animation / Model Checking" + style="push"> + <visibleWhen> + <with + variable="selection"> + <iterate + operator="or"> + <instanceof + value="org.eventb.core.IEventBRoot"> + </instanceof> + </iterate> + </with> + </visibleWhen> + </command> + <!-- <command + commandId="de.prob.ui.startdmc" + icon="icons/prob.png" + label="Start Distributed Modelcheck" + style="push"> + <visibleWhen> + <with + variable="selection"> + <iterate + operator="or"> + <instanceof + value="org.eventb.core.IEventBRoot"> + </instanceof> + </iterate> + </with> + </visibleWhen> + </command> + --> + <menu + commandId="de.prob.ui.navigator.context" + icon="icons/new_prob_mini.png" + id="more_commands" + label="ProB Classic ..."> + <visibleWhen> + <with + variable="selection"> + <iterate + operator="or"> + <instanceof + value="org.eventb.core.IEventBRoot"> + </instanceof> + </iterate> + </with> + </visibleWhen> + <command + commandId="de.prob.ui.classic.export" + icon="icons/prob_mini_logo.gif" + label="Export for use in ProB classic" + style="push"> + </command> + <command + commandId="de.prob.ui.classic.open" + icon="icons/prob_mini_logo.gif" + label="Open in ProB classic" + style="push"> + </command> + </menu> + <separator + name="de.prob.ui.separator1" + visible="true"> + </separator> + </menuContribution> + <menuContribution + class="de.prob.ui.operationview.ParameterMenu" + locationURI="popup:de.prob.ui.OperationView"> + </menuContribution> + <menuContribution + allPopups="false" + locationURI="menu:prob"> + </menuContribution> + <menuContribution + locationURI="menu:de.prob.ui.opview.checks"> + <command + commandId="de.prob.ui.consistency_checking" + icon="icons/Consistency.png" + label="Model Checking" + mnemonic="C" + style="push"> + </command> + <command + commandId="de.prob.ui.ltl_modelchecking" + icon="icons/LTL_Modelcheck.png" + label="LTL Model Checking" + mnemonic="L" + style="push"> + </command> + <command + commandId="de.prob.ui.deadlock_check" + icon="icons/DeadlockCheck.png" + label="Deadlock Freedom Checking" + mnemonic="D" + style="push"> + </command> + <command + commandId="de.prob.ui.invariant_check" + icon="icons/CBCInvariantCheck.png" + label="Invariant Preservation Checking" + mnemonic="I" + style="push"> + </command> + </menuContribution> + <!-- + <menuContribution + allPopups="false" + locationURI="menu:analyze"> + <command + commandId="de.prob.ui.exampleanalyzecommand" + label="Analyze Invariant" + mnemonic="I" + style="toggle"> + </command> + </menuContribution> + --> + <menuContribution locationURI="menu:de.prob.ui.ltl.CounterExampleView"> + <command commandId="de.prob.ui.ltl.counterexampleviewmenuhandler" + label="Show as a table view" + style="radio"> + <parameter + name="org.eclipse.ui.commands.radioStateParameter" + value="Table"> + </parameter> + </command> + <command commandId="de.prob.ui.ltl.counterexampleviewmenuhandler" + label="Show as a tree view" + style="radio"> + <parameter + name="org.eclipse.ui.commands.radioStateParameter" + value="Tree"> + </parameter> + </command> + <command commandId="de.prob.ui.ltl.showCounterexampleInHistory" + label="Show the counter-example in the history"> + </command> + </menuContribution> + + </extension> + <extension + point="org.eclipse.ui.services"> + <sourceProvider + provider="de.prob.ui.services.ModelLoadedProvider"> + <variable + name="de.prob.core.model_loaded" + priorityLevel="workbench"> + </variable> + </sourceProvider> + <sourceProvider + provider="de.prob.ui.services.HistoryActiveProvider"> + <variable + name="de.prob.core.history.forward_service" + priorityLevel="workbench"> + </variable> + <variable + name="de.prob.core.history.backward_service" + priorityLevel="workbench"> + </variable> + </sourceProvider> + </extension> +</plugin> diff --git a/de.prob.ui/src/de/prob/ui/DialogHelpers.java b/de.prob.ui/src/de/prob/ui/DialogHelpers.java new file mode 100644 index 0000000000000000000000000000000000000000..0af6d4473c1dbab39f204a2c97755c033df7ab6d --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/DialogHelpers.java @@ -0,0 +1,31 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.ui; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; + +public final class DialogHelpers { + + private DialogHelpers() { + } + + public static GridLayout createSimpleGroupLayout() { + GridLayout groupLayout = new GridLayout(); + groupLayout.numColumns = 1; + return groupLayout; + } + + public static Group createGroup(final Composite c, final String title) { + Group group = new Group(c, SWT.NONE); + group.setLayout(DialogHelpers.createSimpleGroupLayout()); + group.setText(title); + return group; + } + +} diff --git a/de.prob.ui/src/de/prob/ui/LimitedLogView.java b/de.prob.ui/src/de/prob/ui/LimitedLogView.java new file mode 100644 index 0000000000000000000000000000000000000000..5fc2a21070483137ed329453c6e6a59f37b822eb --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/LimitedLogView.java @@ -0,0 +1,168 @@ +/** + * + */ +package de.prob.ui; + +import org.eclipse.jface.viewers.*; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Table; +import org.eclipse.ui.part.ViewPart; + +import de.prob.core.LimitedLogger; +import de.prob.core.LimitedLogger.LogEntry; + +/** + * This view shows the content of the {@link LimitedLogger} and allows the user + * to see durations between events easily. + * + * @author plagge + * + */ +public class LimitedLogView extends ViewPart implements + LimitedLogger.LogListener { + + private LimitedLogger logger; + private TableViewer viewer; + private Long offset; + + public LimitedLogView() { + } + + @Override + public void createPartControl(Composite parent) { + this.logger = LimitedLogger.getLogger(); + this.logger.registerListener(this); + createViewer(parent); + updateLoggingStart(); + viewer.setInput(logger); + } + + private void createViewer(Composite parent) { + viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL + | SWT.V_SCROLL | SWT.FULL_SELECTION); + createColumns(viewer); + viewer.setContentProvider(new LogContentProvider()); + viewer.setLabelProvider(new LogLabelProvider()); + } + + private void createColumns(TableViewer viewer) { + createColumn(viewer, SWT.RIGHT, "Time", 50); + createColumn(viewer, SWT.LEFT, "Category", 100); + createColumn(viewer, SWT.LEFT, "Description", 300); + + final Table table = viewer.getTable(); + table.setHeaderVisible(true); + table.setLinesVisible(true); + viewer.addDoubleClickListener(new LogViewerDoubleClick()); + } + + private void createColumn(TableViewer viewer, final int style, + final String title, final int width) { + final TableViewerColumn column = new TableViewerColumn(viewer, style); + column.getColumn().setText(title); + column.getColumn().setWidth(width); + column.getColumn().setResizable(true); + column.getColumn().setMoveable(true); + } + + @Override + public void setFocus() { + viewer.getTable().getParent().setFocus(); + } + + @Override + public void dispose() { + super.dispose(); + logger.unregisterListener(this); + logger = null; + } + + public void newLoggingInfo() { + if (viewer != null) { + updateLoggingStart(); + asyncRefresh(); + } + } + + private void updateLoggingStart() { + if (offset == null) { + offset = logger.getFirstLoggingTime(); + } + } + + private void asyncRefresh() { + Display.getDefault().asyncExec(new Runnable() { + public void run() { + viewer.refresh(); + } + }); + } + + private static class LogContentProvider implements + IStructuredContentProvider { + + public Object[] getElements(Object object) { + if (object != null && object instanceof LimitedLogger) { + LimitedLogger logger = (LimitedLogger) object; + return logger.getEntries(); + } else { + return null; + } + } + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object arg1, Object arg2) { + } + } + + private class LogViewerDoubleClick implements IDoubleClickListener { + public void doubleClick(DoubleClickEvent event) { + ISelection selection = event.getSelection(); + if (selection != null && !selection.isEmpty()) { + IStructuredSelection ssel = (IStructuredSelection) selection; + LogEntry entry = (LogEntry) ssel.getFirstElement(); + offset = entry.getTime(); + asyncRefresh(); + } + } + } + + private class LogLabelProvider extends LabelProvider implements + ITableLabelProvider { + + public Image getColumnImage(Object object, int column) { + return null; + } + + public String getColumnText(Object object, int column) { + final String result; + if (object != null && object instanceof LogEntry) { + LogEntry entry = (LogEntry) object; + switch (column) { + case 0: + final long time = entry.getTime() + - (offset == null ? 0 : offset); + result = String.format("%,d", time); + break; + case 1: + result = entry.getCategory(); + break; + case 2: + result = entry.getShortDescription(); + break; + default: + result = null; + } + } else { + result = null; + } + return result; + } + } + +} diff --git a/de.prob.ui/src/de/prob/ui/PerspectiveFactory.java b/de.prob.ui/src/de/prob/ui/PerspectiveFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..f44845d1d0ad058e9f5d925ba7a156d31c1c5b43 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/PerspectiveFactory.java @@ -0,0 +1,59 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.ui; + +import org.eclipse.ui.IFolderLayout; +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.IPerspectiveFactory; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.WorkbenchException; + +import de.prob.logging.Logger; + +public class PerspectiveFactory implements IPerspectiveFactory { + + private static final String PROB_PERSPECTIVE = "de.prob.ui.perspective"; + + @Override + public void createInitialLayout(final IPageLayout layout) { + String editorArea = layout.getEditorArea(); + layout.setEditorAreaVisible(false); + + // Place the project explorer to left of editor area. + IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT, + 0.30f, editorArea); + left.addView("de.prob.ui.OperationView"); + + IFolderLayout leftb = layout.createFolder("leftb", IPageLayout.BOTTOM, + 0.50f, "left"); + leftb.addView("fr.systerel.explorer.navigator.view"); + leftb.addView("org.eventb.ui.views.RodinProblemView"); + + // Place the outline to right of editor area. + IFolderLayout right1 = layout.createFolder("right1", IPageLayout.RIGHT, + 0.6f, editorArea); + right1.addView("de.prob.ui.StateView"); + right1.addView("de.prob.ui.ltl.CounterExampleView"); + IFolderLayout right2 = layout.createFolder("right2", IPageLayout.RIGHT, + 0.6f, "right1"); + right2.addView("de.prob.ui.HistoryView"); + right2.addView("de.prob.ui.EventErrorView"); + } + + public static void openPerspective() { + try { + IWorkbench workbench = PlatformUI.getWorkbench(); + workbench.showPerspective(PROB_PERSPECTIVE, + workbench.getActiveWorkbenchWindow()); + } catch (WorkbenchException e) { + final String message = "Error opening ProB perspective."; + Logger.notifyUser(message, e); + } + } + +} diff --git a/de.prob.ui/src/de/prob/ui/ProBGeneralPreferences.java b/de.prob.ui/src/de/prob/ui/ProBGeneralPreferences.java new file mode 100644 index 0000000000000000000000000000000000000000..8ffededed69fa0c2dc2986a8e82707f91fd97330 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ProBGeneralPreferences.java @@ -0,0 +1,215 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.ui; + +import java.math.BigInteger; +import java.util.Collections; +import java.util.List; + +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.jface.preference.BooleanFieldEditor; +import org.eclipse.jface.preference.ComboFieldEditor; +import org.eclipse.jface.preference.FieldEditor; +import org.eclipse.jface.preference.FieldEditorPreferencePage; +import org.eclipse.jface.preference.IntegerFieldEditor; +import org.eclipse.jface.preference.PreferenceStore; +import org.eclipse.jface.preference.StringFieldEditor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Group; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; +import org.osgi.service.prefs.BackingStoreException; +import org.osgi.service.prefs.Preferences; + +import de.prob.core.Animator; +import de.prob.core.command.GetPreferencesCommand; +import de.prob.core.domainobjects.ProBPreference; +import de.prob.exceptions.ProBException; +import de.prob.logging.Logger; +import de.prob.prolog.term.CompoundPrologTerm; +import de.prob.prolog.term.IntegerPrologTerm; +import de.prob.prolog.term.ListPrologTerm; +import de.prob.prolog.term.PrologTerm; + +/** + * A preferences page extension (Window->Preferences) to change the general + * settings for animating machines + * + * @author Jens Bendisposto, Lukas Diekmann + * + */ +public class ProBGeneralPreferences extends FieldEditorPreferencePage implements + IWorkbenchPreferencePage { + private static final PrologTerm PREF_INT = new CompoundPrologTerm("int"); + private static final PrologTerm PREF_NAT = new CompoundPrologTerm("nat"); + private static final PrologTerm PREF_NAT1 = new CompoundPrologTerm("nat1"); + private static final PrologTerm PREF_BOOL = new CompoundPrologTerm("bool"); + private static final PrologTerm PREF_STRING = new CompoundPrologTerm( + "string"); + + private final Preferences eclipsePrefs; + private final List<ProBPreference> probPrefs; + private final ProBPreferenceStore store = new ProBPreferenceStore(); + + /* + * different constructor to set a different place for storage + */ + public ProBGeneralPreferences(final Preferences alternateStorage) { + super(); + setPreferenceStore(store.getStore()); + eclipsePrefs = alternateStorage; + + Animator animator = Animator.getAnimator(); + List<ProBPreference> preferences = Collections.emptyList(); + try { + preferences = GetPreferencesCommand.getPreferences(animator); + } catch (ProBException e) { + // Ignore, the user has been informed + } finally { + probPrefs = preferences; + store.load(); + } + } + + public ProBGeneralPreferences() { + super(); + setPreferenceStore(store.getStore()); + eclipsePrefs = Platform.getPreferencesService().getRootNode().node( + InstanceScope.SCOPE).node("prob_animation_preferences"); + + Animator animator = Animator.getAnimator(); + List<ProBPreference> preferences = Collections.emptyList(); + try { + preferences = GetPreferencesCommand.getPreferences(animator); + } catch (ProBException e) { + // Ignore, the user has been informed + } finally { + probPrefs = preferences; + store.load(); + } + } + + @Override + protected Control createContents(final Composite parent) { + Group group = new Group(parent, SWT.SHADOW_ETCHED_IN); + group.setLayout(new GridLayout(1, false)); + group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + group.setText("ProB Settings"); + return super.createContents(group); + } + + @Override + protected void createFieldEditors() { + final Composite parent = getFieldEditorParent(); + for (ProBPreference p : probPrefs) { + final FieldEditor editor = createEditor(p, parent); + addField(editor); + } + } + + public void init(final IWorkbench workbench) { + } + + @Override + public boolean performOk() { + super.performOk(); + store.save(); + try { + eclipsePrefs.flush(); + } catch (BackingStoreException e) { + final String message = "Problem while storing preferences. " + + e.getLocalizedMessage(); + Logger.notifyUser(message, e); + } + return true; + } + + private FieldEditor createEditor(final ProBPreference pref, + final Composite parent) { + final PrologTerm type = pref.type; + final String name = pref.name; + final String desc = pref.description; + final FieldEditor field; + + if (PREF_INT.equals(type)) { + field = createIntField(name, desc, parent, Integer.MIN_VALUE, + Integer.MAX_VALUE); + } else if (PREF_NAT.equals(type)) { + field = createIntField(name, desc, parent, 0, Integer.MAX_VALUE); + } else if (PREF_NAT1.equals(type)) { + field = createIntField(name, desc, parent, 1, Integer.MAX_VALUE); + } else if (PREF_STRING.equals(type)) { + field = new StringFieldEditor(name, desc, parent); + } else if (PREF_BOOL.equals(type)) { + field = new BooleanFieldEditor(name, desc, + BooleanFieldEditor.SEPARATE_LABEL, parent); + } else if (type.hasFunctor("range", 2)) { + final CompoundPrologTerm range = (CompoundPrologTerm) type; + final BigInteger lower = ((IntegerPrologTerm) range.getArgument(1)) + .getValue(); + final BigInteger upper = ((IntegerPrologTerm) range.getArgument(2)) + .getValue(); + field = createIntField(name, desc, parent, lower.intValue(), upper + .intValue()); + } else if (type.isList()) { + final ListPrologTerm typelist = (ListPrologTerm) type; + final String[][] comboEntries = new String[typelist.size()][2]; + for (int i = 0; i < typelist.size(); i++) { + final String value = typelist.get(i).toString(); + comboEntries[i][0] = value; + comboEntries[i][1] = value; + } + field = new ComboFieldEditor(name, desc, comboEntries, parent); + } else { + field = new StringFieldEditor(name, desc, parent); + } + return field; + } + + private FieldEditor createIntField(final String name, final String desc, + final Composite parent, final int min, final int max) { + final IntegerFieldEditor intfield = new IntegerFieldEditor(name, desc, + parent); + intfield.setValidRange(min, max); + return intfield; + } + + public class ProBPreferenceStore { + + private final PreferenceStore store; + + public ProBPreferenceStore() { + store = new PreferenceStore("ProB"); + } + + public void load() { + for (ProBPreference p : probPrefs) { + store + .setValue(p.name, eclipsePrefs.get(p.name, + p.defaultValue)); + store.setDefault(p.name, p.defaultValue); + } + } + + public void save() { + for (ProBPreference p : probPrefs) { + eclipsePrefs.put(p.name, store.getString(p.name)); + } + } + + public PreferenceStore getStore() { + return store; + } + + } + +} diff --git a/de.prob.ui/src/de/prob/ui/ProbUiPlugin.java b/de.prob.ui/src/de/prob/ui/ProbUiPlugin.java new file mode 100644 index 0000000000000000000000000000000000000000..05e469e957678b8cb35713a793a913cb01961103 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ProbUiPlugin.java @@ -0,0 +1,96 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.ui; + +import org.eclipse.jface.resource.ImageRegistry; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; + +import de.prob.logging.Logger; +import de.prob.ui.ticket.ProBLogListener; + +public class ProbUiPlugin extends AbstractUIPlugin { + + public static final String PLUGIN_ID = "de.prob.ui"; + + public static final String IMG_FILTER = "IMG_FILTER"; + public static final String IMG_FORWARD = "IMG_FORWARD"; + public static final String IMG_BACK = "IMG_BACK"; + public static final String IMG_RESUME = "IMG_RESUME"; + public static final String IMG_SEARCH = "IMG_SEARCH"; + public static final String IMG_DISABLED = "IMG_DISABLED"; + public static final String IMG_TIMEOUT = "IMG_TIMEOUT"; + public static final String IMG_ENABLED = "IMG_ENABLED"; + public static final String IMG_DOUBLECLICK = "IMG_DOUBLECLICK"; + public static final String OVERLAY = "OVERLAY"; + public static final String CHANGE_STAR = "change_star"; + public static final String IMG_RELOAD = "IMG_RELOAD"; + + private static ProbUiPlugin plugin; + + private BundleContext context; + + public ProbUiPlugin() { + super(); + setInstance(this); + } + + public Bundle[] getInstalledBundles() { + final Bundle[] bundles = context.getBundles(); + final int bundlesSize = bundles.length; + final Bundle[] result = new Bundle[bundlesSize]; + System.arraycopy(bundles, 0, result, 0, bundlesSize); + return result; + } + + private static void setInstance(final ProbUiPlugin p) { + plugin = p; + } + + @Override + public void start(final BundleContext context) throws Exception { + super.start(context); + this.context = context; + Logger.addListener(new ProBLogListener()); + } + + public static ProbUiPlugin getDefault() { + return plugin; + } + + @Override + protected void initializeImageRegistry(final ImageRegistry reg) { + super.initializeImageRegistry(reg); + reg.put(IMG_FORWARD, + imageDescriptorFromPlugin(PLUGIN_ID, "icons/forward.gif")); + reg.put(IMG_BACK, + imageDescriptorFromPlugin(PLUGIN_ID, "icons/back.gif")); + reg.put(IMG_FILTER, + imageDescriptorFromPlugin(PLUGIN_ID, "icons/filter_ps.gif")); + reg.put(IMG_RESUME, + imageDescriptorFromPlugin(PLUGIN_ID, "icons/resume.gif")); + reg.put(IMG_SEARCH, + imageDescriptorFromPlugin(PLUGIN_ID, "icons/search_src.gif")); + reg.put(IMG_DISABLED, + imageDescriptorFromPlugin(PLUGIN_ID, "icons/disabled.png")); + reg.put(IMG_TIMEOUT, + imageDescriptorFromPlugin(PLUGIN_ID, "icons/timeout.png")); + reg.put(IMG_ENABLED, + imageDescriptorFromPlugin(PLUGIN_ID, "icons/enabled.png")); + reg.put(IMG_DOUBLECLICK, + imageDescriptorFromPlugin(PLUGIN_ID, "icons/doubleclick.png")); + reg.put(OVERLAY, + imageDescriptorFromPlugin(PLUGIN_ID, + "icons/splash_overlay_x.png")); + reg.put(CHANGE_STAR, + imageDescriptorFromPlugin(PLUGIN_ID, "icons/star.png")); + reg.put(IMG_RELOAD, + imageDescriptorFromPlugin(PLUGIN_ID, "icons/refresh.gif")); + } + +} diff --git a/de.prob.ui/src/de/prob/ui/StateBasedViewPart.java b/de.prob.ui/src/de/prob/ui/StateBasedViewPart.java new file mode 100644 index 0000000000000000000000000000000000000000..f48e36b08728705d2460243e325840377a37e1c1 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/StateBasedViewPart.java @@ -0,0 +1,158 @@ +/** + * + */ +package de.prob.ui; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.part.ViewPart; +import org.eclipse.ui.services.ISourceProviderService; + +import de.prob.core.Animator; +import de.prob.core.IAnimationListener; +import de.prob.core.ILifecycleListener; +import de.prob.core.domainobjects.Operation; +import de.prob.core.domainobjects.State; +import de.prob.ui.services.HistoryActiveProvider; + +/** + * This serves as a base class for views that depend on the current state of the + * animation. + * + * A message is shown as long no machine is loaded. To use this class, one must + * overwrite {@link #createStatePartControl(Composite)} to create the specific + * view and can overwrite {@link #stateReset()} and + * {@link #stateChanged(State, Operation)} to react to state changes. + * + * @author plagge + */ +public abstract class StateBasedViewPart extends ViewPart implements + IAnimationListener, ILifecycleListener { + + private Composite parent; + private Control noStateMessage; + private Control stateView; + + abstract protected Control createStatePartControl(Composite parent); + + /** + * The machine was reseted. The GUI of the component is usually not + * initialized when this method is called. + * + * So don't modify the GUI, wait for the coming + * {@link #stateChanged(State, Operation)} call later + */ + protected void stateReset() { + } + + /** + * The current state has changed. When this method is called, the GUI + * components are initialized by {@link #createStatePartControl(Composite)}, + * and the call takes place in the UI thread, so you can access the GUI. + * + * @param currentState + * @param operation + */ + protected void stateChanged(final State currentState, + final Operation operation) { + } + + public void createPartControl(final Composite parent) { + this.parent = parent; + StaticListenerRegistry.registerListener((ILifecycleListener) this); + StaticListenerRegistry.registerListener((IAnimationListener) this); + final Animator animator = Animator.getAnimator(); + if (animator.isMachineLoaded()) { + createStateControl(); + final State state = animator.getCurrentState(); + final Operation op = animator.getHistory().getCurrent() + .getOperation(); + stateChanged(state, op); + } else { + createNoStateMessage(); + reset(); + } + } + + private void createNoStateMessage() { + if (noStateMessage == null) { + disposeStateView(); + Label message = new Label(parent, SWT.NONE); + message.setText("no machine available"); + noStateMessage = message; + parent.layout(); + } + } + + private void createStateControl() { + if (stateView == null) { + disposeNoStateMessage(); + stateView = createStatePartControl(parent); + parent.layout(); + } + } + + private void disposeNoStateMessage() { + if (noStateMessage != null && !noStateMessage.isDisposed()) { + noStateMessage.dispose(); + } + noStateMessage = null; + } + + private void disposeStateView() { + if (stateView != null && !stateView.isDisposed()) { + stateView.dispose(); + } + stateView = null; + } + + @Override + public void setFocus() { + if (noStateMessage != null) { + noStateMessage.setFocus(); + } + if (stateView != null) { + stateView.setFocus(); + } + } + + final public void currentStateChanged(final State currentState, + final Operation operation) { + final Runnable runnable = new Runnable() { + public void run() { + createStateControl(); + stateChanged(currentState, operation); + } + }; + Display.getDefault().asyncExec(runnable); + + ISourceProviderService service = (ISourceProviderService) this + .getSite().getService(ISourceProviderService.class); + HistoryActiveProvider sourceProvider = (HistoryActiveProvider) service + .getSourceProvider(HistoryActiveProvider.FORWARD_SERVICE); + sourceProvider.historyChange(); + + } + + final public void reset() { + final Runnable runnable = new Runnable() { + public void run() { + createNoStateMessage(); + stateReset(); + } + }; + Display.getDefault().asyncExec(runnable); + } + + public void dispose() { + super.dispose(); + StaticListenerRegistry.unregisterListener((ILifecycleListener) this); + StaticListenerRegistry.unregisterListener((IAnimationListener) this); + disposeStateView(); + disposeNoStateMessage(); + } + +} diff --git a/de.prob.ui/src/de/prob/ui/StaticListenerRegistry.java b/de.prob.ui/src/de/prob/ui/StaticListenerRegistry.java new file mode 100644 index 0000000000000000000000000000000000000000..aff5a162479650725c76f09d7157305d2f3601c5 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/StaticListenerRegistry.java @@ -0,0 +1,57 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.ui; + +import de.prob.core.IAnimationListener; +import de.prob.core.IComputationListener; +import de.prob.core.ILifecycleListener; +import de.prob.core.ListenerRegistry; +import de.prob.core.domainobjects.Operation; +import de.prob.core.domainobjects.State; + +public class StaticListenerRegistry implements ILifecycleListener, + IComputationListener, IAnimationListener { + + private static final ListenerRegistry registry = new ListenerRegistry(); + + public static void registerListener(final ILifecycleListener listener) { + registry.registerLifecycleListener(listener); + } + + public static void unregisterListener(final ILifecycleListener listener) { + registry.unregisterLifecycleListener(listener); + } + + public static void registerListener(final IComputationListener listener) { + registry.registerComputationListener(listener); + } + + public static void unregisterListener(final IComputationListener listener) { + registry.unregisterComputationListener(listener); + } + + public static void registerListener(final IAnimationListener listener) { + registry.registerAnimationListener(listener); + } + + public static void unregisterListener(final IAnimationListener listener) { + registry.unregisterAnimationListener(listener); + } + + public void reset() { + registry.reset(); + } + + public void computedState(final State state) { + registry.computedState(state); + } + + public void currentStateChanged(final State currentState, + final Operation operation) { + registry.currentStateChanged(currentState, operation); + } +} diff --git a/de.prob.ui/src/de/prob/ui/deadlock/DeadlockCheckFinishedListener.java b/de.prob.ui/src/de/prob/ui/deadlock/DeadlockCheckFinishedListener.java new file mode 100644 index 0000000000000000000000000000000000000000..80b7a915254759caf8b5fce71756dc5c5508067d --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/deadlock/DeadlockCheckFinishedListener.java @@ -0,0 +1,103 @@ +/** + * + */ +package de.prob.ui.deadlock; + +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Shell; + +import de.prob.core.Animator; +import de.prob.core.ProBJobFinishedListener; +import de.prob.core.command.ConstraintBasedDeadlockCheckCommand; +import de.prob.core.command.ConstraintBasedDeadlockCheckCommand.ResultType; +import de.prob.core.command.ExecuteOperationCommand; +import de.prob.core.command.IComposableCommand; +import de.prob.core.domainobjects.Operation; +import de.prob.exceptions.ProBException; +import de.prob.logging.Logger; + +/** + * This JobChangeAdapter presents the user the results of a deadlock freedom + * check. + * + * @see DeadlockCheckHandler + * + * @author plagge + */ +public class DeadlockCheckFinishedListener extends ProBJobFinishedListener { + private final Shell shell; + + public DeadlockCheckFinishedListener(final Shell shell) { + this.shell = shell; + } + + @Override + protected void showResult(final IComposableCommand cmd, + final Animator animator) { + final ConstraintBasedDeadlockCheckCommand command = (ConstraintBasedDeadlockCheckCommand) cmd; + final ResultType result = command.getResult(); + final int dialogType; + final String dialogTitle; + final String message; + if (result == null) { + dialogType = MessageDialog.ERROR; + dialogTitle = "Errow During Deadlock Freedom Check"; + message = "ProB did not return a result"; + } else { + switch (result) { + case NO_DEADLOCK: + dialogType = MessageDialog.INFORMATION; + dialogTitle = "No Deadlock Found"; + message = "The model does not contain any deadlock."; + break; + case ERROR: + dialogType = MessageDialog.ERROR; + dialogTitle = "Errow During Deadlock Freedom Check"; + message = "An unexpected error occurred while typechecking the given predicate."; + break; + case DEADLOCK_FOUND: + dialogType = MessageDialog.WARNING; + dialogTitle = "Deadlock Found"; + message = "The model contains a deadlock, it will be shown in the state view."; + displayDeadlock(command, animator); + break; + case INTERRUPTED: + dialogType = MessageDialog.WARNING; + dialogTitle = "User Interrupt"; + message = "The deadlock check has been interrupted by the user or a time-out."; + break; + default: + Logger.notifyUser("Unexpected result: " + result); + return; + } + } + if (shell.isDisposed()) { + System.out.println("Deadlock freedom check finished: " + + dialogTitle); + } else { + final Runnable runnable = new Runnable() { + @Override + public void run() { + MessageDialog.open(dialogType, shell, dialogTitle, message, + SWT.NONE); + } + }; + shell.getDisplay().asyncExec(runnable); + } + } + + private void displayDeadlock(final ConstraintBasedDeadlockCheckCommand cmd, + final Animator animator) { + final Operation operation = cmd.getDeadlockOperation(); + try { + // we do not reset the history because we want to keep the root + // state, we just start a new path from root + animator.getHistory().gotoPos(0); + ExecuteOperationCommand.executeOperation(animator, operation); + } catch (ProBException e) { + e.notifyUserOnce(); + } + } + +} diff --git a/de.prob.ui/src/de/prob/ui/deadlock/DeadlockCheckHandler.java b/de.prob.ui/src/de/prob/ui/deadlock/DeadlockCheckHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..8f84dfa6687c0c0f4c84739f2a9e46bf714d00ae --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/deadlock/DeadlockCheckHandler.java @@ -0,0 +1,115 @@ +/** + * + */ +package de.prob.ui.deadlock; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jface.dialogs.IInputValidator; +import org.eclipse.jface.dialogs.InputDialog; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.handlers.HandlerUtil; + +import de.prob.core.Animator; +import de.prob.core.LanguageDependendAnimationPart; +import de.prob.core.ProBCommandJob; +import de.prob.core.command.ConstraintBasedDeadlockCheckCommand; +import de.prob.logging.Logger; +import de.prob.parserbase.ProBParseException; +import de.prob.parserbase.ProBParserBaseAdapter; +import de.prob.prolog.term.PrologTerm; + +/** + * This handler provides a simple dialog to ask for an optional predicate to + * check for deadlocks in the model. + * + * @author plagge + */ +public class DeadlockCheckHandler extends AbstractHandler { + @Override + public Object execute(final ExecutionEvent event) throws ExecutionException { + final Shell shell = HandlerUtil.getActiveShell(event); + if (Animator.getAnimator().isMachineLoaded()) { + performDeadlockCheck(shell); + } else { + Logger.notifyUser("No ProB animation running. This is a bug. Please submit a report. Error in declaraion for class DeadlockCheckHandler"); + } + return null; + } + + private void performDeadlockCheck(final Shell shell) + throws ExecutionException { + final Animator animator = Animator.getAnimator(); + final LanguageDependendAnimationPart ldp = animator + .getLanguageDependendPart(); + final IInputValidator validator = new PredicateValidator(ldp); + final InputDialog dialog = new InputDialog( + shell, + "Deadlock Freedom Check", + "Please specify an (optional) predicate to constrain the search space", + "", validator); + final int status = dialog.open(); + if (status == InputDialog.OK) { + startCheck(animator, ldp, dialog.getValue(), shell); + } + } + + private void startCheck(final Animator animator, + final LanguageDependendAnimationPart ldp, final String value, + final Shell shell) throws ExecutionException { + final PrologTerm predicate = parsePredicate(ldp, value); + final ConstraintBasedDeadlockCheckCommand command = new ConstraintBasedDeadlockCheckCommand( + predicate); + final Job job = new ProBCommandJob("Checking for Deadlock Freedom", + animator, command); + job.setUser(true); + job.addJobChangeListener(new DeadlockCheckFinishedListener(shell)); + job.schedule(); + } + + private PrologTerm parsePredicate(final LanguageDependendAnimationPart ldp, + final String input) throws ExecutionException { + final PrologTerm predicate; + if (input != null && input.trim().isEmpty()) { + predicate = null; + } else { + try { + final ProBParserBaseAdapter parser = new ProBParserBaseAdapter( + ldp); + predicate = parser.parsePredicate(input, false); + } catch (Exception e) { + throw (new ExecutionException( + "Exception while parsing the input", e)); + } + } + return predicate; + } + + private static final class PredicateValidator implements IInputValidator { + final LanguageDependendAnimationPart ldp; + + public PredicateValidator(final LanguageDependendAnimationPart ldp) { + this.ldp = ldp; + } + + @Override + public String isValid(final String newText) { + if (newText.trim().isEmpty()) + return null; + if (ldp == null) + return "Cannot parse predicates for the current formalism"; + try { + final ProBParserBaseAdapter parser = new ProBParserBaseAdapter( + ldp); + parser.parsePredicate(newText, false); + } catch (UnsupportedOperationException e) { + return "The parser for this formalism cannot parse predicates"; + } catch (ProBParseException e) { + return e.getLocalizedMessage(); + } + return null; + } + } +} diff --git a/de.prob.ui/src/de/prob/ui/dnd/StaticStateElementTransfer.java b/de.prob.ui/src/de/prob/ui/dnd/StaticStateElementTransfer.java new file mode 100644 index 0000000000000000000000000000000000000000..ab40896e26034d6d18b3d4dabc5c0b0a819ba535 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/dnd/StaticStateElementTransfer.java @@ -0,0 +1,66 @@ +/** + * + */ +package de.prob.ui.dnd; + +import org.eclipse.swt.dnd.ByteArrayTransfer; +import org.eclipse.swt.dnd.TransferData; + +import de.prob.ui.stateview.statetree.StaticStateElement; + +/** + * @author plagge + * + */ +public class StaticStateElementTransfer extends ByteArrayTransfer { + private static final String TYPENAME = "internal_transfer_" + + StaticStateElementTransfer.class.getName(); + private static final int TYPEID = registerType(TYPENAME); + private static StaticStateElementTransfer instance = new StaticStateElementTransfer(); + + private static byte[] EMPTY_BYTE_ARRAY = new byte[0]; + + private StaticStateElement[] currentElements; + + public static StaticStateElementTransfer getInstance() { + return instance; + } + + private StaticStateElementTransfer() { + } + + @Override + protected void javaToNative(final Object object, + final TransferData transferData) { + System.out.println("javaToNative"); + if (object != null && object instanceof StaticStateElement[] + && isSupportedType(transferData)) { + System.out.println("javaToNative: stored"); + currentElements = (StaticStateElement[]) object; + super.javaToNative(EMPTY_BYTE_ARRAY, transferData); + } + } + + @Override + protected Object nativeToJava(final TransferData transferData) { + System.out.println("nativeToJava"); + final StaticStateElement[] result; + if (isSupportedType(transferData)) { + result = currentElements; + System.out.println("nativeToJava: loaded"); + } else { + result = null; + } + return result; + } + + @Override + protected int[] getTypeIds() { + return new int[] { TYPEID }; + } + + @Override + protected String[] getTypeNames() { + return new String[] { TYPENAME }; + } +} diff --git a/de.prob.ui/src/de/prob/ui/errorview/ErrorContentProvider.java b/de.prob.ui/src/de/prob/ui/errorview/ErrorContentProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..566a09c7c4ed7df00fb371c6371f8d7448956bc4 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/errorview/ErrorContentProvider.java @@ -0,0 +1,64 @@ +/** + * + */ +package de.prob.ui.errorview; + +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; + +import de.prob.ui.errorview.ShownErrors.ErrorEvent; +import de.prob.ui.errorview.ShownErrors.ShownStateError; + +/** + * @author plagge + * + */ +public class ErrorContentProvider implements ITreeContentProvider { + + public Object[] getChildren(Object parent) { + ShownStateError[] errors; + if (parent != null && parent instanceof ErrorEvent) { + ErrorEvent errorEvent = (ErrorEvent) parent; + errors = errorEvent.getErrors() + .toArray(ShownStateError.EMPTY_ARRAY); + } else { + errors = null; + } + return errors; + } + + public Object getParent(Object arg) { + if (arg != null) { + if (arg instanceof ShownStateError) { + return ((ShownStateError) arg).getEvent(); + } + if (arg instanceof ErrorEvent) { + return ((ErrorEvent) arg).getShownErrors(); + } + } + return null; + } + + public boolean hasChildren(Object parent) { + // empty nodes are not even created + return parent != null && parent instanceof ErrorEvent; + } + + public Object[] getElements(Object object) { + ErrorEvent[] events; + if (object != null && object instanceof ShownErrors) { + events = ((ShownErrors) object).getErrorEvents().toArray( + ErrorEvent.EMPTY_ARRAY); + } else { + events = null; + } + return events; + } + + public void dispose() { + } + + public void inputChanged(Viewer arg0, Object arg1, Object arg2) { + } + +} diff --git a/de.prob.ui/src/de/prob/ui/errorview/ErrorLabelProvider.java b/de.prob.ui/src/de/prob/ui/errorview/ErrorLabelProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..c97ec85b6b702181581a15ae477ab64a818186f3 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/errorview/ErrorLabelProvider.java @@ -0,0 +1,46 @@ +/** + * + */ +package de.prob.ui.errorview; + +import org.eclipse.jface.viewers.BaseLabelProvider; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.swt.graphics.Image; + +import de.prob.ui.errorview.ShownErrors.ErrorEvent; +import de.prob.ui.errorview.ShownErrors.ShownStateError; + +/** + * @author plagge + * + */ +public class ErrorLabelProvider extends BaseLabelProvider implements + ITableLabelProvider { + + public Image getColumnImage(Object object, int column) { + return null; + } + + public String getColumnText(Object object, int column) { + final String text; + if (column == 0) { + if (object instanceof ShownStateError) { + ShownStateError error = (ShownStateError) object; + text = error.getError().getShortDescription(); + } else if (object instanceof ErrorEvent) { + final ErrorEvent event = (ErrorEvent) object; + final int size = event.getErrors().size(); + StringBuilder sb = new StringBuilder(); + sb.append(event.getEvent()); + sb.append(" (").append(size); + sb.append(size == 1 ? " error)" : " errors)"); + text = sb.toString(); + } else { + text = null; + } + } else { + text = null; + } + return text; + } +} diff --git a/de.prob.ui/src/de/prob/ui/errorview/ShownErrors.java b/de.prob.ui/src/de/prob/ui/errorview/ShownErrors.java new file mode 100644 index 0000000000000000000000000000000000000000..cf6683f4456ed2728f4000d631c8d395e46ff238 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/errorview/ShownErrors.java @@ -0,0 +1,136 @@ +package de.prob.ui.errorview; + +import java.util.*; +import java.util.Map.Entry; + +import de.prob.core.domainobjects.MachineDescription; +import de.prob.core.domainobjects.State; +import de.prob.core.domainobjects.StateError; + +public class ShownErrors { + private MachineDescription description; + private State state; + private Collection<ErrorEvent> errorEvents; + + @SuppressWarnings("unchecked") + public void update(MachineDescription description, State state) { + Collection<StateError> errors = state == null ? Collections.EMPTY_LIST + : state.getStateBasedErrors(); + Map<String, Collection<StateError>> emap = new HashMap<String, Collection<StateError>>(); + for (StateError error : errors) { + final String event = error.getEvent(); + Collection<StateError> evErrors = emap.get(event); + if (evErrors == null) { + evErrors = new ArrayList<StateError>(); + emap.put(event, evErrors); + } + evErrors.add(error); + } + Collection<ErrorEvent> errorEvents = new ArrayList<ErrorEvent>(); + for (String event : description.getEventNames()) { + Collection<StateError> eventErrors = emap.get(event); + if (eventErrors != null && !eventErrors.isEmpty()) { + ErrorEvent ee = new ErrorEvent(event, this, eventErrors); + errorEvents.add(ee); + } + emap.remove(event); + } + + for (Entry<String, Collection<StateError>> entry : emap.entrySet()) { + Collection<StateError> eventErrors = entry.getValue(); + if (eventErrors != null && !eventErrors.isEmpty()) { + ErrorEvent ee = new ErrorEvent(entry.getKey(), this, eventErrors); + errorEvents.add(ee); + } + } + + + this.errorEvents = errorEvents; + this.description = description; + this.state = state; + } + + public MachineDescription getDescription() { + return description; + } + + public State getState() { + return state; + } + + @SuppressWarnings("unchecked") + public Collection<ErrorEvent> getErrorEvents() { + return errorEvents == null ? Collections.EMPTY_LIST : errorEvents; + } + + public static class ErrorEvent { + public static final ErrorEvent[] EMPTY_ARRAY = new ErrorEvent[0]; + + private final String event; + private final ShownErrors shown; + private final Collection<ShownStateError> errors; + + public ErrorEvent(String event, ShownErrors shown, + Collection<StateError> errors) { + this.event = event; + this.shown = shown; + Collection<ShownStateError> es = new ArrayList<ShownStateError>(); + for (StateError se : errors) { + es.add(new ShownStateError(this, se)); + } + this.errors = Collections.unmodifiableCollection(es); + } + + @Override + public boolean equals(Object o) { + if (o == null) + return false; + if (o == this) + return true; + if (o instanceof ErrorEvent) { + ErrorEvent other = (ErrorEvent) o; + return this.event.equals(other.event) + && this.shown.equals(other.shown); + } else { + return false; + } + } + + @Override + public int hashCode() { + return event.hashCode(); + } + + public String getEvent() { + return event; + } + + public Collection<ShownStateError> getErrors() { + return errors; + } + + public ShownErrors getShownErrors() { + return shown; + } + } + + public static class ShownStateError { + public static final ShownStateError[] EMPTY_ARRAY = new ShownStateError[0]; + private final ErrorEvent event; + private final StateError error; + + public ShownStateError(ErrorEvent event, StateError error) { + this.event = event; + this.error = error; + } + + public ErrorEvent getEvent() { + return event; + } + + public StateError getError() { + return error; + } + + } +} diff --git a/de.prob.ui/src/de/prob/ui/errorview/StateErrorView.java b/de.prob.ui/src/de/prob/ui/errorview/StateErrorView.java new file mode 100644 index 0000000000000000000000000000000000000000..a76ae1f638b31e9565db384e911bdeaa951b4d19 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/errorview/StateErrorView.java @@ -0,0 +1,92 @@ +/** + * + */ +package de.prob.ui.errorview; + +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.TreeViewerColumn; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.SashForm; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Text; + +import de.prob.core.Animator; +import de.prob.core.domainobjects.Operation; +import de.prob.core.domainobjects.State; +import de.prob.ui.StateBasedViewPart; +import de.prob.ui.errorview.ShownErrors.ShownStateError; + +/** + * This view shows the errors that are specific to a certain state. + * + * @author plagge + */ +public class StateErrorView extends StateBasedViewPart { + public static final String VIEWID = "de.prob.ui.EventErrorView"; + private TreeViewer errorTree; + private Text text; + private final ShownErrors errors = new ShownErrors(); + + @Override + public Control createStatePartControl(final Composite parent) { + SashForm sashForm = new SashForm(parent, SWT.HORIZONTAL | SWT.SMOOTH); + + createErrorTree(sashForm); + + text = new Text(sashForm, SWT.MULTI | SWT.V_SCROLL); + text.setText(""); + text.setEditable(false); + + errorTree.addSelectionChangedListener(new ErrorSelection()); + + return sashForm; + } + + private void createErrorTree(final SashForm sashForm) { + errorTree = new TreeViewer(sashForm); + errorTree.getTree().setHeaderVisible(false); + errorTree.getTree().setLinesVisible(false); + errorTree.setAutoExpandLevel(2); + + TreeViewerColumn col = new TreeViewerColumn(errorTree, SWT.LEFT); + col.getColumn().setText("Short description"); + col.getColumn().setResizable(true); + col.getColumn().setWidth(100); + + errorTree.setContentProvider(new ErrorContentProvider()); + errorTree.setLabelProvider(new ErrorLabelProvider()); + errorTree.setInput(errors); + } + + @Override + public void stateChanged(final State currentState, final Operation operation) { + errors.update(Animator.getAnimator().getMachineDescription(), + currentState); + errorTree.refresh(); + } + + private class ErrorSelection implements ISelectionChangedListener { + + public void selectionChanged(final SelectionChangedEvent event) { + IStructuredSelection selection = (IStructuredSelection) event + .getSelection(); + final String msg; + if (selection.isEmpty()) { + msg = ""; + } else { + Object sel = selection.getFirstElement(); + if (sel instanceof ShownStateError) { + final ShownStateError error = (ShownStateError) sel; + msg = error.getError().getLongDescription(); + } else { + msg = ""; + } + } + text.setText(msg); + } + } +} diff --git a/de.prob.ui/src/de/prob/ui/eventb/AnimationPreferencesDialog.java b/de.prob.ui/src/de/prob/ui/eventb/AnimationPreferencesDialog.java new file mode 100644 index 0000000000000000000000000000000000000000..0466131ae4d10556bc386f3fd73127074b2f8ed3 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/eventb/AnimationPreferencesDialog.java @@ -0,0 +1,636 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.ui.eventb; + +import java.util.ArrayList; +import java.util.UUID; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.preference.PreferenceDialog; +import org.eclipse.jface.preference.PreferenceLabelProvider; +import org.eclipse.jface.preference.PreferenceManager; +import org.eclipse.jface.preference.PreferenceNode; +import org.eclipse.jface.preference.PreferencePage; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.JFaceColors; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.viewers.ViewerComparator; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CLabel; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.MessageBox; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.ToolBar; +import org.eclipse.swt.widgets.ToolItem; +import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.eventb.core.IEventBRoot; +import org.osgi.service.prefs.BackingStoreException; +import org.osgi.service.prefs.Preferences; +import org.rodinp.core.IInternalElement; +import org.rodinp.core.RodinCore; + +import de.prob.core.Animator; +import de.prob.core.command.LoadEventBModelCommand; +import de.prob.exceptions.ProBException; +import de.prob.logging.Logger; + +/** + * A dialog similar to the <code>LaunchConfigurationsDialog</code> for managing + * custom configurations to animate machines + * + * @see PreferenceDialog + * @author Lukas Diekmann + */ +public class AnimationPreferencesDialog extends PreferenceDialog { + + private Preferences configurationStorage; + + public static final String pluginId = "de.prob.ui"; + public static final String default_configuration_name = "General Configuration"; + public static final String preferencesName = "prob_configurations"; + public static final String okButtonText = "Animate"; + public static final String nodeTitleKey = "title"; + public static final String nodeTitleKeyError = "TitleNotFound"; + public static final String proBParentNodeId = "ProB Configurations"; + + private static final String shellTitle = "Manage ProB Configurations"; + private static final String flushingErrorMessage = "Problem while storing configurations. "; + private static final String loadConfigurationsError = "Problem while loading configurations. "; + private static final String readingErrorMessage = "Problem while reading configuration. "; + + private IEventBRoot selectedEventBRoot; + + public AnimationPreferencesDialog(final Shell parentShell, + final PreferenceManager manager) { + super(parentShell, manager); + getPreferenceManager().removeAll(); + addProBParentNode(); + } + + @Override + public void updateButtons() { + getButton(IDialogConstants.OK_ID).setEnabled(isCurrentPageValid()); + } + + @Override + protected void configureShell(final Shell newShell) { + super.configureShell(newShell); + newShell.setText(shellTitle); + } + + /** + * When a configuration name has been changed, update page title and refresh + * TreeViewer + */ + @Override + public void updateTitle() { + super.updateTitle(); + getTreeViewer().refresh(); + } + + /** + * Get the configuration that was selected last when the dialog closed. + * + * @return + */ + public Preferences getSelectedConfiguration() { + return getConfigurationStorage().node(getSelectedNodePreference()); + } + + /** + * Adds a new composite that divides the left dialog area into two rows and + * inserts a <code>ToolBar</code> for creating, duplicating and deleting + * <code>ProBAnimationPreferences</code> + * + * @see org.eclipse.jface.preference.PreferenceDialog#createTreeAreaContents(org.eclipse.swt.widgets.Composite) + */ + @Override + protected Control createTreeAreaContents(final Composite parent) { + + // add Composite to divide area + Composite treeAreaContentsDivider = new Composite(parent, SWT.NONE); + + // set Layout, LayoutData and Color of the Composite + GridLayout gl = new GridLayout(1, false); + gl.marginHeight = gl.marginWidth = 0; + treeAreaContentsDivider.setLayout(gl); + treeAreaContentsDivider.setBackground(parent.getBackground()); + GridData gd = new GridData(GridData.FILL_BOTH); + treeAreaContentsDivider.setLayoutData(gd); + + // TODO: use ToolBarManager + // Create ToolBar and set Layout + + ToolBar tb = new ToolBar(treeAreaContentsDivider, SWT.SHADOW_ETCHED_IN); + tb.setLayoutData(new GridData(SWT.HORIZONTAL)); + + // add ToolBar Items + ToolItem tiNew = new ToolItem(tb, SWT.PUSH); + tiNew.setImage(PlatformUI.getWorkbench().getSharedImages() + .getImage(ISharedImages.IMG_OBJ_FILE)); + tiNew.setToolTipText("Create new configuration"); + tiNew.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(final SelectionEvent event) { + addPreference("New Configuration", false); + } + }); + + ToolItem tiDup = new ToolItem(tb, SWT.PUSH); + tiDup.setImage(PlatformUI.getWorkbench().getSharedImages() + .getImage(ISharedImages.IMG_TOOL_COPY)); + tiDup.setToolTipText("Duplicate selected configuration"); + tiDup.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(final SelectionEvent event) { + duplicatePreference(); + } + }); + + ToolItem tiDel = new ToolItem(tb, SWT.PUSH); + tiDel.setImage(PlatformUI.getWorkbench().getSharedImages() + .getImage(ISharedImages.IMG_TOOL_DELETE)); + tiDel.setToolTipText("Delete selected configuration"); + tiDel.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(final SelectionEvent event) { + deletePreference(); + } + }); + + // Build the tree and put it into the composite. + // inherited from PreferencesDialog + setTreeViewer(createTreeViewer(treeAreaContentsDivider)); + getTreeViewer().setInput(getPreferenceManager()); + updateTreeFont(JFaceResources.getDialogFont()); + + // set TreeViewer layout to fill the Composite + getTreeViewer().getControl().setLayoutData( + new GridData(GridData.FILL_BOTH)); + + // set a custom LabelProvider (to show icons) and the custom Comparator + // (for sorting elements) + getTreeViewer().setLabelProvider(new ProBLabelProvider()); + getTreeViewer().setComparator(new ViewerComparator()); + getTreeViewer().expandAll(); + + layoutTreeAreaControl(treeAreaContentsDivider); + return treeAreaContentsDivider; + } + + /** + * Changes the text of the okButton to "Animate" + */ + @Override + protected void createButtonsForButtonBar(final Composite parent) { + super.createButtonsForButtonBar(parent); + super.getShell().getDefaultButton().setText(okButtonText); + } + + /** + * Creates a new composite used as TitleArea similar to the TitleArea in + * <code>TitleAreaDialog</code> and <code>LaunchConfigurationsDialog</code> + * + */ + @Override + protected Control createDialogArea(final Composite parent) { + + // define some default values + Display display = getParentShell().getDisplay(); + Color bgColor = JFaceColors.getBannerBackground(display); + + // Create TitleArea + Composite newTitleArea = new Composite(parent, SWT.NONE); + GridLayout gl = new GridLayout(1, false); + gl.marginHeight = gl.marginWidth = 0; + gl.numColumns = 2; + gl.marginLeft = 5; + newTitleArea.setLayout(gl); + newTitleArea.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + newTitleArea.setBackground(bgColor); + + // add TitleMessage + Label titleMessage = new Label(newTitleArea, SWT.NONE); + titleMessage.setText("Create, manage and run ProB configurations"); + titleMessage.setFont(JFaceResources.getBannerFont()); + titleMessage.setBackground(bgColor); + + Label titleImageLabel = new Label(newTitleArea, SWT.NONE); + titleImageLabel.setAlignment(SWT.RIGHT); + titleImageLabel.setBackground(bgColor); + ImageDescriptor imageDescriptor = AbstractUIPlugin + .imageDescriptorFromPlugin(pluginId, + "icons/prob_animation_dialog.png"); + if (imageDescriptor != null) { + titleImageLabel.setImage(imageDescriptor.createImage()); + } + titleImageLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + Label titleBarSeparator = new Label(parent, SWT.HORIZONTAL + | SWT.SEPARATOR); + titleBarSeparator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + return super.createDialogArea(parent); + } + + /** + * Adds a new <code>ProBAnimationPreference</code> to the Dialog and stores + * it in the persistent store + * + * @param name + * of the new configuration + * @param duplicate + * true if the new configuration should duplicate the settings + * from another configuration + */ + private void addPreference(final String name, final boolean duplicate) { + + // look if the name is already used and + // add a number to the name in that case + String nodeTitle = getValidName(name); + if (nodeTitle != null) { + + // create the new configuration + String uniqueId = UUID.randomUUID().toString(); + Preferences newPreferences = getConfigurationStorage().node( + uniqueId); + + // Duplicate keys + if (duplicate) { + try { + for (String s : getSelectedConfiguration().keys()) { + newPreferences.put(s, + getSelectedConfiguration().get(s, null)); + } + } catch (BackingStoreException e) { + notifyBackingStoreError(readingErrorMessage, e); + } + } else { + if (selectedEventBRoot != null) { + newPreferences.put("project", selectedEventBRoot + .getEventBProject().toString()); + newPreferences.put("machine", selectedEventBRoot + .getRodinFile().getElementName()); + } + } + + // add Title (overwrite inherited title if duplicated) + newPreferences.put("title", nodeTitle); + + // Create PreferencePage and save it at once (in case the + // user hits cancel after adding a new node) + ProBAnimationPreferencePage preferencePage = new ProBAnimationPreferencePage( + uniqueId, getConfigurationStorage()); + preferencePage.performOk(); + + // add the PreferncePage to the TreeView + PreferenceNode node = new PreferenceNode(uniqueId, preferencePage); + getPreferenceManager().addTo(proBParentNodeId, node); + + getTreeViewer().refresh(); + setSelectedNodePreference(preferencePage.getConfigurationId()); + selectSavedItem(); + } + } + + /** + * Creates a duplicate of the selected configuration + */ + private void duplicatePreference() { + String name; + if (getSelectedConfiguration() == null) { + name = default_configuration_name; + addPreference(name, false); + } else { + name = getSelectedConfiguration().get("title", null); + addPreference(name, true); + } + } + + /** + * Deletes the selected configuration and automatically selects the next + * configuration. + */ + private void deletePreference() { + if (getSelectedPage() instanceof ProBAnimationPreferencePage) { + ProBAnimationPreferencePage deletePage = (ProBAnimationPreferencePage) getSelectedPage(); + String deleteId = deletePage.getConfigurationId(); + + try { + getConfigurationStorage().node(deleteId).removeNode(); + + } catch (BackingStoreException e) { + // do nothing + } finally { + + saveConfigurations(); + + // get selected Item and find its parent + TreeItem selectedItem = getTreeViewer().getTree() + .getSelection()[0]; + TreeItem parent = selectedItem.getParentItem(); + + // Find next item to be selected + int nextIndex = -1; + int currentIndex = parent.indexOf(selectedItem); + if (currentIndex < parent.getItemCount() - 1) { + nextIndex = currentIndex; + } else if (currentIndex > 0) { + nextIndex = currentIndex - 1; + } + + // remove page from PreferenceManager + getPreferenceManager().find(parent.getText()).remove(deleteId); + + getTreeViewer().refresh(); + + // select next Page + if (parent.getItemCount() > 0) { + PreferenceNode nextNode = (PreferenceNode) parent.getItem( + nextIndex).getData(); + setSelectedNodePreference(nextNode.getId()); + selectSavedItem(); + } else { + setSelectedNode(parent.getText()); + selectSavedItem(); + } + } + } + } + + /** + * Checks if a node with this name already exists and returns a new name if + * necessary. + * + * @param name + * original name + * @return a safe name + */ + private String getValidName(final String name) { + + String bareName = name.replaceAll(" \\([0-9]+\\)", ""); + String safeName = name; + + try { + + // get all numbers that are not available + ArrayList<Integer> numbers = new ArrayList<Integer>(); + for (String s : getConfigurationStorage().childrenNames()) { + String title = getConfigurationStorage().node(s).get("title", + null); + if (title != null + && title.replaceAll(" \\([0-9]+\\)", "").equals( + bareName)) { + + // get number from title + char ch = title.charAt(title.length() - 2); + if (Character.isDigit(ch)) { + numbers.add(Character.getNumericValue(ch)); + } else { + numbers.add(0); + } + } + } + + // find an available number + int count = 0; + while (numbers.contains(count)) { + count++; + } + + // create name + if (count > 0) { + safeName = bareName + " (" + count + ")"; + } + } catch (BackingStoreException e) { + notifyBackingStoreError(readingErrorMessage, e); + return null; + } + + return safeName; + } + + /** + * Sets the element that was selected before opening the dialog. Needed for + * setting an initial project and machine when creating a new configuration. + * + * @param element + */ + public void setSelectedEventBRoot(final IEventBRoot element) { + selectedEventBRoot = element; + } + + /** + * Adds the parent node for the ProB configurations. + */ + public void addProBParentNode() { + InfoPage infoPage = new InfoPage(); + infoPage.setTitle(proBParentNodeId); + PreferenceNode proBParentNode = new PreferenceNode(proBParentNodeId, + infoPage); + getPreferenceManager().addToRoot(proBParentNode); + } + + /** + * loads all user defined <code>ProBAnimationPreferencePages</code> to show + * them in the TreeViewer of the <code>ProBAnimationPreferencesDialog</code> + */ + public void loadConfigurations() { + + Preferences preferences = getConfigurationStorage(); + try { + for (String nodeName : preferences.childrenNames()) { + ProBAnimationPreferencePage preference = new ProBAnimationPreferencePage( + nodeName, getConfigurationStorage()); + PreferenceNode node = new PreferenceNode(nodeName, preference); + // getPreferenceManager().addToRoot(node); + getPreferenceManager().addTo(proBParentNodeId, node); + } + } catch (BackingStoreException e) { + notifyBackingStoreError(loadConfigurationsError, e); + } + } + + /** + * returns the ConfigurationScope where the data is stored + */ + public Preferences getConfigurationStorage() { + if (configurationStorage == null) { + configurationStorage = Platform.getPreferencesService() + .getRootNode().node(InstanceScope.SCOPE) + .node(preferencesName); + } + return configurationStorage; + } + + public void saveConfigurations() { + try { + getConfigurationStorage().flush(); + } catch (BackingStoreException e) { + notifyBackingStoreError(flushingErrorMessage, e); + } + } + + public void notifyBackingStoreError(final String m, final Exception e) { + final String message = m + e.getLocalizedMessage(); + Logger.notifyUser(message, e); + } + + /** + * Adds an icon to the elements of the <code>TreeViewer</code> + * + */ + private static class ProBLabelProvider extends PreferenceLabelProvider { + @Override + public Image getImage(final Object element) { + return AbstractUIPlugin.imageDescriptorFromPlugin(pluginId, + "icons/new_prob_mini.png").createImage(); + } + } + + /** + * Opens the ConfigurationDialog for animating machines. + * + * @param currentSelection + * : defines the machine and its project; used as default when + * adding a new configuration + */ + public static void openAndAnimate(final IEventBRoot currentSelection) { + Shell shell = new Shell(); + AnimationPreferencesDialog dialog = new AnimationPreferencesDialog( + shell, new PreferenceManager()); + + dialog.loadConfigurations(); + if (currentSelection != null) { + dialog.setSelectedEventBRoot(currentSelection); + } + + if (dialog.open() == AnimationPreferencesDialog.OK) { + + Preferences selConfig = dialog.getSelectedConfiguration(); + + // cancel if no configuration page was selected + if (selConfig == null) + return; + + // get project and machine + String projectName = selConfig.get("project", ""); + String machineName = selConfig.get("machine", ""); + + /* get the machine-file that has to be animated */ + IInternalElement animateElement = null; + if (!projectName.equals("") + && ResourcesPlugin.getWorkspace().getRoot() + .getProject(projectName).exists()) { + if (!machineName.equals("") + && ResourcesPlugin.getWorkspace().getRoot() + .getProject(projectName).getFile(machineName) + .exists()) { + IFile animateFile = ResourcesPlugin.getWorkspace() + .getRoot().getProject(projectName) + .getFile(machineName); + animateElement = RodinCore.valueOf(animateFile).getRoot(); + } + } + + /* if machine cannot be found, show error message and throw error */ + if (animateElement == null) { + MessageBox messageBox = new MessageBox(shell, SWT.ICON_ERROR + | SWT.OK); + messageBox.setText("Error"); + messageBox.setMessage("Cannot animate machine: Project '" + + projectName + "' or machine '" + machineName + + "' do not exist."); + messageBox.open(); + + throw new UnsupportedOperationException( + "Cannot animate machine: Project '" + projectName + + "' or machine '" + machineName + + "' do not exist."); + } + + /* + * if everything is fine, get Animator and try to animate the + * machine + */ + final Animator animator = Animator.getAnimator(); + + // tell animator which configuration to use + animator.setCustomConfiguration(selConfig); + + try { + LoadEventBModelCommand.load(animator, + (IEventBRoot) animateElement); + } catch (ProBException e) { + // We cannot recover from this, but the user has been informed + return; + } + } + } + + /** + * A PreferencePage for ParentNodes to display some information. + * + */ + private static class InfoPage extends PreferencePage { + + @Override + protected Control createContents(final Composite parent) { + + // remove buttons + this.noDefaultAndApplyButton(); + + Label lbInfo = new Label(parent, SWT.NONE); + lbInfo.setText("Configure animation settings from this dialog:"); + + CLabel lbNew = new CLabel(parent, SWT.NONE); + lbNew.setImage(PlatformUI.getWorkbench().getSharedImages() + .getImage(ISharedImages.IMG_OBJ_FILE)); + lbNew.setText("- Press the 'New' button to create a new configuration."); + + CLabel lbDup = new CLabel(parent, SWT.LEFT); + lbDup.setText("- Press the 'Duplicate' button to copy the selected configuration."); + lbDup.setImage(PlatformUI.getWorkbench().getSharedImages() + .getImage(ISharedImages.IMG_TOOL_COPY)); + + CLabel lbDel = new CLabel(parent, SWT.NONE); + lbDel.setImage(PlatformUI.getWorkbench().getSharedImages() + .getImage(ISharedImages.IMG_TOOL_DELETE)); + lbDel.setText("- Press the 'Delete' button to remove the selected configuration."); + + Label lbAdditionalInfo = new Label(parent, SWT.NONE); + lbAdditionalInfo + .setText("There is also a general setting for animating machines under Preferences->ProB."); + + return parent; + } + + @Override + public boolean isValid() { + // This Page is never valid + return true; + } + + } + +} diff --git a/de.prob.ui/src/de/prob/ui/eventb/AnimationRefinementAction.java b/de.prob.ui/src/de/prob/ui/eventb/AnimationRefinementAction.java new file mode 100644 index 0000000000000000000000000000000000000000..3464a31425ecd625357adef62d3e2dc93ff378d8 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/eventb/AnimationRefinementAction.java @@ -0,0 +1,143 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.ui.eventb; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.dialogs.InputDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IObjectActionDelegate; +import org.eclipse.ui.IWorkbenchPart; +import org.eventb.core.EventBPlugin; +import org.eventb.core.IContextRoot; +import org.eventb.core.IMachineRoot; +import org.rodinp.core.IRodinFile; +import org.rodinp.core.IRodinProject; +import org.rodinp.core.RodinCore; +import org.rodinp.core.RodinDBException; + +import de.prob.logging.Logger; + +public class AnimationRefinementAction implements IObjectActionDelegate { + + private ISelection selection; + private IWorkbenchPart part; + + public AnimationRefinementAction() { + } + + public void setActivePart(final IAction action, + final IWorkbenchPart targetPart) { + this.part = targetPart; + + } + + public void run(final IAction action) { + // Get the Selection + if (!(selection instanceof IStructuredSelection)) { + return; + } + final IStructuredSelection ssel = (IStructuredSelection) selection; + if (ssel.size() != 1) { + return; + } + final Object element = ssel.getFirstElement(); + + IMachineRoot abs = null; + + if ((element instanceof IMachineRoot)) { + abs = (IMachineRoot) element; + } + if ((element instanceof IContextRoot)) { + // FIXME could be done for contexts as well + // we start with models + // abs = (IMachineRoot) element; + } + + if (abs == null) { + return; + } + + String basename = askForBaseName(abs.getRodinFile()); + + IContextRoot ctx = createContext(abs, basename); + createRefinement(abs, basename, ctx); + openWizard(); + } + + private IMachineRoot getMachineFileRoot(final String name, + final IRodinProject prj) { + final String fileName = EventBPlugin.getMachineFileName(name); + return (IMachineRoot) prj.getRodinFile(fileName).getRoot(); + } + + private IContextRoot createContext(final IMachineRoot abs, + final String basename) { + final String fileName = EventBPlugin.getContextFileName(basename + + "_ctx"); + IRodinFile file = abs.getRodinProject().getRodinFile(fileName); + try { + file.create(true, null); + IContextRoot root = (IContextRoot) file.getRoot(); + if (!root.exists()) { + root.create(null, null); + } + return root; + } catch (RodinDBException e1) { + String message = "Internal Error \n" + e1.getLocalizedMessage(); + Logger.notifyUser(message, e1); + e1.printStackTrace(); + } + return null; + } + + private void createRefinement(final IMachineRoot abs, final String name, + final IContextRoot ctx) { + IMachineRoot conc = getMachineFileRoot(name + "_mch", + abs.getRodinProject()); + CreateRefinement op = new CreateRefinement(abs, conc, ctx); + try { + RodinCore.run(op, null); + } catch (RodinDBException e) { + // TODO report error to end user + e.printStackTrace(); + return; + } + } + + /** + * Asks the user the name of the concrete machine to create and returns it. + * + * @param abs + * the abstract machine to refine + * @return the concrete machine entered by the user or <code>null</code> if + * canceled. + */ + private String askForBaseName(final IRodinFile abs) { + final InputDialog dialog = new InputDialog( + part.getSite().getShell(), + "New REFINES Clause", + "Please enter the name of the new animation model (the tool will automatically append _mch resp. _ctx)", + abs.getBareName() + "_ani1", new FileInputValidator(abs + .getRodinProject())); + dialog.open(); + + final String name = dialog.getValue(); + return name; + } + + private void openWizard() { + + } + + public void selectionChanged(final IAction action, + final ISelection selection) { + this.selection = selection; + + } + +} diff --git a/de.prob.ui/src/de/prob/ui/eventb/ClassicPreferences.java b/de.prob.ui/src/de/prob/ui/eventb/ClassicPreferences.java new file mode 100644 index 0000000000000000000000000000000000000000..d078c9eee3f6aa09dce6b386c880545fa54026b4 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/eventb/ClassicPreferences.java @@ -0,0 +1,127 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.ui.eventb; + +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.jface.preference.PreferencePage; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; +import org.osgi.service.prefs.BackingStoreException; +import org.osgi.service.prefs.Preferences; + +public class ClassicPreferences extends PreferencePage implements + IWorkbenchPreferencePage { + + public static final class PushButton extends SelectionAdapter { + + private final Text text; + private final Shell shell; + + public PushButton(final Shell shell, final Text text) { + this.shell = shell; + this.text = text; + } + + @Override + public void widgetSelected(final SelectionEvent e) { + super.widgetSelected(e); + FileDialog dialog = new FileDialog(shell, SWT.OPEN); + String open = dialog.open(); + text.setText(open); + } + + } + + private Preferences prefNode; + private Text text; + + public ClassicPreferences() { + super(); + } + + public ClassicPreferences(final String title) { + super(title); + } + + public ClassicPreferences(final String title, final ImageDescriptor image) { + super(title, image); + } + + @Override + protected Control createContents(final Composite parent) { + Composite pageComponent = new Composite(parent, SWT.NULL); + + GridLayout layout = new GridLayout(); + layout.numColumns = 3; + layout.marginHeight = 0; + layout.marginWidth = 0; + + pageComponent.setLayout(layout); + + Label label = new Label(pageComponent, SWT.NONE); + label.setText("Location of ProB classic:"); + text = new Text(pageComponent, SWT.NONE); + String location = prefNode.get("location", ""); + // text.setLayoutData(new RowData(100, SWT.DEFAULT)); + text.setText(location); + + Button browseButton = new Button(pageComponent, SWT.PUSH); + browseButton.setText("Browse"); + browseButton.addSelectionListener(new PushButton(pageComponent + .getShell(), text)); + Label versionRemark = new Label(pageComponent, SWT.WRAP); + versionRemark + .setText("Note: This needs a tcl/tk version of ProB that is not older than 1.3.0 Beta6\nYou can obtain a copy of ProB from http://www.stups.uni-duesseldorf.de/ProB\n"); + + GridData gridData2 = new GridData(); + gridData2.horizontalSpan = 3; + versionRemark.setLayoutData(gridData2); + + // Link link = new Link(pageComponent, SWT.BORDER); + // link + // .setText("This a very simple <A href=\"/downloads.php\">link</A> widget."); + // link.setSize(140, 40); + // link.addListener(SWT.Selection, new Listener() { + // public void handleEvent(final Event event) { + // System.out.println("Selection: " + event.text); + // } + // }); + + return pageComponent; + } + + @Override + public boolean performOk() { + prefNode.put("location", text.getText()); + try { + prefNode.flush(); + } catch (BackingStoreException e) { + e.printStackTrace(); + } + return super.performOk(); + } + + public void init(final IWorkbench workbench) { + prefNode = Platform.getPreferencesService().getRootNode().node( + InstanceScope.SCOPE).node("prob_classic_preferences"); + } + +} diff --git a/de.prob.ui/src/de/prob/ui/eventb/ConsistencyCheckCommand.java b/de.prob.ui/src/de/prob/ui/eventb/ConsistencyCheckCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..f399fd2f45dce3d8e20393080bd39523d9816be3 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/eventb/ConsistencyCheckCommand.java @@ -0,0 +1,42 @@ +package de.prob.ui.eventb; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.IHandler; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.PlatformUI; + +import de.prob.core.Animator; +import de.prob.ui.PerspectiveFactory; +import de.prob.ui.ProbUiPlugin; + +public class ConsistencyCheckCommand extends AbstractHandler implements + IHandler { + + public Object execute(final ExecutionEvent event) throws ExecutionException { + PerspectiveFactory.openPerspective(); + + final Animator animator = Animator.getAnimator(); + final Shell shell = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getShell(); + if (!animator.isRunning()) { + ErrorDialog.openError(shell, "Error", + "Please start an animation first", new Status( + IStatus.ERROR, ProbUiPlugin.PLUGIN_ID, + "Please start an animation first", null)); + return null; + } + + ConsistencyCheckingDialog md = new ConsistencyCheckingDialog(shell); + + md.setBlockOnOpen(true); + + md.open(); + return null; + } + +} diff --git a/de.prob.ui/src/de/prob/ui/eventb/ConsistencyCheckingDialog.java b/de.prob.ui/src/de/prob/ui/eventb/ConsistencyCheckingDialog.java new file mode 100644 index 0000000000000000000000000000000000000000..614f7c18ec6aa13c3d41836cbafccd15589cee38 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/eventb/ConsistencyCheckingDialog.java @@ -0,0 +1,159 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.ui.eventb; + +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Shell; + +import de.prob.core.command.ConsistencyCheckingSearchOption; +import de.prob.core.command.SymmetryReductionOption; +import de.prob.ui.DialogHelpers; + +public class ConsistencyCheckingDialog extends Dialog { + + private final class StartButtonSelectionListener implements + SelectionListener { + private final Button[] checks; + private final Button[] symmetry; + + private StartButtonSelectionListener(final Button[] checks, + final Button[] symmetry) { + this.checks = checks; + this.symmetry = symmetry; + } + + public void widgetSelected(final SelectionEvent e) { + String symmetryOption = selectSymmetryOption(symmetry); + Set<ConsistencyCheckingSearchOption> selectSettings = selectSettings(checks); + scheduleJob(selectSettings, symmetryOption); + close(); + } + + private Set<ConsistencyCheckingSearchOption> selectSettings( + final Button[] checks) { + HashSet<ConsistencyCheckingSearchOption> result = new HashSet<ConsistencyCheckingSearchOption>(); + for (int i = 0; i < checks.length; i++) { + if (checks[i].getSelection()) { + result.add(ConsistencyCheckingSearchOption.get(i)); + } + } + return result; + } + + private String selectSymmetryOption(final Button[] symmetry) { + int symmetryOption = 0; + for (int i = 0; i < symmetry.length; i++) { + if (symmetry[i].getSelection()) { + symmetryOption = i; + break; + } + } + return SymmetryReductionOption.get(symmetryOption).name(); + } + + private void scheduleJob( + final Set<ConsistencyCheckingSearchOption> selectSettings, + final String symmetryOption) { + job = new ConsistencyCheckingJob("Consistency Checking", + selectSettings, symmetryOption); + job.setUser(true); + job.addJobChangeListener(new ConsistencyCheckingFinishedListener(shell)); + job.schedule(); + } + + public void widgetDefaultSelected(final SelectionEvent e) { + // Do nothing + } + } + + private Job job; + private final Shell shell; + private Button startButton; + + protected ConsistencyCheckingDialog(final Shell shell) { + super(shell); + this.shell = shell; + } + + @Override + protected Control createDialogArea(final Composite parent) { + + Composite comp = (Composite) super.createDialogArea(parent); + + GridLayout layout = (GridLayout) comp.getLayout(); + layout.numColumns = 1; + + GridLayout glayout = new GridLayout(2, true); + Composite c = new Composite(comp, SWT.NONE); + c.setLayout(glayout); + + final Button[] checks = createSettingsGroup(c); + final Button[] symmetry = createSymmetryGroup(c); + + GridData data = new GridData(GridData.HORIZONTAL_ALIGN_CENTER); + startButton = new Button(comp, SWT.PUSH); + startButton.setText("Start Consistency Checking"); + startButton.setLayoutData(data); + startButton.addSelectionListener(new StartButtonSelectionListener( + checks, symmetry)); + return comp; + + } + + private Button[] createSymmetryGroup(final Composite c) { + Group group = DialogHelpers.createGroup(c, "Symmetry Reduction"); + SymmetryReductionOption[] symmetryOptions = SymmetryReductionOption + .values(); + final Button[] symmetry = new Button[symmetryOptions.length]; + + for (int i = 0; i < symmetryOptions.length; i++) { + symmetry[i] = new Button(group, SWT.RADIO); + symmetry[i].setText(symmetryOptions[i].getDescription()); + symmetry[i].setSelection(symmetryOptions[i].isDefault()); + } + return symmetry; + } + + private Button[] createSettingsGroup(final Composite c) { + Group group = DialogHelpers.createGroup(c, "Settings"); + final ConsistencyCheckingSearchOption[] options = ConsistencyCheckingSearchOption + .values(); + final Button[] checks = new Button[options.length]; + + for (int i = 0; i < options.length; i++) { + checks[i] = new Button(group, SWT.CHECK); + checks[i].setText(options[i].getDescription()); + checks[i].setSelection(options[i].isEnabledByDefault()); + } + return checks; + } + + @Override + protected void createButtonsForButtonBar(final Composite parent) { + + } + + @Override + protected void configureShell(final Shell shell) { + super.configureShell(shell); + shell.setText("Consistency Checking"); + } + +} diff --git a/de.prob.ui/src/de/prob/ui/eventb/ConsistencyCheckingFinishedListener.java b/de.prob.ui/src/de/prob/ui/eventb/ConsistencyCheckingFinishedListener.java new file mode 100644 index 0000000000000000000000000000000000000000..0033754c8c5ae6bfc19e203639b8e3b12c0f9d46 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/eventb/ConsistencyCheckingFinishedListener.java @@ -0,0 +1,242 @@ +/** + * (c) 2009-11 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.ui.eventb; + +import java.util.List; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.IJobChangeEvent; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.core.runtime.jobs.JobChangeAdapter; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.swt.widgets.Shell; + +import de.prob.core.Animator; +import de.prob.core.ProblemHandler; +import de.prob.core.command.ComputeCoverageCommand; +import de.prob.core.command.ComputeCoverageCommand.ComputeCoverageResult; +import de.prob.core.command.ConsistencyCheckingCommand.Result; +import de.prob.core.command.GetTraceCommand; +import de.prob.core.command.ReplayTraceCommand; +import de.prob.exceptions.ProBException; +import de.prob.logging.Logger; +import de.prob.ui.ProbUiPlugin; + +public class ConsistencyCheckingFinishedListener extends JobChangeAdapter { + + private static final String SEPARATOR_LINE = "==================================================="; + private static final String PLUGIN_ID = ProbUiPlugin.PLUGIN_ID; + private final Shell shell; + private final Animator animator = Animator.getAnimator(); + + public ConsistencyCheckingFinishedListener(final Shell shell) { + this.shell = shell; + } + + @Override + public void done(final IJobChangeEvent event) { + super.done(event); + Job job = event.getJob(); + if (job instanceof ConsistencyCheckingJob) { + ConsistencyCheckingJob ccJob = (ConsistencyCheckingJob) job; + showResult(ccJob.getModelCheckingResult()); + } else { + final String message = "The job has a wrong type. Expected ConsistencyCheckingJob but got " + + job.getClass(); + Logger.notifyUserWithoutBugreport(message); + } + } + + private void showResult(final Result modelCheckingResult) { + MultiStatus status = null; + ; + try { + status = createResult(modelCheckingResult); + } catch (ProBException e) { + e.notifyUserOnce(); + // No way to recover from this, but the User has been informed + } + displayResult(status); + } + + private MultiStatus createResult(final Result results) throws ProBException { + + if (results == null) { + final String message = "The last result from modelchecker was unexpectely null."; + ProblemHandler.raiseCommandException(message); + } + + ComputeCoverageResult coverage = computeCoverage(); + String header_text = "Model Checking finished"; + String text = ""; + // This code below is very boilerplate/clunky: replace by dictionary + + // lookup ?? + switch (results) { + case ok: + text = createOkResult(); + break; + case ok_not_all_nodes_considered: + text = createOkButNotFinishedResult(); + break; + case deadlock: + List<String> traceDeadlock = GetTraceCommand.getTrace(animator); + text = createDeadlockResult(traceDeadlock); + replayErrorTrace(); + header_text = "Deadlock found!"; + break; + case invariant_violation: + List<String> trace = GetTraceCommand.getTrace(animator); + text = createInvariantViolationResult(trace); + replayErrorTrace(); + header_text = "Invariant Violation found!"; + break; + case assertion_violation: + List<String> atrace = GetTraceCommand.getTrace(animator); + text = createAssertionViolationResult(atrace); + replayErrorTrace(); + header_text = "Theorem Violation found!"; + break; + case state_error: + List<String> setrace = GetTraceCommand.getTrace(animator); + text = createStateErrorResult(setrace); + replayErrorTrace(); + header_text = "State Error found!"; + break; + case well_definedness_error: + List<String> wdtrace = GetTraceCommand.getTrace(animator); + text = createWDErrorResult(wdtrace); + replayErrorTrace(); + header_text = "Well-Definedness Error found!"; + break; + case general_error: + List<String> getrace = GetTraceCommand.getTrace(animator); + text = createGeneralErrorResult(getrace); + replayErrorTrace(); + header_text = "General Error found!"; + break; + } + MultiStatus info = new MultiStatus(ProbUiPlugin.PLUGIN_ID, 1, + header_text, null); + info.add(new Status(IStatus.INFO, PLUGIN_ID, 1, text, null)); + info.add(new Status(IStatus.INFO, PLUGIN_ID, 1, SEPARATOR_LINE, null)); + + appendCoverageStatistics(coverage, PLUGIN_ID, info); + return info; + } + + private String createInvariantViolationResult(final List<String> trace) { + StringBuffer sb = new StringBuffer(); + sb.append("Invariant violation found.\n"); + sb.append("ProB has detected a state that violates the invariant.\n"); + sb.append("The following is the trace that led to the violation:\n"); + appendTrace(trace, sb); + return sb.toString(); + } + + private String createAssertionViolationResult(final List<String> trace) { + StringBuffer sb = new StringBuffer(); + sb.append("Theorem violation found.\n"); + sb.append("ProB has detected a state that violates the theorems.\n"); + sb.append("The following is the trace that led to the violation:\n"); + appendTrace(trace, sb); + return sb.toString(); + } + + private String createStateErrorResult(final List<String> trace) { + StringBuffer sb = new StringBuffer(); + sb.append("ProB has detected an erroneous state (e.g., witness error, guard strengthening error).\n"); + sb.append("The following is the trace that led to the error:\n"); + appendTrace(trace, sb); + return sb.toString(); + } + + private String createWDErrorResult(final List<String> trace) { + StringBuffer sb = new StringBuffer(); + sb.append("ProB has detected a state which caused a well-definedness error(e.g., division by zero).\n"); + sb.append("The following is the trace that led to the error:\n"); + appendTrace(trace, sb); + return sb.toString(); + } + + private String createGeneralErrorResult(final List<String> trace) { + StringBuffer sb = new StringBuffer(); + sb.append("ProB has detected a state which caused an internal error.\n"); + sb.append("This is probably a bug (please report).\n"); + sb.append("The following is the trace that led to the error:\n"); + appendTrace(trace, sb); + return sb.toString(); + } + + private String createDeadlockResult(final List<String> trace) { + StringBuffer sb = new StringBuffer(); + sb.append("Deadlock found.\n"); + sb.append("ProB has detected a state where all guards are false.\n"); + sb.append("The following is the trace that led to the deadlock:\n"); + appendTrace(trace, sb); + return sb.toString(); + } + + private void appendTrace(final List<String> trace, final StringBuffer sb) { + for (String s : trace) { + sb.append(s); + sb.append('\n'); + } + } + + private String createOkButNotFinishedResult() { + return "No errors found, but not all possible " + + "nodes have been visited (Due to animation parameter restrictions)."; + } + + private String createOkResult() { + return "No errors found\n" + + "Model Checking finished, all nodes visited.\n"; + } + + private void replayErrorTrace() throws ProBException { + ReplayTraceCommand.replay(animator); + } + + private void displayResult(final MultiStatus info) { + shell.getDisplay().asyncExec(new Runnable() { + public void run() { + ErrorDialog.openError(shell, "Model Checking finished", null, + info); + } + }); + } + + private ComputeCoverageResult computeCoverage() throws ProBException { + return ComputeCoverageCommand.getCoverage(animator); + } + + private void appendCoverageStatistics(final ComputeCoverageResult coverage, + final String PID, final MultiStatus info) { + info.add(new Status(IStatus.INFO, PID, 1, "Coverage statistics:", null)); + info.add(new Status(IStatus.INFO, PID, 1, "Total Number of Nodes:" + + coverage.getTotalNumberOfNodes(), null)); + info.add(new Status(IStatus.INFO, PID, 1, + "Total Number of Transitions:" + + coverage.getTotalNumberOfTransitions(), null)); + info.add(new Status(IStatus.INFO, PID, 1, "Node Statistics:", null)); + for (String s : coverage.getNodes()) { + info.add(new Status(IStatus.INFO, PID, 1, s, null)); + } + info.add(new Status(IStatus.INFO, PID, 1, "Operations Statistics:", + null)); + for (String s : coverage.getOps()) { + info.add(new Status(IStatus.INFO, PID, 1, s, null)); + } + info.add(new Status(IStatus.INFO, PID, 1, "Uncovered Operations:", null)); + for (String s : coverage.getUncovered()) { + info.add(new Status(IStatus.INFO, PID, 1, s, null)); + } + } + +} \ No newline at end of file diff --git a/de.prob.ui/src/de/prob/ui/eventb/ConsistencyCheckingJob.java b/de.prob.ui/src/de/prob/ui/eventb/ConsistencyCheckingJob.java new file mode 100644 index 0000000000000000000000000000000000000000..d0a19b51556a857cff89ff484f35ec345f0a2444 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/eventb/ConsistencyCheckingJob.java @@ -0,0 +1,84 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.ui.eventb; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; + +import de.prob.core.Animator; +import de.prob.core.command.ConsistencyCheckingCommand; +import de.prob.core.command.ConsistencyCheckingSearchOption; +import de.prob.core.command.SetPreferenceCommand; +import de.prob.core.command.ConsistencyCheckingCommand.Result; +import de.prob.exceptions.ProBException; + +public class ConsistencyCheckingJob extends Job { + + private final Animator animator = Animator.getAnimator(); + private boolean abort = false; + private final List<String> options; + private final String symmetryOption; + private Result modelCheckingResult = null; + + public ConsistencyCheckingJob(final String name, + final Set<ConsistencyCheckingSearchOption> options, + final String symmetryOption) { + super(name); + List<String> optlist = new ArrayList<String>(); + for (ConsistencyCheckingSearchOption modelCheckingOption : options) { + optlist.add(modelCheckingOption.name()); + } + this.options = Collections.unmodifiableList(optlist); + this.symmetryOption = symmetryOption; + } + + public Result getModelCheckingResult() { + return modelCheckingResult; + } + + @Override + protected IStatus run(final IProgressMonitor monitor) { + if (!setSymmetry()) { + return Status.CANCEL_STATUS; + } + + monitor.beginTask("Model checking", IProgressMonitor.UNKNOWN); + while (!abort) { + try { + modelCheckingResult = doSomeModelchecking(); + monitor.worked(500); + } catch (ProBException e) { + return Status.CANCEL_STATUS; // Failed + } + abort = modelCheckingResult.isAbort() || monitor.isCanceled(); + } + return Status.OK_STATUS; + } + + private boolean setSymmetry() { + try { + SetPreferenceCommand.setPreference(animator, "SYMMETRY_MODE", + symmetryOption); + } catch (ProBException e) { + return false; // Failed + } + return true; + } + + private Result doSomeModelchecking() throws ProBException { + return ConsistencyCheckingCommand.modelcheck(animator, 500, options) + .getResult(); + } + +} diff --git a/de.prob.ui/src/de/prob/ui/eventb/CreateConfigurationHandler.java b/de.prob.ui/src/de/prob/ui/eventb/CreateConfigurationHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..ece9a541a8b579462c19a02ee3d702dc68613f84 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/eventb/CreateConfigurationHandler.java @@ -0,0 +1,35 @@ +package de.prob.ui.eventb; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.IHandler; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.handlers.HandlerUtil; +import org.eventb.core.IEventBRoot; + +import de.prob.ui.PerspectiveFactory; + +public class CreateConfigurationHandler extends AbstractHandler implements + IHandler { + + public Object execute(final ExecutionEvent event) throws ExecutionException { + + ISelection fSelection = HandlerUtil.getCurrentSelection(event); + if (!(fSelection instanceof IStructuredSelection)) + return null; + final IStructuredSelection ssel = (IStructuredSelection) fSelection; + if (ssel.size() != 1) + return null; + final Object element = ssel.getFirstElement(); + if (!(element instanceof IEventBRoot)) + return null; + + PerspectiveFactory.openPerspective(); + + AnimationPreferencesDialog.openAndAnimate((IEventBRoot) element); + + return null; + } +} diff --git a/de.prob.ui/src/de/prob/ui/eventb/CreateRefinement.java b/de.prob.ui/src/de/prob/ui/eventb/CreateRefinement.java new file mode 100644 index 0000000000000000000000000000000000000000..a6b0ac33c72321ff4815fedcc32572252bdedc4a --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/eventb/CreateRefinement.java @@ -0,0 +1,132 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.ui.eventb; + +import static org.eventb.core.IConvergenceElement.Convergence.*; + +import java.util.Arrays; +import java.util.List; + +import org.eclipse.core.resources.IWorkspaceRunnable; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eventb.core.IContextRoot; +import org.eventb.core.IEvent; +import org.eventb.core.IEventBRoot; +import org.eventb.core.IMachineRoot; +import org.eventb.core.IRefinesEvent; +import org.eventb.core.IRefinesMachine; +import org.eventb.core.ISeesContext; +import org.eventb.core.IVariable; +import org.eventb.core.IConvergenceElement.Convergence; +import org.rodinp.core.IInternalElement; +import org.rodinp.core.IInternalElementType; +import org.rodinp.core.IRodinDB; +import org.rodinp.core.RodinDBException; + +public class CreateRefinement implements IWorkspaceRunnable { + private final IMachineRoot abs; + private final IMachineRoot con; + private final IContextRoot ctx; + + public CreateRefinement(final IMachineRoot abs, final IMachineRoot con, + final IContextRoot ctx) { + this.abs = abs; + this.con = con; + this.ctx = ctx; + } + + public void run(final IProgressMonitor monitor) throws RodinDBException { + con.getRodinFile().create(false, monitor); + con.setConfiguration(abs.getConfiguration(), null); + createRefinesMachineClause(monitor); + copyChildrenOfType(con, abs, ISeesContext.ELEMENT_TYPE, null, monitor); + ISeesContext seesClause = con.getSeesClause(ctx.getComponentName()); + seesClause.create(null, monitor); + copyChildrenOfType(con, abs, IVariable.ELEMENT_TYPE, null, monitor); + createEvents(monitor); + con.getRodinFile().save(null, false); + } + + private void createRefinesMachineClause(final IProgressMonitor monitor) + throws RodinDBException { + final IRefinesMachine refines = con.createChild( + IRefinesMachine.ELEMENT_TYPE, null, monitor); + refines.setAbstractMachineName(abs.getComponentName(), monitor); + } + + @SuppressWarnings("unchecked") + private <T extends IInternalElement> void copyChildrenOfType( + final IEventBRoot destination, final IEventBRoot original, + final IInternalElementType<T> type, final T additional, + final IProgressMonitor monitor) throws RodinDBException { + + T[] elements = original.getChildrenOfType(type); + if (elements.length == 0) { + return; + } + if (additional != null) { + List<T> list = Arrays.asList(elements); + list.add(additional); + elements = (T[]) list.toArray(); + } + final IEventBRoot[] containers = new IEventBRoot[] { destination }; + final IRodinDB rodinDB = destination.getRodinDB(); + rodinDB.copy(elements, containers, null, null, false, monitor); + } + + private void createEvents(final IProgressMonitor monitor) + throws RodinDBException { + final IEvent[] absEvts = abs.getChildrenOfType(IEvent.ELEMENT_TYPE); + for (IEvent absEvt : absEvts) { + createEvent(absEvt, monitor); + } + } + + private void createEvent(final IEvent absEvt, final IProgressMonitor monitor) + throws RodinDBException { + final String name = absEvt.getElementName(); + final String label = absEvt.getLabel(); + final IEvent conEvt = con.getEvent(name); + conEvt.create(null, monitor); + conEvt.setLabel(label, monitor); + conEvt.setExtended(true, monitor); + createRefinesEventClause(conEvt, label, monitor); + if (absEvt.hasComment()) { + conEvt.setComment(absEvt.getComment(), monitor); + } + setConvergence(conEvt, absEvt, monitor); + } + + private void createRefinesEventClause(final IEvent conEvt, + final String label, final IProgressMonitor monitor) + throws RodinDBException { + if (!label.equals(IEvent.INITIALISATION)) { + final IRefinesEvent refines = conEvt.createChild( + IRefinesEvent.ELEMENT_TYPE, null, monitor); + refines.setAbstractEventLabel(label, monitor); + } + } + + private void setConvergence(final IEvent conEvt, final IEvent absEvt, + final IProgressMonitor monitor) throws RodinDBException { + final Convergence absCvg = absEvt.getConvergence(); + final Convergence conCvg = computeRefinementConvergence(absCvg); + conEvt.setConvergence(conCvg, monitor); + } + + private Convergence computeRefinementConvergence(final Convergence absCvg) { + switch (absCvg) { + case ANTICIPATED: + return ANTICIPATED; + case CONVERGENT: + case ORDINARY: + return ORDINARY; + } + return ORDINARY; + } + +} diff --git a/de.prob.ui/src/de/prob/ui/eventb/ExportClassicHandler.java b/de.prob.ui/src/de/prob/ui/eventb/ExportClassicHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..a789cc14e295f6e5752a55320e200516e2c30c65 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/eventb/ExportClassicHandler.java @@ -0,0 +1,124 @@ +package de.prob.ui.eventb; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.Writer; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.IHandler; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.handlers.HandlerUtil; +import org.eventb.core.IEventBRoot; +import org.eventb.core.IMachineRoot; +import org.osgi.service.prefs.BackingStoreException; +import org.osgi.service.prefs.Preferences; + +import de.prob.core.translator.TranslationFailedException; +import de.prob.eventb.translator.TranslatorFactory; +import de.prob.logging.Logger; + +public class ExportClassicHandler extends AbstractHandler implements IHandler { + + public Object execute(final ExecutionEvent event) throws ExecutionException { + final IEventBRoot root = getSelectedEventBRoot(event); + if (root != null) { + final Preferences prefs = Platform.getPreferencesService() + .getRootNode().node(InstanceScope.SCOPE) + .node("prob_export_preferences"); + final Shell shell = HandlerUtil.getActiveShell(event); + final String fileName = askForExportFile(prefs, shell, root); + if (fileName != null) { + exportToClassic(fileName, root); + } + } + return null; + } + + private IEventBRoot getSelectedEventBRoot(final ExecutionEvent event) { + final ISelection fSelection = HandlerUtil.getCurrentSelection(event); + IEventBRoot root = null; + if (fSelection instanceof IStructuredSelection) { + final IStructuredSelection ssel = (IStructuredSelection) fSelection; + if (ssel.size() == 1 + && ssel.getFirstElement() instanceof IEventBRoot) { + root = (IEventBRoot) ssel.getFirstElement(); + } + } + return root; + } + + private String askForExportFile(final Preferences prefs, final Shell shell, + final IEventBRoot root) { + final String path = prefs.get("dir", System.getProperty("user.home")); + + final FileDialog dialog = new FileDialog(shell, SWT.SAVE); + dialog.setFilterExtensions(new String[] { "*.eventb" }); + + dialog.setFilterPath(path); + final String subext = (root instanceof IMachineRoot) ? "_mch" : "_ctx"; + dialog.setFileName(root.getComponentName() + subext + ".eventb"); + String result = dialog.open(); + if (result != null) { + final String newPath = dialog.getFilterPath(); + if (!path.equals(newPath)) { + prefs.put("dir", newPath); + try { + prefs.flush(); + } catch (BackingStoreException e) { + // Ignore, if preferences are not stored correctly we simply + // ignore it (annoying, but not critical) + } + } + if (!result.endsWith(".eventb")) { + result += ".eventb"; + } + } + return result; + } + + public static void exportToClassic(final String filename, + final IEventBRoot root) { + final boolean isSafeToWrite = isSafeToWrite(filename); + + if (isSafeToWrite) { + Writer fw = null; + try { + fw = new FileWriter(filename); + TranslatorFactory.translate(root, new PrintWriter(fw)); + fw.append('\n'); + } catch (TranslationFailedException e) { + e.notifyUserOnce(); + } catch (IOException e) { + Logger.notifyUser("Unable to create file '" + filename + "'"); + } finally { + if (fw != null) { + try { + fw.close(); + } catch (IOException e) { + } + } + } + } + } + + private static boolean isSafeToWrite(final String filename) { + if (new File(filename).exists()) { + final MessageDialog dialog = new MessageDialog(null, "File exists", + null, "The file exists. Do you want to overwrite it?", + MessageDialog.QUESTION, new String[] { "Yes", "No" }, 0); + return dialog.open() == 0; + } else + return true; + } +} diff --git a/de.prob.ui/src/de/prob/ui/eventb/FileInputValidator.java b/de.prob.ui/src/de/prob/ui/eventb/FileInputValidator.java new file mode 100644 index 0000000000000000000000000000000000000000..a351f9fc0ac8f142316b16194ade2f37c5fb7db9 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/eventb/FileInputValidator.java @@ -0,0 +1,35 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.ui.eventb; + +import org.eclipse.jface.dialogs.IInputValidator; +import org.eventb.core.IEventBProject; +import org.rodinp.core.IRodinFile; +import org.rodinp.core.IRodinProject; + +public class FileInputValidator implements IInputValidator { + private final IEventBProject prj; + + FileInputValidator(final IRodinProject prj) { + this.prj = (IEventBProject) prj.getAdapter(IEventBProject.class); + } + + public String isValid(final String newText) { + if (newText.equals("")) { + return "Name must not be empty."; + } + IRodinFile file = prj.getMachineFile(newText + "_mch"); + if (file != null && file.exists()) { + return "File name " + newText + " already exists."; + } + file = prj.getContextFile(newText + "_ctx"); + if (file != null && file.exists()) { + return "File name " + newText + " already exists."; + } + return null; + } +} diff --git a/de.prob.ui/src/de/prob/ui/eventb/OpenClassicHandler.java b/de.prob.ui/src/de/prob/ui/eventb/OpenClassicHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..c53488f10b328de79cffebc948172c8e3470a743 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/eventb/OpenClassicHandler.java @@ -0,0 +1,117 @@ +package de.prob.ui.eventb; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.IHandler; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.handlers.HandlerUtil; +import org.eventb.core.IEventBRoot; +import org.eventb.core.IMachineRoot; +import org.osgi.service.prefs.Preferences; + +import de.prob.logging.Logger; + +public class OpenClassicHandler extends AbstractHandler implements IHandler { + + private ISelection fSelection; + + public Object execute(final ExecutionEvent event) throws ExecutionException { + fSelection = HandlerUtil.getCurrentSelection(event); + + final String location = getBinaryLocation(); + if (location == null) { + Logger.notifyUserWithoutBugreport("You need to specify a location for the ProB tcl/tk version. See Preferences -> ProB Classic"); + } else { + final IEventBRoot root = getSelection(); + if (root != null) { + final File temp = createTempFile(); + final String tmp = temp.getAbsolutePath(); + ExportClassicHandler.exportToClassic(tmp, root); + + runProBClassic(location, tmp); + } + } + return null; + } + + private static final class ClassicConsole implements Runnable { + private final BufferedReader output; + + private ClassicConsole(final BufferedReader output) { + this.output = output; + } + + public void run() { + try { + while (true) { + final String line = output.readLine(); + if (line == null) { + break; + } + System.out.println("ProB Classic: " + line); + } + } catch (IOException e) { + } finally { + try { + output.close(); + } catch (IOException e1) { + } + } + + } + } + + private void runProBClassic(final String probBinary, final String modelFile) { + Process process = null; + try { + final String command = probBinary + " " + modelFile; + process = Runtime.getRuntime().exec(command); + final BufferedReader output = new BufferedReader( + new InputStreamReader(process.getInputStream())); + new Thread(new ClassicConsole(output)).start(); + + } catch (IOException e) { + Logger.notifyUserWithoutBugreport("You need to specify a location for the ProB tcl/tk version. See Preferences -> ProB Classic"); + } + } + + private String getBinaryLocation() { + Preferences preferences = Platform.getPreferencesService() + .getRootNode().node(InstanceScope.SCOPE) + .node("prob_classic_preferences"); + return preferences.get("location", null); + } + + private File createTempFile() { + File temp = null; + try { + temp = File.createTempFile("prob_", ".eventb"); + temp.deleteOnExit(); + } catch (IOException e) { + Logger.notifyUserWithoutBugreport("Something went wrong while saving temp file.\n" + + e.getLocalizedMessage()); + } + return temp; + } + + private IMachineRoot getSelection() { + if (!(fSelection instanceof IStructuredSelection)) + return null; + final IStructuredSelection ssel = (IStructuredSelection) fSelection; + if (ssel.size() != 1) + return null; + if (!(ssel.getFirstElement() instanceof IMachineRoot)) + return null; + return (IMachineRoot) ssel.getFirstElement(); + } + +} diff --git a/de.prob.ui/src/de/prob/ui/eventb/ProBAnimationPreferencePage.java b/de.prob.ui/src/de/prob/ui/eventb/ProBAnimationPreferencePage.java new file mode 100644 index 0000000000000000000000000000000000000000..5c9a6cf85a5a5b4be28e9111612d983dc8146d42 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/eventb/ProBAnimationPreferencePage.java @@ -0,0 +1,333 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.ui.eventb; + +import java.util.ArrayList; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.preference.StringButtonFieldEditor; +import org.eclipse.jface.preference.StringFieldEditor; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Group; +import org.eclipse.ui.dialogs.ContainerSelectionDialog; +import org.eclipse.ui.dialogs.ElementListSelectionDialog; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.service.prefs.BackingStoreException; +import org.osgi.service.prefs.Preferences; + +import de.prob.ui.ProBGeneralPreferences; + +/** + * Provides an extension to <code>ProBGeneralPreferences</code> with an own + * storage place and an extra field for changing the title. + * + * @see ProBGeneralPreferences + * @author Lukas Diekmann + */ +public class ProBAnimationPreferencePage extends ProBGeneralPreferences { + + private final static String TITLEERROR = "Unkown name"; + private final Preferences configurationScope; + private final String configurationId; + + // Name Field + private ConfigNameFieldEditor fdName; + private MachineFieldEditor fdMachine; + private ProjectFieldEditor fdProject; + + /** + * @param configurationName + * titlename, also used for finding this config in the + * configurationStore + * @param configurationStore + * general storage path + */ + public ProBAnimationPreferencePage(final String configurationName, + final Preferences configurationStore) { + super(configurationStore.node(configurationName)); + this.configurationId = configurationName; + this.configurationScope = configurationStore; + } + + @Override + protected Control createContents(final Composite parent) { + + Group group = new Group(parent, SWT.SHADOW_ETCHED_IN); + group.setLayout(new GridLayout(1, false)); + group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + group.setText("General Settings"); + + // since the fields somehow destroy the margins of Group, use an + // additional composite here + Composite content1 = new Composite(group, SWT.NONE); + content1.setLayout(new GridLayout(3, false)); + content1.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + fdName = new ConfigNameFieldEditor("configname", "Name:", content1); + fdName.setPage(this); + fdName.setPropertyChangeListener(this); + fdName.fillIntoGrid(content1, 3); + + addField(fdName); // add to FieldEditor list for correct validation + getPreferenceStore().setValue("configname", + getConfigurationScope().node(configurationId).get("title", "")); + getPreferenceStore().setDefault("configname", ""); + + fdProject = new ProjectFieldEditor("projectname", "Project:", content1); + fdProject.setPage(this); + fdProject.setPropertyChangeListener(this); + + addField(fdProject); // add to FieldEditor list for correct validation + getPreferenceStore().setValue( + "projectname", + getConfigurationScope().node(configurationId) + .get("project", "")); + getPreferenceStore().setDefault("projectname", ""); + + fdMachine = new MachineFieldEditor("machinename", "Machine:", content1); + fdMachine.setPage(this); + fdMachine.setPropertyChangeListener(this); + + addField(fdMachine); + getPreferenceStore().setValue( + "machinename", + getConfigurationScope().node(configurationId) + .get("machine", "")); + getPreferenceStore().setDefault("machinename", ""); + + return super.createContents(parent); + } + + @Override + public boolean performOk() { + if (fdName != null) { + getConfigNode().put("title", fdName.getStringValue()); + getContainer().updateTitle(); + } + + // Save machine and project + if (fdProject != null) { + getConfigurationScope().node(configurationId).put("project", + fdProject.getStringValue()); + } + if (fdMachine != null) { + getConfigurationScope().node(configurationId).put("machine", + fdMachine.getStringValue()); + } + + // Save ProB Settings + super.performOk(); + + return true; + } + + public String getConfigurationId() { + return configurationId; + } + + @Override + public String getTitle() { + + String title = getConfigurationScope().node(configurationId).get( + "title", TITLEERROR); + if (title == TITLEERROR) { + title = configurationId; + } + return title; + } + + private Preferences getConfigNode() { + return getConfigurationScope().node(configurationId); + } + + private Preferences getConfigurationScope() { + return configurationScope; + } + + /** + * A FieldEditor with a StringField and a button, to select a machine from a + * certain project + * + * @author Lukas Diekmann + * + */ + private class MachineFieldEditor extends StringButtonFieldEditor { + + private String lastmachine = ""; + + public MachineFieldEditor(final String name, final String labelText, + final Composite parent) { + init(name, labelText); + setChangeButtonText(JFaceResources.getString("Search...")); + setErrorMessage("Machine not specified."); + setValidateStrategy(VALIDATE_ON_KEY_STROKE); + createControl(parent); + } + + @Override + protected String changePressed() { + + IProject project = ResourcesPlugin.getWorkspace().getRoot() + .getProject(fdProject.getStringValue()); + ElementListSelectionDialog dialog = new ElementListSelectionDialog( + getShell(), new MachineLabelProvider()); + dialog.setTitle("Select Machine"); + dialog.setMessage("Select a machine:"); + + try { + ArrayList<IResource> resources = new ArrayList<IResource>(); + for (IResource r : project.members()) { + if (r.getType() == IResource.FILE + && (r.getFileExtension().equals("bum") || r + .getFileExtension().equals("buc"))) { + resources.add(r); + } + } + dialog.setElements(resources.toArray()); + + } catch (CoreException e2) { + // FIXME: display message? + } finally { + dialog.open(); + if (dialog.getResult() != null && dialog.getResult().length > 0) { + lastmachine = ((IResource) dialog.getResult()[0]).getName(); + } + } + return lastmachine; + } + } + + private static class MachineLabelProvider extends LabelProvider { + + @Override + public Image getImage(final Object element) { + if (((IResource) element).getFileExtension().equals("bum")) { + return AbstractUIPlugin.imageDescriptorFromPlugin( + AnimationPreferencesDialog.pluginId, + "icons/mch_obj.gif").createImage(); + } else if (((IResource) element).getFileExtension().equals("buc")) { + return AbstractUIPlugin.imageDescriptorFromPlugin( + AnimationPreferencesDialog.pluginId, + "icons/ctx_obj.gif").createImage(); + } + return null; + } + + @Override + public String getText(final Object element) { + if (element instanceof IResource) { + return ((IResource) element).getName(); + } else { + return element == null ? "" : element.toString(); + } + } + } + + /** + * A field editor with a StringField and a Button, to select a project from + * the workspace + * + * @author Lukas Diekmann + * + */ + private static class ProjectFieldEditor extends StringButtonFieldEditor { + + private String lastproject; + + public ProjectFieldEditor(final String name, final String labelText, + final Composite parent) { + init(name, labelText); + setChangeButtonText(JFaceResources.getString("Browse...")); + setValidateStrategy(VALIDATE_ON_KEY_STROKE); + setErrorMessage("Project not specified."); + createControl(parent); + } + + @Override + protected String changePressed() { + ContainerSelectionDialog dialog = new ContainerSelectionDialog( + getShell(), null, true, "Select a project:"); + dialog.setTitle("Select Project"); + dialog.open(); + if (dialog.getResult() != null && dialog.getResult().length > 0) { + lastproject = ResourcesPlugin.getWorkspace().getRoot() + .getProject(dialog.getResult()[0].toString()).getName(); + } + return lastproject; + } + + } + + /** + * A <code>StringFieldEditor</code> extension with an additional validation + * method, checking for duplicate configuration names or empty strings + * + * @author Lukas Diekmann + */ + private class ConfigNameFieldEditor extends StringFieldEditor { + + private static final String nameExistsError = "A configuration with this name already exists!"; + private static final String emptyStringError = "A name is required for this configuration!"; + + public ConfigNameFieldEditor(final String name, final String labelText, + final Composite parent) { + super(name, labelText, UNLIMITED, VALIDATE_ON_KEY_STROKE, parent); + } + + @Override + protected boolean doCheckState() { + + if (getStringValue().equals(getConfigNode().get("title", null))) { + return true; + } + + if ("".equals(getStringValue())) { + setErrorMessage(emptyStringError); + return false; + } + + boolean nameExists = false; + // check if the name is used by another config + try { + for (String s : getConfigurationScope().childrenNames()) { + + Preferences node = getConfigurationScope().node(s); + if (node.get("title", null) != null + && node.get("title", null).equals(getStringValue())) { + nameExists = true; + } + + } + } catch (BackingStoreException e) { + nameExists = true; + } + + // return false if the name already exists in ANOTHER configuration + if (getStringValue().equals( + AnimationPreferencesDialog.default_configuration_name) + || (nameExists && !getStringValue().equals( + getPreferenceStore().getDefaultString( + getPreferenceName())))) { + setErrorMessage(nameExistsError); + return false; + } else { + return true; + } + } + } + +} diff --git a/de.prob.ui/src/de/prob/ui/eventb/StartAnimationHandler.java b/de.prob.ui/src/de/prob/ui/eventb/StartAnimationHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..3635bc29a0290ab49569005982bd1e4a98fb5532 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/eventb/StartAnimationHandler.java @@ -0,0 +1,152 @@ +package de.prob.ui.eventb; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.IHandler; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceChangeEvent; +import org.eclipse.core.resources.IResourceChangeListener; +import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.handlers.HandlerUtil; +import org.eventb.core.IContextRoot; +import org.eventb.core.IEventBRoot; +import org.eventb.core.IMachineRoot; +import org.rodinp.core.IRodinFile; +import org.rodinp.core.RodinCore; + +import de.prob.core.Animator; +import de.prob.core.LimitedLogger; +import de.prob.core.command.LoadEventBModelCommand; +import de.prob.exceptions.ProBException; +import de.prob.logging.Logger; +import de.prob.ui.PerspectiveFactory; + +public class StartAnimationHandler extends AbstractHandler implements IHandler { + + public static class ModificationListener implements IResourceChangeListener { + + private final IPath path; + + public ModificationListener(final IFile resource) { + if (resource == null) { + path = null; + } else { + this.path = resource.getProject().getFullPath(); + } + } + + public void resourceChanged(final IResourceChangeEvent event) { + if (path != null) { + final IResourceDelta delta = event.getDelta(); + IResourceDelta member = delta.findMember(path); + if (member != null) { + Animator.getAnimator().setDirty(); + } + } + } + } + + private ISelection fSelection; + private ModificationListener listener; + + public Object execute(final ExecutionEvent event) throws ExecutionException { + + fSelection = HandlerUtil.getCurrentSelection(event); + + // Get the Selection + final IEventBRoot rootElement = getRootElement(); + final IFile resource = extractResource(rootElement); + + if (!checkErrorMarkers(resource)) { + String message = "A model/context in your project contains Errors or Warnings. This can lead to unexpected behavior (e.g. missing variables) when animating."; + Logger.notifyUserWithoutBugreport(message); + } + ; + + if (resource != null) { + LimitedLogger.getLogger().log("user started animation", + rootElement.getElementName(), null); + registerModificationListener(resource); + PerspectiveFactory.openPerspective(); + + final Animator animator = Animator.getAnimator(); + try { + LoadEventBModelCommand.load(animator, rootElement); + } catch (ProBException e) { + e.notifyUserOnce(); + throw new ExecutionException("Loading the machine failed", e); + } + } + return null; + } + + private boolean checkErrorMarkers(final IFile resource) { + IProject project = resource.getProject(); + try { + IMarker[] markers = project.findMarkers( + "org.eclipse.core.resources.problemmarker", true, + IResource.DEPTH_INFINITE); + return markers.length == 0; + } catch (CoreException e1) { + + } + return false; + } + + private IEventBRoot getRootElement() { + IEventBRoot root = null; + if (fSelection instanceof IStructuredSelection) { + final IStructuredSelection ssel = (IStructuredSelection) fSelection; + if (ssel.size() == 1) { + final Object element = ssel.getFirstElement(); + if (element instanceof IEventBRoot) { + root = (IEventBRoot) element; + } else if (element instanceof IFile) { + IRodinFile rodinFile = RodinCore.valueOf((IFile) element); + if (rodinFile != null) + root = (IEventBRoot) rodinFile.getRoot(); + } + } + } + return root; + } + + private IFile extractResource(final IEventBRoot rootElement) { + IFile resource = null; + if (rootElement == null) { + resource = null; + } else if (rootElement instanceof IMachineRoot) { + resource = ((IMachineRoot) rootElement).getSCMachineRoot() + .getResource(); + } else if (rootElement instanceof IContextRoot) { + resource = ((IContextRoot) rootElement).getSCContextRoot() + .getResource(); + } + return resource; + } + + private void registerModificationListener(final IFile resource) { + if (listener != null) { + ResourcesPlugin.getWorkspace().removeResourceChangeListener( + listener); + } + listener = new ModificationListener(resource); + ResourcesPlugin.getWorkspace().addResourceChangeListener(listener); + } + + public void selectionChanged(final IAction action, + final ISelection selection) { + fSelection = selection; + } + +} diff --git a/de.prob.ui/src/de/prob/ui/eventb/StartDistributedModelcheckHandler.java b/de.prob.ui/src/de/prob/ui/eventb/StartDistributedModelcheckHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..c0c52be3bf8551c8a736b964f679c66295289773 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/eventb/StartDistributedModelcheckHandler.java @@ -0,0 +1,149 @@ +package de.prob.ui.eventb; + +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.net.Socket; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.IHandler; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceChangeEvent; +import org.eclipse.core.resources.IResourceChangeListener; +import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.handlers.HandlerUtil; +import org.eventb.core.IContextRoot; +import org.eventb.core.IEventBRoot; +import org.eventb.core.IMachineRoot; + +import de.prob.core.Animator; +import de.prob.core.LimitedLogger; +import de.prob.core.command.CommandException; +import de.prob.core.command.LoadEventBModelCommand; +import de.prob.logging.Logger; +import de.prob.prolog.term.PrologTerm; + +public class StartDistributedModelcheckHandler extends AbstractHandler implements IHandler { + + public static class ModificationListener implements IResourceChangeListener { + + private final IPath path; + + public ModificationListener(final IFile resource) { + if (resource == null) { + path = null; + } else { + this.path = resource.getProject().getFullPath(); + } + } + + public void resourceChanged(final IResourceChangeEvent event) { + if (path != null) { + final IResourceDelta delta = event.getDelta(); + IResourceDelta member = delta.findMember(path); + if (member != null) { + Animator.getAnimator().setDirty(); + } + } + } + } + + private ISelection fSelection; + + public Object execute(final ExecutionEvent event) throws ExecutionException { + + fSelection = HandlerUtil.getCurrentSelection(event); + + // Get the Selection + final IEventBRoot rootElement = getRootElement(); + final IFile resource = extractResource(rootElement); + + if (!checkErrorMarkers(resource)) { + String message = "A model/context in your project contains Errors or Warnings. This can lead to unexpected behavior (e.g. missing variables) when animating."; + Logger.notifyUserWithoutBugreport(message); + } + ; + + if (resource != null) { + LimitedLogger.getLogger().log("user started distributed modelcheck", + rootElement.getElementName(), null); + try { + PrologTerm output = LoadEventBModelCommand.toPrologTerm(rootElement); + Socket s = null; + try { + s = new Socket("localhost", 4444); + new ObjectOutputStream(s.getOutputStream()).writeObject(output); + } catch (IOException e) { + Logger.notifyUserWithoutBugreport("unable to connect to master", e); + } finally { + if (s != null) { + try { + s.close(); + } catch (IOException e) { + // ignore + } + } + } + } catch (CommandException e) { + throw new ExecutionException("unable to translate model", e); + } + } + return null; + } + + private boolean checkErrorMarkers(final IFile resource) { + IProject project = resource.getProject(); + try { + IMarker[] markers = project.findMarkers( + "org.eclipse.core.resources.problemmarker", true, + IResource.DEPTH_INFINITE); + return markers.length == 0; + } catch (CoreException e1) { + + } + return false; + } + + private IEventBRoot getRootElement() { + IEventBRoot root = null; + if (fSelection instanceof IStructuredSelection) { + final IStructuredSelection ssel = (IStructuredSelection) fSelection; + if (ssel.size() == 1) { + final Object element = ssel.getFirstElement(); + if (element instanceof IEventBRoot) { + root = (IEventBRoot) element; + } + } + } + return root; + } + + private IFile extractResource(final IEventBRoot rootElement) { + IFile resource = null; + if (rootElement == null) { + resource = null; + } else if (rootElement instanceof IMachineRoot) { + resource = ((IMachineRoot) rootElement).getSCMachineRoot() + .getResource(); + } else if (rootElement instanceof IContextRoot) { + resource = ((IContextRoot) rootElement).getSCContextRoot() + .getResource(); + } + return resource; + } + + public void selectionChanged(final IAction action, + final ISelection selection) { + fSelection = selection; + } + +} diff --git a/de.prob.ui/src/de/prob/ui/historyview/HistoryElementLabelProvider.java b/de.prob.ui/src/de/prob/ui/historyview/HistoryElementLabelProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..037673f10de18486b1ad020cc83a3c98bde1b40d --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/historyview/HistoryElementLabelProvider.java @@ -0,0 +1,37 @@ +/** + * + */ +package de.prob.ui.historyview; + +import org.eclipse.swt.graphics.Color; + +import de.prob.ui.historyview.HistoryView.HistViewItem; +import de.prob.ui.stateview.StateLabelProvider; +import de.prob.ui.stateview.statetree.StaticStateElement; + +/** + * Label provider for the columns of the history view that contain StateElements + * (like in the state view). To be consistent with the state view, the class + * acts as a delegate to a {@link StateLabelProvider} object. + * + * @author plagge + */ +public class HistoryElementLabelProvider extends HistoryLabelProvider { + private final StateLabelProvider slProvider = new StateLabelProvider(); + private final StaticStateElement sse; + + public HistoryElementLabelProvider(final StaticStateElement sse) { + super(); + this.sse = sse; + } + + @Override + protected String getText(final HistViewItem item) { + return slProvider.getText(item.getDestination(), sse); + } + + @Override + protected Color getForeground(final HistViewItem item) { + return slProvider.getForeground(item.getDestination(), sse); + } +} diff --git a/de.prob.ui/src/de/prob/ui/historyview/HistoryEventLabelProvider.java b/de.prob.ui/src/de/prob/ui/historyview/HistoryEventLabelProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..f407ed98c034bc03d58546d176b7347400f68b28 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/historyview/HistoryEventLabelProvider.java @@ -0,0 +1,42 @@ +package de.prob.ui.historyview; + +import java.util.List; + +import de.prob.core.domainobjects.Operation; +import de.prob.core.domainobjects.Operation.EventStackElement; +import de.prob.ui.historyview.HistoryView.HistViewItem; + +/** + * Label provider for the columns of the history view that contain the names of + * executed events. + * + * @author plagge + */ +class HistoryEventLabelProvider extends HistoryLabelProvider { + private final int eventStackPosition; + + public HistoryEventLabelProvider(final int eventStackPosition) { + super(); + this.eventStackPosition = eventStackPosition; + } + + @Override + protected String getText(final HistViewItem item) { + final String result; + final Operation operation = item.getOperation(); + if (operation != null) { + List<EventStackElement> stack = operation.getEventStack(); + if (stack != null) { + result = eventStackPosition < stack.size() ? stack.get( + eventStackPosition).getEventName() : null; + } else { + result = eventStackPosition == 0 ? operation.getName() : null; + } + } else { + result = eventStackPosition == 0 ? HistoryViewStrings.uninitialisedState + : null; + } + return result == null ? "" : result; + } + +} \ No newline at end of file diff --git a/de.prob.ui/src/de/prob/ui/historyview/HistoryLabelProvider.java b/de.prob.ui/src/de/prob/ui/historyview/HistoryLabelProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..5a5af8d54d75e905628fe89e7c795816f2d4855c --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/historyview/HistoryLabelProvider.java @@ -0,0 +1,54 @@ +/** + * + */ +package de.prob.ui.historyview; + +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.viewers.CellLabelProvider; +import org.eclipse.jface.viewers.ViewerCell; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.widgets.Display; + +import de.prob.ui.historyview.HistoryView.HistViewItem; + +/** + * Base class for label provider for the columns of the history view. + * + * @author plagge + */ +public abstract class HistoryLabelProvider extends CellLabelProvider { + private final Color currentPositionColor = Display.getDefault() + .getSystemColor(SWT.COLOR_INFO_BACKGROUND); + final Font bold = JFaceResources.getFontRegistry().getBold( + JFaceResources.BANNER_FONT); + + @Override + public void update(final ViewerCell cell) { + final Object element = cell.getElement(); + if (element != null && element instanceof HistViewItem) { + final HistViewItem item = (HistViewItem) element; + cell.setText(getText(item)); + cell.setForeground(getForeground(item)); + cell.setBackground(getBackground(item)); + cell.setFont(getFont(item)); + } + } + + protected Font getFont(final HistViewItem item) { + return item.isSameAsCurrent() ? bold : null; + } + + protected Color getBackground(final HistViewItem item) { + return item.isActive() ? currentPositionColor : null; + } + + protected String getText(final HistViewItem item) { + return null; + } + + protected Color getForeground(final HistViewItem item) { + return null; + } +} diff --git a/de.prob.ui/src/de/prob/ui/historyview/HistoryView.java b/de.prob.ui/src/de/prob/ui/historyview/HistoryView.java new file mode 100644 index 0000000000000000000000000000000000000000..06ef8f16339580de0ed17d6ac063c41b0c3d8018 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/historyview/HistoryView.java @@ -0,0 +1,255 @@ +/** + * + */ +package de.prob.ui.historyview; + +import java.util.Collection; + +import org.apache.commons.lang.ArrayUtils; +import org.apache.commons.lang.ObjectUtils; +import org.eclipse.jface.layout.TableColumnLayout; +import org.eclipse.jface.viewers.ColumnWeightData; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerDropAdapter; +import org.eclipse.swt.SWT; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.DropTargetListener; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.dnd.TransferData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; + +import de.prob.core.Animator; +import de.prob.core.domainobjects.History; +import de.prob.core.domainobjects.HistoryItem; +import de.prob.core.domainobjects.Operation; +import de.prob.core.domainobjects.State; +import de.prob.exceptions.ProBException; +import de.prob.logging.Logger; +import de.prob.ui.StateBasedViewPart; +import de.prob.ui.dnd.StaticStateElementTransfer; +import de.prob.ui.stateview.statetree.StaticStateElement; + +/** + * The history view shows the current history of the animator. This includes the + * name of executed events and optional expressions on the state. + * + * @author plagge + */ +public class HistoryView extends StateBasedViewPart { + public static final String VIEW_ID = "de.prob.ui.HistoryView"; + + private TableViewer tableViewer; + + @Override + protected Control createStatePartControl(final Composite parent) { + Composite tableComposite = new Composite(parent, SWT.NONE); + tableViewer = new TableViewer(tableComposite, SWT.NONE); + tableViewer.setContentProvider(new HistContentProvider()); + // tableViewer.setLabelProvider(new HistoryLabelProviderOld()); + tableViewer.addDoubleClickListener(new HistDoubleClickListener()); + createColumns(tableComposite); + final Table table = tableViewer.getTable(); + table.setHeaderVisible(true); + table.setLinesVisible(true); + initDragAndDrop(); + return tableComposite; + } + + private void initDragAndDrop() { + Transfer[] transferTypes = new Transfer[] { StaticStateElementTransfer + .getInstance() }; + DropTargetListener dropListener = new ViewerDropAdapter(tableViewer) { + @Override + public boolean validateDrop(final Object target, final int type, + final TransferData transferData) { + final boolean isSupported = StaticStateElementTransfer + .getInstance().isSupportedType(transferData); + // System.out.println("validateDrop: is " + // + (isSupported ? "" : "not ") + "supported, type=" + // + type); + return isSupported; + } + + @Override + public boolean performDrop(final Object data) { + // System.out.println("peformDrop"); + if (data != null && data instanceof StaticStateElement[]) + return true; + else + return false; + } + }; + tableViewer.addDropSupport(DND.DROP_COPY | DND.DROP_MOVE, + transferTypes, dropListener); + } + + public void addColumns(final Collection<StaticStateElement> elements) { + final Runnable update = new Runnable() { + public void run() { + final Composite parent = tableViewer.getTable().getParent(); + final TableColumnLayout layout = (TableColumnLayout) parent + .getLayout(); + for (final StaticStateElement element : elements) { + createColumn(layout, element.getLabel(), + new HistoryElementLabelProvider(element), false); + } + parent.layout(); + parent.redraw(); + tableViewer.refresh(); + } + }; + Display.getDefault().asyncExec(update); + } + + private void createColumns(final Composite composite) { + final Animator animator = Animator.getAnimator(); + final String[] events = animator.getMachineDescription() + .getModelNames().toArray(new String[0]); + ArrayUtils.reverse(events); + final TableColumnLayout layout = new TableColumnLayout(); + composite.setLayout(layout); + if (events.length > 0) { + int pos = 0; + for (final String event : events) { + final boolean isFirst = pos == 0; + createColumn(layout, event, new HistoryEventLabelProvider(pos), + isFirst); + pos++; + } + } else { + createColumn(layout, "Event", new HistoryEventLabelProvider(0), + false); + } + } + + private void createColumn(final TableColumnLayout layout, + final String header, final HistoryLabelProvider labelProvider, + final boolean setMinimumSize) { + final TableViewerColumn tvc = new TableViewerColumn(tableViewer, + SWT.NONE); + tvc.setLabelProvider(labelProvider); + final TableColumn column = tvc.getColumn(); + column.setText(header); + column.setResizable(true); + column.setMoveable(true); + final ColumnWeightData weightData = setMinimumSize ? new ColumnWeightData( + 1, 100) : new ColumnWeightData(1); + layout.setColumnData(column, weightData); + } + + @Override + protected void stateChanged(final State currentState, + final Operation operation) { + final Animator animator = Animator.getAnimator(); + final History history = animator.getHistory(); + final HistoryItem[] items = history.getAllItems(); + final int size = items.length; + final HistViewItem[] vItems = new HistViewItem[size]; + final HistViewItem current; + if (size > 0) { + final int activeItem = history.getCurrentPosition(); + final State cs = items[activeItem].getState(); + vItems[0] = new HistViewItem(0, items[0].getState(), null, + activeItem == 0, + ObjectUtils.equals(items[0].getState(), cs)); + for (int i = 1; i < size; i++) { + final boolean active = activeItem == i; + final State state = items[i].getState(); + final Operation op = items[i - 1].getOperation(); + vItems[i] = new HistViewItem(i, state, op, active, + ObjectUtils.equals(cs, state)); + } + current = vItems[activeItem]; + ArrayUtils.reverse(vItems); + } else { + current = null; + } + tableViewer.setInput(vItems); + tableViewer.refresh(); + if (current != null) { + tableViewer.reveal(current); + } + } + + static class HistViewItem { + private final int historyPosition; + private final State dstState; + private final Operation operation; + private final boolean isActive, sameAsCurrent; + + public HistViewItem(final int historyPosition, final State dstState, + final Operation operation, final boolean isActive, + final boolean sameAsCurrent) { + this.historyPosition = historyPosition; + this.dstState = dstState; + this.operation = operation; + this.isActive = isActive; + this.sameAsCurrent = sameAsCurrent; + } + + public State getDestination() { + return dstState; + } + + public Operation getOperation() { + return operation; + } + + public boolean isActive() { + return isActive; + } + + public boolean isSameAsCurrent() { + return sameAsCurrent; + } + + public void jumpToState() throws ProBException { + final History history = Animator.getAnimator().getHistory(); + history.gotoPos(historyPosition); + } + } + + private static class HistContentProvider implements + IStructuredContentProvider { + + public Object[] getElements(final Object data) { + return data == null ? new HistViewItem[0] : (HistViewItem[]) data; + } + + public void dispose() { + } + + public void inputChanged(final Viewer arg0, final Object arg1, + final Object arg2) { + } + } + + private static class HistDoubleClickListener implements + IDoubleClickListener { + private static final String EXCEPTION_MSG = "exception raised while trying to jump to state"; + + public void doubleClick(final DoubleClickEvent event) { + IStructuredSelection sel = (IStructuredSelection) event + .getSelection(); + if (sel != null && !sel.isEmpty()) { + HistViewItem item = (HistViewItem) sel.getFirstElement(); + try { + item.jumpToState(); + } catch (ProBException e) { + Logger.notifyUser(EXCEPTION_MSG, e); + } + } + } + } + +} diff --git a/de.prob.ui/src/de/prob/ui/historyview/HistoryViewStrings.java b/de.prob.ui/src/de/prob/ui/historyview/HistoryViewStrings.java new file mode 100644 index 0000000000000000000000000000000000000000..0e8369b3fed08e233e1b4d1fca6910d85a6ac86a --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/historyview/HistoryViewStrings.java @@ -0,0 +1,21 @@ +/** + * + */ +package de.prob.ui.historyview; + +import org.eclipse.osgi.util.NLS; + +/** + * Natural language strings for the history view + * + * @author plagge + */ +public class HistoryViewStrings extends NLS { + public static String uninitialisedState; + + static { + final Class<HistoryViewStrings> clazz = HistoryViewStrings.class; + initializeMessages(clazz.getName(), clazz); + } + +} diff --git a/de.prob.ui/src/de/prob/ui/historyview/HistoryViewStrings.properties b/de.prob.ui/src/de/prob/ui/historyview/HistoryViewStrings.properties new file mode 100644 index 0000000000000000000000000000000000000000..6531e550688009fd3dfa1cb27eda296d4f5c1c0f --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/historyview/HistoryViewStrings.properties @@ -0,0 +1 @@ +uninitialisedState=(uninitialised state) diff --git a/de.prob.ui/src/de/prob/ui/internal/GenericAnalyzeHandler.java b/de.prob.ui/src/de/prob/ui/internal/GenericAnalyzeHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..41168305cac6fff9a91c9aee50451abcbfe66f7c --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/internal/GenericAnalyzeHandler.java @@ -0,0 +1,113 @@ +package de.prob.ui.internal; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.dialogs.TitleAreaDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.handlers.HandlerUtil; + +import de.prob.core.Animator; +import de.prob.core.ProBCommandJob; +import de.prob.core.ProBJobFinishedListener; +import de.prob.core.command.CommandException; +import de.prob.core.command.IComposableCommand; +import de.prob.core.command.ISimpleTextCommand; +import de.prob.logging.Logger; + +public abstract class GenericAnalyzeHandler extends AbstractHandler { + + public class GenericAnalyzeFinishedHandler extends ProBJobFinishedListener { + + private final Shell shell; + + public GenericAnalyzeFinishedHandler(Shell shell) { + this.shell = shell; + } + + @Override + protected void showResult(IComposableCommand command, Animator animator) { + if (command instanceof ISimpleTextCommand) { + ISimpleTextCommand textcommand = (ISimpleTextCommand) command; + String text = textcommand.getResultingText(); + display(text); + } else { + Logger.notifyUser( + "The invoked command did not implement the correct interface. Please report this bug.", + new CommandException( + "Error in " + + command.getClass() + + ". Class should implement ISimpleTextCommand.")); + } + } + + private void display(final String text) { + + final TitleAreaDialog titleAreaDialog = new TitleAreaDialog(shell) { + + @Override + protected Control createDialogArea(Composite parent) { + + setTitle(name); + + Composite composite = (Composite) super + .createDialogArea(parent); + Text t = new Text(composite, SWT.WRAP | SWT.MULTI | SWT.BORDER + | SWT.H_SCROLL | SWT.V_SCROLL); + GridData gridData = + new GridData( + GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL); + gridData.grabExcessVerticalSpace = true; + + t.setLayoutData(gridData); + + + t.append(text); + return composite; + } + + }; + + final Runnable runnable = new Runnable() { + @Override + public void run() { + titleAreaDialog.open(); + } + }; + shell.getDisplay().asyncExec(runnable); + } + } + + private final ISimpleTextCommand command; + private final String name; + + public GenericAnalyzeHandler(ISimpleTextCommand command, String name) { + this.command = command; + this.name = name; + } + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + final Shell shell = HandlerUtil.getActiveShell(event); + Animator animator = Animator.getAnimator(); + if (animator.isMachineLoaded()) { + final ProBCommandJob job = new ProBCommandJob(name, animator, + command); + GenericAnalyzeFinishedHandler finishedHandler = new GenericAnalyzeFinishedHandler( + shell); + job.setUser(true); + job.addJobChangeListener(finishedHandler); + job.schedule(); + + } else { + Logger.notifyUser("No ProB animation running. This is a bug. Please submit a report. Error in declaraion of class "+this.getClass()); + } + return null; + } + +} diff --git a/de.prob.ui/src/de/prob/ui/internal/InvariantAnalyzeHandler.java b/de.prob.ui/src/de/prob/ui/internal/InvariantAnalyzeHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..e7001d44c1b35e59b25664f1891b03a410659a75 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/internal/InvariantAnalyzeHandler.java @@ -0,0 +1,11 @@ +package de.prob.ui.internal; + +import de.prob.core.command.AnalyseInvariantCommand; + +public class InvariantAnalyzeHandler extends GenericAnalyzeHandler { + + public InvariantAnalyzeHandler() { + super(new AnalyseInvariantCommand(), "Analyze Invariant"); + } + +} diff --git a/de.prob.ui/src/de/prob/ui/internal/OpenWebsiteCommand.java b/de.prob.ui/src/de/prob/ui/internal/OpenWebsiteCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..8eb13950254a4eb912255c3abc8881c0d9c23978 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/internal/OpenWebsiteCommand.java @@ -0,0 +1,46 @@ +package de.prob.ui.internal; + +import java.net.MalformedURLException; +import java.net.URL; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.browser.IWorkbenchBrowserSupport; + +import de.prob.logging.Logger; + +public class OpenWebsiteCommand extends AbstractHandler { + + public Object execute(final ExecutionEvent event) throws ExecutionException { + + String url = event.getParameter("de.prob.ui.openwebsite.url"); + + URL websiteurl = null; + try { + websiteurl = new URL(url); + } catch (MalformedURLException e1) { + // File a bug report! + String message = "Internal error. Malformed website URL (" + url + + "). Please file a bug report."; + Logger.notifyUser(message, e1); + return null; + } + + IWorkbenchBrowserSupport browserSupport = PlatformUI.getWorkbench() + .getBrowserSupport(); + + try { + browserSupport.getExternalBrowser().openURL(websiteurl); + } catch (PartInitException e1) { + String message = "Internal error. Cannt open external browser."; + Logger.notifyUser(message, e1); + return null; + } + + return null; + } + +} diff --git a/de.prob.ui/src/de/prob/ui/internal/ShowProBConfigCommand.java b/de.prob.ui/src/de/prob/ui/internal/ShowProBConfigCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..8d75af40058f9eb8f57b7daf864ff431bdea360e --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/internal/ShowProBConfigCommand.java @@ -0,0 +1,41 @@ +package de.prob.ui.internal; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.IHandler; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.ISelectionService; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.handlers.HandlerUtil; +import org.eventb.core.IEventBRoot; + +import de.prob.ui.eventb.AnimationPreferencesDialog; + +public class ShowProBConfigCommand extends AbstractHandler implements IHandler { + + public Object execute(final ExecutionEvent event) throws ExecutionException { + + IEventBRoot selectedObject = null; + + IWorkbenchWindow window = HandlerUtil + .getActiveWorkbenchWindowChecked(event); + + ISelectionService selectionService = window.getSelectionService(); + + ISelection selection = selectionService + .getSelection("fr.systerel.explorer.navigator.view"); + + if (selection instanceof IStructuredSelection) { + IStructuredSelection sel = (IStructuredSelection) selection; + Object s = sel.getFirstElement(); + if (s instanceof IEventBRoot) { + selectedObject = (IEventBRoot) s; + } + } + + AnimationPreferencesDialog.openAndAnimate(selectedObject); + return null; + } +} diff --git a/de.prob.ui/src/de/prob/ui/invcheck/InvariantCheckDialog.java b/de.prob.ui/src/de/prob/ui/invcheck/InvariantCheckDialog.java new file mode 100644 index 0000000000000000000000000000000000000000..8dc5b0ea8aeb238d48a1e20155a5c69eab39e2c9 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/invcheck/InvariantCheckDialog.java @@ -0,0 +1,81 @@ +/** + * + */ +package de.prob.ui.invcheck; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ListViewer; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; + +/** + * @author plagge + * + */ +public class InvariantCheckDialog extends Dialog { + + private final Collection<String> events; + + private ListViewer listviewer; + private Collection<String> selected; + + public InvariantCheckDialog(final Shell parentShell, + final Collection<String> events) { + super(parentShell); + this.events = new ArrayList<String>(events); + } + + @Override + protected Control createDialogArea(final Composite parent) { + final Composite composite = (Composite) super.createDialogArea(parent); + composite.getShell().setText("Constraint Based Invariant Check"); + composite.setLayout(new GridLayout()); + // final Button check = new Button(composite, SWT.CHECK); + final Label label1 = new Label(composite, SWT.NONE); + label1.setText("You can limit the analysis to some events."); + final Label label2 = new Label(composite, SWT.NONE); + label2.setText("If no event is chosen, all events will be checked."); + listviewer = new ListViewer(composite, SWT.MULTI | SWT.V_SCROLL + | SWT.BORDER); + final GridData listLayout = new GridData(); + listLayout.grabExcessHorizontalSpace = true; + listviewer.getList().setLayoutData(listLayout); + listviewer.setContentProvider(new ArrayContentProvider()); + listviewer.setInput(events); + listviewer.addSelectionChangedListener(new ISelectionChangedListener() { + @Override + public void selectionChanged(final SelectionChangedEvent event) { + final ISelection sel = event.getSelection(); + if (sel instanceof IStructuredSelection) { + final IStructuredSelection ssel = (IStructuredSelection) sel; + final Collection<String> newSelection = new ArrayList<String>(); + for (Iterator<?> it = ssel.iterator(); it.hasNext();) { + final Object item = it.next(); + newSelection.add(item.toString()); + } + selected = newSelection; + } + } + }); + composite.pack(); + return composite; + } + + public Collection<String> getSelected() { + return selected; + } +} diff --git a/de.prob.ui/src/de/prob/ui/invcheck/InvariantCheckFinishedListener.java b/de.prob.ui/src/de/prob/ui/invcheck/InvariantCheckFinishedListener.java new file mode 100644 index 0000000000000000000000000000000000000000..01401e325f653319cc13d282b5f0eb69fae759bd --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/invcheck/InvariantCheckFinishedListener.java @@ -0,0 +1,94 @@ +/** + * + */ +package de.prob.ui.invcheck; + +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Shell; + +import de.prob.core.Animator; +import de.prob.core.ProBJobFinishedListener; +import de.prob.core.command.ConstraintBasedInvariantCheckCommand; +import de.prob.core.command.ConstraintBasedInvariantCheckCommand.ResultType; +import de.prob.core.command.ExecuteOperationCommand; +import de.prob.core.command.IComposableCommand; +import de.prob.core.domainobjects.Operation; +import de.prob.exceptions.ProBException; +import de.prob.logging.Logger; + +/** + * + * @author plagge + * + */ +public class InvariantCheckFinishedListener extends ProBJobFinishedListener { + + private final Shell shell; + + public InvariantCheckFinishedListener(final Shell shell) { + this.shell = shell; + } + + @Override + protected void showResult(final IComposableCommand command, + final Animator animator) { + final ConstraintBasedInvariantCheckCommand invCmd = (ConstraintBasedInvariantCheckCommand) command; + final ResultType result = invCmd.getResult(); + final int dialogType; + final String dialogTitle; + final String message; + switch (result) { + case INTERRUPTED: + dialogType = MessageDialog.WARNING; + dialogTitle = "User Interrupt"; + message = "The invariant check has been interrupted by the user."; + break; + case NO_VIOLATION_FOUND: + dialogType = MessageDialog.INFORMATION; + dialogTitle = "No Invariant Violation found"; + message = "No possible invariant violation has been found."; + break; + case VIOLATION_FOUND: + dialogType = MessageDialog.ERROR; + dialogTitle = "Invariant Violation found"; + message = "An invariant violation has been found.\nThe first found example will be shown in the history."; + displayViolation(invCmd, animator); + break; + default: + Logger.notifyUser("Unexpected result: " + result); + return; + } + if (shell.isDisposed()) { + System.out.println("Invariant Check finished: " + dialogTitle); + } else { + final Runnable runnable = new Runnable() { + @Override + public void run() { + MessageDialog.open(dialogType, shell, dialogTitle, message, + SWT.NONE); + } + }; + shell.getDisplay().asyncExec(runnable); + } + } + + private void displayViolation( + final ConstraintBasedInvariantCheckCommand cmd, + final Animator animator) { + final ConstraintBasedInvariantCheckCommand.InvariantCheckCounterExample example = cmd + .getCounterExamples().iterator().next(); + final Operation step1 = example.getStep1(); + final Operation step2 = example.getStep2(); + try { + // we do not reset the history because we want to keep the root + // state, we just start a new path from root + animator.getHistory().gotoPos(0); + ExecuteOperationCommand.executeOperation(animator, step1); + ExecuteOperationCommand.executeOperation(animator, step2); + } catch (ProBException e) { + e.notifyUserOnce(); + } + } + +} diff --git a/de.prob.ui/src/de/prob/ui/invcheck/InvariantCheckHandler.java b/de.prob.ui/src/de/prob/ui/invcheck/InvariantCheckHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..10b5538bfba497af2cde8e4841390592bd3a9307 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/invcheck/InvariantCheckHandler.java @@ -0,0 +1,73 @@ +/** + * + */ +package de.prob.ui.invcheck; + +import java.util.Collection; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jface.dialogs.InputDialog; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.handlers.HandlerUtil; + +import de.prob.core.Animator; +import de.prob.core.ProBCommandJob; +import de.prob.core.command.ConstraintBasedInvariantCheckCommand; +import de.prob.core.domainobjects.MachineDescription; + +/** + * + * @author plagge + */ +public class InvariantCheckHandler extends AbstractHandler { + @Override + public Object execute(final ExecutionEvent event) throws ExecutionException { + final Shell shell = HandlerUtil.getActiveShell(event); + final Animator animator = Animator.getAnimator(); + if (animator.isMachineLoaded()) { + performInvariantCheck(animator, shell); + } else { + MessageDialog + .openError( + shell, + "Error: No ProB animation running", + "To perform a constraint based invariant check, please start the animation of the model first."); + } + return null; + } + + private void performInvariantCheck(final Animator animator, + final Shell shell) throws ExecutionException { + final MachineDescription md = animator.getMachineDescription(); + final Collection<String> events = md.getEventNames(); + if (events.isEmpty()) { + MessageDialog.openError(shell, "Invariant Check: No Events", + "The model does not contain any events to check!"); + + } else { + final InvariantCheckDialog dialog = new InvariantCheckDialog(shell, + events); + final int status = dialog.open(); + if (status == InputDialog.OK) { + startCheck(animator, dialog.getSelected(), shell); + } + } + } + + private void startCheck(final Animator animator, + final Collection<String> events, final Shell shell) + throws ExecutionException { + final ConstraintBasedInvariantCheckCommand command = new ConstraintBasedInvariantCheckCommand( + events); + final Job job = new ProBCommandJob( + "Checking for Invariant Preservation", animator, command); + job.setUser(true); + job.addJobChangeListener(new InvariantCheckFinishedListener(shell)); + job.schedule(); + } + +} diff --git a/de.prob.ui/src/de/prob/ui/ltl/CEHistoryHandler.java b/de.prob.ui/src/de/prob/ui/ltl/CEHistoryHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..92d841cb6b3c023e24d6c2675aff24403a85113e --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ltl/CEHistoryHandler.java @@ -0,0 +1,80 @@ +/** + * + */ +package de.prob.ui.ltl; + +import java.util.List; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.IHandler; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; + +import de.prob.core.Animator; +import de.prob.core.command.SetTraceCommand; +import de.prob.core.domainobjects.Operation; +import de.prob.core.domainobjects.ltl.CounterExample; +import de.prob.exceptions.ProBException; +import de.prob.ui.ProbUiPlugin; + +/** + * This handler is used to take the current counter-example and fill it into the + * history. + * + * @author plagge + */ +public class CEHistoryHandler extends AbstractHandler implements IHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + final IWorkbenchWindow window = ProbUiPlugin.getDefault() + .getWorkbench().getActiveWorkbenchWindow(); + final CounterExampleView view = findCEView(window); + if (view != null) { + final CounterExample ce = view.getCurrentCounterExample(); + if (ce != null) { + try { + showCounterexampleInAnimator(ce); + } catch (ProBException e) { + e.notifyUserOnce(); + throw new ExecutionException( + "ProB setTrace command failed", e); + } + } + } + return null; + } + + private void showCounterexampleInAnimator(CounterExample ce) + throws ProBException { + final List<Operation> fullPath = ce.getFullPath(); + final SetTraceCommand cmd = new SetTraceCommand(fullPath); + final Animator animator = Animator.getAnimator(); + animator.execute(cmd); + cmd.setTraceInHistory(animator, fullPath.size()); + } + + private CounterExampleView findCEView(final IWorkbenchWindow window) { + final IWorkbenchPage page = window.getActivePage(); + IViewPart view = page.findView(CounterExampleView.ID); + if (view == null) { + MessageDialog.openError(window.getShell(), "Internal Error", + "Cannot not find the History View"); + return null; + } else { + if (view instanceof CounterExampleView) + return (CounterExampleView) view; + else { + MessageDialog.openError(window.getShell(), "Internal Error", + "Not expected type of the Counter Example View: " + + view.getClass().getName()); + return null; + } + } + } + +} diff --git a/de.prob.ui/src/de/prob/ui/ltl/CounterExampleBinaryEditPart.java b/de.prob.ui/src/de/prob/ui/ltl/CounterExampleBinaryEditPart.java new file mode 100644 index 0000000000000000000000000000000000000000..2f2d2c9ff55393846547933fee8b21be68891486 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ltl/CounterExampleBinaryEditPart.java @@ -0,0 +1,14 @@ +package de.prob.ui.ltl; + +import org.eclipse.draw2d.IFigure; + +import de.prob.core.domainobjects.ltl.CounterExampleProposition; + +public final class CounterExampleBinaryEditPart extends + CounterExamplePropositionEditPart { + @Override + protected IFigure createFigure() { + CounterExampleProposition model = (CounterExampleProposition) getModel(); + return new CounterExampleBinaryFigure(model); + } +} diff --git a/de.prob.ui/src/de/prob/ui/ltl/CounterExampleBinaryFigure.java b/de.prob.ui/src/de/prob/ui/ltl/CounterExampleBinaryFigure.java new file mode 100644 index 0000000000000000000000000000000000000000..fbdbd44d05969dc73a09292bf5e6328ecdac8682 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ltl/CounterExampleBinaryFigure.java @@ -0,0 +1,196 @@ +package de.prob.ui.ltl; + +import java.util.Hashtable; +import java.util.List; + +import org.eclipse.draw2d.Connection; +import org.eclipse.draw2d.Ellipse; +import org.eclipse.draw2d.Label; +import org.eclipse.draw2d.MouseEvent; +import org.eclipse.draw2d.Panel; +import org.eclipse.draw2d.TitleBarBorder; +import org.eclipse.draw2d.geometry.Rectangle; + +import de.prob.core.domainobjects.ltl.CounterExampleBinaryOperator; +import de.prob.core.domainobjects.ltl.CounterExampleProposition; + +public final class CounterExampleBinaryFigure extends + CounterExamplePropositionFigure { + private Panel firstPanel; + private Panel secondPanel; + + protected final Hashtable<Ellipse, Integer> firstArgumentEllipses1 = new Hashtable<Ellipse, Integer>(); + protected final Hashtable<Integer, Ellipse> firstArgumentEllipses2 = new Hashtable<Integer, Ellipse>(); + private final Hashtable<Ellipse, Integer> secondArgumentEllipses1 = new Hashtable<Ellipse, Integer>(); + private final Hashtable<Integer, Ellipse> secondArgumentEllipses2 = new Hashtable<Integer, Ellipse>(); + + public CounterExampleBinaryFigure(CounterExampleProposition model) { + super(model); + } + + @Override + protected void drawProposition(final CounterExamplePropositionFigure parent) { + removeAll(); + + Rectangle bounds = new Rectangle(height, height, height + * (model.getValues().size() * 2 + 1), (int) (9.0 / 2 * height)); + + if (parent != null) { + Rectangle parentBounds = parent.getBounds(); + bounds = new Rectangle(parentBounds.x - borderHeight, + parentBounds.y + parentBounds.height + height / 2, + parentBounds.width, (int) (9.0 / 2 * height)); + } + + getParent().setConstraint(this, bounds); + setBounds(bounds); + + int stateId = model.getStateId(); + + CounterExampleProposition firstArgument = ((CounterExampleBinaryOperator) model) + .getFirstArgument(); + List<Integer> firstPositions = ((CounterExampleBinaryOperator) model) + .getFirstHighlightedPositions().get(stateId); + Rectangle firstPanelBounds = new Rectangle(bounds.x + + (int) (2.0 / 5 * height), + bounds.y + (int) (2.0 / 5 * height), bounds.width, + bounds.height / 2); + firstPanel = drawPropositionFigure(parent, bounds, firstArgument, + firstPositions, firstArgumentEllipses1, firstArgumentEllipses2, + firstPanelBounds, stateId, height); + + Rectangle secondPanelBounds = new Rectangle(bounds.x + 20, bounds.y + + (int) (12.0 / 5 * height), bounds.width, bounds.height / 2); + CounterExampleProposition secondArgument = ((CounterExampleBinaryOperator) model) + .getSecondArgument(); + + List<Integer> secondPositions = ((CounterExampleBinaryOperator) model) + .getSecondHighlightedPositions().get(stateId); + secondPanel = drawPropositionFigure(parent, bounds, secondArgument, + secondPositions, secondArgumentEllipses1, + secondArgumentEllipses2, secondPanelBounds, stateId, 3 * height); + } + + @Override + public void mousePressed(MouseEvent me) { + super.mousePressed(me); + int stateId; + + CounterExampleProposition firstArgument = ((CounterExampleBinaryOperator) model) + .getFirstArgument(); + List<CounterExampleProposition> firstChildren = firstArgument + .getChildren(); + firstChildren = firstChildren.subList(1, firstChildren.size()); + setTrasparent(firstChildren); + + CounterExamplePropositionFigure firstArgumentFigure = getFigure(firstArgument); + + for (Connection connection : firstArgumentFigure.getConnections() + .values()) { + connection.setVisible(false); + } + + CounterExampleProposition secondArgument = ((CounterExampleBinaryOperator) model) + .getSecondArgument(); + List<CounterExampleProposition> secondChildren = secondArgument + .getChildren(); + secondChildren = secondChildren.subList(1, secondChildren.size()); + setTrasparent(secondChildren); + + CounterExamplePropositionFigure secondArgumentFigure = getFigure(secondArgument); + + for (Connection connection : secondArgumentFigure.getConnections() + .values()) { + connection.setVisible(false); + } + + Object source = me.getSource(); + + if (firstPanel == null || secondPanel == null) + return; + + TitleBarBorder firstBorder = (TitleBarBorder) firstPanel.getBorder(); + TitleBarBorder secondBorder = (TitleBarBorder) secondPanel.getBorder(); + + if (firstArgumentEllipses1.containsKey(source)) { + secondBorder.setFont(normalFont); + secondArgument.setVisible(false); + + stateId = firstArgumentEllipses1.get(source); + + if (firstArgument.getStateId() == stateId) { + boolean visible = !firstArgument.isVisible(); + + if (firstArgument.hasChildren()) { + firstBorder.setFont(visible ? boldFont : normalFont); + } + + firstArgument.setVisible(visible); + } else { + if (firstArgument.hasChildren()) { + firstBorder.setFont(boldFont); + } + + firstArgument.setStateId(stateId); + firstArgument.setVisible(true); + } + } else { + firstBorder.setFont(normalFont); + firstArgument.setVisible(false); + + stateId = secondArgumentEllipses1.get(source); + + if (secondArgument.getStateId() == stateId) { + boolean visible = !secondArgument.isVisible(); + + if (secondArgument.hasChildren()) { + secondBorder.setFont(visible ? boldFont : normalFont); + } + + secondArgument.setVisible(visible); + } else { + if (secondArgument.hasChildren()) { + secondBorder.setFont(boldFont); + } + + secondArgument.setStateId(stateId); + secondArgument.setVisible(true); + } + } + } + + @Override + public void mouseEntered(MouseEvent me) { + Ellipse source = (Ellipse) me.getSource(); + + CounterExampleProposition argument = null; + int stateId; + + if (firstArgumentEllipses1.containsKey(source)) { + argument = ((CounterExampleBinaryOperator) model) + .getFirstArgument(); + stateId = firstArgumentEllipses1.get(source); + } else { + argument = ((CounterExampleBinaryOperator) model) + .getSecondArgument(); + stateId = secondArgumentEllipses1.get(source); + } + + if (!argument.hasChildren()) + return; + + boolean painted = argument.isVisible(); + int argumentStateId = argument.getStateId(); + + Label label = new Label(); + label.setForegroundColor(foregroundColor); + + String text = "open "; + + if (stateId == argumentStateId) + text = painted ? "close " : "open "; + + label.setText("Click to " + text + argument); + source.setToolTip(label); + } +} diff --git a/de.prob.ui/src/de/prob/ui/ltl/CounterExampleComposite.java b/de.prob.ui/src/de/prob/ui/ltl/CounterExampleComposite.java new file mode 100644 index 0000000000000000000000000000000000000000..0152782e41487318a6953e62944e459c7759e6a0 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ltl/CounterExampleComposite.java @@ -0,0 +1,35 @@ +package de.prob.ui.ltl; + +import org.eclipse.swt.widgets.Composite; + +/*** + * Provides a customer widget for a counter example view + * + * @author Andriy Tolstoy + * + */ +public final class CounterExampleComposite extends Composite { + + private Composite tableView; + private Composite treeView; + + public CounterExampleComposite(Composite parent, int style) { + super(parent, style); + } + + public void setTableComposite(Composite composite) { + tableView = composite; + } + + public void setTreeComposite(Composite composite) { + treeView = composite; + } + + public Composite getTableView() { + return tableView; + } + + public Composite getTreeView() { + return treeView; + } +} diff --git a/de.prob.ui/src/de/prob/ui/ltl/CounterExampleContentProvider.java b/de.prob.ui/src/de/prob/ui/ltl/CounterExampleContentProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..3ff5eb18e7fc8a4652d6a555aefaf39a55a22928 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ltl/CounterExampleContentProvider.java @@ -0,0 +1,92 @@ +package de.prob.ui.ltl; + +import java.util.List; + +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; + +import de.prob.core.domainobjects.ltl.CounterExampleBinaryOperator; +import de.prob.core.domainobjects.ltl.CounterExampleProposition; +import de.prob.core.domainobjects.ltl.CounterExampleUnaryOperator; + +/*** + * Provides a content provider for a counter-example tree view + * + * @author Andriy Tolstoy + * + */ +public final class CounterExampleContentProvider implements + ITreeContentProvider { + + /** + * Returns the children of an element + */ + @Override + public Object[] getChildren(Object parentElement) { + if (parentElement instanceof List) { + return ((List<?>) parentElement).toArray(); + } + + if (parentElement instanceof CounterExampleUnaryOperator) { + Object[] children = new Object[1]; + children[0] = ((CounterExampleUnaryOperator) parentElement) + .getArgument(); + return children; + } + + if (parentElement instanceof CounterExampleBinaryOperator) { + Object[] children = new Object[2]; + children[0] = ((CounterExampleBinaryOperator) parentElement) + .getFirstArgument(); + children[1] = ((CounterExampleBinaryOperator) parentElement) + .getSecondArgument(); + return children; + } + + return new Object[0]; + } + + /** + * Returns the parent of an element + */ + @Override + public Object getParent(Object element) { + if (element instanceof CounterExampleProposition) { + return ((CounterExampleProposition) element).getParent(); + } + + return null; + } + + /** + * Returns whether an element has children + */ + @Override + public boolean hasChildren(Object element) { + if (element instanceof List) { + return ((List<?>) element).size() > 0; + } else if (element instanceof CounterExampleUnaryOperator) { + return true; + } else if (element instanceof CounterExampleBinaryOperator) { + return true; + } + + return false; + } + + /** + * Returns the root element + */ + @Override + public Object[] getElements(Object inputElement) { + return getChildren(inputElement); + } + + @Override + public void dispose() { + } + + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } +} diff --git a/de.prob.ui/src/de/prob/ui/ltl/CounterExampleEditPart.java b/de.prob.ui/src/de/prob/ui/ltl/CounterExampleEditPart.java new file mode 100644 index 0000000000000000000000000000000000000000..7a9d3b83e14c26f3e234615d8bf74adb1aa9c316 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ltl/CounterExampleEditPart.java @@ -0,0 +1,35 @@ +package de.prob.ui.ltl; + +import java.util.List; + +import org.eclipse.draw2d.IFigure; +import org.eclipse.gef.editparts.AbstractGraphicalEditPart; + +import de.prob.core.domainobjects.ltl.CounterExample; +import de.prob.core.domainobjects.ltl.CounterExampleProposition; + +public final class CounterExampleEditPart extends AbstractGraphicalEditPart { + @Override + protected IFigure createFigure() { + CounterExample model = (CounterExample) getModel(); + return new CounterExampleFigure(model); + } + + @Override + public List<CounterExampleProposition> getModelChildren() { + CounterExample model = (CounterExample) getModel(); + List<CounterExampleProposition> children = model.getPropositions(); + + return children; + } + + @Override + protected void refreshVisuals() { + CounterExampleFigure figure = (CounterExampleFigure) getFigure(); + figure.update(); + } + + @Override + protected void createEditPolicies() { + } +} diff --git a/de.prob.ui/src/de/prob/ui/ltl/CounterExampleEditPartFactory.java b/de.prob.ui/src/de/prob/ui/ltl/CounterExampleEditPartFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..337ed06ecba07871bac60e41690842de9ebac328 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ltl/CounterExampleEditPartFactory.java @@ -0,0 +1,31 @@ +package de.prob.ui.ltl; + +import org.eclipse.gef.EditPart; +import org.eclipse.gef.EditPartFactory; + +import de.prob.core.domainobjects.ltl.CounterExample; +import de.prob.core.domainobjects.ltl.CounterExampleBinaryOperator; +import de.prob.core.domainobjects.ltl.CounterExamplePredicate; +import de.prob.core.domainobjects.ltl.CounterExampleUnaryOperator; + +public final class CounterExampleEditPartFactory implements EditPartFactory { + + @Override + public EditPart createEditPart(EditPart context, Object model) { + EditPart editPart = null; + + if (model instanceof CounterExample) + editPart = new CounterExampleEditPart(); + else if (model instanceof CounterExamplePredicate) + editPart = new CounterExamplePredicateEditPart(); + else if (model instanceof CounterExampleUnaryOperator) + editPart = new CounterExampleUnaryEditPart(); + else if (model instanceof CounterExampleBinaryOperator) + editPart = new CounterExampleBinaryEditPart(); + + if (editPart != null) + editPart.setModel(model); + + return editPart; + } +} diff --git a/de.prob.ui/src/de/prob/ui/ltl/CounterExampleFigure.java b/de.prob.ui/src/de/prob/ui/ltl/CounterExampleFigure.java new file mode 100644 index 0000000000000000000000000000000000000000..27279c80d424f6d4a7aba22d866ee9793f797901 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ltl/CounterExampleFigure.java @@ -0,0 +1,34 @@ +package de.prob.ui.ltl; + +import org.eclipse.draw2d.AbstractLabeledBorder; +import org.eclipse.draw2d.ColorConstants; +import org.eclipse.draw2d.Figure; +import org.eclipse.draw2d.GroupBoxBorder; +import org.eclipse.draw2d.XYLayout; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Font; + +import de.prob.core.domainobjects.ltl.CounterExample; + +public final class CounterExampleFigure extends Figure { + private final CounterExample model; + + public CounterExampleFigure(CounterExample model) { + this.model = model; + setLayoutManager(new XYLayout()); + AbstractLabeledBorder border = new GroupBoxBorder(); + border.setTextColor(ColorConstants.lightBlue); + Font font = new Font(null, "Arial", 10, SWT.BOLD); + border.setFont(font); + border.setLabel(model.getPropositionRoot() + ", PathType - " + + model.getPathType().name()); + setBorder(border); + } + + public CounterExample getModel() { + return model; + } + + public void update() { + } +} diff --git a/de.prob.ui/src/de/prob/ui/ltl/CounterExampleMouseAdapter.java b/de.prob.ui/src/de/prob/ui/ltl/CounterExampleMouseAdapter.java new file mode 100644 index 0000000000000000000000000000000000000000..2123275b68beb9a8f698751072e8aa417fb94b18 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ltl/CounterExampleMouseAdapter.java @@ -0,0 +1,139 @@ +package de.prob.ui.ltl; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.viewers.ViewerCell; +import org.eclipse.jface.viewers.ViewerRow; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Display; + +import de.prob.core.domainobjects.ltl.CounterExampleBinaryOperator; +import de.prob.core.domainobjects.ltl.CounterExampleProposition; +import de.prob.core.domainobjects.ltl.CounterExampleUnaryOperator; + +public final class CounterExampleMouseAdapter extends MouseAdapter { + private final List<ViewerCell> coloredCells = new ArrayList<ViewerCell>(); + private final CounterExampleTreeViewer treeViewer; + + public CounterExampleMouseAdapter(CounterExampleTreeViewer treeViewer) { + this.treeViewer = treeViewer; + } + + @Override + public void mouseDown(MouseEvent e) { + for (ViewerCell cell : coloredCells) { + cell.setBackground(Display.getDefault().getSystemColor( + SWT.COLOR_WHITE)); + } + + coloredCells.clear(); + + ViewerCell cell = treeViewer.getCell(new Point(e.x, e.y)); + + if (cell != null && cell.getColumnIndex() > 0) { + cell.setBackground(Display.getDefault().getSystemColor( + SWT.COLOR_YELLOW)); + coloredCells.add(cell); + + Object element = cell.getElement(); + + System.out.println("Parent element: " + element); + int columnIndex = cell.getColumnIndex(); + + ViewerRow row = cell.getViewerRow(); + + if (element instanceof CounterExampleUnaryOperator) { + CounterExampleUnaryOperator unary = (CounterExampleUnaryOperator) element; + CounterExampleProposition first = unary.getArgument(); + ViewerRow firstRow = getNeighborRow(row, first); + + if (firstRow != null) { + List<List<Integer>> allPositions = unary + .getHighlightedPositions(); + + if (columnIndex - 1 < allPositions.size()) { + List<Integer> positions = allPositions + .get(columnIndex - 1); + markArgument(firstRow, positions); + } + } + } else if (element instanceof CounterExampleBinaryOperator) { + CounterExampleBinaryOperator binary = (CounterExampleBinaryOperator) element; + CounterExampleProposition first = binary.getFirstArgument(); + CounterExampleProposition second = binary.getSecondArgument(); + + ViewerRow firstRow = getNeighborRow(row, first); + ViewerRow secondRow = getNeighborRow(row, second); + + if (firstRow != null && secondRow != null) { + List<List<Integer>> firstAllPositions = binary + .getFirstHighlightedPositions(); + List<List<Integer>> secondAllPositions = binary + .getSecondHighlightedPositions(); + + Assert.isTrue(firstAllPositions.size() == secondAllPositions + .size()); + + if (columnIndex - 1 < firstAllPositions.size()) { + List<Integer> firstPositions = binary + .getFirstHighlightedPositions().get( + columnIndex - 1); + List<Integer> secondPositions = binary + .getSecondHighlightedPositions().get( + columnIndex - 1); + + markArgument(firstRow, firstPositions); + markArgument(secondRow, secondPositions); + } + } + } + } + } + + private ViewerRow getNeighborRow(ViewerRow propositionRow, + CounterExampleProposition argument) { + ViewerRow argumentRow = propositionRow; + Object element; + + do { + argumentRow = argumentRow.getNeighbor(ViewerRow.BELOW, false); + + if (argumentRow == null) + return null; + + element = argumentRow.getElement(); + } while (!element.equals(argument)); + + return argumentRow; + } + + private void markArgument(ViewerRow row, List<Integer> positions) { + Display display = Display.getDefault(); + + if (row != null) { + for (Integer position : positions) { + ViewerCell neighborCell = row.getCell(position + 1); + + System.out.println("Argument: " + neighborCell.getElement()); + + if (neighborCell.getText().equals("T")) { + neighborCell.setBackground(display + .getSystemColor(SWT.COLOR_GREEN)); + } else if (neighborCell.getText().equals("F")) { + neighborCell.setBackground(display + .getSystemColor(SWT.COLOR_RED)); + } else if (neighborCell.getText().equals("U")) { + neighborCell.setBackground(display + .getSystemColor(SWT.COLOR_GRAY)); + } + + coloredCells.add(neighborCell); + } + } + } +} diff --git a/de.prob.ui/src/de/prob/ui/ltl/CounterExampleMouseMoveAdapter.java b/de.prob.ui/src/de/prob/ui/ltl/CounterExampleMouseMoveAdapter.java new file mode 100644 index 0000000000000000000000000000000000000000..10dc2710115078e53099630e8d52c51d7493a609 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ltl/CounterExampleMouseMoveAdapter.java @@ -0,0 +1,73 @@ +package de.prob.ui.ltl; + +import java.util.List; + +import org.eclipse.jface.viewers.ViewerCell; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseMoveListener; +import org.eclipse.swt.graphics.Point; + +import de.prob.core.command.LtlCheckingCommand.PathType; +import de.prob.core.domainobjects.ltl.CounterExampleBinaryOperator; +import de.prob.core.domainobjects.ltl.CounterExampleProposition; +import de.prob.core.domainobjects.ltl.CounterExampleUnaryOperator; + +public final class CounterExampleMouseMoveAdapter implements MouseMoveListener { + private final CounterExampleTreeViewer treeViewer; + private ViewerCell currentCell; + + public CounterExampleMouseMoveAdapter(CounterExampleTreeViewer treeViewer) { + this.treeViewer = treeViewer; + } + + @Override + public void mouseMove(MouseEvent e) { + ViewerCell cell = treeViewer.getCell(new Point(e.x, e.y)); + + if (cell != null && !cell.equals(currentCell)) { + currentCell = cell; + CounterExampleProposition element = (CounterExampleProposition) cell + .getElement(); + PathType pathType = element.getPathType(); + int loopEntry = element.getLoopEntry(); + String toolTip = "PathType: " + pathType + ", loopEntry = " + + loopEntry; + + int columnIndex = cell.getColumnIndex(); + + if (cell.getColumnIndex() > 0) { + if (element instanceof CounterExampleUnaryOperator) { + CounterExampleUnaryOperator unary = (CounterExampleUnaryOperator) element; + List<List<Integer>> allPositions = unary + .getHighlightedPositions(); + + if (columnIndex - 1 < allPositions.size()) { + List<Integer> positions = allPositions + .get(columnIndex - 1); + toolTip += ". Positions: " + positions; + } + } else if (element instanceof CounterExampleBinaryOperator) { + CounterExampleBinaryOperator binary = (CounterExampleBinaryOperator) element; + + List<List<Integer>> firstAllPositions = binary + .getFirstHighlightedPositions(); + + if (columnIndex - 1 < firstAllPositions.size()) { + List<Integer> firstPositions = binary + .getFirstHighlightedPositions().get( + columnIndex - 1); + List<Integer> secondPositions = binary + .getSecondHighlightedPositions().get( + columnIndex - 1); + + toolTip += ". FirstPositions: " + firstPositions; + toolTip += ", SecondPositions: " + secondPositions; + } + } + } + + cell.getControl().setToolTipText(toolTip); + System.out.println(element); + } + } +} diff --git a/de.prob.ui/src/de/prob/ui/ltl/CounterExamplePredicateEditPart.java b/de.prob.ui/src/de/prob/ui/ltl/CounterExamplePredicateEditPart.java new file mode 100644 index 0000000000000000000000000000000000000000..81503b54a21776a75e2478dcbc0255066bf44734 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ltl/CounterExamplePredicateEditPart.java @@ -0,0 +1,14 @@ +package de.prob.ui.ltl; + +import org.eclipse.draw2d.IFigure; + +import de.prob.core.domainobjects.ltl.CounterExampleProposition; + +public final class CounterExamplePredicateEditPart extends + CounterExamplePropositionEditPart { + @Override + protected IFigure createFigure() { + CounterExampleProposition model = (CounterExampleProposition) getModel(); + return new CounterExamplePredicateFigure(model); + } +} diff --git a/de.prob.ui/src/de/prob/ui/ltl/CounterExamplePredicateFigure.java b/de.prob.ui/src/de/prob/ui/ltl/CounterExamplePredicateFigure.java new file mode 100644 index 0000000000000000000000000000000000000000..35fdfaf6ce9845bb3192a3517a27a928c01a3473 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ltl/CounterExamplePredicateFigure.java @@ -0,0 +1,47 @@ +package de.prob.ui.ltl; + +import java.util.Hashtable; + +import org.eclipse.draw2d.Ellipse; +import org.eclipse.draw2d.Label; +import org.eclipse.draw2d.MouseEvent; +import org.eclipse.draw2d.geometry.Rectangle; + +import de.prob.core.domainobjects.ltl.CounterExampleProposition; + +public final class CounterExamplePredicateFigure extends + CounterExamplePropositionFigure { + protected final Hashtable<Ellipse, Integer> ellipses1 = new Hashtable<Ellipse, Integer>(); + protected final Hashtable<Integer, Ellipse> ellipses2 = new Hashtable<Integer, Ellipse>(); + + public CounterExamplePredicateFigure(CounterExampleProposition model) { + super(model); + setToolTip(new Label(model.toString())); + } + + @Override + protected void drawProposition(final CounterExamplePropositionFigure parent) { + if (parent != null) + return; + + removeAll(); + Rectangle bounds = new Rectangle(height, height, height + * (model.getValues().size() * 2 + 1), 2 * height); + + getParent().setConstraint(this, bounds); + setBounds(bounds); + + int stateId = model.getStateId(); + + drawPropositionFigure(parent, bounds, null, null, ellipses1, ellipses2, + null, stateId, 3 * height / 5); + } + + @Override + public void mousePressed(MouseEvent me) { + } + + @Override + public void mouseEntered(MouseEvent me) { + } +} diff --git a/de.prob.ui/src/de/prob/ui/ltl/CounterExamplePropositionEditPart.java b/de.prob.ui/src/de/prob/ui/ltl/CounterExamplePropositionEditPart.java new file mode 100644 index 0000000000000000000000000000000000000000..34677e78cb34724e4702f77aaf01ee09f15eb5cf --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ltl/CounterExamplePropositionEditPart.java @@ -0,0 +1,47 @@ +package de.prob.ui.ltl; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import org.eclipse.gef.editparts.AbstractGraphicalEditPart; + +import de.prob.core.domainobjects.ltl.CounterExampleProposition; + +public abstract class CounterExamplePropositionEditPart extends + AbstractGraphicalEditPart implements PropertyChangeListener { + @Override + public void activate() { + if (!isActive()) { + CounterExampleProposition model = (CounterExampleProposition) getModel(); + model.addPropertyChangeListener(this); + } + + super.activate(); + } + + @Override + public void deactivate() { + if (isActive()) { + CounterExampleProposition model = (CounterExampleProposition) getModel(); + model.removePropertyChangeListener(this); + } + + super.deactivate(); + } + + @Override + protected void refreshVisuals() { + CounterExamplePropositionFigure figure = (CounterExamplePropositionFigure) getFigure(); + figure.getParent().repaint(); + figure.update(); + } + + @Override + protected void createEditPolicies() { + } + + @Override + public void propertyChange(PropertyChangeEvent event) { + refresh(); + } +} diff --git a/de.prob.ui/src/de/prob/ui/ltl/CounterExamplePropositionFigure.java b/de.prob.ui/src/de/prob/ui/ltl/CounterExamplePropositionFigure.java new file mode 100644 index 0000000000000000000000000000000000000000..5c2c8c56e4b276f7ef21ade1bfdbfea8408080b6 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ltl/CounterExamplePropositionFigure.java @@ -0,0 +1,425 @@ +package de.prob.ui.ltl; + +import java.util.Collections; +import java.util.Hashtable; +import java.util.List; + +import org.eclipse.draw2d.AbstractLabeledBorder; +import org.eclipse.draw2d.BorderLayout; +import org.eclipse.draw2d.ChopboxAnchor; +import org.eclipse.draw2d.ColorConstants; +import org.eclipse.draw2d.Connection; +import org.eclipse.draw2d.Ellipse; +import org.eclipse.draw2d.Figure; +import org.eclipse.draw2d.GroupBoxBorder; +import org.eclipse.draw2d.Label; +import org.eclipse.draw2d.MouseEvent; +import org.eclipse.draw2d.MouseListener; +import org.eclipse.draw2d.MouseMotionListener; +import org.eclipse.draw2d.Panel; +import org.eclipse.draw2d.PolygonDecoration; +import org.eclipse.draw2d.Polyline; +import org.eclipse.draw2d.PolylineConnection; +import org.eclipse.draw2d.TitleBarBorder; +import org.eclipse.draw2d.XYLayout; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.PointList; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; + +import de.prob.core.command.LtlCheckingCommand.PathType; +import de.prob.core.domainobjects.ltl.CounterExample; +import de.prob.core.domainobjects.ltl.CounterExampleProposition; +import de.prob.core.domainobjects.ltl.CounterExampleValueType; + +public abstract class CounterExamplePropositionFigure extends Figure implements + MouseListener, MouseMotionListener { + public static class Alpha { + public static final int MASKED = 30; + public static final int HIGHLIGHED = 250; + }; + + protected final CounterExampleProposition model; + + protected final Color foregroundColor = ColorConstants.lightBlue; + protected final Color backgroundColor = new Color(null, 255, 255, 206); + + protected final Font normalFont = new Font(null, "Arial", 10, SWT.NORMAL); + protected final Font boldFont = new Font(null, "Arial", 10, SWT.BOLD); + + protected final int height = 50; + protected final int borderHeight = 19; + + protected final Hashtable<Integer, Connection> connections = new Hashtable<Integer, Connection>(); + + public CounterExamplePropositionFigure(CounterExampleProposition model) { + this.model = model; + setLayoutManager(new XYLayout()); + AbstractLabeledBorder border = new GroupBoxBorder(); + border.setTextColor(foregroundColor); + border.setLabel(model.getFullName()); + border.setFont(boldFont); + + setBorder(border); + setBackgroundColor(backgroundColor); + setOpaque(true); + } + + public void update() { + Label label = new Label(model.toString()); + label.setForegroundColor(foregroundColor); + setToolTip(label); + setVisible(true); + + if (model.isVisible()) { + CounterExampleProposition parentModel = model.getParent(); + CounterExamplePropositionFigure parent = getFigure(parentModel); + drawProposition(parent); + } else { + setVisible(false); + } + } + + protected CounterExamplePropositionFigure getFigure( + final CounterExampleProposition proposition) { + if (proposition != null) { + // We know that each element is of type + // CounterExamplePropositionFigure, + // but IFigure.getParent() returns just a list + @SuppressWarnings("unchecked") + List<CounterExamplePropositionFigure> figures = getParent() + .getChildren(); + + for (CounterExamplePropositionFigure figure : figures) { + if (figure.getModel().equals(proposition)) { + return figure; + } + } + } + + return null; + } + + protected void setTrasparent(List<CounterExampleProposition> children) { + for (CounterExampleProposition child : children) { + CounterExamplePropositionFigure childFigure = getFigure(child); + + for (Connection connection : childFigure.getConnections().values()) { + connection.setVisible(false); + } + + child.setVisible(false); + } + } + + protected abstract void drawProposition( + final CounterExamplePropositionFigure parent); + + protected CounterExampleProposition getModel() { + return model; + } + + protected Color getEllipseColor(CounterExampleValueType value) { + Color color = ColorConstants.gray; + + if (value.equals(CounterExampleValueType.TRUE)) + color = ColorConstants.green; + else if (value.equals(CounterExampleValueType.FALSE)) + color = ColorConstants.red; + + return color; + } + + protected String getOperationName(int index) { + CounterExampleFigure parentFigure = (CounterExampleFigure) getParent(); + CounterExample parentModel = parentFigure.getModel(); + String operationName = parentModel.getStates().get(index) + .getOperation().getName(); + return operationName; + } + + protected Hashtable<Integer, Connection> getConnections() { + return connections; + } + + protected void drawLoop(Figure parent, Ellipse source, Ellipse target, + int alpha, String operationName, Color loopColor) { + PolylineConnection connection = new PolylineConnection(); + connection.setAlpha(alpha); + connection.setAntialias(SWT.ON); + connection.setLineWidth(2); + + Label label = new Label(operationName); + label.setForegroundColor(foregroundColor); + connection.setToolTip(label); + connection.setForegroundColor(loopColor); + + PointList points = new PointList(); + Rectangle sourceBounds = source.getBounds(); + Rectangle targetBounds = target.getBounds(); + points.addPoint(new Point(sourceBounds.x + height + borderHeight, + sourceBounds.y + height / 2 + borderHeight)); + points.addPoint(new Point(sourceBounds.x + height + 3.0 / 10 * height + + borderHeight, sourceBounds.y + height / 2 + borderHeight)); + points.addPoint(new Point(sourceBounds.x + height + 3.0 / 10 * height + + borderHeight, sourceBounds.y - height / 5 + borderHeight)); + points.addPoint(new Point(targetBounds.x + height / 2 + borderHeight, + targetBounds.y - height / 5 + borderHeight)); + points.addPoint(new Point(targetBounds.x + height / 2 + borderHeight, + targetBounds.y + borderHeight)); + connection.setPoints(points); + + PolygonDecoration decoration = new PolygonDecoration(); + decoration.setAlpha(alpha); + decoration.setAntialias(SWT.ON); + PointList decorationPointList = new PointList(); + decorationPointList.addPoint(0, 0); + decorationPointList.addPoint(-1, 1); + decorationPointList.addPoint(-1, 0); + decorationPointList.addPoint(-1, -1); + decoration.setTemplate(decorationPointList); + + connection.setTargetDecoration(decoration); + + parent.add(connection); + } + + protected void drawFinite(Figure parent, Ellipse source, int alpha) { + Polyline polyline = new Polyline(); + polyline.setAlpha(alpha); + polyline.setAntialias(SWT.ON); + polyline.setLineWidth(2); + polyline.setToolTip(new Label("Finite")); + + PointList points = new PointList(); + Rectangle sourceBounds = source.getBounds(); + points.addPoint(new Point(sourceBounds.x + height + borderHeight, + sourceBounds.y + height / 2 + borderHeight)); + points.addPoint(new Point(sourceBounds.x + height + 3.0 / 10 * height + + borderHeight, sourceBounds.y + height / 2 + borderHeight)); + points.addPoint(new Point(sourceBounds.x + height + 3.0 / 10 * height + + borderHeight, sourceBounds.y + borderHeight + height / 4)); + points.addPoint(new Point(sourceBounds.x + height + 3.0 / 10 * height + + borderHeight, sourceBounds.y + borderHeight + + (int) (3.0 / 4 * height))); + polyline.setPoints(points); + + parent.add(polyline); + } + + protected void drawChildParentConnection(final Ellipse ellipse, + int stateId, final CounterExamplePropositionFigure parent) { + if (connections.containsKey(stateId)) { + connections.get(stateId).setVisible(true); + } else { + PolylineConnection connection = new PolylineConnection(); + connection.setAntialias(SWT.ON); + connection.setLineStyle(SWT.LINE_SOLID); + connection.setLineWidth(2); + + Rectangle sourceBounds = parent.getBounds(); + Rectangle targetBounds = getBounds(); + + PointList points = new PointList(); + points.addPoint(ellipse.getBounds().x + borderHeight + height / 2, + sourceBounds.y + sourceBounds.height); + points.addPoint(ellipse.getBounds().x + borderHeight + height / 2, + targetBounds.y + borderHeight); + connection.setPoints(points); + + PolygonDecoration decoration = new PolygonDecoration(); + decoration.setAntialias(SWT.ON); + PointList decorationPointList = new PointList(); + decorationPointList.addPoint(0, 0); + decorationPointList.addPoint(-1, 1); + decorationPointList.addPoint(-1, 0); + decorationPointList.addPoint(-1, -1); + decoration.setTemplate(decorationPointList); + + connection.setSourceDecoration(decoration); + getParent().add(connection); + connections.put(stateId, connection); + } + } + + protected Panel drawPropositionFigure( + final CounterExamplePropositionFigure parent, + final Rectangle bounds, final CounterExampleProposition argument, + final List<Integer> positions, + final Hashtable<Ellipse, Integer> ellipses1, + final Hashtable<Integer, Ellipse> ellipses2, + final Rectangle panelBounds, int stateId, int argumentHeight) { + ellipses1.clear(); + ellipses2.clear(); + + PathType pathType = model.getPathType(); + + List<CounterExampleValueType> values = argument != null ? argument + .getValues() : model.getValues(); + + Panel panel = null; + + if (panelBounds != null) { + panel = new Panel(); + panel.setBounds(panelBounds); + final TitleBarBorder border = new TitleBarBorder(); + border.setBackgroundColor(backgroundColor); + border.setTextColor(foregroundColor); + border.setLabel(argument.toString()); + border.setFont(normalFont); + panel.setBorder(border); + add(panel); + } + + for (int i = 0; i < values.size(); i++) { + CounterExampleValueType value = values.get(i); + final Ellipse ellipse = new Ellipse(); + + if (positions != null && !positions.contains(i)) { + ellipse.setAlpha(Alpha.MASKED); + } + + ellipse.setAntialias(SWT.ON); + ellipse.setLineWidth(2); + ellipse.setOpaque(true); + ellipse.addMouseListener(this); + ellipse.addMouseMotionListener(this); + ellipse.setBackgroundColor(getEllipseColor(value)); + + ellipses1.put(ellipse, i); + ellipses2.put(i, ellipse); + Label label = new Label(value.toString()); + label.setOpaque(false); + ellipse.setLayoutManager(new BorderLayout()); + ellipse.add(label, BorderLayout.CENTER); + + if (panel != null) + panel.add(ellipse); + else + add(ellipse); + + int x = (bounds.x + height) * (i + 1); + int y = bounds.y + argumentHeight + + (pathType == PathType.INFINITE ? height / 10 : 0); + ellipse.setBounds(new Rectangle(x, y, height, height)); + + if (i > 0) { + ChopboxAnchor source = new ChopboxAnchor(ellipse); + Ellipse targetEllipse = ellipses2.get(i - 1); + + if (targetEllipse == null) + continue; + + ChopboxAnchor target = new ChopboxAnchor(targetEllipse); + + PolylineConnection connection = new PolylineConnection(); + connection.setAntialias(SWT.ON); + connection.setLineStyle(SWT.LINE_SOLID); + connection.setLineWidth(2); + connection.setToolTip(new Label(getOperationName(i - 1))); + connection.setSourceAnchor(source); + connection.setTargetAnchor(target); + + if (argument != null && argument.isTransition() + || model.isTransition()) + connection.setForegroundColor(getEllipseColor(values + .get(i - 1))); + + PolygonDecoration decoration = new PolygonDecoration(); + decoration.setAntialias(SWT.ON); + PointList decorationPointList = new PointList(); + decorationPointList.addPoint(0, 0); + decorationPointList.addPoint(-1, 1); + decorationPointList.addPoint(-1, 0); + decorationPointList.addPoint(-1, -1); + decoration.setTemplate(decorationPointList); + + if (positions == null + || (positions.contains(i) && (stateId >= Collections + .min(positions) ? i != Collections + .min(positions) : true))) { + decoration.setAlpha(Alpha.HIGHLIGHED); + connection.setAlpha(Alpha.HIGHLIGHED); + } else { + decoration.setAlpha(Alpha.MASKED); + connection.setAlpha(Alpha.MASKED); + } + + connection.setSourceDecoration(decoration); + + if (panel != null) + panel.add(connection); + else + add(connection); + } + + if (i == values.size() - 1) { + if (pathType.equals(PathType.INFINITE)) { + int loopEntry = model.getLoopEntry(); + + String operationName = getOperationName(ellipses1 + .get(ellipse)); + Ellipse target = ellipses2.get(model.getLoopEntry()); + + Color loopColor = ColorConstants.black; + + if (argument != null && argument.isTransition() + || model.isTransition()) + loopColor = getEllipseColor(values.get(i)); + + drawLoop( + panel != null ? panel : this, + ellipse, + target, + (positions == null || positions.contains(loopEntry) + && (positions.contains(i) || i == stateId)) ? Alpha.HIGHLIGHED + : Alpha.MASKED, operationName, loopColor); + } else if (pathType.equals(PathType.REDUCED)) { + drawFinite( + panel != null ? panel : this, + ellipse, + (positions == null || positions.contains(i)) ? Alpha.HIGHLIGHED + : Alpha.MASKED); + } + } + } + + if (parent != null) { + Ellipse ellipse = ellipses2.get(stateId); + drawChildParentConnection(ellipse, stateId, parent); + } + + return panel; + } + + @Override + public void mouseReleased(MouseEvent me) { + } + + @Override + public void mousePressed(MouseEvent me) { + System.out.println(me.x + "," + me.y); + } + + @Override + public void mouseDoubleClicked(MouseEvent me) { + } + + @Override + public void mouseDragged(MouseEvent me) { + } + + @Override + public void mouseExited(MouseEvent me) { + } + + @Override + public void mouseHover(MouseEvent me) { + } + + @Override + public void mouseMoved(MouseEvent me) { + } +} diff --git a/de.prob.ui/src/de/prob/ui/ltl/CounterExampleTreeLabelProvider.java b/de.prob.ui/src/de/prob/ui/ltl/CounterExampleTreeLabelProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..eb39b3475abd22510951d8d949eee748a7ca1361 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ltl/CounterExampleTreeLabelProvider.java @@ -0,0 +1,52 @@ +package de.prob.ui.ltl; + +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.swt.graphics.Image; + +import de.prob.core.domainobjects.ltl.CounterExampleProposition; +import de.prob.core.domainobjects.ltl.CounterExampleValueType; + +/*** + * Provides a label provider for a counter-example tree view + * + * @author Andriy Tolstoy + * + */ +public final class CounterExampleTreeLabelProvider implements + ITableLabelProvider { + @Override + public Image getColumnImage(final Object element, final int columnIndex) { + return null; + } + + @Override + public String getColumnText(final Object element, final int columnIndex) { + if (columnIndex == 0) { + String proposition = ((CounterExampleProposition) element) + .toString(); + return proposition; + } else { + CounterExampleValueType value = ((CounterExampleProposition) element) + .getValues().get(columnIndex - 1); + return value.toString(); + } + } + + @Override + public void addListener(final ILabelProviderListener listener) { + } + + @Override + public void dispose() { + } + + @Override + public boolean isLabelProperty(final Object element, final String property) { + return false; + } + + @Override + public void removeListener(final ILabelProviderListener listener) { + } +} diff --git a/de.prob.ui/src/de/prob/ui/ltl/CounterExampleTreeViewer.java b/de.prob.ui/src/de/prob/ui/ltl/CounterExampleTreeViewer.java new file mode 100644 index 0000000000000000000000000000000000000000..cfd4217acec24479cce970cc8a0d553185cb66c2 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ltl/CounterExampleTreeViewer.java @@ -0,0 +1,60 @@ +package de.prob.ui.ltl; + +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Item; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeItem; + +public final class CounterExampleTreeViewer extends TreeViewer { + + public CounterExampleTreeViewer(Composite parent, int style) { + super(parent, style); + } + + @Override + protected Item getItemAt(Point p) { + Tree tree = getTree(); + TreeItem[] selection = tree.getSelection(); + + if (selection.length == 1) { + int columnCount = tree.getColumnCount(); + + for (int i = 0; i < columnCount; i++) { + if (selection[0].getBounds(i).contains(p)) { + return selection[0]; + } + } + } + + TreeItem item = getItemAt(null, p); + + return item; + } + + private TreeItem getItemAt(TreeItem parentItem, Point point) { + TreeItem[] items = (parentItem == null) ? getTree().getItems() + : parentItem.getItems(); + + for (int i = 0; i < items.length; i++) { + for (int j = 0; j < getTree().getColumnCount(); j++) { + if (items[i].getBounds(j).contains(point)) { + return items[i]; + } + } + + TreeItem foundItem = null; + + if (items[i].getExpanded() == true) { + foundItem = getItemAt(items[i], point); + } + + if (foundItem != null) { + return foundItem; + } + } + + return null; + } +} diff --git a/de.prob.ui/src/de/prob/ui/ltl/CounterExampleUnaryEditPart.java b/de.prob.ui/src/de/prob/ui/ltl/CounterExampleUnaryEditPart.java new file mode 100644 index 0000000000000000000000000000000000000000..6e2181b1124fd9394d659f295f2fc935c6e93227 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ltl/CounterExampleUnaryEditPart.java @@ -0,0 +1,14 @@ +package de.prob.ui.ltl; + +import org.eclipse.draw2d.IFigure; + +import de.prob.core.domainobjects.ltl.CounterExampleProposition; + +public final class CounterExampleUnaryEditPart extends + CounterExamplePropositionEditPart { + @Override + protected IFigure createFigure() { + CounterExampleProposition model = (CounterExampleProposition) getModel(); + return new CounterExampleUnaryFigure(model); + } +} diff --git a/de.prob.ui/src/de/prob/ui/ltl/CounterExampleUnaryFigure.java b/de.prob.ui/src/de/prob/ui/ltl/CounterExampleUnaryFigure.java new file mode 100644 index 0000000000000000000000000000000000000000..65c69f7276a4f9ed81a8a958e5cc8006c8f5cb6a --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ltl/CounterExampleUnaryFigure.java @@ -0,0 +1,126 @@ +package de.prob.ui.ltl; + +import java.util.Hashtable; +import java.util.List; + +import org.eclipse.draw2d.Connection; +import org.eclipse.draw2d.Ellipse; +import org.eclipse.draw2d.Label; +import org.eclipse.draw2d.MouseEvent; +import org.eclipse.draw2d.MouseMotionListener; +import org.eclipse.draw2d.Panel; +import org.eclipse.draw2d.TitleBarBorder; +import org.eclipse.draw2d.geometry.Rectangle; + +import de.prob.core.domainobjects.ltl.CounterExampleProposition; +import de.prob.core.domainobjects.ltl.CounterExampleUnaryOperator; + +public final class CounterExampleUnaryFigure extends + CounterExamplePropositionFigure implements MouseMotionListener { + private Panel panel; + + protected final Hashtable<Ellipse, Integer> argumentEllipses1 = new Hashtable<Ellipse, Integer>(); + protected final Hashtable<Integer, Ellipse> argumentEllipses2 = new Hashtable<Integer, Ellipse>(); + + public CounterExampleUnaryFigure(CounterExampleProposition model) { + super(model); + } + + @Override + protected void drawProposition(final CounterExamplePropositionFigure parent) { + removeAll(); + + Rectangle bounds = new Rectangle(height, height, height + * (model.getValues().size() * 2 + 1), (int) (5.0 / 2 * height)); + + if (parent != null) { + Rectangle parentBounds = parent.getBounds(); + bounds = new Rectangle(parentBounds.x - borderHeight, + parentBounds.y + parentBounds.height + height / 2, + parentBounds.width, (int) (5.0 / 2 * height)); + } + + getParent().setConstraint(this, bounds); + setBounds(bounds); + + int stateId = model.getStateId(); + + CounterExampleProposition argument = ((CounterExampleUnaryOperator) model) + .getArgument(); + List<Integer> positions = ((CounterExampleUnaryOperator) model) + .getHighlightedPositions().get(stateId); + Rectangle panelBounds = new Rectangle(bounds.x + + (int) (2.0 / 5 * height), + bounds.y + (int) (2.0 / 5 * height), bounds.width, + bounds.height); + + panel = drawPropositionFigure(parent, bounds, argument, positions, + argumentEllipses1, argumentEllipses2, panelBounds, stateId, + height); + } + + @Override + public void mousePressed(MouseEvent me) { + super.mousePressed(me); + + int stateId = argumentEllipses1.get(me.getSource()); + + CounterExampleProposition argument = ((CounterExampleUnaryOperator) model) + .getArgument(); + + List<CounterExampleProposition> children = argument.getChildren(); + children = children.subList(1, children.size()); + setTrasparent(children); + + CounterExamplePropositionFigure argumentFigure = getFigure(argument); + + for (Connection connection : argumentFigure.getConnections().values()) { + connection.setVisible(false); + } + + TitleBarBorder border = (TitleBarBorder) panel.getBorder(); + + if (argument.getStateId() == stateId) { + boolean visible = !argument.isVisible(); + + if (argument.hasChildren()) { + border.setFont(visible ? boldFont : normalFont); + } + + argument.setVisible(visible); + } else { + if (argument.hasChildren()) { + border.setFont(boldFont); + } + + argument.setStateId(stateId); + argument.setVisible(true); + } + } + + @Override + public void mouseEntered(MouseEvent me) { + Ellipse source = (Ellipse) me.getSource(); + + CounterExampleProposition argument = ((CounterExampleUnaryOperator) model) + .getArgument(); + + if (!argument.hasChildren()) + return; + + boolean painted = argument.isVisible(); + int argumentStateId = argument.getStateId(); + int stateId = argumentEllipses1.get(source); + + Label label = new Label(); + label.setForegroundColor(foregroundColor); + + String text = "open "; + + if (stateId == argumentStateId) + text = painted ? "close " : "open "; + + label.setText("Click to " + text + argument); + source.setToolTip(label); + } +} diff --git a/de.prob.ui/src/de/prob/ui/ltl/CounterExampleView.java b/de.prob.ui/src/de/prob/ui/ltl/CounterExampleView.java new file mode 100644 index 0000000000000000000000000000000000000000..a9f0773fb4828410bde244b5406d2577f4871617 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ltl/CounterExampleView.java @@ -0,0 +1,314 @@ +package de.prob.ui.ltl; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +import org.eclipse.core.commands.Command; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.ParameterizedCommand; +import org.eclipse.gef.DefaultEditDomain; +import org.eclipse.gef.EditDomain; +import org.eclipse.gef.GraphicalViewer; +import org.eclipse.gef.RootEditPart; +import org.eclipse.gef.editparts.ScalableRootEditPart; +import org.eclipse.gef.editparts.ZoomManager; +import org.eclipse.gef.ui.actions.PrintAction; +import org.eclipse.gef.ui.actions.ZoomInAction; +import org.eclipse.gef.ui.actions.ZoomOutAction; +import org.eclipse.gef.ui.parts.ScrollingGraphicalViewer; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.layout.TableColumnLayout; +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.ColumnWeightData; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.TreeViewerColumn; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CTabFolder; +import org.eclipse.swt.custom.CTabItem; +import org.eclipse.swt.custom.SashForm; +import org.eclipse.swt.custom.StackLayout; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.handlers.HandlerUtil; +import org.eclipse.ui.menus.CommandContributionItem; +import org.eclipse.ui.part.ViewPart; + +import de.prob.core.domainobjects.ltl.CounterExample; +import de.prob.core.domainobjects.ltl.CounterExampleProposition; + +/*** + * Provides a view for a counter-example + * + * @author Andriy Tolstoy + * + */ +public final class CounterExampleView extends ViewPart { + public static final String ID = "de.prob.ui.ltl.CounterExampleView"; + private static final String COUNTEREXAMPLE_DATA_KEY = "counterexample"; + + private final List<CounterExample> counterExamples = new ArrayList<CounterExample>(); + + private static CTabFolder tabFolder; + + private RootEditPart rootEditPart; + private GraphicalViewer graphicalViewer; + private EditDomain editDomain; + + @Override + public void createPartControl(final Composite parent) { + tabFolder = new CTabFolder(parent, SWT.BORDER); + } + + @Override + public void setFocus() { + tabFolder.setFocus(); + } + + public void addCounterExample(final CounterExample counterExample) { + counterExamples.add(counterExample); + + final Runnable runnable = new Runnable() { + @Override + public void run() { + final CTabItem tabItem = createTabItem(counterExample); + tabFolder.setSelection(tabItem); + tabFolder.update(); + } + }; + Display.getDefault().asyncExec(runnable); + } + + public CounterExample getCurrentCounterExample() { + final CTabItem selection = tabFolder.getSelection(); + return selection == null ? null : (CounterExample) selection + .getData(COUNTEREXAMPLE_DATA_KEY); + } + + @Override + public Object getAdapter(@SuppressWarnings("rawtypes") Class type) { + if (type == ZoomManager.class) + return ((ScalableRootEditPart) rootEditPart).getZoomManager(); + else if (type == GraphicalViewer.class) { + return graphicalViewer; + } else if (type == EditDomain.class) { + return editDomain; + } else if (type == IWorkbenchPage.class) { + return getSite().getPage(); + } + + return null; + } + + public static void setViewType(String viewType) { + for (CTabItem tabItem : tabFolder.getItems()) { + Control control = tabItem.getControl(); + + if (!(control instanceof SashForm)) + return; + + SashForm sashForm = (SashForm) control; + + if (sashForm.getChildren().length <= 0) + return; + if (!(sashForm.getChildren()[0] instanceof CounterExampleComposite)) + return; + + CounterExampleComposite composite = (CounterExampleComposite) sashForm + .getChildren()[0]; + + if (!(composite.getLayout() instanceof StackLayout)) + return; + + StackLayout stackLayout = (StackLayout) composite.getLayout(); + + stackLayout.topControl = viewType.equals("Table") ? composite + .getTableView() : composite.getTreeView(); + + composite.layout(); + } + } + + private CTabItem createTabItem(final CounterExample counterExample) { + final CTabItem tabItem = new CTabItem(tabFolder, SWT.CLOSE); + tabItem.setText(counterExample.getPropositionRoot().toString()); + tabItem.setData(COUNTEREXAMPLE_DATA_KEY, counterExample); + + final SashForm sashForm = new SashForm(tabFolder, SWT.HORIZONTAL); + tabItem.setControl(sashForm); + + CounterExampleComposite composite = new CounterExampleComposite( + sashForm, SWT.None); + + StackLayout stackLayout = new StackLayout(); + composite.setLayout(stackLayout); + + Composite tableView = new Composite(composite, SWT.None); + createTableViewer(tableView, counterExample); + + Composite treeView = new Composite(composite, SWT.None); + treeView.setLayout(new FillLayout()); + createTreeViewer(treeView, counterExample); + + composite.setTableComposite(tableView); + composite.setTreeComposite(treeView); + + if (tabFolder.getChildren().length == 1) { + MenuManager manager = (MenuManager) getViewSite().getActionBars() + .getMenuManager(); + + if (manager.getItems().length > 0) { + if (manager.getItems()[0] instanceof CommandContributionItem) { + CommandContributionItem item = (CommandContributionItem) manager + .getItems()[0]; + + ParameterizedCommand parameterizedCommand = item + .getCommand(); + + try { + Command command = parameterizedCommand.getCommand(); + HandlerUtil.updateRadioState(command, "Table"); + } catch (ExecutionException e) { + e.printStackTrace(); + } + } + } + } + + String currentViewType = CounterExampleViewMenuHandler + .getCurrentViewType(); + stackLayout.topControl = currentViewType.equals("Table") ? tableView + : treeView; + + rootEditPart = new ScalableRootEditPart(); + + graphicalViewer = new ScrollingGraphicalViewer(); + graphicalViewer.createControl(sashForm); + graphicalViewer.getControl().setBackground( + Display.getDefault().getSystemColor(SWT.COLOR_WHITE)); + graphicalViewer.setRootEditPart(rootEditPart); + graphicalViewer.setEditPartFactory(new CounterExampleEditPartFactory()); + graphicalViewer.setContents(counterExample); + + editDomain = new DefaultEditDomain(null); + editDomain.addViewer(graphicalViewer); + + ZoomManager zoomManager = ((ScalableRootEditPart) rootEditPart) + .getZoomManager(); + + IAction zoomIn = new ZoomInAction(zoomManager); + IAction zoomOut = new ZoomOutAction(zoomManager); + IAction print = new PrintAction(this); + + IActionBars actionBar = getViewSite().getActionBars(); + actionBar.getMenuManager().add(zoomIn); + actionBar.getMenuManager().add(zoomOut); + actionBar.getMenuManager().add(print); + + return tabItem; + } + + private TableViewer createTableViewer(Composite parent, + final CounterExample counterExample) { + final TableViewer tableViewer = new TableViewer(parent); + tableViewer.getTable().setHeaderVisible(true); + tableViewer.getTable().setLinesVisible(true); + + final TableColumnLayout layout = new TableColumnLayout(); + parent.setLayout(layout); + createEventColumn(tableViewer, layout); + + final Collection<CounterExampleProposition> propositions = counterExample + .getPropositions(); + + for (CounterExampleProposition proposition : propositions) { + createPropositionColumn(tableViewer, layout, proposition); + } + + tableViewer.setContentProvider(new ArrayContentProvider()); + tableViewer.setInput(counterExample.getStates()); + + return tableViewer; + } + + private TreeViewer createTreeViewer(Composite parent, + CounterExample counterExample) { + final CounterExampleTreeViewer treeViewer = new CounterExampleTreeViewer( + parent, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL); + + treeViewer.getTree().setHeaderVisible(true); + treeViewer.getTree().setLinesVisible(true); + + TreeViewerColumn propositionColumn = new TreeViewerColumn(treeViewer, + SWT.CENTER); + propositionColumn.getColumn().setAlignment(SWT.CENTER); + propositionColumn.getColumn().setText("Proposition"); + propositionColumn.getColumn().setResizable(false); + + for (int j = 0; j < counterExample.getStates().size(); j++) { + TreeViewerColumn column = new TreeViewerColumn(treeViewer, + SWT.CENTER); + column.getColumn().setAlignment(SWT.CENTER); + column.getColumn().setText( + "State " + counterExample.getStates().get(j).getState() + + " (" + + counterExample.getStates().get(j).getOperation() + + ")"); + + column.getColumn().pack(); + column.getColumn().setResizable(false); + } + + treeViewer.setLabelProvider(new CounterExampleTreeLabelProvider()); + treeViewer.setContentProvider(new CounterExampleContentProvider()); + + // treeViewer.getTree().addMouseListener( + // new CounterExampleMouseAdapter(treeViewer)); + + treeViewer.getTree().addMouseMoveListener( + new CounterExampleMouseMoveAdapter(treeViewer)); + + // List<CounterExampleProposition> propositions = new + // ArrayList<CounterExampleProposition>(); + // propositions.add(counterExample.getPropositionRoot()); + treeViewer.setInput(Arrays + .asList(new CounterExampleProposition[] { counterExample + .getPropositionRoot() })); + treeViewer.expandAll(); + propositionColumn.getColumn().pack(); + + return treeViewer; + } + + private void createPropositionColumn(final TableViewer tableViewer, + final TableColumnLayout layout, + final CounterExampleProposition proposition) { + final TableViewerColumn tableViewerColumn = new TableViewerColumn( + tableViewer, SWT.NONE); + tableViewerColumn.setLabelProvider(new PropositionColumnLabelProvider( + proposition)); + tableViewerColumn.getColumn().setText(proposition.toString()); + tableViewerColumn.getColumn().setAlignment(SWT.CENTER); + layout.setColumnData(tableViewerColumn.getColumn(), + new ColumnWeightData(1)); + } + + private void createEventColumn(final TableViewer tableViewer, + final TableColumnLayout layout) { + final TableViewerColumn tableViewerColumn = new TableViewerColumn( + tableViewer, SWT.NONE); + tableViewerColumn.setLabelProvider(new EventColumnLabelProvider()); + tableViewerColumn.getColumn().setText("Event"); + tableViewerColumn.getColumn().setAlignment(SWT.CENTER); + layout.setColumnData(tableViewerColumn.getColumn(), + new ColumnWeightData(1)); + } +} \ No newline at end of file diff --git a/de.prob.ui/src/de/prob/ui/ltl/CounterExampleViewMenuHandler.java b/de.prob.ui/src/de/prob/ui/ltl/CounterExampleViewMenuHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..863bf35afd61c3ad24dd2a817dae0aeaf96f91c1 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ltl/CounterExampleViewMenuHandler.java @@ -0,0 +1,37 @@ +package de.prob.ui.ltl; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.IHandler; +import org.eclipse.ui.handlers.HandlerUtil; +import org.eclipse.ui.handlers.RadioState; + +/*** + * Provides a menu handler for a menu in a counter-example view + * + * @author Andriy Tolstoy + * + */ + +public final class CounterExampleViewMenuHandler extends AbstractHandler + implements IHandler { + + private static String currentViewType = "Table"; + + @Override + public Object execute(final ExecutionEvent event) throws ExecutionException { + if (HandlerUtil.matchesRadioState(event)) + return null; + + currentViewType = event.getParameter(RadioState.PARAMETER_ID); + HandlerUtil.updateRadioState(event.getCommand(), currentViewType); + + CounterExampleView.setViewType(currentViewType); + return null; + } + + public static String getCurrentViewType() { + return currentViewType; + } +} diff --git a/de.prob.ui/src/de/prob/ui/ltl/EventColumnLabelProvider.java b/de.prob.ui/src/de/prob/ui/ltl/EventColumnLabelProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..a938ab796808bd43ac0b731c4bfa86d0d8611a81 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ltl/EventColumnLabelProvider.java @@ -0,0 +1,26 @@ +/** + * + */ +package de.prob.ui.ltl; + +import org.eclipse.jface.viewers.CellLabelProvider; +import org.eclipse.jface.viewers.ViewerCell; + +import de.prob.core.domainobjects.Operation; +import de.prob.core.domainobjects.ltl.CounterExampleState; + +/** + * @author plagge + * + */ +public final class EventColumnLabelProvider extends CellLabelProvider { + @Override + public void update(final ViewerCell cell) { + final CounterExampleState state = (CounterExampleState) cell + .getElement(); + final Operation operation = state.getOperation(); + + if (operation != null) + cell.setText(operation.getName()); + } +} diff --git a/de.prob.ui/src/de/prob/ui/ltl/LtlCheckingDialog.java b/de.prob.ui/src/de/prob/ui/ltl/LtlCheckingDialog.java new file mode 100644 index 0000000000000000000000000000000000000000..d8bd0443cef961829e36f9e044f0abae20cb2c60 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ltl/LtlCheckingDialog.java @@ -0,0 +1,409 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.ui.ltl; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; + +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.core.runtime.preferences.ConfigurationScope; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.core.runtime.preferences.IScopeContext; +import org.eclipse.jface.dialogs.DialogTray; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.dialogs.TrayDialog; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Cursor; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.ToolBar; +import org.eclipse.swt.widgets.ToolItem; + +import de.be4.ltl.core.parser.LtlParseException; +import de.be4.ltl.core.parser.LtlParser; +import de.prob.core.Animator; +import de.prob.core.command.CommandException; +import de.prob.core.command.LtlCheckingCommand; +import de.prob.core.command.SymmetryReductionOption; +import de.prob.logging.Logger; +import de.prob.prolog.term.PrologTerm; +import de.prob.ui.DialogHelpers; + +public final class LtlCheckingDialog extends TrayDialog { + private static final StartOption[] START_MODES = new StartOption[] { + new StartOption(LtlCheckingCommand.StartMode.init, + "Start in the (possible several) initialisation states of the model"), + new StartOption(LtlCheckingCommand.StartMode.starthere, + "Start the evaluation of the formula in the current state"), + new StartOption( + LtlCheckingCommand.StartMode.checkhere, + "Start the search as in init, but check the formula F in the current state by constructing a new formula (current -> F)") }; + + private final Shell shell; + private boolean trayOpened = false; + + private Combo formulas = null; + private Combo startingPointOptions = null; + private Combo symmetryOptions = null; + + protected LtlCheckingDialog(final Shell shell) { + super(shell); + this.shell = shell; + } + + @Override + protected void createButtonsForButtonBar(final Composite parent) { + } + + @Override + protected void configureShell(final Shell shell) { + super.configureShell(shell); + shell.setText("LTL Checking"); + } + + @Override + protected Control createDialogArea(final Composite parent) { + Composite dialogArea = (Composite) super.createDialogArea(parent); + GridLayout layout = (GridLayout) dialogArea.getLayout(); + layout.numColumns = 1; + + formulas = createFormulas(dialogArea); + startingPointOptions = createStartingPointOptions(dialogArea); + symmetryOptions = createSymmetryOptions(dialogArea); + + Button startButton = new Button(dialogArea, SWT.PUSH); + startButton.setText("Start LTL Checking"); + startButton + .setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER)); + startButton.addSelectionListener(new StartButtonSelectionListener()); + return dialogArea; + } + + @Override + protected Control createHelpControl(Composite parent) { + ToolBar toolBar = new ToolBar(parent, SWT.FLAT | SWT.NO_FOCUS); + ((GridLayout) parent.getLayout()).numColumns++; + toolBar.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER)); + + final Cursor cursor = new Cursor(parent.getDisplay(), SWT.CURSOR_HAND); + toolBar.setCursor(cursor); + toolBar.addDisposeListener(new DisposeListener() { + @Override + public void widgetDisposed(DisposeEvent e) { + cursor.dispose(); + } + }); + + ToolItem item = new ToolItem(toolBar, SWT.NONE); + Image image = JFaceResources.getImage(DLG_IMG_HELP); + + if (image != null) + item.setImage(JFaceResources.getImage(DLG_IMG_HELP)); + + item.setToolTipText(JFaceResources.getString("helpToolTip")); + + item.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (trayOpened) { + closeTray(); + } else { + openTray(new DialogTray() { + @Override + protected Control createContents(Composite parent) { + final StyledText help = new StyledText(parent, + SWT.READ_ONLY); + help.setEditable(false); + help.setEnabled(false); + help.setText(LtlStrings.ltlHelpText); + help.setBackground(Display.getDefault() + .getSystemColor(SWT.COLOR_WHITE)); + + return help; + } + }); + } + + trayOpened = !trayOpened; + } + }); + + return toolBar; + } + + private Combo createFormulas(final Composite parent) { + final Group group = DialogHelpers.createGroup(parent, "Formula:"); + group.setLayout(new GridLayout(2, false)); + group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + final Combo combo = new Combo(group, SWT.None); + combo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + for (String formula : getFormulas()) { + combo.add(formula); + } + + combo.select(0); + + Button button = new Button(group, SWT.None); + button.setText("Open..."); + button.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent event) { + FileDialog fileDialog = new FileDialog(shell, SWT.OPEN); + fileDialog.setFilterExtensions(new String[] { "*.ltl", "*.*" }); + fileDialog.setFilterNames(new String[] { "LTL files (*.ltl)", + "All files (*.*)" }); + String fileName = fileDialog.open(); + + if (fileName != null) { + BufferedReader reader = null; + + try { + reader = new BufferedReader(new FileReader(fileName)); + + String formula = null; + List<String> formulaItems = Arrays.asList(formulas + .getItems()); + + while ((formula = reader.readLine()) != null) { + formula = formula.trim(); + + if (formula.equals("") + || (formula.length() > 0 && formula + .charAt(0) == '#')) + continue; + + PrologTerm parsedFormula = parseLTLFormula(formula); + + if (parsedFormula != null) { + if (!formulaItems.contains(formula)) + formulas.add(formula); + } else { + break; + } + } + + formulas.select(0); + saveFormulas(new TreeSet<String>(Arrays.asList(formulas + .getItems()))); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (CommandException e) { + e.printStackTrace(); + } finally { + try { + reader.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + }); + + return combo; + } + + private Combo createStartingPointOptions(final Composite parent) { + final Group group = DialogHelpers + .createGroup(parent, "Starting Point:"); + group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + final Combo combo = new Combo(group, SWT.READ_ONLY); + combo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + for (StartOption startOption : START_MODES) { + combo.add(startOption.description); + } + + combo.select(0); + + return combo; + } + + private Combo createSymmetryOptions(final Composite parent) { + Group group = DialogHelpers.createGroup(parent, "Symmetry Reduction:"); + group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + final Combo combo = new Combo(group, SWT.READ_ONLY); + combo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + SymmetryReductionOption[] symmetryOptions = SymmetryReductionOption + .values(); + + for (SymmetryReductionOption startOption : symmetryOptions) { + combo.add(startOption.getDescription()); + } + + combo.select(0); + + return combo; + } + + private void saveFormulas(Set<String> formulas) { + IScopeContext configContext = new ConfigurationScope(); + IEclipsePreferences configNode = configContext + .getNode("de.prob.ui.ltl.CounterExampleView"); + + if (configNode != null) { + try { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + ObjectOutputStream objectOutputStream = new ObjectOutputStream( + byteArrayOutputStream); + objectOutputStream.writeObject(formulas); + objectOutputStream.flush(); + + byte[] formula = byteArrayOutputStream.toByteArray(); + configNode.putByteArray("formula", formula); + + objectOutputStream.close(); + byteArrayOutputStream.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + @SuppressWarnings("unchecked") + private Set<String> getFormulas() { + IScopeContext configContext = new ConfigurationScope(); + IEclipsePreferences configNode = configContext + .getNode("de.prob.ui.ltl.CounterExampleView"); + + byte[] formula = null; + if (configNode != null) { + formula = configNode.getByteArray("formula", null); + } + + Set<String> formulas; + if (formula != null) { + try { + ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream( + formula); + ObjectInputStream objectInputStream = new ObjectInputStream( + byteArrayInputStream); + + formulas = (Set<String>) objectInputStream.readObject(); + } catch (ClassNotFoundException e) { + Logger.notifyUser( + "Class not found exception when trying to read formulas", + e); + formulas = new HashSet<String>(); + } catch (IOException e) { + Logger.notifyUser("Unexpected IO exception", e); + formulas = new HashSet<String>(); + } + } else { + formulas = new HashSet<String>(); + } + + return formulas; + } + + private PrologTerm parseLTLFormula(String formula) throws CommandException { + final Animator animator = Animator.getAnimator(); + PrologTerm parsedFormula = null; + final LtlParser parser = new LtlParser( + animator.getLanguageDependendPart()); + + try { + parsedFormula = parser.generatePrologTerm(formula, "root"); + } catch (LtlParseException e) { // see Task#163 + MessageDialog.openError(getShell(), "Syntax error", + e.getLocalizedMessage()); + } + + return parsedFormula; + } + + private final class StartButtonSelectionListener extends SelectionAdapter { + @Override + public void widgetSelected(final SelectionEvent event) { + PrologTerm parsedFormula = null; + + try { + String formula = formulas.getText(); + parsedFormula = parseLTLFormula(formula); + + if (parsedFormula != null) { + List<String> formulaItems = Arrays.asList(formulas + .getItems()); + + if (!formulaItems.contains(formula)) + formulas.add(formula); + + saveFormulas(new TreeSet<String>(Arrays.asList(formulas + .getItems()))); + } + } catch (CommandException exception) { + // the only thing we can do is to abort + close(); + } + + if (parsedFormula != null) { + + LtlCheckingCommand.StartMode startOption = START_MODES[startingPointOptions + .getSelectionIndex()].mode; + String symmetryOption = SymmetryReductionOption.get( + symmetryOptions.getSelectionIndex()).name(); + + scheduleJob(parsedFormula, startOption, symmetryOption); + close(); + } + } + + private void scheduleJob(final PrologTerm parsedFormula, + final LtlCheckingCommand.StartMode option, + final String symmetryOption) { + final Job job = new LtlCheckingJob("LTL Model Checking", + parsedFormula, option, symmetryOption); + job.setUser(true); + job.addJobChangeListener(new LtlCheckingFinishedListener(shell)); + job.schedule(); + } + } + + private static final class StartOption { + private final LtlCheckingCommand.StartMode mode; + private final String description; + + private StartOption(LtlCheckingCommand.StartMode mode, + String description) { + this.mode = mode; + this.description = description; + } + } +} diff --git a/de.prob.ui/src/de/prob/ui/ltl/LtlCheckingFinishedListener.java b/de.prob.ui/src/de/prob/ui/ltl/LtlCheckingFinishedListener.java new file mode 100644 index 0000000000000000000000000000000000000000..0e38e2b732e6748a8528741de7be93ba38178a27 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ltl/LtlCheckingFinishedListener.java @@ -0,0 +1,120 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.ui.ltl; + +import org.eclipse.core.runtime.jobs.IJobChangeEvent; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.core.runtime.jobs.JobChangeAdapter; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; + +import de.prob.core.command.LtlCheckingCommand.PathType; +import de.prob.core.command.LtlCheckingCommand.Result; +import de.prob.core.domainobjects.ltl.CounterExample; +import de.prob.logging.Logger; +import de.prob.prolog.term.ListPrologTerm; + +public final class LtlCheckingFinishedListener extends JobChangeAdapter { + + private final Shell shell; + + public LtlCheckingFinishedListener(final Shell shell) { + this.shell = shell; + } + + @Override + public void done(final IJobChangeEvent event) { + super.done(event); + Job job = event.getJob(); + if (job instanceof LtlCheckingJob) { + LtlCheckingJob ltlJob = (LtlCheckingJob) job; + if (!ltlJob.isAnErrorOccurred()) { + showResult(ltlJob.getModelCheckingResult()); + } + } else { + final String message = "The job has a wrong type. Expected LtlCheckingJob but got " + + job.getClass(); + Logger.notifyUserWithoutBugreport(message); + } + } + + private void showResult(final Result modelCheckingResult) { + Logger.assertProB("modelCheckingResult != null", + modelCheckingResult != null); + + final String message; + final String title; + final int displayType; + switch (modelCheckingResult.getStatus()) { + case incomplete: + title = LtlStrings.ltlResultIncompleteTitle; + message = LtlStrings.ltlResultIncompleteTitle; + displayType = MessageDialog.WARNING; + break; + case ok: + title = LtlStrings.ltlResultOkTitle; + message = LtlStrings.ltlResultOkMessage; + displayType = MessageDialog.INFORMATION; + break; + case counterexample: + title = LtlStrings.ltlResultCounterexampleTitle; + if (modelCheckingResult.getPathType() == PathType.INFINITE) { + message = LtlStrings.ltlResultCounterexampleMessage + + LtlStrings.ltlLoopAdvice; + } else { + message = LtlStrings.ltlResultCounterexampleMessage; + } + displayType = MessageDialog.ERROR; + break; + case nostart: + title = LtlStrings.ltlResultNoStartTitle; + message = LtlStrings.ltlResultNoStartMessage; + displayType = MessageDialog.WARNING; + break; + case typeerror: + Logger.notifyUser("Internal error: Type-Checking the LTL formula failed"); + return; + default: + Logger.notifyUser("Uncovered case in LTL Result Type: " + + modelCheckingResult); + return; + } + + final Runnable runnable = new Runnable() { + @Override + public void run() { + MessageDialog + .open(displayType, shell, title, message, SWT.NONE); + ListPrologTerm counterExample = modelCheckingResult + .getCounterexample(); + if (counterExample != null) { + showCounterexampleInView(modelCheckingResult); + } + } + }; + shell.getDisplay().asyncExec(runnable); + } + + private void showCounterexampleInView(final Result modelCheckingResult) { + final CounterExample counterExample = new CounterExample( + modelCheckingResult); + final IWorkbenchPage workbenchPage = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage(); + try { + final CounterExampleView counterExampleView = (CounterExampleView) workbenchPage + .showView(CounterExampleView.ID); + counterExampleView.addCounterExample(counterExample); + } catch (PartInitException e) { + Logger.notifyUser("Failed to create the LTL view.", e); + } + + } +} diff --git a/de.prob.ui/src/de/prob/ui/ltl/LtlCheckingJob.java b/de.prob.ui/src/de/prob/ui/ltl/LtlCheckingJob.java new file mode 100644 index 0000000000000000000000000000000000000000..b4ec10349fd06183643c4b6eacfcc128c3688600 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ltl/LtlCheckingJob.java @@ -0,0 +1,86 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.ui.ltl; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; + +import de.prob.core.Animator; +import de.prob.core.command.LtlCheckingCommand; +import de.prob.core.command.LtlCheckingCommand.Result; +import de.prob.core.command.SetPreferenceCommand; +import de.prob.exceptions.ProBException; +import de.prob.prolog.term.PrologTerm; + +public final class LtlCheckingJob extends Job { + + private final Animator animator = Animator.getAnimator(); + private final PrologTerm formula; + private final LtlCheckingCommand.StartMode option; + private final String symmetry; + + private boolean abort = false; + private Result modelCheckingResult; + private boolean anErrorOccurred = false; + + public LtlCheckingJob(final String name, final PrologTerm parsedFormula, + final LtlCheckingCommand.StartMode option, final String symmetry) { + super(name); + this.formula = parsedFormula; + this.option = option; + this.symmetry = symmetry; + } + + @Override + protected IStatus run(final IProgressMonitor monitor) { + anErrorOccurred = false; + + if (!setSymmetry()) + return Status.CANCEL_STATUS; + monitor.beginTask("Checking LTL Formula", IProgressMonitor.UNKNOWN); + + while (!abort) { + try { + modelCheckingResult = doSomeModelchecking(); + monitor.worked(500); + } catch (ProBException e) { + // We cannot recover from this, but the user has been informed + e.notifyUserOnce(); + anErrorOccurred = true; + return Status.CANCEL_STATUS; + } + abort = modelCheckingResult.isAbort() || monitor.isCanceled(); + } + + return Status.OK_STATUS; + } + + public Result getModelCheckingResult() { + return modelCheckingResult; + } + + public boolean isAnErrorOccurred() { + return anErrorOccurred; + } + + private Result doSomeModelchecking() throws ProBException { + return LtlCheckingCommand.modelCheck(animator, formula, 500, option); + } + + private boolean setSymmetry() { + try { + SetPreferenceCommand.setPreference(animator, "SYMMETRY_MODE", + symmetry); + } catch (ProBException e) { + return false; // Failed + } + return true; + } + +} diff --git a/de.prob.ui/src/de/prob/ui/ltl/LtlCommand.java b/de.prob.ui/src/de/prob/ui/ltl/LtlCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..be753d9ad23a0a39891335b324d389f9a9f47374 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ltl/LtlCommand.java @@ -0,0 +1,62 @@ +package de.prob.ui.ltl; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.IHandler; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.handlers.HandlerUtil; +import org.eclipse.ui.services.ISourceProviderService; + +import de.prob.core.Animator; +import de.prob.ui.PerspectiveFactory; +import de.prob.ui.ProbUiPlugin; +import de.prob.ui.services.ModelLoadedProvider; + +public final class LtlCommand extends AbstractHandler implements IHandler { + @Override + public Object execute(final ExecutionEvent event) throws ExecutionException { + + IWorkbenchWindow window = HandlerUtil + .getActiveWorkbenchWindowChecked(event); + final Shell shell = window.getShell(); + + if (!isEnabled(window)) { // prevent from being called while no + // animation is running + ErrorDialog.openError(shell, "Error", + "Please start an animation first", new Status( + IStatus.ERROR, ProbUiPlugin.PLUGIN_ID, + "Please start an animation first", null)); + return null; + } + + PerspectiveFactory.openPerspective(); + + final Animator animator = Animator.getAnimator(); + + if (!animator.isRunning()) + return null; + + LtlCheckingDialog md = new LtlCheckingDialog(shell); + + md.setBlockOnOpen(true); + + md.open(); + + return null; + } + + private boolean isEnabled(final IWorkbenchWindow window) { + ISourceProviderService service = (ISourceProviderService) window + .getService(ISourceProviderService.class); + // get our source provider by querying by the variable name + ModelLoadedProvider sourceProvider = (ModelLoadedProvider) service + .getSourceProvider(ModelLoadedProvider.SERVICE); + return sourceProvider.isEnabled(); + } + +} diff --git a/de.prob.ui/src/de/prob/ui/ltl/LtlStrings.java b/de.prob.ui/src/de/prob/ui/ltl/LtlStrings.java new file mode 100644 index 0000000000000000000000000000000000000000..de9962448cdff5c995adf91963e686233d1fe60b --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ltl/LtlStrings.java @@ -0,0 +1,31 @@ +/** + * + */ +package de.prob.ui.ltl; + +import org.eclipse.osgi.util.NLS; + +/** + * @author plagge + * + */ +public final class LtlStrings extends NLS { + public static String ltlLoopAdvice; + + public static String ltlHelpText; + + public static String ltlResultIncompleteTitle; + public static String ltlResultIncompleteMessage; + public static String ltlResultOkTitle; + public static String ltlResultOkMessage; + public static String ltlResultCounterexampleTitle; + public static String ltlResultCounterexampleMessage; + public static String ltlResultNoStartTitle; + public static String ltlResultNoStartMessage; + + static { + final Class<LtlStrings> clazz = LtlStrings.class; + initializeMessages(clazz.getName(), clazz); + } + +} diff --git a/de.prob.ui/src/de/prob/ui/ltl/LtlStrings.properties b/de.prob.ui/src/de/prob/ui/ltl/LtlStrings.properties new file mode 100644 index 0000000000000000000000000000000000000000..d6f55b327312e4ce662c8abc7a2a0eba000bf2e3 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ltl/LtlStrings.properties @@ -0,0 +1,19 @@ +ltlHelpText=About LTL Checking\n\nLTL Syntax:\n\ +-use {...} for B predicates\n\ +-G, F, X, U, W, R, true, false, not, &, or, and, =>\n\ + are part of the supported LTL syntax\n\ +-use e(op) to check if an operation op is enabled\n\ +-use sink to check if no operation is enabled that leads to another state\n\ +-use brackets to check what is the next operation, e.g. [reset] => X{db={}}\n\ +-Past-LTL is supported: Y, H, O, S, T are the duals to X, G, F, U, R + +ltlResultIncompleteTitle=Modelchecking not completed +ltlResultIncompleteMessage=No counterexample has been found, but not all possible nodes have been visited (Due to animation parameter restrictions). +ltlResultOkTitle=Modelchecking successfully finished +ltlResultOkMessage=No counterexample has been found, all nodes have been visited. +ltlResultCounterexampleTitle=Counterexample found +ltlResultCounterexampleMessage=A counterexample has been found. It will be shown in the LTL view.\n (Please note that the view is actively developed. Currently it provides only a very basic functionality.) +ltlResultNoStartTitle=No initialisation found +ltlResultNoStartMessage=No initialised state to start from has been found.\nProB could not initialise the machine, maybe there is a problem with the animation settings. Try to animate the model first. + +ltlLoopAdvice=\nThe counterexample contains a loop. It will be highlighted in yellow. diff --git a/de.prob.ui/src/de/prob/ui/ltl/PropositionColumnLabelProvider.java b/de.prob.ui/src/de/prob/ui/ltl/PropositionColumnLabelProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..985fc74246adbed4c75fcb8c42fbcb65d98f38b1 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ltl/PropositionColumnLabelProvider.java @@ -0,0 +1,34 @@ +/** + * + */ +package de.prob.ui.ltl; + +import org.eclipse.jface.viewers.CellLabelProvider; +import org.eclipse.jface.viewers.ViewerCell; + +import de.prob.core.domainobjects.ltl.CounterExampleProposition; +import de.prob.core.domainobjects.ltl.CounterExampleState; +import de.prob.core.domainobjects.ltl.CounterExampleValueType; + +/** + * @author plagge + * + */ +public final class PropositionColumnLabelProvider extends CellLabelProvider { + final CounterExampleProposition proposition; + + public PropositionColumnLabelProvider(final CounterExampleProposition proposition) { + super(); + this.proposition = proposition; + } + + @Override + public void update(final ViewerCell cell) { + final CounterExampleState state = (CounterExampleState) cell + .getElement(); + final int index = state.getIndex(); + final CounterExampleValueType value = proposition.getValues() + .get(index); + cell.setText(value.toString()); + } +} diff --git a/de.prob.ui/src/de/prob/ui/operationview/DoubleClickBehaviorHandler.java b/de.prob.ui/src/de/prob/ui/operationview/DoubleClickBehaviorHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..4c8813d705b1d7099e8537f27e55674dfaa490f7 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/operationview/DoubleClickBehaviorHandler.java @@ -0,0 +1,23 @@ +package de.prob.ui.operationview; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.IHandler; +import org.eclipse.ui.handlers.HandlerUtil; +import org.eclipse.ui.handlers.RadioState; + +public class DoubleClickBehaviorHandler extends AbstractHandler implements + IHandler { + + public Object execute(final ExecutionEvent event) throws ExecutionException { + if (HandlerUtil.matchesRadioState(event)) + return null; // we are already in the updated state - do nothing + String currentState = event.getParameter(RadioState.PARAMETER_ID); + + OperationTableViewer.setDoubleClickBehavior(currentState); + + HandlerUtil.updateRadioState(event.getCommand(), currentState); + return null; + } +} diff --git a/de.prob.ui/src/de/prob/ui/operationview/ExecuteEventHandler.java b/de.prob.ui/src/de/prob/ui/operationview/ExecuteEventHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..8653bb42aab36ae1922c95fa9d96c5afef5f052f --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/operationview/ExecuteEventHandler.java @@ -0,0 +1,49 @@ +package de.prob.ui.operationview; + +import java.util.List; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.IHandler; + +import de.prob.core.Animator; +import de.prob.core.command.ExecuteOperationCommand; +import de.prob.core.domainobjects.Operation; +import de.prob.exceptions.ProBException; +import de.prob.logging.Logger; + +public class ExecuteEventHandler extends AbstractHandler implements IHandler { + + public Object execute(final ExecutionEvent event) throws ExecutionException { + long id = -1; + try { + id = Long.parseLong(event.getParameter("de.prob.ui.operation")); + } catch (NumberFormatException e) { + Logger.notifyUser("Internal Error. Please submit a bugreport", e); + } + Logger.assertProB("id >= 0", id >= 0); + + List<Operation> operations = OperationTableViewer.getInstance() + .getSelectedOperations(); + + if (operations.isEmpty()) + return null; + + for (Operation operation : operations) { + long cid = operation.getId(); + if (cid == id) { + try { + ExecuteOperationCommand.executeOperation( + Animator.getAnimator(), operation); + } catch (ProBException e) { + e.notifyUserOnce(); + throw new ExecutionException( + "executing the operation failed", e); + } + } + } + + return null; + } +} diff --git a/de.prob.ui/src/de/prob/ui/operationview/ExecuteRandomHandler.java b/de.prob.ui/src/de/prob/ui/operationview/ExecuteRandomHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..9961f1c3287d687ed5203bdef6b46e43fd2a9525 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/operationview/ExecuteRandomHandler.java @@ -0,0 +1,84 @@ +package de.prob.ui.operationview; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.IHandler; +import org.eclipse.jface.dialogs.IInputValidator; +import org.eclipse.jface.dialogs.InputDialog; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.handlers.HandlerUtil; + +import de.prob.core.Animator; +import de.prob.core.command.ExecuteRandomStepsCommand; +import de.prob.exceptions.ProBException; + +public class ExecuteRandomHandler extends AbstractHandler implements IHandler { + + public Object execute(final ExecutionEvent event) throws ExecutionException { + Shell shell = HandlerUtil.getActiveShell(event); + int steps = -1; + try { + steps = Integer.parseInt(event + .getParameter("de.prob.ui.randomoperation.steps")); + } catch (NumberFormatException e) { + // ignore, we will open Dialog + } + + if (steps < 0) { + try { + steps = askForValue(shell); + } catch (NumberFormatException e) { + // something went terribly wrong, do nothing + return null; + } + + } + + animate(steps); + + return null; + } + + public void animate(final int steps) { + /* + * make sure no other operation can be executed during random animation. + * The refresh() method will initialize the opTable again. + */ + // opTable.dispose(); + // opTable = null; + try { + final Animator animator = Animator.getAnimator(); + ExecuteRandomStepsCommand.executeOperation(animator, steps); + } catch (ProBException e) { + // We cannot recover from this, but the user has been informed + return; + } + } + + private int askForValue(final Shell shell) { + InputDialog inputDialog = new InputDialog(shell, "Random Animation", + "Number of steps:", "1", new IInputValidator() { + String errormsg = "Number must be a non-negative Integer."; + + public String isValid(final String newText) { + Integer num; + try { + num = Integer.parseInt(newText); + } catch (NumberFormatException e) { + return errormsg; + } + if (num < 0) { + return errormsg; + } + return null; + } + }); + inputDialog.open(); + String answer = inputDialog.getValue(); + if (answer != null) { + return Integer.parseInt(answer); + } else + throw new NumberFormatException(); + } +} diff --git a/de.prob.ui/src/de/prob/ui/operationview/Filter.java b/de.prob.ui/src/de/prob/ui/operationview/Filter.java new file mode 100644 index 0000000000000000000000000000000000000000..3b885837e588f1ab56ed174ea7db24e5e09bb2e8 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/operationview/Filter.java @@ -0,0 +1,52 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.ui.operationview; + +public class Filter { + + private final String pattern; + private final String name; + private Boolean enabled = true; + + public Filter(String pattern) { + this.pattern = pattern; + this.name = pattern; + } + + public Filter(String pattern, String name, Boolean enabled) { + this.pattern = pattern; + this.name = name; + this.enabled = enabled; + } + + public Boolean getEnabled() { + return enabled; + } + + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } + + public String getPattern() { + return pattern; + } + + public String toString() { + StringBuilder stringBuilder = new StringBuilder(name); + stringBuilder.append(" pattern:"); + stringBuilder.append(pattern); + stringBuilder.append(" ("); + stringBuilder.append(enabled ? "enabled" : "disabled"); + stringBuilder.append(")"); + return stringBuilder.toString(); + } + + public String getName() { + return name; + } + +} diff --git a/de.prob.ui/src/de/prob/ui/operationview/FilterDialog.java b/de.prob.ui/src/de/prob/ui/operationview/FilterDialog.java new file mode 100644 index 0000000000000000000000000000000000000000..ebcb896db3eaacc69295a256ba9c879841d8ab3a --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/operationview/FilterDialog.java @@ -0,0 +1,344 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.ui.operationview; + +import java.util.LinkedList; +import java.util.List; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.FormAttachment; +import org.eclipse.swt.layout.FormData; +import org.eclipse.swt.layout.FormLayout; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Dialog; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.swt.widgets.Text; + +public class FilterDialog extends Dialog implements SelectionListener { + final Shell dialog; + private Button buttonNew; + private Button buttonRemove; + private Button buttonSelectAll; + private Button buttonDeselectAll; + private Table table; + private Button buttonDone; + private List<Filter> filters = new LinkedList<Filter>(); + private static final String TABLE_INFO = "User patterns to exclude from the view:"; + + public FilterDialog(final Shell parent, final List<Filter> filters) { + super(parent); + dialog = new Shell(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL + | SWT.RESIZE); + dialog.setText("Filters"); + createControls(); + setFilters(filters); + } + + public FilterDialog(final Shell parent, final int style, + final List<Filter> filters) { + super(parent, style); + dialog = new Shell(parent, style); + dialog.setText("Filters"); + createControls(); + setFilters(filters); + } + + private void setFilters(final List<Filter> filters) { + if (filters == null) { + return; + } + this.filters.addAll(filters); + for (Filter filter : filters) { + TableItem tableItem = new TableItem(table, SWT.NONE); + tableItem.setText(filter.getName()); + tableItem.setChecked(filter.getEnabled()); + tableItem.setData(filter); + } + } + + private void createControls() { + dialog.setLayout(new RowLayout()); + + FormLayout formLayout = new FormLayout(); + formLayout.spacing = 5; + formLayout.marginHeight = 15; + formLayout.marginWidth = 10; + dialog.setLayout(formLayout); + + Label label1 = new Label(dialog, SWT.NONE); + label1.setText(TABLE_INFO); + FormData formaData = new FormData(); + label1.setLayoutData(formaData); + + table = new Table(dialog, SWT.CHECK | SWT.BORDER); + formaData = new FormData(); + formaData.left = new FormAttachment(0, 0); + formaData.top = new FormAttachment(label1, -5); + formaData.right = new FormAttachment(75, 0); + formaData.bottom = new FormAttachment(90, 0); + table.setLayoutData(formaData); + + buttonNew = new Button(dialog, SWT.PUSH); + buttonNew.setText("&New"); + buttonNew.addSelectionListener(this); + formaData = new FormData(); + formaData.top = new FormAttachment(label1, 0); + formaData.left = new FormAttachment(table, 0); + formaData.right = new FormAttachment(100, 0); + buttonNew.setLayoutData(formaData); + + buttonRemove = new Button(dialog, SWT.PUSH); + buttonRemove.setText("&Remove"); + buttonRemove.addSelectionListener(this); + formaData = new FormData(); + formaData.top = new FormAttachment(buttonNew, 0); + formaData.left = new FormAttachment(table, 0); + formaData.right = new FormAttachment(100, 0); + buttonRemove.setLayoutData(formaData); + + buttonSelectAll = new Button(dialog, SWT.PUSH); + buttonSelectAll.setText("Select &All"); + buttonSelectAll.addSelectionListener(this); + formaData = new FormData(); + formaData.top = new FormAttachment(table); + buttonSelectAll.setLayoutData(formaData); + + buttonDeselectAll = new Button(dialog, SWT.PUSH); + buttonDeselectAll.setText("&Deselect All"); + buttonDeselectAll.addSelectionListener(this); + formaData = new FormData(); + formaData.top = new FormAttachment(table, 0); + formaData.left = new FormAttachment(buttonSelectAll); + buttonDeselectAll.setLayoutData(formaData); + + buttonDone = new Button(dialog, SWT.PUSH); + buttonDone.setText(" &Ok "); + buttonDone.addSelectionListener(this); + formaData = new FormData(); + formaData.top = new FormAttachment(table, 0); + formaData.right = new FormAttachment(100, 0); + buttonDone.setLayoutData(formaData); + + // FormData button1Data = new FormData(); + // button1Data.left = new FormAttachment(0, 0); + // button1Data.right = new FormAttachment(sash, 0); + // button1Data.top = new FormAttachment(0, 0); + // button1Data.bottom = new FormAttachment(100, 0); + // button1.setLayoutData(button1Data); + + dialog.pack(); + } + + /** + * Show the Dialog. + * + * @return A List of Strings whith the activated user filters. + */ + public List<Filter> open() { + dialog.open(); + + Display display = dialog.getDisplay(); + while (!dialog.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + + return filters; + } + + public void widgetDefaultSelected(final SelectionEvent e) { + + } + + public void widgetSelected(final SelectionEvent e) { + if (e.getSource() == buttonNew) { + // InputDialog inputDialog = new InputDialog(dialog, "Add New + // Filter", + // "Pattern to exclude from the view:", null, + // new IInputValidator() { + // + // public String isValid(String newText) { + // if (newText != null && newText.length() > 0) { + // return null; + // } + // return ""; + // } + // + // }); + // + // inputDialog.open(); + + FilterInputDialog filterDialog = new FilterInputDialog(dialog); + Filter newFilter = filterDialog.open(); + + if (newFilter != null) { + TableItem tableItem = new TableItem(table, SWT.NONE); + tableItem.setText(newFilter.getName()); + tableItem.setChecked(true); + tableItem.setData(newFilter); + } + + } else if (e.getSource() == buttonRemove) { + if (table.getSelectionCount() > 0) { + table.getSelection()[0].dispose(); + } + } else if (e.getSource() == buttonSelectAll) { + TableItem[] items = table.getItems(); + for (TableItem item : items) { + item.setChecked(true); + } + } else if (e.getSource() == buttonDeselectAll) { + TableItem[] items = table.getItems(); + for (TableItem item : items) { + item.setChecked(false); + } + } else if (e.getSource() == buttonDone) { + TableItem[] items = table.getItems(); + filters = new LinkedList<Filter>(); + for (TableItem item : items) { + Assert.isTrue(item.getData() instanceof Filter); + filters.add((Filter) item.getData()); + } + dialog.dispose(); + } + + } + + private static final class FilterInputDialog extends Dialog { + private String pattern; + private String name; + private Text textName; + private Text textPattern; + + private Button buttonOk; + + public FilterInputDialog(final Shell parent) { + super(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL); + } + + public Filter open() { + Shell parent = getParent(); + Shell shell = new Shell(parent, SWT.DIALOG_TRIM + | SWT.APPLICATION_MODAL); + shell.setText(getText()); + + createControls(shell); + + shell.pack(); + shell.open(); + Display display = parent.getDisplay(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + + if (pattern == null) { + return null; + } + + if (name == null || name.length() == 0) { + name = pattern; + } + + return new Filter(pattern, name, true); + } + + private void createControls(final Shell shell) { + + FormLayout formLayout = new FormLayout(); + formLayout.marginHeight = 15; + formLayout.marginWidth = 10; + formLayout.spacing = 5; + shell.setLayout(formLayout); + + Label labelPattern = new Label(shell, SWT.NONE); + labelPattern + .setText("Pattern to exclude from the view:\n(Pattern is case sensitive. *=any string, ?=any character.)"); + FormData formData = new FormData(); + formData.left = new FormAttachment(0, 0); + labelPattern.setLayoutData(formData); + + textPattern = new Text(shell, SWT.BORDER); + formData = new FormData(); + formData.width = 300; + formData.left = new FormAttachment(0, 0); + formData.right = new FormAttachment(100, 0); + formData.top = new FormAttachment(labelPattern); + textPattern.setLayoutData(formData); + + Label labelName = new Label(shell, SWT.NONE); + labelName.setText("Name (optional):"); + formData = new FormData(); + formData.left = new FormAttachment(0, 0); + formData.top = new FormAttachment(textPattern); + labelName.setLayoutData(formData); + + textName = new Text(shell, SWT.BORDER); + formData = new FormData(); + formData.width = 300; + formData.left = new FormAttachment(0, 0); + formData.right = new FormAttachment(100, 0); + formData.top = new FormAttachment(labelName); + textName.setLayoutData(formData); + + Button buttonCancel = new Button(shell, SWT.BORDER); + buttonCancel.setText("&Cancel"); + formData = new FormData(); + formData.right = new FormAttachment(100, 0); + formData.top = new FormAttachment(textName); + buttonCancel.setLayoutData(formData); + + buttonOk = new Button(shell, SWT.BORDER); + buttonOk.setText(" &Ok "); + formData = new FormData(); + formData.right = new FormAttachment(buttonCancel, 0); + formData.top = new FormAttachment(textName); + buttonOk.setLayoutData(formData); + buttonOk.setEnabled(false); + + buttonCancel.addListener(SWT.Selection, new Listener() { + public void handleEvent(final Event event) { + pattern = null; + shell.dispose(); + } + }); + buttonOk.addListener(SWT.Selection, new Listener() { + public void handleEvent(final Event event) { + name = textName.getText(); + shell.dispose(); + } + }); + textPattern.addListener(SWT.Modify, new Listener() { + public void handleEvent(final Event event) { + if (textPattern.getText().length() == 0) { + pattern = null; + buttonOk.setEnabled(false); + } else { + name = textName.getText(); + pattern = textPattern.getText(); + buttonOk.setEnabled(true); + } + } + }); + + shell.setDefaultButton(buttonOk); + } + + } +} diff --git a/de.prob.ui/src/de/prob/ui/operationview/FilterListener.java b/de.prob.ui/src/de/prob/ui/operationview/FilterListener.java new file mode 100644 index 0000000000000000000000000000000000000000..968b52a52048eb9934ffaf1aa5b681c271a065c9 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/operationview/FilterListener.java @@ -0,0 +1,13 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.ui.operationview; + +public interface FilterListener { + + void filtersChanged(); + +} diff --git a/de.prob.ui/src/de/prob/ui/operationview/FilterManager.java b/de.prob.ui/src/de/prob/ui/operationview/FilterManager.java new file mode 100644 index 0000000000000000000000000000000000000000..100c18c1abf82449ef3f697457ec16a2e361db41 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/operationview/FilterManager.java @@ -0,0 +1,158 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.ui.operationview; + +import java.util.LinkedList; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.MenuItem; + +public class FilterManager implements SelectionListener { + + protected List<Filter> filters = new LinkedList<Filter>(); + protected Menu filtersMenu; + protected List<FilterListener> listeners = new LinkedList<FilterListener>(); + protected MenuItem configureItem; + + public FilterManager(final Menu menu) { + if (menu == null) { + throw new IllegalArgumentException("menu can not be null"); + } + filtersMenu = menu; + addConfigureItem(); + } + + private void addConfigureItem() { + new MenuItem(filtersMenu, SWT.SEPARATOR); + + configureItem = new MenuItem(filtersMenu, SWT.NONE); + configureItem.setText("&Configure..."); + configureItem.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(final SelectionEvent e) { + super.widgetSelected(e); + showFilterPopup(); + } + }); + } + + private void showFilterPopup() { + FilterDialog filterDialog = new FilterDialog(Display.getCurrent() + .getActiveShell(), filters); + clearMenu(); + this.filters = filterDialog.open(); + for (Filter filter : filters) { + addFilterToMenu(filter); + } + filtersChanged(); + } + + /** + * dispose all MenuItems representing a filter from this.filters + */ + private void clearMenu() { + for (MenuItem item : filtersMenu.getItems()) { + if (item.getData() instanceof Filter) { + Filter filter = (Filter) item.getData(); + if (filters.contains(filter)) { + item.dispose(); + } + } + } + } + + protected void addFilterToMenu(final Filter filter) { + final MenuItem item = new MenuItem(filtersMenu, SWT.CHECK); + item.setText(filter.getName()); + item.setSelection(filter.getEnabled()); + item.setData(filter); + item.addSelectionListener(this); + } + + /** + * Shortcut for addFilter(pattern, pattern) + * + * @param pattern + * : the new filters pattern and name + * @return the new filter + */ + public Filter addFilter(final String pattern) { + return addFilter(pattern, pattern); + } + + /** + * creates and adds a new enabled filter + * + * @param pattern + * : pattern of the new filter + * @param name + * : name of the new Filter + * @return the new filter + */ + public Filter addFilter(final String pattern, final String name) { + Filter filter = new Filter(pattern, name, true); + addFilter(filter); + return filter; + } + + public void addFilter(final Filter filter) { + filters.add(filter); + addFilterToMenu(filter); + } + + /** + * + * @param string + * @return true if text matches any enabled filter + */ + public boolean match(final String text) { + for (Filter filter : filters) { + if (filter.getEnabled()) { + StringMatcher stringMatcher = new StringMatcher(filter + .getPattern(), false, false); + if (stringMatcher.match(text)) { + return true; + } + } + + } + return false; + } + + public void addFilterListener(final FilterListener listener) { + listeners.add(listener); + } + + public void removeFilterListener(final FilterListener listener) { + listeners.remove(listener); + } + + public void widgetDefaultSelected(final SelectionEvent e) { + } + + public void widgetSelected(final SelectionEvent e) { + if (e.getSource() instanceof MenuItem) { + MenuItem item = (MenuItem) e.getSource(); + Filter filter = (Filter) item.getData(); + filter.setEnabled(item.getSelection()); + filtersChanged(); + } + } + + public void filtersChanged() { + for (FilterListener l : listeners) { + l.filtersChanged(); + } + } + +} diff --git a/de.prob.ui/src/de/prob/ui/operationview/HistoryBackHandler.java b/de.prob.ui/src/de/prob/ui/operationview/HistoryBackHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..561434f694a82c6dbb5fa0f34038e07c6c1a286d --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/operationview/HistoryBackHandler.java @@ -0,0 +1,34 @@ +package de.prob.ui.operationview; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.IHandler; + +import de.prob.core.Animator; +import de.prob.core.domainobjects.History; +import de.prob.exceptions.ProBException; +import de.prob.logging.Logger; + +public class HistoryBackHandler extends AbstractHandler implements IHandler { + + public Object execute(final ExecutionEvent event) throws ExecutionException { + + History history = Animator.getAnimator().getHistory(); + Logger.assertProB("history != null", history != null); + int pos = history.getCurrentPosition() - 1; + try { + pos = Integer + .parseInt(event.getParameter("de.prob.ui.history.pos")); + } catch (NumberFormatException e) { + // one step back + } + Logger.assertProB("pos >= 0", pos >= 0); + try { + history.gotoPos(pos); + } catch (ProBException e) { + Logger.notifyUser("Internal Error. Please submit a bugreport", e); + } + return null; + } +} diff --git a/de.prob.ui/src/de/prob/ui/operationview/HistoryBackwardMenu.java b/de.prob.ui/src/de/prob/ui/operationview/HistoryBackwardMenu.java new file mode 100644 index 0000000000000000000000000000000000000000..3e810ec7463f6866b3bfb085af5ce53580a28ae3 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/operationview/HistoryBackwardMenu.java @@ -0,0 +1,72 @@ +package de.prob.ui.operationview; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Stack; + +import org.eclipse.swt.SWT; +import org.eclipse.ui.menus.CommandContributionItem; +import org.eclipse.ui.menus.CommandContributionItemParameter; +import org.eclipse.ui.menus.ExtensionContributionFactory; +import org.eclipse.ui.menus.IContributionRoot; +import org.eclipse.ui.services.IServiceLocator; + +import de.prob.core.Animator; +import de.prob.core.domainobjects.History; +import de.prob.core.domainobjects.HistoryItem; +import de.prob.core.domainobjects.Operation; + +public class HistoryBackwardMenu extends ExtensionContributionFactory { + + public HistoryBackwardMenu() { + } + + private final Stack<CommandContributionItem> items = new Stack<CommandContributionItem>(); + + @Override + public void createContributionItems(final IServiceLocator serviceLocator, + final IContributionRoot additions) { + + Animator animator = Animator.getAnimator(); + History history = animator.getHistory(); + if (history.isEmpty()) + return; + + int pos = 0; + String lastItem = "(root)"; + Iterator<HistoryItem> iterator = history.iterator(); + + int currentPosition = history.getCurrentPosition(); + while (iterator.hasNext()) { + HistoryItem historyItem = iterator.next(); + if (pos < currentPosition) { + items.push(createEntry(serviceLocator, lastItem, pos)); + Operation operation = historyItem.getOperation(); + lastItem = operation != null ? operation.toString() + : historyItem.getState().toString(); + } else + break; + pos++; + } + while (!items.isEmpty()) { + additions.addContributionItem(items.pop(), null); + } + } + + private CommandContributionItem createEntry( + final IServiceLocator serviceLocator, final String lastItem, + final int pos) { + CommandContributionItemParameter p = new CommandContributionItemParameter( + serviceLocator, "", "de.prob.ui.history.back", SWT.PUSH); + + HashMap<String, String> map = new HashMap<String, String>(1); + map.put("de.prob.ui.history.pos", Integer.toString(pos)); + p.parameters = map; + + p.label = lastItem; + CommandContributionItem item = new CommandContributionItem(p); + item.setVisible(true); + return item; + } + +} diff --git a/de.prob.ui/src/de/prob/ui/operationview/HistoryForwardHandler.java b/de.prob.ui/src/de/prob/ui/operationview/HistoryForwardHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..6400e4526a019b86446d5f236c0e8a074110e0b2 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/operationview/HistoryForwardHandler.java @@ -0,0 +1,34 @@ +package de.prob.ui.operationview; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.IHandler; + +import de.prob.core.Animator; +import de.prob.core.domainobjects.History; +import de.prob.exceptions.ProBException; +import de.prob.logging.Logger; + +public class HistoryForwardHandler extends AbstractHandler implements IHandler { + + public Object execute(final ExecutionEvent event) throws ExecutionException { + History history = Animator.getAnimator().getHistory(); + Logger.assertProB("history != null", history != null); + int pos = history.getCurrentPosition() + 1; + try { + pos = Integer + .parseInt(event.getParameter("de.prob.ui.history.pos")); + } catch (NumberFormatException e) { + // one step back + } + Logger.assertProB("pos < last position", pos < history.size()); + try { + history.gotoPos(pos); + } catch (ProBException e) { + Logger.notifyUser("Internal Error. Please submit a bugreport", e); + } + return null; + } + +} diff --git a/de.prob.ui/src/de/prob/ui/operationview/HistoryForwardMenu.java b/de.prob.ui/src/de/prob/ui/operationview/HistoryForwardMenu.java new file mode 100644 index 0000000000000000000000000000000000000000..0f621e32efbe0e0e7805c6ec859da94fdffdc945 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/operationview/HistoryForwardMenu.java @@ -0,0 +1,68 @@ +package de.prob.ui.operationview; + +import java.util.HashMap; +import java.util.Iterator; + +import org.eclipse.swt.SWT; +import org.eclipse.ui.menus.CommandContributionItem; +import org.eclipse.ui.menus.CommandContributionItemParameter; +import org.eclipse.ui.menus.ExtensionContributionFactory; +import org.eclipse.ui.menus.IContributionRoot; +import org.eclipse.ui.services.IServiceLocator; + +import de.prob.core.Animator; +import de.prob.core.domainobjects.History; +import de.prob.core.domainobjects.HistoryItem; +import de.prob.core.domainobjects.Operation; + +public class HistoryForwardMenu extends ExtensionContributionFactory { + + public HistoryForwardMenu() { + } + + @Override + public void createContributionItems(final IServiceLocator serviceLocator, + final IContributionRoot additions) { + + Animator animator = Animator.getAnimator(); + History history = animator.getHistory(); + if (history.isEmpty()) + return; + + Iterator<HistoryItem> iterator = history.iterator(); + String lastItem = "(root)"; + int pos = 0; + + int currentPosition = history.getCurrentPosition(); + + + while (iterator.hasNext()) { + HistoryItem historyItem = iterator.next(); + if (pos > currentPosition) + additions.addContributionItem( + createEntry(serviceLocator, lastItem, pos), null); + Operation operation = historyItem.getOperation(); + lastItem = operation != null ? operation.toString() + : historyItem.getState().toString(); + pos++; + } + + } + + private CommandContributionItem createEntry( + final IServiceLocator serviceLocator, final String lastItem, + final int pos) { + CommandContributionItemParameter p = new CommandContributionItemParameter( + serviceLocator, "", "de.prob.ui.history.forward", SWT.PUSH); + + HashMap<String, String> map = new HashMap<String, String>(1); + map.put("de.prob.ui.history.pos", Integer.toString(pos)); + p.parameters = map; + + p.label = lastItem; + CommandContributionItem item = new CommandContributionItem(p); + item.setVisible(true); + return item; + } + +} diff --git a/de.prob.ui/src/de/prob/ui/operationview/NullHandler.java b/de.prob.ui/src/de/prob/ui/operationview/NullHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..04358299e8fff2ea956c670adcba3a8ec7a019ad --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/operationview/NullHandler.java @@ -0,0 +1,14 @@ +package de.prob.ui.operationview; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.IHandler; + +public class NullHandler extends AbstractHandler implements IHandler { + + public Object execute(final ExecutionEvent event) throws ExecutionException { + return null; + } + +} diff --git a/de.prob.ui/src/de/prob/ui/operationview/OperationFilterManager.java b/de.prob.ui/src/de/prob/ui/operationview/OperationFilterManager.java new file mode 100644 index 0000000000000000000000000000000000000000..66541e6d42098256dfb0c1b7f0e3f666c07941b6 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/operationview/OperationFilterManager.java @@ -0,0 +1,63 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.ui.operationview; + +import java.util.LinkedList; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.MenuItem; + + +public class OperationFilterManager extends FilterManager { + + private final List<Filter> operationFilters = new LinkedList<Filter>(); + + public OperationFilterManager(final Menu menu) { + super(menu); + } + + public void addOperationFilter(final Filter filter) { + MenuItem[] items = filtersMenu.getItems(); + int pos = 0; + for (MenuItem item : items) { + if (item == configureItem) { + break; + } + pos++; + } + pos--; + operationFilters.add(filter); + + final MenuItem item = new MenuItem(filtersMenu, SWT.CHECK, pos); + item.setText(filter.getName()); + item.setSelection(filter.getEnabled()); + item.setData(filter); + item.addSelectionListener(this); + } + + @Override + public boolean match(final String text) { + if (super.match(text)) { + return true; + } else { + for (Filter filter : operationFilters) { + if (filter.getEnabled()) { + StringMatcher stringMatcher = new StringMatcher(filter + .getPattern(), false, false); + if (stringMatcher.match(text)) { + return true; + } + } + + } + } + return false; + } + +} diff --git a/de.prob.ui/src/de/prob/ui/operationview/OperationSelectionDialog.java b/de.prob.ui/src/de/prob/ui/operationview/OperationSelectionDialog.java new file mode 100644 index 0000000000000000000000000000000000000000..be0ad8ced076086914ab306988239c4f85f14226 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/operationview/OperationSelectionDialog.java @@ -0,0 +1,629 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.ui.operationview; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.ListIterator; + +import org.eclipse.jface.dialogs.TitleAreaDialog; +import org.eclipse.jface.dialogs.TrayDialog; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.CheckboxCellEditor; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.EditingSupport; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.FormAttachment; +import org.eclipse.swt.layout.FormData; +import org.eclipse.swt.layout.FormLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Sash; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.ui.plugin.AbstractUIPlugin; + +import de.prob.core.Animator; +import de.prob.core.command.GetOperationNamesCommand; +import de.prob.core.domainobjects.Operation; +import de.prob.core.domainobjects.OperationInfo; +import de.prob.exceptions.ProBException; +import de.prob.ui.ProbUiPlugin; + +/** + * Creates a <code>Dialog</code> that lists all of the available + * <code>Operations</code> in the current <code>ActiveState</code> of the + * <code>Animator</code>. For a better comparison of the available Operations, + * the user can switch between a normal and simplified view. + * + * @author Lukas Diekmann + * + */ +public class OperationSelectionDialog extends TrayDialog { + + private static final String IMG_CHECKED = "icons/checked.gif"; + private static final String IMG_UNCHECKED = "icons/unchecked.gif"; + private static final int MIN_ARGUMENT_LENGTH = 20; + + private String shellTitle = ""; + private final Animator animator; + private final List<String> arguments = new ArrayList<String>(); + private List<Operation> enabledOperations = null; + + private final List<Boolean> hiddenColumns = new ArrayList<Boolean>(); + private final List<Object> hiddenArguments = new ArrayList<Object>(); + + private Button btSwitchOperation = null; + + private TableViewer tbvOps; + private TableViewer argRepTable; + + private Operation lastSelectedOperation = null; + private boolean opsHidden = false; + + // String[] alphabet = { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", + // "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", + // "X", "Y", "Z" }; + + public OperationSelectionDialog(final Shell parentShell) { + super(parentShell); + animator = Animator.getAnimator(); + } + + @Override + protected void okPressed() { + IStructuredSelection sel = (IStructuredSelection) tbvOps.getSelection(); + OperationEntry entry = (OperationEntry) sel.getFirstElement(); + lastSelectedOperation = entry.getOperation(); + super.okPressed(); + } + + @Override + protected boolean isResizable() { + return true; + } + + @Override + protected void configureShell(final Shell newShell) { + super.configureShell(newShell); + newShell.setSize(400, 500); + // newShell.setMinimumSize(250, 200); + newShell.setText("Select Operation: " + shellTitle); + } + + public void setTitle(final String title) { + shellTitle = title; + } + + /* ------------------- CREATE METHODS FOR THE DIALOG -------------------- */ + /* ---------------------------------------------------------------------- */ + + @Override + protected Control createContents(final Composite parent) { + Composite contents = new Composite(parent, SWT.NONE); + contents.setLayoutData(new GridData(GridData.FILL_BOTH)); + contents.setLayout(new GridLayout()); + dialogArea = createDialogArea(contents); + buttonBar = createButtonBar(contents); + return contents; + } + + @Override + protected Control createDialogArea(final Composite parent) { + + Composite content = new Composite(parent, SWT.NONE); + + content.setLayoutData(new GridData(GridData.FILL_BOTH)); + content.setLayout(new FormLayout()); + + Sash sash = new Sash(content, SWT.HORIZONTAL); + + // Check if there are long-enough arguments that may be filtered + boolean argumentsAreShortened = argumentsAreShortened(); + + FormData data = new FormData(); + if (argumentsAreShortened) { + data.top = new FormAttachment(50, 0); // Attach to top + } else { + data.top = new FormAttachment(100, 0); // Attach to top + } + data.left = new FormAttachment(0, 0); // Attach halfway across + data.right = new FormAttachment(100, 0); // Attach halfway across + sash.setLayoutData(data); + + Group gpOperations = new Group(content, SWT.SHADOW_ETCHED_IN); + gpOperations.setText("Operations"); + data = new FormData(); + data.top = new FormAttachment(0, 0); + data.bottom = new FormAttachment(sash, 0); + data.left = new FormAttachment(0, 0); + data.right = new FormAttachment(100, 0); + gpOperations.setLayoutData(data); + gpOperations.setLayout(new GridLayout(1, false)); + + Composite tableComp = new Composite(gpOperations, SWT.NONE); + tableComp.setLayoutData(new GridData(GridData.FILL_BOTH)); + tableComp.setLayout(new FillLayout()); + createOperationsTable(tableComp); + + if (argumentsAreShortened) { + Group gpArgRep = new Group(content, SWT.SHADOW_ETCHED_IN); + gpArgRep.setText("Argument replacements"); + data = new FormData(); + data.top = new FormAttachment(sash, 0); + data.bottom = new FormAttachment(100, 0); + data.left = new FormAttachment(0, 0); + data.right = new FormAttachment(100, 0); + gpArgRep.setLayoutData(data); + gpArgRep.setLayout(new GridLayout(1, false)); + + Composite tableComp2 = new Composite(gpArgRep, SWT.NONE); + tableComp2.setLayoutData(new GridData(GridData.FILL_BOTH)); + tableComp2.setLayout(new FillLayout()); + + createArgReplacementTable(tableComp2); + } + btSwitchOperation = new Button(gpOperations, SWT.PUSH); + btSwitchOperation.setText("Show/Hide equal columns"); + btSwitchOperation.addSelectionListener(new SelectionListener() { + + public void widgetDefaultSelected(final SelectionEvent e) { + } + + public void widgetSelected(final SelectionEvent e) { + hideSameArguments(); + } + + }); + + return content; + } + + /* ------------- ADDITIONAL METHODS (GETTERS / SETTERS/ ETC) ------------ */ + /* ---------------------------------------------------------------------- */ + + /** + * Get the <code>Operation</code> that was last selected in OperationsTable + * + * @return <code>Operation</code> + */ + private Operation getSelectedOperation() { + return lastSelectedOperation; + } + + /** + * Creates and Instance of <code>OperationSelectionDialog</code> and returns + * the selected <code>Operation</code>. + * + * @return <code>Operation</code> + */ + public static Operation getOperation(final List<Operation> list) { + String shellTitle = ""; + if (list.get(0) != null) { + shellTitle = list.get(0).getName(); + } + OperationSelectionDialog osd = new OperationSelectionDialog(new Shell()); + osd.setTitle(shellTitle); + osd.setEnabledOperations(list); + if (osd.open() == TitleAreaDialog.OK) + return osd.getSelectedOperation(); + else + return null; + } + + /** + * Check if there are argument going to be filtered. + * + * @return + */ + private boolean argumentsAreShortened() { + for (Operation op : getEnabledOperations()) { + for (String arg : op.getArguments()) { + if (arg.length() > MIN_ARGUMENT_LENGTH) + return true; + } + } + return false; + } + + /** + * Hides those columns where all <code>Operations</code> have the same + * <code>Argument</code> + */ + private void hideSameArguments() { + if (!opsHidden) { + // hide column (if all operations have the same argument) + List<Operation> opList = getEnabledOperations(); + final Operation firstOp = opList.get(0); + for (int i = 0; i < firstOp.getArguments().size(); i++) { + boolean valuesAreEqual = allValuesAreEqual(opList, i); + hiddenColumns.set(i, valuesAreEqual); + } + } else { + // show columns + ListIterator<Boolean> l = hiddenColumns.listIterator(); + while (l.hasNext()) { + l.next(); + l.set(false); + } + } + + // switch Button + opsHidden = !opsHidden; + + // refresh table + tbvOps.refresh(); + packTableColumns(tbvOps); + } + + private boolean allValuesAreEqual(final Collection<Operation> operations, + final int argNum) { + if (operations.isEmpty()) + return true; + else { + String firstArg = null; + for (final Operation op : operations) { + final String curArg = op.getArguments().get(argNum); + if (firstArg == null) { + firstArg = curArg; + } else { + if (!firstArg.equals(curArg)) + return false; + } + } + return true; + } + } + + /** + * Sets a predefined list of operations. Operations from Animator won't be + * used then. + * + * @param ArrayList + * of Operations + */ + private void setEnabledOperations(final List<Operation> al) { + enabledOperations = al; + } + + /** + * Gets all possible Operations from the current ActiveState of the Animator + * + * @return + */ + private List<Operation> getEnabledOperations() { + if (enabledOperations == null) { + enabledOperations = animator.getCurrentState() + .getEnabledOperations(); + } + return enabledOperations; + } + + private List<String> getOperationParams(final Operation op) { + Collection<OperationInfo> infos = null; + try { + infos = GetOperationNamesCommand.getNames(animator); + } catch (ProBException e) { + e.notifyUserOnce(); + } + final OperationInfo params = infos == null ? null : OperationInfo + .getParams(op.getName(), infos); + final List<String> result; + if (params != null) { + result = params.getParameters(); + } else { + // If we cannot see the parameter names, we just use the operation's + // number of arguments and use empty titles + final int numArgs = op.getArguments().size(); + result = new ArrayList<String>(numArgs); + for (int i = 0; i < numArgs; i++) { + result.add(""); + } + } + return result; + } + + /* + * --------- CREATE METHODS FOR THE ARGUMENT REPLACEMENT TABLE --------- + */ + + private void createArgReplacementTable(final Composite parent) { + argRepTable = new TableViewer(parent, SWT.BORDER | SWT.H_SCROLL + | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.SINGLE); + createArgReplacmentColumns(argRepTable); + argRepTable.setContentProvider(new ArgRepContentProvider()); + argRepTable.setLabelProvider(new ArgRepLabelProvider()); + argRepTable.setInput(getEnabledOperations()); + packTableColumns(argRepTable); + } + + private void createArgReplacmentColumns(final TableViewer tbViewer) { + TableViewerColumn hide = new TableViewerColumn(tbViewer, SWT.NONE); + hide.getColumn().setText("!"); + hide.getColumn().setResizable(true); + hide.setEditingSupport(new EditingSupport(tbViewer) { + + @Override + protected boolean canEdit(final Object element) { + return true; + } + + @Override + protected CellEditor getCellEditor(final Object element) { + return new CheckboxCellEditor(tbViewer.getTable()); + } + + /* + * There are no SelectionListeners for fields, so we use the + * getValue method from EditingSupport, which is called when an + * element is selected + */ + @Override + protected Object getValue(final Object element) { + if (hiddenArguments.contains(element)) { + hiddenArguments.remove(element); + } else { + hiddenArguments.add(element); + } + tbViewer.refresh(element); + tbvOps.refresh(); + packTableColumns(tbvOps); + return null; + } + + @Override + protected void setValue(final Object element, final Object value) { + } + + }); + + TableViewerColumn repl = new TableViewerColumn(tbViewer, SWT.NONE); + repl.getColumn().setText("Repl."); + repl.getColumn().setResizable(true); + + TableViewerColumn org = new TableViewerColumn(tbViewer, SWT.NONE); + org.getColumn().setText("Original"); + org.getColumn().setResizable(true); + + Table table = tbViewer.getTable(); + table.setHeaderVisible(true); + table.setLinesVisible(true); + + } + + /* ------------- CREATE METHODS FOR THE OPERATIONS TABLE ---------------- */ + /* ---------------------------------------------------------------------- */ + + private void createOperationsTable(final Composite parent) { + tbvOps = new TableViewer(parent, SWT.BORDER | SWT.H_SCROLL + | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.SINGLE); + List<Operation> opList = getEnabledOperations(); + + List<String> params = getOperationParams(opList.get(0)); + + // fix for nondeterministic operations that have no parameters + if (params.size() == 0) { + params = new ArrayList<String>(); + params.add(""); + } + + createOperationsTableColumns(tbvOps, params); + tbvOps.setContentProvider(new OperationsContentProvider()); + tbvOps.setLabelProvider(new OperationsLabelProvider()); + tbvOps.setInput(opList); + tbvOps.addDoubleClickListener(new IDoubleClickListener() { + + public void doubleClick(final DoubleClickEvent event) { + okPressed(); + } + }); + packTableColumns(tbvOps); + } + + private void createOperationsTableColumns(final TableViewer tbViewer, + final List<String> params) { + + int count = 0; + + for (String string : params) { + final int index = count; + hiddenColumns.add(false); + TableViewerColumn column = new TableViewerColumn(tbViewer, SWT.NONE); + column.getColumn().setText(string); + column.getColumn().setResizable(true); + column.getColumn().pack(); + column.getColumn().addSelectionListener(new SelectionListener() { + + public void widgetDefaultSelected(final SelectionEvent e) { + hiddenColumns.set(index, !hiddenColumns.get(index)); + tbViewer.refresh(); + packTableColumns(tbViewer); + } + + public void widgetSelected(final SelectionEvent e) { + } + }); + count++; + } + + Table table = tbViewer.getTable(); + table.setHeaderVisible(true); + table.setLinesVisible(true); + } + + private void packTableColumns(final TableViewer tbViewer) { + for (TableColumn col : tbViewer.getTable().getColumns()) { + col.pack(); + } + } + + /** + * Defines the look of the strings for argument replacing + * + * @param index + * @return String + */ + private String getReplacementString(final int index) { + return "[" + index + "]"; + } + + /* ---------------- PROVIDERS FOR THE OPERATIONS TABLE ------------------ */ + /* ---------------------------------------------------------------------- */ + + private class OperationsLabelProvider extends LabelProvider implements + ITableLabelProvider { + public Image getColumnImage(final Object element, final int columnIndex) { + return null; + } + + public String getColumnText(final Object element, final int columnIndex) { + if (hiddenColumns.get(columnIndex)) + return "-"; + else { + OperationEntry entry = (OperationEntry) element; + if (!entry.isInternalNondeterminism()) { + final Operation op = entry.getOperation(); + final String argument = op.getArguments().get(columnIndex); + if (hiddenArguments.contains(argument)) + return getReplacementString(arguments.indexOf(argument)); + else + return argument; + } else + return "Non-deterministic choice #" + entry.getPosition(); + } + } + + } + + private static class OperationEntry { + private final Operation operation; + private final int position; + + public OperationEntry(final Operation operation, final int position) { + this.operation = operation; + this.position = position; + } + + public Operation getOperation() { + return operation; + } + + public int getPosition() { + return position; + } + + public boolean isInternalNondeterminism() { + return operation.getArguments().isEmpty(); + } + } + + private static class OperationsContentProvider implements + IStructuredContentProvider { + + public void dispose() { + } + + public void inputChanged(final Viewer viewer, final Object oldInput, + final Object newInput) { + } + + @SuppressWarnings("unchecked") + public Object[] getElements(final Object inputElement) { + final Collection<Operation> operations = (List<Operation>) inputElement; + OperationEntry[] elements = new OperationEntry[operations.size()]; + int pos = 0; + for (final Operation op : operations) { + elements[pos] = new OperationEntry(op, pos); + pos++; + } + return elements; + } + + } + + /* ------------------ PROVIDERS FOR THE HISTORY TABLE ------------------- */ + /* ---------------------------------------------------------------------- */ + + private class ArgRepLabelProvider extends LabelProvider implements + ITableLabelProvider { + + public Image getColumnImage(final Object element, final int columnIndex) { + if (columnIndex == 0) { + if (hiddenArguments.contains(element)) + return AbstractUIPlugin.imageDescriptorFromPlugin( + ProbUiPlugin.PLUGIN_ID, IMG_CHECKED).createImage(); + else + return AbstractUIPlugin.imageDescriptorFromPlugin( + ProbUiPlugin.PLUGIN_ID, IMG_UNCHECKED) + .createImage(); + } else + return null; + + } + + public String getColumnText(final Object element, final int columnIndex) { + if (columnIndex == 1) { + int index = arguments.indexOf(element); + return getReplacementString(index); + } else if (columnIndex == 2) + return (String) element; + else + return ""; + } + } + + /** + * Fills the HistoryTable with arguments and their replacements. The + * arguments that will be replaced, can be filtered in the getElements + * method. + */ + private class ArgRepContentProvider implements IStructuredContentProvider { + + public void dispose() { + } + + public void inputChanged(final Viewer viewer, final Object oldInput, + final Object newInput) { + } + + @SuppressWarnings("unchecked") + public Object[] getElements(final Object inputElement) { + List<Operation> operations = (List<Operation>) inputElement; + + // create Array with all possible Arguments (from all Operations) + for (Operation op : operations) { + for (String arg : op.getArguments()) { + if (arg.length() > MIN_ARGUMENT_LENGTH + && !arguments.contains(arg)) { + arguments.add(arg); + } + } + } + + return arguments.toArray(); + } + } + +} diff --git a/de.prob.ui/src/de/prob/ui/operationview/OperationTableViewer.java b/de.prob.ui/src/de/prob/ui/operationview/OperationTableViewer.java new file mode 100644 index 0000000000000000000000000000000000000000..e6e1b7352db04f6805d2ccd57000c7fc45a7f11a --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/operationview/OperationTableViewer.java @@ -0,0 +1,290 @@ +package de.prob.ui.operationview; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Random; + +import org.eclipse.core.commands.Command; +import org.eclipse.core.commands.State; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerFilter; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.commands.ICommandService; +import org.eclipse.ui.handlers.IHandlerService; + +import de.prob.core.Animator; +import de.prob.core.LimitedLogger; +import de.prob.core.command.ExecuteOperationCommand; +import de.prob.core.command.GetOperationNamesCommand; +import de.prob.core.domainobjects.Operation; +import de.prob.core.domainobjects.OperationInfo; +import de.prob.exceptions.ProBException; +import de.prob.logging.Logger; + +public class OperationTableViewer { + + public enum DoubleClickBehaviour { + NORMAL, RANDOM, DIALOG + }; + + private static DoubleClickBehaviour doubleClickBehaviour = DoubleClickBehaviour.NORMAL; + private static OperationTableViewer instance; + private final Collection<String> operationNames = getAllOperations(); + private final TableViewer viewer; + + private static final ViewerFilter DISABLED_OPS_FILTER = new ViewerFilter() { + @Override + public boolean select(final Viewer viewer, final Object parentElement, + final Object element) { + if (!(element instanceof ArrayList<?>)) + return false; + return true; + } + }; + + private OperationTableViewer(final Composite parent, final int style) { + viewer = new TableViewer(parent, style); + createColumns(); + viewer.setContentProvider(new OperationsContentProvider(operationNames)); + viewer.setLabelProvider(new OperationsLabelProvider(this)); + viewer.addDoubleClickListener(new OTVDoubleClickListener()); + + Table table = viewer.getTable(); + table.setHeaderVisible(true); + table.setLinesVisible(true); + } + + private Collection<String> getAllOperations() { + Collection<String> list = new ArrayList<String>(); + try { + list = OperationInfo.extractNames(GetOperationNamesCommand + .getNames(Animator.getAnimator())); + } catch (ProBException e) { + + } + return list; + } + + public void refresh() { + viewer.refresh(); + packTableColumns(); + } + + private void createColumns() { + TableViewerColumn column1 = new TableViewerColumn(viewer, SWT.NONE); + column1.getColumn().setText("Event"); + column1.getColumn().setResizable(true); + column1.getColumn().pack(); + + TableViewerColumn column2 = new TableViewerColumn(viewer, SWT.NONE); + column2.getColumn().setText("Parameter(s)"); + column2.getColumn().setResizable(true); + column2.getColumn().pack(); + } + + /** + * Recalculate size of all columns + */ + private void packTableColumns() { + for (TableColumn column : viewer.getTable().getColumns()) { + column.pack(); + } + } + + /** + * Gets the ArrayList of Operations from the selected Item in the Table + * + * @return ArrayList (Operation) + */ + @SuppressWarnings("unchecked") + public List<Operation> getSelectedOperations() { + if (viewer.getSelection() != null + && viewer.getSelection() instanceof IStructuredSelection) { + final IStructuredSelection ssel = (IStructuredSelection) viewer + .getSelection(); + if (ssel.getFirstElement() instanceof ArrayList) + return (List<Operation>) ssel.getFirstElement(); + } + return Collections.emptyList(); + } + + /* ---------------- LISTENERS FOR THE OPERATIONS TABLE ------------------ */ + /* ---------------------------------------------------------------------- */ + + /** + * Listener that selects and executes an operation, when a double-click in + * the table occurs + */ + private class OTVDoubleClickListener implements IDoubleClickListener { + + public void doubleClick(final DoubleClickEvent event) { + if (!getSelectedOperations().isEmpty()) { + LimitedLogger.getLogger().log("user chooses event", null, null); + switch (doubleClickBehaviour) { + case NORMAL: + executeSingleOperation(0); + break; + case RANDOM: + executeRandomOperation(); + break; + case DIALOG: + IHandlerService service = (IHandlerService) PlatformUI + .getWorkbench().getService(IHandlerService.class); + try { + service.executeCommand( + "de.prob.ui.show_parameter_dialog", null); + } catch (Exception e) { + Logger.assertFail("Exception when calling Handler Service"); + } + break; + } + } + } + + } + + /** + * Executes a random operation. + */ + private void executeRandomOperation() { + List<Operation> selectedOperations = getSelectedOperations(); + int use = new Random().nextInt(selectedOperations.size()); + executeSingleOperation(use); + // ExecuteRandomStepsCommand.executeOperation(Animator.getAnimator(), + // 1); + } + + /** + * Executes a specific operation given by the index. + * + * @param index + */ + private void executeSingleOperation(final int index) { + try { + ExecuteOperationCommand.executeOperation(Animator.getAnimator(), + getSelectedOperations().get(index)); + } catch (ProBException e) { + e.notifyUserOnce(); + } + } + + /** + * Opens the OperationSelectionDialog if there are many operations + * available. Otherwise executes the operation that is there. + */ + // private void openSelectionDialog() { + // if (getSelectedOperations().size() > 1) { + // final Operation op = OperationSelectionDialog + // .getOperation(getSelectedOperations()); + // if (op != null) { + // try { + // ExecuteOperationCommand.executeOperation( + // Animator.getAnimator(), op); + // } catch (ProBException e) { + // e.notifyUserOnce(); + // } + // } + // } else { + // executeSingleOperation(0); + // } + // } + + /** + * Converts a list of Arguments to a readable (short) String. + * + * @param argLength + * Maximum length an argument can have + * @param totalLength + * Maximum length of the final String + * @param params + * List containing the Arguments + * @return + */ + public static String convertParamsToString(final int argLength, + final int totalLength, final List<String> params) { + StringBuffer sb = new StringBuffer(); + boolean first = true; + for (final String parameter : params) { + if (!first) { + sb.append(", "); + } + int length = parameter.length(); + if (length > argLength) { + if (argLength > 6) { + sb.append(parameter.substring(0, argLength - 3)); + } + sb.append("..."); + } else { + sb.append(parameter); + } + first = false; + } + String result = sb.toString(); + if (result.length() >= totalLength) { + result = result.substring(0, totalLength) + " [...]"; + } + return result; + } + + /** + * Sets the doubleclick behavior for the TableItems + */ + public static void setDoubleClickBehavior(final String behavior) { + doubleClickBehaviour = DoubleClickBehaviour.valueOf(behavior); + } + + public TableViewer getViewer() { + return viewer; + } + + public static OperationTableViewer create(final Composite pageComposite, + final int i) { + if (instance == null) { + instance = new OperationTableViewer(pageComposite, i); + + ICommandService service = (ICommandService) PlatformUI + .getWorkbench().getService(ICommandService.class); + Command command = service + .getCommand("de.prob.ui.filter_enabled_only"); + State state = command + .getState("org.eclipse.ui.commands.toggleState"); + if (state == null) + instance.unapplyFilter(); + else { + if ((Boolean) state.getValue()) + instance.applyFilter(); + else + instance.unapplyFilter(); + } + } + return instance; + } + + public static OperationTableViewer getInstance() { + return instance; + } + + public static void destroy() { + instance = null; + } + + public void applyFilter() { + getViewer().setFilters(new ViewerFilter[] { DISABLED_OPS_FILTER }); + } + + public void unapplyFilter() { + getViewer().resetFilters(); + } + +} diff --git a/de.prob.ui/src/de/prob/ui/operationview/OperationViewPart.java b/de.prob.ui/src/de/prob/ui/operationview/OperationViewPart.java new file mode 100644 index 0000000000000000000000000000000000000000..5725774b6b500b8ab442789c6163235a80d789d9 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/operationview/OperationViewPart.java @@ -0,0 +1,98 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.ui.operationview; + +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.ui.IWorkbenchActionConstants; +import org.eclipse.ui.services.ISourceProviderService; + +import de.prob.core.domainobjects.Operation; +import de.prob.core.domainobjects.State; +import de.prob.ui.StateBasedViewPart; +import de.prob.ui.services.ModelLoadedProvider; + +/** + * This class defines the view that shows the currently available operations. + */ +public class OperationViewPart extends StateBasedViewPart implements + FilterListener { + + private Composite pageComposite; + + @Override + public Control createStatePartControl(final Composite parent) { + pageComposite = new Composite(parent, SWT.NULL); + pageComposite.setLayout(new FillLayout()); + OperationTableViewer.create(pageComposite, SWT.BORDER | SWT.H_SCROLL + | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.SINGLE); + hookContextMenu(); + updateModelLoadedProvider(); + return pageComposite; + } + + /** + * This method is called whenever the activeState of the Animator changes + * (i.e. Animation of a new file, running an operation) + */ + @Override + protected void stateChanged(final State activeState, + final Operation operation) { + OperationTableViewer.getInstance().getViewer().setInput(activeState); + OperationTableViewer.getInstance().refresh(); + + } + + private void hookContextMenu() { + final OperationViewPart x = this; + TableViewer viewer = OperationTableViewer.getInstance().getViewer(); + MenuManager menuMgr = new MenuManager("#PopupMenu"); + menuMgr.setRemoveAllWhenShown(true); + menuMgr.addMenuListener(new IMenuListener() { + public void menuAboutToShow(final IMenuManager manager) { + x.fillContextMenu(manager); + } + }); + Menu menu = menuMgr.createContextMenu(viewer.getControl()); + viewer.getControl().setMenu(menu); + getSite().registerContextMenu(menuMgr, viewer); + } + + private void fillContextMenu(final IMenuManager manager) { + manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); + } + + @Override + protected void stateReset() { + OperationTableViewer.destroy(); + } + + public void filtersChanged() { + Display.getDefault().asyncExec(new Runnable() { + public void run() { + OperationTableViewer.getInstance().refresh(); + } + }); + } + + private void updateModelLoadedProvider() { + ISourceProviderService service = (ISourceProviderService) this + .getSite().getService(ISourceProviderService.class); + ModelLoadedProvider sourceProvider = (ModelLoadedProvider) service + .getSourceProvider(ModelLoadedProvider.SERVICE); + sourceProvider.setEnabled(true); + } +} diff --git a/de.prob.ui/src/de/prob/ui/operationview/OperationsContentProvider.java b/de.prob.ui/src/de/prob/ui/operationview/OperationsContentProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..3396cb605d79abb28979173fd1847778ddc47311 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/operationview/OperationsContentProvider.java @@ -0,0 +1,70 @@ +package de.prob.ui.operationview; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.Viewer; + +import de.prob.core.domainobjects.Operation; +import de.prob.core.domainobjects.State; + +/** + * Creates a new list of Operations, merging the list of available operations + * with the list of enabled operations. Before adding the enabled operations, + * they are divided into groups by their operation name + * + */ +class OperationsContentProvider implements IStructuredContentProvider { + + private final Collection<String> allOperations; + + public OperationsContentProvider(final Collection<String> allOperations) { + this.allOperations = allOperations; + } + + public void dispose() { + } + + public void inputChanged(final Viewer viewer, final Object oldInput, + final Object newInput) { + } + + public Object[] getElements(final Object inputElement) { + + List<Object> mergedOperations = new ArrayList<Object>(); + + // add all available operations + + mergedOperations.addAll(allOperations); + if (inputElement != null && inputElement instanceof State) { + State state = (State) inputElement; + // group and add all enabled Operations + Map<String, List<Operation>> enabledOps = new HashMap<String, List<Operation>>(); + for (Operation op : state.getEnabledOperations()) { + List<Operation> list = enabledOps.get(op.getName()); + if (list == null) { + list = new ArrayList<Operation>(); + enabledOps.put(op.getName(), list); + } + list.add(op); + } + + // merge them + for (List<Operation> al : enabledOps.values()) { + Operation op = al.get(0); + int index = mergedOperations.indexOf(op.getName()); + if (index >= 0) { + mergedOperations.set(index, al); + } else { + mergedOperations.add(al); + } + } + } + + return mergedOperations.toArray(); + } +} \ No newline at end of file diff --git a/de.prob.ui/src/de/prob/ui/operationview/OperationsLabelProvider.java b/de.prob.ui/src/de/prob/ui/operationview/OperationsLabelProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..30bfb2b9a96b19ffbb975feecf3aa105a0e3cf19 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/operationview/OperationsLabelProvider.java @@ -0,0 +1,101 @@ +package de.prob.ui.operationview; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.swt.graphics.Image; + +import de.prob.core.Animator; +import de.prob.core.domainobjects.Operation; +import de.prob.ui.ProbUiPlugin; + +/** + * Returns the labels for the TableViewer. The first column gets the name of the + * operation, the second column a preview of the first operation with a button, + * opening the OperationSelectionDialog + */ +class OperationsLabelProvider extends LabelProvider implements + ITableLabelProvider { + private final OperationTableViewer operationTableViewer; + + private final Image imgDisabled = ProbUiPlugin.getDefault() + .getImageRegistry().getDescriptor(ProbUiPlugin.IMG_DISABLED) + .createImage(); + private final Image imgTimeout = ProbUiPlugin.getDefault() + .getImageRegistry().getDescriptor(ProbUiPlugin.IMG_TIMEOUT) + .createImage(); + private final Image imgEnabled = ProbUiPlugin.getDefault() + .getImageRegistry().getDescriptor(ProbUiPlugin.IMG_ENABLED) + .createImage(); + + /** + * @param operationTableViewer + */ + public OperationsLabelProvider( + final OperationTableViewer operationTableViewer) { + this.operationTableViewer = operationTableViewer; + } + + // character code for "times" (similar to the letter x) + private static final char TIMES = 215; + + public Image getColumnImage(final Object element, final int columnIndex) { + if (columnIndex == 0) { + if (element instanceof String) { + + boolean timeout = Animator.getAnimator().getCurrentState() + .isTimeoutOp((String) element); + + if (timeout) + return imgTimeout; + else + return imgDisabled; + } else if (element instanceof ArrayList<?>) + return imgEnabled; + } + return null; + } + + @SuppressWarnings("unchecked") + public String getColumnText(final Object element, final int columnIndex) { + + // return the operation name + if (columnIndex == 0) { + if (element instanceof String) + return (String) element; + else if (element instanceof List) { + List<Operation> ops = ((List<Operation>) element); + final Operation op = ops.get(0); + final int size = ops.size(); + if (size > 1) { + StringBuilder sb = new StringBuilder(); + sb.append(op.getName()); + sb.append(" (").append(TIMES); + sb.append(size).append(')'); + return sb.toString(); + } else + return op.getName(); + } + } + + // return a preview of the first operation and add a button + if (columnIndex == 1) { + if (element instanceof ArrayList) { + ArrayList<Operation> ops = (ArrayList<Operation>) element; + + if (ops.size() > 0) { + Operation op = ops.get(0); + List<String> args = op.getArguments(); + int columnWidth = this.operationTableViewer.getViewer() + .getTable().getColumn(columnIndex).getWidth(); + return OperationTableViewer.convertParamsToString(10, + columnWidth / 6, args); + + } + } + } + return ""; + } +} \ No newline at end of file diff --git a/de.prob.ui/src/de/prob/ui/operationview/ParameterMenu.java b/de.prob.ui/src/de/prob/ui/operationview/ParameterMenu.java new file mode 100644 index 0000000000000000000000000000000000000000..3240d8bb150e01fba79a1454bad613e4adfbfbf6 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/operationview/ParameterMenu.java @@ -0,0 +1,75 @@ +package de.prob.ui.operationview; + +import java.util.HashMap; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.ui.menus.CommandContributionItem; +import org.eclipse.ui.menus.CommandContributionItemParameter; +import org.eclipse.ui.menus.ExtensionContributionFactory; +import org.eclipse.ui.menus.IContributionRoot; +import org.eclipse.ui.services.IServiceLocator; + +import de.prob.core.domainobjects.Operation; + +public class ParameterMenu extends ExtensionContributionFactory { + + private int nondetcounter; + + public ParameterMenu() { + } + + @Override + public void createContributionItems(final IServiceLocator serviceLocator, + final IContributionRoot additions) { + + List<Operation> operations = OperationTableViewer.getInstance() + .getSelectedOperations(); + + if (operations.isEmpty()) + return; + + nondetcounter = 0; + + for (Operation operation : operations) { + long id = operation.getId(); + additions.addContributionItem( + createEntry(serviceLocator, operation, id), null); + + } + + CommandContributionItemParameter contributionParameters = new CommandContributionItemParameter( + serviceLocator, "", "de.prob.ui.show_parameter_dialog", + SWT.PUSH); + contributionParameters.label = "Show Dialog ..."; + CommandContributionItem dialogItem = new CommandContributionItem( + contributionParameters); + additions.addContributionItem(dialogItem, null); + + } + + private CommandContributionItem createEntry( + final IServiceLocator serviceLocator, final Operation op, + final long id) { + + String itemText; + if (op.getArguments() != null && op.getArguments().size() > 0) { + itemText = OperationTableViewer.convertParamsToString(15, 25, + op.getArguments()); + } else { + itemText = "Non-deterministic choice #" + (++nondetcounter); + } + + CommandContributionItemParameter p = new CommandContributionItemParameter( + serviceLocator, "", "de.prob.ui.execute_event", SWT.PUSH); + p.label = itemText; + + HashMap<String, String> map = new HashMap<String, String>(1); + map.put("de.prob.ui.operation", Long.toString(id)); + p.parameters = map; + + CommandContributionItem item = new CommandContributionItem(p); + item.setVisible(true); + return item; + } +} diff --git a/de.prob.ui/src/de/prob/ui/operationview/RestartHandler.java b/de.prob.ui/src/de/prob/ui/operationview/RestartHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..80de56c123317e84786f8abaa768ba2bb85a850d --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/operationview/RestartHandler.java @@ -0,0 +1,24 @@ +package de.prob.ui.operationview; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.IHandler; + +import de.prob.core.Animator; +import de.prob.exceptions.ProBException; + +public class RestartHandler extends AbstractHandler implements IHandler { + + public Object execute(final ExecutionEvent event) throws ExecutionException { + Animator animator = Animator.getAnimator(); + try { + animator.getLanguageDependendPart().reload(animator); + } catch (ProBException e) { + e.notifyUserOnce(); + throw new ExecutionException("Restarting the machine failed", e); + } + return null; + } + +} diff --git a/de.prob.ui/src/de/prob/ui/operationview/ShowOnlyEnabledOpsHandler.java b/de.prob.ui/src/de/prob/ui/operationview/ShowOnlyEnabledOpsHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..823c5f04ed8aa1b84520a5598e4224577da7702c --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/operationview/ShowOnlyEnabledOpsHandler.java @@ -0,0 +1,29 @@ +package de.prob.ui.operationview; + +import org.eclipse.core.commands.*; +import org.eclipse.ui.handlers.HandlerUtil; + +public class ShowOnlyEnabledOpsHandler extends AbstractHandler implements + IHandler { + + public Object execute(final ExecutionEvent event) throws ExecutionException { + Command command = event.getCommand(); + boolean showOnlyEnabledStates = !HandlerUtil + .toggleCommandState(command); + // use the old value and perform the operation + + OperationTableViewer otv = OperationTableViewer.getInstance(); + if (otv == null) + return null; + if (showOnlyEnabledStates) { + otv.applyFilter(); + } else { + otv.unapplyFilter(); + } + + // needed to fix "lazy" TableEditor + // OperationTableViewer.getInstance().getViewer().getTable().select(0); + + return null; + } +} diff --git a/de.prob.ui/src/de/prob/ui/operationview/ShowParameterDialogHandler.java b/de.prob.ui/src/de/prob/ui/operationview/ShowParameterDialogHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..ec410a7cfd8e33066a7d82c4ca56cb838a29993d --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/operationview/ShowParameterDialogHandler.java @@ -0,0 +1,34 @@ +package de.prob.ui.operationview; + +import java.util.List; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.IHandler; + +import de.prob.core.Animator; +import de.prob.core.command.ExecuteOperationCommand; +import de.prob.core.domainobjects.Operation; +import de.prob.exceptions.ProBException; + +public class ShowParameterDialogHandler extends AbstractHandler implements + IHandler { + + public Object execute(final ExecutionEvent event) throws ExecutionException { + + List<Operation> s = OperationTableViewer.getInstance() + .getSelectedOperations(); + + Operation op = OperationSelectionDialog.getOperation(s); + if (op == null) + return null; + try { + ExecuteOperationCommand + .executeOperation(Animator.getAnimator(), op); + } catch (ProBException e) { + e.notifyUserOnce(); + } + return null; + } +} diff --git a/de.prob.ui/src/de/prob/ui/operationview/StringMatcher.java b/de.prob.ui/src/de/prob/ui/operationview/StringMatcher.java new file mode 100644 index 0000000000000000000000000000000000000000..b6572e3eb859f0d15970616da1d64b427421d757 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/operationview/StringMatcher.java @@ -0,0 +1,445 @@ +package de.prob.ui.operationview; + +/* + * Unfortunatly there is no public version of this class in Eclipse (only some copies in internal packages + * + * + * */ + + +import java.util.Vector; + + class StringMatcher { + protected String fPattern; + + protected int fLength; // pattern length + + protected boolean fIgnoreWildCards; + + protected boolean fIgnoreCase; + + protected boolean fHasLeadingStar; + + protected boolean fHasTrailingStar; + + protected String fSegments[]; //the given pattern is split into * separated segments + + /* boundary value beyond which we don't need to search in the text */ + protected int fBound = 0; + + protected static final char fSingleWildCard = '\u0000'; + + public static class Position { + int start; //inclusive + + int end; //exclusive + + public Position(int start, int end) { + this.start = start; + this.end = end; + } + + public int getStart() { + return start; + } + + public int getEnd() { + return end; + } + } + + /** + * StringMatcher constructor takes in a String object that is a simple + * pattern which may contain '*' for 0 and many characters and + * '?' for exactly one character. + * + * Literal '*' and '?' characters must be escaped in the pattern + * e.g., "\*" means literal "*", etc. + * + * Escaping any other character (including the escape character itself), + * just results in that character in the pattern. + * e.g., "\a" means "a" and "\\" means "\" + * + * If invoking the StringMatcher with string literals in Java, don't forget + * escape characters are represented by "\\". + * + * @param pattern the pattern to match text against + * @param ignoreCase if true, case is ignored + * @param ignoreWildCards if true, wild cards and their escape sequences are ignored + * (everything is taken literally). + */ + public StringMatcher(String pattern, boolean ignoreCase, + boolean ignoreWildCards) { + if (pattern == null) { + throw new IllegalArgumentException(); + } + fIgnoreCase = ignoreCase; + fIgnoreWildCards = ignoreWildCards; + fPattern = pattern; + fLength = pattern.length(); + + if (fIgnoreWildCards) { + parseNoWildCards(); + } else { + parseWildCards(); + } + } + + /** + * Find the first occurrence of the pattern between <code>start</code)(inclusive) + * and <code>end</code>(exclusive). + * @param text the String object to search in + * @param start the starting index of the search range, inclusive + * @param end the ending index of the search range, exclusive + * @return an <code>StringMatcher.Position</code> object that keeps the starting + * (inclusive) and ending positions (exclusive) of the first occurrence of the + * pattern in the specified range of the text; return null if not found or subtext + * is empty (start==end). A pair of zeros is returned if pattern is empty string + * Note that for pattern like "*abc*" with leading and trailing stars, position of "abc" + * is returned. For a pattern like"*??*" in text "abcdf", (1,3) is returned + */ + public StringMatcher.Position find(String text, int start, int end) { + if (text == null) { + throw new IllegalArgumentException(); + } + + int tlen = text.length(); + if (start < 0) { + start = 0; + } + if (end > tlen) { + end = tlen; + } + if (end < 0 || start >= end) { + return null; + } + if (fLength == 0) { + return new Position(start, start); + } + if (fIgnoreWildCards) { + int x = posIn(text, start, end); + if (x < 0) { + return null; + } + return new Position(x, x + fLength); + } + + int segCount = fSegments.length; + if (segCount == 0) { + return new Position(start, end); + } + + int curPos = start; + int matchStart = -1; + int i; + for (i = 0; i < segCount && curPos < end; ++i) { + String current = fSegments[i]; + int nextMatch = regExpPosIn(text, curPos, end, current); + if (nextMatch < 0) { + return null; + } + if (i == 0) { + matchStart = nextMatch; + } + curPos = nextMatch + current.length(); + } + if (i < segCount) { + return null; + } + return new Position(matchStart, curPos); + } + + /** + * match the given <code>text</code> with the pattern + * @return true if matched otherwise false + * @param text a String object + */ + public boolean match(String text) { + if(text == null) { + return false; + } + return match(text, 0, text.length()); + } + + /** + * Given the starting (inclusive) and the ending (exclusive) positions in the + * <code>text</code>, determine if the given substring matches with aPattern + * @return true if the specified portion of the text matches the pattern + * @param text a String object that contains the substring to match + * @param start marks the starting position (inclusive) of the substring + * @param end marks the ending index (exclusive) of the substring + */ + public boolean match(String text, int start, int end) { + if (null == text) { + throw new IllegalArgumentException(); + } + + if (start > end) { + return false; + } + + if (fIgnoreWildCards) { + return (end - start == fLength) + && fPattern.regionMatches(fIgnoreCase, 0, text, start, + fLength); + } + int segCount = fSegments.length; + if (segCount == 0 && (fHasLeadingStar || fHasTrailingStar)) { + return true; + } + if (start == end) { + return fLength == 0; + } + if (fLength == 0) { + return start == end; + } + + int tlen = text.length(); + if (start < 0) { + start = 0; + } + if (end > tlen) { + end = tlen; + } + + int tCurPos = start; + int bound = end - fBound; + if (bound < 0) { + return false; + } + int i = 0; + String current = fSegments[i]; + int segLength = current.length(); + + /* process first segment */ + if (!fHasLeadingStar) { + if (!regExpRegionMatches(text, start, current, 0, segLength)) { + return false; + } else { + ++i; + tCurPos = tCurPos + segLength; + } + } + if ((fSegments.length == 1) && (!fHasLeadingStar) + && (!fHasTrailingStar)) { + // only one segment to match, no wildcards specified + return tCurPos == end; + } + /* process middle segments */ + while (i < segCount) { + current = fSegments[i]; + int currentMatch; + int k = current.indexOf(fSingleWildCard); + if (k < 0) { + currentMatch = textPosIn(text, tCurPos, end, current); + if (currentMatch < 0) { + return false; + } + } else { + currentMatch = regExpPosIn(text, tCurPos, end, current); + if (currentMatch < 0) { + return false; + } + } + tCurPos = currentMatch + current.length(); + i++; + } + + /* process final segment */ + if (!fHasTrailingStar && tCurPos != end) { + int clen = current.length(); + return regExpRegionMatches(text, end - clen, current, 0, clen); + } + return i == segCount; + } + + /** + * This method parses the given pattern into segments seperated by wildcard '*' characters. + * Since wildcards are not being used in this case, the pattern consists of a single segment. + */ + private void parseNoWildCards() { + fSegments = new String[1]; + fSegments[0] = fPattern; + fBound = fLength; + } + + /** + * Parses the given pattern into segments seperated by wildcard '*' characters. + * @param p, a String object that is a simple regular expression with '*' and/or '?' + */ + private void parseWildCards() { + if (fPattern.startsWith("*")) { //$NON-NLS-1$ + fHasLeadingStar = true; + } + if (fPattern.endsWith("*")) {//$NON-NLS-1$ + /* make sure it's not an escaped wildcard */ + if (fLength > 1 && fPattern.charAt(fLength - 2) != '\\') { + fHasTrailingStar = true; + } + } + + Vector<String> temp = new Vector<String>(); + + int pos = 0; + StringBuffer buf = new StringBuffer(); + while (pos < fLength) { + char c = fPattern.charAt(pos++); + switch (c) { + case '\\': + if (pos >= fLength) { + buf.append(c); + } else { + char next = fPattern.charAt(pos++); + /* if it's an escape sequence */ + if (next == '*' || next == '?' || next == '\\') { + buf.append(next); + } else { + /* not an escape sequence, just insert literally */ + buf.append(c); + buf.append(next); + } + } + break; + case '*': + if (buf.length() > 0) { + /* new segment */ + temp.addElement(buf.toString()); + fBound += buf.length(); + buf.setLength(0); + } + break; + case '?': + /* append special character representing single match wildcard */ + buf.append(fSingleWildCard); + break; + default: + buf.append(c); + } + } + + /* add last buffer to segment list */ + if (buf.length() > 0) { + temp.addElement(buf.toString()); + fBound += buf.length(); + } + + fSegments = new String[temp.size()]; + temp.copyInto(fSegments); + } + + /** + * @param text a string which contains no wildcard + * @param start the starting index in the text for search, inclusive + * @param end the stopping point of search, exclusive + * @return the starting index in the text of the pattern , or -1 if not found + */ + protected int posIn(String text, int start, int end) {//no wild card in pattern + int max = end - fLength; + + if (!fIgnoreCase) { + int i = text.indexOf(fPattern, start); + if (i == -1 || i > max) { + return -1; + } + return i; + } + + for (int i = start; i <= max; ++i) { + if (text.regionMatches(true, i, fPattern, 0, fLength)) { + return i; + } + } + + return -1; + } + + /** + * @param text a simple regular expression that may only contain '?'(s) + * @param start the starting index in the text for search, inclusive + * @param end the stopping point of search, exclusive + * @param p a simple regular expression that may contains '?' + * @return the starting index in the text of the pattern , or -1 if not found + */ + protected int regExpPosIn(String text, int start, int end, String p) { + int plen = p.length(); + + int max = end - plen; + for (int i = start; i <= max; ++i) { + if (regExpRegionMatches(text, i, p, 0, plen)) { + return i; + } + } + return -1; + } + + /** + * + * @return boolean + * @param text a String to match + * @param start int that indicates the starting index of match, inclusive + * @param end</code> int that indicates the ending index of match, exclusive + * @param p String, String, a simple regular expression that may contain '?' + * @param ignoreCase boolean indicating wether code>p</code> is case sensitive + */ + protected boolean regExpRegionMatches(String text, int tStart, String p, + int pStart, int plen) { + while (plen-- > 0) { + char tchar = text.charAt(tStart++); + char pchar = p.charAt(pStart++); + + /* process wild cards */ + if (!fIgnoreWildCards) { + /* skip single wild cards */ + if (pchar == fSingleWildCard) { + continue; + } + } + if (pchar == tchar) { + continue; + } + if (fIgnoreCase) { + if (Character.toUpperCase(tchar) == Character + .toUpperCase(pchar)) { + continue; + } + // comparing after converting to upper case doesn't handle all cases; + // also compare after converting to lower case + if (Character.toLowerCase(tchar) == Character + .toLowerCase(pchar)) { + continue; + } + } + return false; + } + return true; + } + + /** + * @param text the string to match + * @param start the starting index in the text for search, inclusive + * @param end the stopping point of search, exclusive + * @param p a pattern string that has no wildcard + * @return the starting index in the text of the pattern , or -1 if not found + */ + protected int textPosIn(String text, int start, int end, String p) { + + int plen = p.length(); + int max = end - plen; + + if (!fIgnoreCase) { + int i = text.indexOf(p, start); + if (i == -1 || i > max) { + return -1; + } + return i; + } + + for (int i = start; i <= max; ++i) { + if (text.regionMatches(true, i, p, 0, plen)) { + return i; + } + } + + return -1; + } +} \ No newline at end of file diff --git a/de.prob.ui/src/de/prob/ui/services/AbstractBoolProvider.java b/de.prob.ui/src/de/prob/ui/services/AbstractBoolProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..f18362d3c7b784b81a24ee71435cb11a039fa857 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/services/AbstractBoolProvider.java @@ -0,0 +1,51 @@ +package de.prob.ui.services; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.ui.AbstractSourceProvider; +import org.eclipse.ui.ISources; + +public abstract class AbstractBoolProvider extends AbstractSourceProvider { + + private final String service; + + public static final String ENABLED = "enabled"; + public static final String DISABLED = "disabled"; + private boolean enabled = false; + + public AbstractBoolProvider(final String service) { + this.service = service; + } + + public void dispose() { + + } + + public Map<String, String> getCurrentState() { + Map<String, String> currentState = new HashMap<String, String>(1); + String current = enabled ? ENABLED : DISABLED; + currentState.put(service, current); + return currentState; + } + + public String[] getProvidedSourceNames() { + return new String[] { service }; + } + + public void setEnabled(final boolean enabled) { + if (nochange(enabled)) + return; + this.enabled = enabled; + fireSourceChanged(ISources.WORKBENCH, getCurrentState()); + } + + public boolean isEnabled() { + return enabled; + } + + private boolean nochange(final boolean enabled) { + return this.enabled == enabled; + } + +} diff --git a/de.prob.ui/src/de/prob/ui/services/HistoryActiveProvider.java b/de.prob.ui/src/de/prob/ui/services/HistoryActiveProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..94af1de154539734f67e8a28a48c419482ed378f --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/services/HistoryActiveProvider.java @@ -0,0 +1,62 @@ +package de.prob.ui.services; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.ui.AbstractSourceProvider; +import org.eclipse.ui.ISources; + +import de.prob.core.Animator; +import de.prob.core.domainobjects.History; + +public class HistoryActiveProvider extends AbstractSourceProvider { + + public static final String ENABLED = "enabled"; + public static final String DISABLED = "disabled"; + public static final String FORWARD_SERVICE = "de.prob.core.history.forward_service"; + public static final String BACKWARD_SERVICE = "de.prob.core.history.backward_service"; + + private boolean forward = false; + private boolean backward = false; + + public Map<String, String> getCurrentState() { + Map<String, String> state = new HashMap<String, String>(2); + addToState(state, backward, BACKWARD_SERVICE); + addToState(state, forward, FORWARD_SERVICE); + return state; + } + + private void addToState(final Map<String, String> state, + final boolean flag, final String service) { + String f = flag ? ENABLED : DISABLED; + state.put(service, f); + } + + public String[] getProvidedSourceNames() { + return new String[] { FORWARD_SERVICE, BACKWARD_SERVICE }; + } + + public boolean isBackwardEnabled() { + return backward; + } + + public boolean isForwardEnabled() { + return forward; + } + + public void historyChange() { + History history = Animator.getAnimator().getHistory(); + int current = history.getCurrentPosition(); + boolean notEmpty = !history.isEmpty(); + boolean notFirst = current != 0; + boolean notLast = current != history.size() - 1; + + backward = notEmpty && notFirst; + forward = notEmpty && notLast; + fireSourceChanged(ISources.WORKBENCH, getCurrentState()); + } + + public void dispose() { + + } +} diff --git a/de.prob.ui/src/de/prob/ui/services/ModelLoadedProvider.java b/de.prob.ui/src/de/prob/ui/services/ModelLoadedProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..73061fcb019ba709e548a5a684a33b37bfeee074 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/services/ModelLoadedProvider.java @@ -0,0 +1,11 @@ +package de.prob.ui.services; + +public class ModelLoadedProvider extends AbstractBoolProvider { + + public static final String SERVICE = "de.prob.core.model_loaded"; + + public ModelLoadedProvider() { + super(SERVICE); + } + +} diff --git a/de.prob.ui/src/de/prob/ui/stateview/AddFormulaHandler.java b/de.prob.ui/src/de/prob/ui/stateview/AddFormulaHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..134bf771662499fe3a69f7dcefda9621c4302409 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/stateview/AddFormulaHandler.java @@ -0,0 +1,110 @@ +package de.prob.ui.stateview; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.IHandler; +import org.eclipse.jface.dialogs.IInputValidator; +import org.eclipse.jface.dialogs.InputDialog; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.handlers.HandlerUtil; + +import de.prob.core.Animator; +import de.prob.core.LanguageDependendAnimationPart; +import de.prob.core.command.EvaluationInsertFormulaCommand; +import de.prob.core.domainobjects.EvaluationElement; +import de.prob.exceptions.ProBException; +import de.prob.parserbase.ProBParseException; +import de.prob.parserbase.ProBParserBaseAdapter; +import de.prob.prolog.term.PrologTerm; + +public class AddFormulaHandler extends AbstractHandler implements IHandler { + + public Object execute(final ExecutionEvent event) throws ExecutionException { + final Runnable runnable = new Runnable() { + public void run() { + Shell shell = HandlerUtil.getActiveShell(event); + final String title = StateViewStrings.dialogTitleEnterNewFormula; + final String msg = StateViewStrings.dialogMessageEnterNewFormula; + Animator animator = Animator.getAnimator(); + final LanguageDependendAnimationPart ldp = animator + .getLanguageDependendPart(); + final ProBParserBaseAdapter parser = new ProBParserBaseAdapter( + ldp); + final IInputValidator validator = new FormulaValidator(parser); + InputDialog dialog = new InputDialog(shell, title, msg, "", + validator); + int button = dialog.open(); + if (button == InputDialog.OK) { + final String entered = dialog.getValue(); + PrologTerm parsed = null; + try { + parsed = parser.parsePredicate(entered, false); + } catch (ProBParseException pe) { + try { + parsed = parser.parseExpression(entered, false); + } catch (ProBParseException ee) { + MessageDialog.openError(shell, title, + StateViewStrings.dialogSyntaxError); + } + } + if (parsed != null) { + try { + final EvaluationElement staticElement = EvaluationInsertFormulaCommand + .insertFormula(parsed); + + final IWorkbenchPage activePage = PlatformUI + .getWorkbench().getActiveWorkbenchWindow() + .getActivePage(); + final StateViewPart view = (StateViewPart) activePage + .findView(StateViewPart.STATE_VIEW_ID); + if (view != null) { + view.addUserDefinedExpression(staticElement); + } else { + MessageDialog.openError(shell, "Error", + "Unable to access state view"); + } + } catch (ProBException e) { + e.notifyUserOnce(); + } + } + } + } + }; + Display.getDefault().asyncExec(runnable); + return null; + } + + private static class FormulaValidator implements IInputValidator { + private final ProBParserBaseAdapter parser; + + public FormulaValidator(final ProBParserBaseAdapter parser) { + this.parser = parser; + } + + public String isValid(final String input) { + String error = null; + if (input.trim().length() == 0) { + error = ""; + } else { + try { + parser.parsePredicate(input, false); + } catch (ProBParseException e) { + final String msg = e.getMessage(); + try { + parser.parseExpression(input, false); + } catch (ProBParseException e2) { + error = msg; + } + } + } + return error; + } + + } + +} diff --git a/de.prob.ui/src/de/prob/ui/stateview/BooleanLabelProvider.java b/de.prob.ui/src/de/prob/ui/stateview/BooleanLabelProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..4cd243180d4cfe8c8cd23562a191e93819cac438 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/stateview/BooleanLabelProvider.java @@ -0,0 +1,123 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +/** + * + */ +package de.prob.ui.stateview; + +import org.eclipse.jface.viewers.BaseLabelProvider; +import org.eclipse.jface.viewers.IColorProvider; +import org.eclipse.jface.viewers.IFontProvider; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.LabelProviderChangedEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; + +/** + * The BooleanLabelProvider acts as LabelProvider for text, image, font, fore- + * and background color and visibility. + * + * Its input is a boolean value which may be null. So we distinct between three + * states: INACTIVE, OK and KO. For each part (text/image/font etc.) and state + * one can define a value. + * + * @author plagge + */ +public class BooleanLabelProvider extends BaseLabelProvider implements + ILabelProvider, IColorProvider, IFontProvider, IVisibilityProvider { + private static int INACTIVE = 0; + private static int OK = 1; + private static int KO = 2; + + private final Color[] foregroundColors = { null, null, null }; + private final Color[] backgroundColors = { null, null, null }; + private final String[] texts = { null, null, null }; + private final Image[] images = { null, null, null }; + private final Font[] fonts = { null, null, null }; + + private boolean hideInactive = false; + + private static int toState(Object element) { + final int state; + if (element != null && element instanceof Boolean) { + state = (((Boolean) element).booleanValue()) ? OK : KO; + } else { + state = INACTIVE; + } + return state; + } + + public Color getBackground(Object element) { + return backgroundColors[toState(element)]; + } + + public Color getForeground(Object element) { + return foregroundColors[toState(element)]; + } + + public Image getImage(Object element) { + return images[toState(element)]; + } + + public String getText(Object element) { + return texts[toState(element)]; + } + + public Font getFont(Object element) { + return fonts[toState(element)]; + } + + public boolean isVisible(Object element) { + return !(hideInactive && toState(element) == INACTIVE); + } + + public void setTexts(final String inactive, final String ok, final String ko) { + texts[INACTIVE] = inactive; + texts[OK] = ok; + texts[KO] = ko; + fireChangedEvent(); + } + + public void setImages(final Image inactive, final Image ok, final Image ko) { + images[INACTIVE] = inactive; + images[OK] = ok; + images[KO] = ko; + fireChangedEvent(); + } + + public void setForegroundColors(final Color inactive, final Color ok, + final Color ko) { + foregroundColors[INACTIVE] = inactive; + foregroundColors[OK] = ok; + foregroundColors[KO] = ko; + fireChangedEvent(); + } + + public void setBackgroundColors(final Color inactive, final Color ok, + final Color ko) { + backgroundColors[INACTIVE] = inactive; + backgroundColors[OK] = ok; + backgroundColors[KO] = ko; + fireChangedEvent(); + } + + public void setFonts(final Font inactive, final Font ok, final Font ko) { + fonts[INACTIVE] = inactive; + fonts[OK] = ok; + fonts[KO] = ko; + fireChangedEvent(); + } + + public void hideWhenInactive(final boolean hide) { + this.hideInactive = hide; + } + + private void fireChangedEvent() { + fireLabelProviderChanged(new LabelProviderChangedEvent(this)); + } +} diff --git a/de.prob.ui/src/de/prob/ui/stateview/IVisibilityProvider.java b/de.prob.ui/src/de/prob/ui/stateview/IVisibilityProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..3b47cea78235ff7903035a5e492b11f9643261ef --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/stateview/IVisibilityProvider.java @@ -0,0 +1,13 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.ui.stateview; + +import org.eclipse.jface.viewers.IBaseLabelProvider; + +public interface IVisibilityProvider extends IBaseLabelProvider { + boolean isVisible(Object element); +} diff --git a/de.prob.ui/src/de/prob/ui/stateview/LabelViewer.java b/de.prob.ui/src/de/prob/ui/stateview/LabelViewer.java new file mode 100644 index 0000000000000000000000000000000000000000..525a6d41166f2f4159bb5d39e1f55fad4e272e65 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/stateview/LabelViewer.java @@ -0,0 +1,115 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +/** + * + */ +package de.prob.ui.stateview; + +import org.eclipse.jface.viewers.ContentViewer; +import org.eclipse.jface.viewers.IBaseLabelProvider; +import org.eclipse.jface.viewers.IColorProvider; +import org.eclipse.jface.viewers.IContentProvider; +import org.eclipse.jface.viewers.IFontProvider; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; + +/** + * This LabelViewer controls the status of a simple SWT label. + * + * You can use {@link ILabelProvider} to control text and image, + * {@link IFontProvider} for the font, {@link IColorProvider} for back- and + * foreground colors and {@link IVisibilityProvider} to conrol the Label's + * visibility. + * + * You must use a {@link ISimpleContentProvider} to provide a content. + * + * @author plagge + */ +public class LabelViewer extends ContentViewer { + + private final Label label; + private Object content; + private ISelection selection; + + public LabelViewer(final Composite parent, final int style) { + super(); + label = new Label(parent, style); + label.setText(""); + } + + public LabelViewer(final Label label) { + super(); + this.label = label; + } + + public Label getLabel() { + return label; + } + + @Override + public Control getControl() { + return label; + } + + @Override + public ISelection getSelection() { + return this.selection; + } + + public void addMouseListener(final MouseListener listener) { + label.addMouseListener(listener); + } + + @Override + public void refresh() { + IBaseLabelProvider provider = getLabelProvider(); + if (provider instanceof ILabelProvider) { + final ILabelProvider labelprovider = (ILabelProvider) provider; + final String text = labelprovider.getText(content); + label.setText(text == null ? "" : text); + } + if (provider instanceof IFontProvider) { + final IFontProvider fontprovider = (IFontProvider) provider; + label.setFont(fontprovider.getFont(content)); + } + if (provider instanceof IColorProvider) { + final IColorProvider colorProvider = (IColorProvider) provider; + label.setBackground(colorProvider.getBackground(content)); + label.setForeground(colorProvider.getForeground(content)); + } + if (provider instanceof IVisibilityProvider) { + final IVisibilityProvider visibilityProvider = (IVisibilityProvider) provider; + label.setVisible(visibilityProvider.isVisible(content)); + } + label.update(); + } + + @Override + public void setSelection(final ISelection selection, final boolean reveal) { + this.selection = selection; + } + + @Override + protected void inputChanged(final Object input, final Object oldInput) { + super.inputChanged(input, oldInput); + content = ((ISimpleContentProvider) getContentProvider()) + .convert(input); + refresh(); + } + + /** + * This interface defines a trivial ContentProvider which just maps an input + * to an output. + */ + public static interface ISimpleContentProvider extends IContentProvider { + Object convert(Object element); + } +} diff --git a/de.prob.ui/src/de/prob/ui/stateview/LoadShortestTraceHandler.java b/de.prob.ui/src/de/prob/ui/stateview/LoadShortestTraceHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..aee72bf1b6b50c0bdf3a7ea0b92472f379598314 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/stateview/LoadShortestTraceHandler.java @@ -0,0 +1,101 @@ +package de.prob.ui.stateview; + +import java.util.List; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.IHandler; + +import de.prob.core.Animator; +import de.prob.core.command.ExploreStateCommand; +import de.prob.core.command.GetFullTraceCommand; +import de.prob.core.command.SetStateCommand; +import de.prob.core.domainobjects.Operation; +import de.prob.core.domainobjects.State; +import de.prob.exceptions.ProBException; + +public class LoadShortestTraceHandler extends AbstractHandler implements + IHandler { + + private List<String> states; + private final Animator animator; + + public LoadShortestTraceHandler() { + animator = Animator.getAnimator(); + } + + public Object execute(final ExecutionEvent event) throws ExecutionException { + String stateId = animator.getCurrentState().getId(); + + // set core state + try { + SetStateCommand.setState(animator, stateId); + } catch (ProBException e) { + // We cannot recover from this, but the user has been informed + return null; + } + + loadTrace(); + + try { + animator.getHistory().gotoPos(0); + } catch (ProBException e) { + // We cannot recover from this, but the user has been informed + return null; + } + State state = animator.getCurrentState(); + + try { + for (String nextState : states) { + final Operation op = getOperationByDstId(nextState, + state.getEnabledOperations()); + + state = ExploreStateCommand.exploreState(animator, stateId); + + // append state- and operation objects to history + animator.getHistory().add(state, op); + + animator.announceCurrentStateChanged(state, op); + } + } catch (ProBException e) { + e.notifyUserOnce(); + } + return null; + } + + /** + * load the trace to state <code>stateId</code> from <code>animator</code> + * and set <code>states</code> and <code>operations</code> + */ + private void loadTrace() { + try { + states = GetFullTraceCommand.getTrace(animator).getStates(); + } catch (ProBException e) { + e.notify(); + // We cannot recover from this, but the user has been informed + return; + } + + } + + /** + * Find and return the first Operation in <code>operations</code> with + * <code>dstId</code> as destination state. If no such Operation can be + * found, returns <code>null</code>. + * + * @param dstId + * @param operations + * @return + */ + private Operation getOperationByDstId(final String dstId, + final List<Operation> operations) { + + for (Operation op : operations) { + if (op.getDestination().equals(dstId)) + return op; + } + + return null; + } +} diff --git a/de.prob.ui/src/de/prob/ui/stateview/ShowInHistoryHandler.java b/de.prob.ui/src/de/prob/ui/stateview/ShowInHistoryHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..e32a50cb284a9c0058db782de59b1898d410fddf --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/stateview/ShowInHistoryHandler.java @@ -0,0 +1,88 @@ +/** + * + */ +package de.prob.ui.stateview; + +import java.util.ArrayList; +import java.util.Collection; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.IHandler; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.handlers.HandlerUtil; + +import de.prob.ui.ProbUiPlugin; +import de.prob.ui.historyview.HistoryView; +import de.prob.ui.stateview.statetree.StaticStateElement; + +/** + * This handler copies the selected entries in the state view to the history + * view. + * + * @author plagge + */ +public class ShowInHistoryHandler extends AbstractHandler implements IHandler { + + public Object execute(final ExecutionEvent event) throws ExecutionException { + final ISelection selection = HandlerUtil + .getActiveWorkbenchWindow(event).getActivePage().getSelection(); + if (selection != null && selection instanceof IStructuredSelection) { + final IStructuredSelection sel = (IStructuredSelection) selection; + final Collection<StaticStateElement> sses = new ArrayList<StaticStateElement>(); + for (final Object element : sel.toList()) { + if (element instanceof StaticStateElement) { + sses.add((StaticStateElement) element); + } + } + if (!sses.isEmpty()) { + addToHistory(sses); + } + } + return null; + } + + private void addToHistory(final Collection<StaticStateElement> sses) { + final IWorkbenchWindow window = ProbUiPlugin.getDefault() + .getWorkbench().getActiveWorkbenchWindow(); + final IViewPart view = findHistoryView(window); + if (view != null) { + HistoryView hview = (HistoryView) view; + hview.addColumns(sses); + } + } + + private HistoryView findHistoryView(final IWorkbenchWindow window) { + final IWorkbenchPage page = window.getActivePage(); + IViewPart view = page.findView(HistoryView.VIEW_ID); + if (view == null) { + try { + view = page.showView(HistoryView.VIEW_ID); + } catch (PartInitException e) { + MessageDialog.openError(window.getShell(), "Internal Error", + "Error while opening the History View"); + } + } + if (view == null) { + MessageDialog.openError(window.getShell(), "Internal Error", + "Cannot not find the History View"); + return null; + } else { + if (view instanceof HistoryView) + return (HistoryView) view; + else { + MessageDialog.openError(window.getShell(), "Internal Error", + "Not expected type of the History View: " + + view.getClass().getName()); + return null; + } + } + } +} diff --git a/de.prob.ui/src/de/prob/ui/stateview/ShownState.java b/de.prob.ui/src/de/prob/ui/stateview/ShownState.java new file mode 100644 index 0000000000000000000000000000000000000000..62eb4fa284f93f08f2ec86ec2fcb64731f8a6289 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/stateview/ShownState.java @@ -0,0 +1,168 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +/** + * + */ +package de.prob.ui.stateview; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; + +import de.prob.core.domainobjects.MachineDescription; +import de.prob.core.domainobjects.State; +import de.prob.core.domainobjects.MachineDescription.Section; + +/** + * An instance of this class contains two states: A current state and an + * (optional) last state. + * + * TODO: This class should be replaced as soon as possible + * + * @author plagge + */ +public class ShownState { + public static final String OTHER_SECTION_ID = "__Other__"; + + private State current, last; + private MachineDescription description; + + private Collection<String> usedSections; + private List<String> otherVariables; + + private void reset() { + usedSections = null; + otherVariables = null; + } + + private void compute() { + if (usedSections == null) { + usedSections = new HashSet<String>(); + addUsedSections(current); + addUsedSections(last); + } + } + + public void setMachineDescription(final MachineDescription description) { + reset(); + this.description = description; + } + + public void setCurrent(final State current) { + reset(); + this.current = current; + } + + public void setLast(final State last) { + reset(); + this.last = last; + } + + /** + * @return the machine description object of the loaded machine to which the + * current and last state belongs to + */ + public MachineDescription getMachineDescription() { + return description; + } + + /** + * @return all sections names as list, from the most abstract one to the + * most concrete, never <code>null</code> + */ + public List<String> getSections() { + compute(); + final List<String> sectionNames; + if (description == null) { + sectionNames = Collections.emptyList(); + } else { + final List<Section> neSecs = description.getNonEmptySections(); + sectionNames = new ArrayList<String>(neSecs.size()); + for (Section s : neSecs) { + sectionNames.add(s.getName()); + } + } + final List<String> allSectionNames; + if (isOtherSectionNeeded()) { + allSectionNames = new ArrayList<String>(sectionNames); + allSectionNames.add(OTHER_SECTION_ID); + } else { + allSectionNames = sectionNames; + } + return allSectionNames; + } + + /** + * @param section + * the name of a section (machine/context), never + * <code>null</code> + * @return if there is a variable in the given section that has a value in + * the current or last state + */ + public boolean sectionHasValue(final String section) { + compute(); + return usedSections.contains(section); + } + + /** + * @param section + * the name of a section (machine/context), never + * <code>null</code> + * @return a list of variable names that are present in the given section, + * never <code>null</code>, even if the section is unknown + */ + public List<String> getSectionVariables(final String section) { + compute(); + final List<String> result; + if (OTHER_SECTION_ID.equals(section) && isOtherSectionNeeded()) { + result = otherVariables; + } else { + final List<String> vars; + if (description == null) { + vars = Collections.emptyList(); + } else { + vars = description.getIdentifiersOfSection(section); + } + if (vars == null) { + result = Collections.emptyList(); + } else { + result = vars; + } + } + return result; + } + + private boolean isOtherSectionNeeded() { + return sectionHasValue(OTHER_SECTION_ID); + } + + private void addUsedSections(final State state) { + if (state != null) { + for (String id : state.getValues().keySet()) { + final String section = description == null ? null : description + .getSectionOfIdentifier(id); + if (section != null) { + usedSections.add(section); + usedSections.addAll(description + .getAllSectionsOfIdentifier(id)); + } else { + usedSections.add(OTHER_SECTION_ID); + if (otherVariables == null) { + otherVariables = new ArrayList<String>(); + } + if (!otherVariables.contains(id)) { + otherVariables.add(id); + } + } + usedSections.add(section == null ? OTHER_SECTION_ID : section); + } + } + } + +} diff --git a/de.prob.ui/src/de/prob/ui/stateview/SimpleContentProvider.java b/de.prob.ui/src/de/prob/ui/stateview/SimpleContentProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..503be7af7bad44c05e78d83fe6f6d6a52a5b9bd6 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/stateview/SimpleContentProvider.java @@ -0,0 +1,30 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +/** + * + */ +package de.prob.ui.stateview; + +import org.eclipse.jface.viewers.Viewer; + +import de.prob.ui.stateview.LabelViewer.ISimpleContentProvider; + +/** + * The default base class for {@link ISimpleContentProvider} + * + * @author plagge + */ +public abstract class SimpleContentProvider implements + LabelViewer.ISimpleContentProvider { + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + +} diff --git a/de.prob.ui/src/de/prob/ui/stateview/StateLabelProvider.java b/de.prob.ui/src/de/prob/ui/stateview/StateLabelProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..9c405743544315e9823bc72f9d8d54ab82083f56 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/stateview/StateLabelProvider.java @@ -0,0 +1,85 @@ +/** + * + */ +package de.prob.ui.stateview; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; + +import de.prob.core.domainobjects.State; +import de.prob.ui.stateview.statetree.EStateTreeElementProperty; +import de.prob.ui.stateview.statetree.StateDependendElement; +import de.prob.ui.stateview.statetree.StaticStateElement; + +/** + * A StateLabelProvider defines some properties of an entry in a table (like + * color, image, text). + * + * @author plagge + */ +public class StateLabelProvider { + public Image getImage(final State state, final StaticStateElement element) { + return null; + } + + public String getText(final State state, final StaticStateElement element) { + final String result; + if (element != null) { + StateDependendElement sde = getStateDependendElement(state, element); + result = sde == null ? null : sde.getValue(); + } else { + result = null; + } + return result; + } + + public Color getBackground(final State state, + final StaticStateElement element) { + return null; + } + + public Color getForeground(final State state, + final StaticStateElement element) { + final EStateTreeElementProperty property = getPropertyValue(state, + element); + int colorcst = SWT.COLOR_BLACK; + if (property != null) { + switch (property) { + case FALSE: + colorcst = SWT.COLOR_RED; + break; + case TRUE: + colorcst = SWT.COLOR_DARK_GREEN; + break; + case INACTIVE: + colorcst = SWT.COLOR_GRAY; + break; + case NONBOOLEAN: + colorcst = SWT.COLOR_BLACK; + break; + case ERROR: + colorcst = SWT.COLOR_MAGENTA; + break; + default: + break; + } + } else { + colorcst = SWT.COLOR_GRAY; + } + return Display.getCurrent().getSystemColor(colorcst); + } + + private static EStateTreeElementProperty getPropertyValue( + final State state, final StaticStateElement elem) { + StateDependendElement sde = getStateDependendElement(state, elem); + return sde == null ? null : sde.getProperty(); + } + + private static StateDependendElement getStateDependendElement( + final State state, final StaticStateElement elem) { + return state == null ? null : elem.getValue(state); + } + +} diff --git a/de.prob.ui/src/de/prob/ui/stateview/StateViewPart.java b/de.prob.ui/src/de/prob/ui/stateview/StateViewPart.java new file mode 100644 index 0000000000000000000000000000000000000000..7680e3500695125cc43a8b5dd6e9b7e927765d6f --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/stateview/StateViewPart.java @@ -0,0 +1,494 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.ui.stateview; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.TreeViewerColumn; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerFilter; +import org.eclipse.swt.SWT; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.DragSourceEvent; +import org.eclipse.swt.dnd.DragSourceListener; +import org.eclipse.swt.dnd.TextTransfer; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.ui.IWorkbenchActionConstants; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; + +import de.prob.core.Animator; +import de.prob.core.LanguageDependendAnimationPart; +import de.prob.core.LimitedLogger; +import de.prob.core.command.EvaluationGetTopLevelCommand; +import de.prob.core.command.EvaluationGetValuesCommand; +import de.prob.core.domainobjects.EvaluationElement; +import de.prob.core.domainobjects.MachineDescription; +import de.prob.core.domainobjects.Operation; +import de.prob.core.domainobjects.State; +import de.prob.exceptions.ProBException; +import de.prob.logging.Logger; +import de.prob.ui.StateBasedViewPart; +import de.prob.ui.dnd.StaticStateElementTransfer; +import de.prob.ui.errorview.StateErrorView; +import de.prob.ui.stateview.statetree.StateTreeElement; +import de.prob.ui.stateview.statetree.StateTreeExpression; +import de.prob.ui.stateview.statetree.StateTreeExpressionSection; +import de.prob.ui.stateview.statetree.StateTreeSection; +import de.prob.ui.stateview.statetree.StateTreeVariable; +import de.prob.ui.stateview.statetree.StaticStateElement; + +/** + * This is the view that shows variables and formulas for the current state. + * + * @author plagge + */ +public class StateViewPart extends StateBasedViewPart { + public static final String STATE_VIEW_ID = "de.prob.ui.StateView"; + + private static final ShowMultipleVarsFilter DUP_FILTER = new ShowMultipleVarsFilter(); + + private Composite pageComposite; + + private TreeViewer treeViewer; + private LabelViewer invariantViewer; + private LabelViewer stateErrorViewer; + private LabelViewer timeoutViewer; + + private ShownState shownState; + + private LabelViewer modelchangeViewer; + + private Collection<EvaluationElement> topEvaluationElements; + private StateTreeExpressionSection expressionSection; + private final VarLabelProvider varLabelProvider = new VarLabelProvider(); + + @Override + public Control createStatePartControl(final Composite parent) { + pageComposite = new Composite(parent, SWT.NONE); + final GridLayout layout = new GridLayout(2, true); + pageComposite.setLayout(layout); + createVariableTree(); + createSignalLabels(); + pageComposite.pack(); + + hookContextMenu(); + + getSite().setSelectionProvider(treeViewer); + + initDragAndDrop(); + + initialiseFilter(); + + return pageComposite; + } + + private void initialiseFilter() { + org.eclipse.core.commands.State filterState = ToggleShowDuplicatesHandler + .getCurrentState(getSite()); + setDuplicateVariableFilter((Boolean) filterState.getValue()); + } + + private void hookContextMenu() { + final StateViewPart x = this; + TreeViewer viewer = treeViewer; + MenuManager menuMgr = new MenuManager("#PopupMenu"); + menuMgr.setRemoveAllWhenShown(true); + menuMgr.addMenuListener(new IMenuListener() { + public void menuAboutToShow(final IMenuManager manager) { + x.fillContextMenu(manager); + } + }); + Menu menu = menuMgr.createContextMenu(viewer.getControl()); + viewer.getControl().setMenu(menu); + getSite().registerContextMenu(menuMgr, viewer); + } + + private void fillContextMenu(final IMenuManager manager) { + manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); + } + + private void initDragAndDrop() { + Transfer[] transferTypes = new Transfer[] { + StaticStateElementTransfer.getInstance(), + TextTransfer.getInstance() }; + treeViewer.addDragSupport(DND.DROP_COPY, transferTypes, + new DragSourceListener() { + public void dragStart(final DragSourceEvent event) { + // System.out.println("dragStart"); + } + + public void dragSetData(final DragSourceEvent event) { + // System.out.println("dragSetData"); + final IStructuredSelection selection = (IStructuredSelection) treeViewer + .getSelection(); + StaticStateElement[] elements = new StaticStateElement[selection + .size()]; + int i = 0; + for (Iterator<?> it = selection.iterator(); it + .hasNext(); i++) { + elements[i] = (StaticStateElement) it.next(); + } + if (StaticStateElementTransfer.getInstance() + .isSupportedType(event.dataType)) { + // System.out + // .println("dragSetData: static state element"); + event.data = elements; + } else if (TextTransfer.getInstance().isSupportedType( + event.dataType)) { + StringBuilder sb = new StringBuilder(); + boolean first = true; + for (final StaticStateElement element : elements) { + if (!first) { + sb.append(", "); + first = false; + } + sb.append(element.getLabel()); + } + event.data = sb.toString(); + // System.out.println("dragSetData: text"); + } + } + + public void dragFinished(final DragSourceEvent event) { + // System.out.println("dragFinished"); + } + }); + } + + @Override + protected void stateChanged(final State activeState, + final Operation operation) { + LimitedLogger.getLogger().log("state view: new state", + activeState == null ? null : activeState.getId(), null); + initShownState(); + final Animator animator = Animator.getAnimator(); + final State lastState = animator.getHistory().getState(-1); + shownState.setCurrent(activeState); + shownState.setLast(lastState); + loadEvaluationElements(shownState, activeState, lastState); + varLabelProvider.setStates(activeState, lastState); + treeViewer.refresh(true); + invariantViewer.setInput(activeState); + stateErrorViewer.setInput(activeState); + timeoutViewer.setInput(activeState); + modelchangeViewer.setInput(activeState); + } + + private void loadEvaluationElements(final ShownState shownState, + final State current, final State last) { + Set<EvaluationElement> visibleElements = new HashSet<EvaluationElement>(); + boolean errorShown = false; + visibleElements.addAll(topEvaluationElements); + try { + for (final Object obj : treeViewer.getVisibleExpandedElements()) { + if (obj instanceof StateTreeExpression) { + StateTreeExpression ste = (StateTreeExpression) obj; + EvaluationElement elem = ste.getStaticElement(); + visibleElements.add(elem); + visibleElements.addAll(Arrays.asList(elem.getChildren())); + } + } + EvaluationGetValuesCommand.getValuesForExpressionsCached(current, + visibleElements); + EvaluationGetValuesCommand.getValuesForExpressionsCached(last, + visibleElements); + } catch (ProBException e) { + if (!errorShown) { + e.notifyUserOnce(); + } + } + } + + @Override + protected void stateReset() { + shownState = null; + varLabelProvider.setStates(null, null); + } + + private void initShownState() { + if (shownState == null) { + try { + EvaluationElement[] tops = EvaluationGetTopLevelCommand + .retrieveTopLevelElements(); + topEvaluationElements = new ArrayList<EvaluationElement>( + Arrays.asList(tops)); + } catch (ProBException e) { + e.notifyUserOnce(); + topEvaluationElements = Collections.emptyList(); + } + shownState = new ShownState(); + final MachineDescription md = Animator.getAnimator() + .getMachineDescription(); + shownState.setMachineDescription(md); + final StateTreeElement[] topLevelElements = new StateTreeElement[shownState + .getSections().size() + 1]; + int i = 0; + for (final String section : shownState.getSections()) { + topLevelElements[i] = new StateTreeSection(section, md); + i++; + } + expressionSection = new StateTreeExpressionSection( + StateViewStrings.formulasSectionLabel, + topEvaluationElements); + topLevelElements[i] = expressionSection; + treeViewer.setInput(topLevelElements); + } + } + + private void createSignalLabels() { + final GridData signalLayout = new GridData(); + signalLayout.horizontalAlignment = SWT.FILL; + + // define some colors and fonts + final Display display = Display.getCurrent(); + final Color gray = display.getSystemColor(SWT.COLOR_GRAY); + final Color green = display.getSystemColor(SWT.COLOR_GREEN); + final Color red = display.getSystemColor(SWT.COLOR_RED); + final Font bold = JFaceResources.getFontRegistry().getBold( + JFaceResources.BANNER_FONT); + + // create the LabelViewer for the invariant + invariantViewer = new LabelViewer(pageComposite, SWT.NONE); + invariantViewer.getLabel().setLayoutData(signalLayout); + invariantViewer.getLabel().setToolTipText( + StateViewStrings.signalInvariantTooltip); + final BooleanLabelProvider invProvider = new BooleanLabelProvider(); + invProvider.setTexts(null, StateViewStrings.signalInvariantGood, + StateViewStrings.signalInvariantBad); + invProvider.setBackgroundColors(gray, green, red); + invProvider.setFonts(null, null, bold); + invariantViewer.setLabelProvider(invProvider); + invariantViewer.setContentProvider(new InvContentProvider()); + + // create the LabelViewer for state-based errors + stateErrorViewer = new LabelViewer(pageComposite, SWT.NONE); + stateErrorViewer.getLabel().setLayoutData(signalLayout); + stateErrorViewer.getLabel().setToolTipText( + StateViewStrings.signalEventerrorTooltip); + final BooleanLabelProvider errorProvider = new BooleanLabelProvider(); + errorProvider.setTexts(null, StateViewStrings.signalEventerrorGood, + StateViewStrings.signalEventerrorBad); + errorProvider.setBackgroundColors(gray, green, red); + errorProvider.setFonts(null, null, null); + stateErrorViewer.setLabelProvider(errorProvider); + stateErrorViewer.setContentProvider(new StateErrorProvider()); + stateErrorViewer.addMouseListener(new ErrorViewDoubleClick()); + + // create the LabelViewer for changed model + modelchangeViewer = new LabelViewer(pageComposite, SWT.NONE); + modelchangeViewer.getLabel().setLayoutData(signalLayout); + modelchangeViewer.getLabel().setToolTipText( + StateViewStrings.signalModelmodifiedTooltip); + modelchangeViewer.addMouseListener(new ResetAnimationListener()); + + final BooleanLabelProvider modelchangeProvider = new BooleanLabelProvider(); + modelchangeProvider.setTexts(null, null, + StateViewStrings.signalModelmodifiedBad); + modelchangeProvider.setBackgroundColors(gray, gray, red); + modelchangeProvider.setFonts(null, null, bold); + modelchangeProvider.hideWhenInactive(false); + modelchangeViewer.setLabelProvider(modelchangeProvider); + modelchangeViewer.setContentProvider(new ModelChangeContentProvider()); + + // create the LabelViewer for the timeout + timeoutViewer = new LabelViewer(pageComposite, SWT.NONE); + timeoutViewer.getLabel().setLayoutData(signalLayout); + timeoutViewer.getLabel().setToolTipText( + StateViewStrings.signalTimeoutTooltip); + + final BooleanLabelProvider timeoutProvider = new BooleanLabelProvider(); + timeoutProvider.setTexts(null, null, StateViewStrings.signalTimeoutBad); + timeoutProvider.setBackgroundColors(gray, gray, red); + timeoutProvider.setFonts(null, null, bold); + timeoutProvider.hideWhenInactive(false); + timeoutViewer.setLabelProvider(timeoutProvider); + timeoutViewer.setContentProvider(new TimeoutContentProvider()); + + } + + private void createVariableTree() { + final GridData treeViewerLayout = new GridData(); + treeViewerLayout.grabExcessHorizontalSpace = true; + treeViewerLayout.grabExcessVerticalSpace = true; + treeViewerLayout.horizontalAlignment = SWT.FILL; + treeViewerLayout.verticalAlignment = SWT.FILL; + treeViewerLayout.horizontalSpan = 2; + + treeViewer = new TreeViewer(pageComposite); + treeViewer.getTree().setLayoutData(treeViewerLayout); + treeViewer.getTree().setHeaderVisible(true); + treeViewer.getTree().setLinesVisible(true); + treeViewer.setAutoExpandLevel(2); + + TreeViewerColumn col1 = new TreeViewerColumn(treeViewer, SWT.LEFT); + col1.getColumn().setText(StateViewStrings.columnHeaderName); + col1.getColumn().setResizable(true); + col1.getColumn().setWidth(200); + + TreeViewerColumn col2 = new TreeViewerColumn(treeViewer, SWT.RIGHT); + col2.getColumn().setText(StateViewStrings.columnHeaderCurrentvalue); + col2.getColumn().setResizable(true); + col2.getColumn().setWidth(150); + + TreeViewerColumn col3 = new TreeViewerColumn(treeViewer, SWT.RIGHT); + col3.getColumn().setText(StateViewStrings.columnHeaderPreviousvalue); + col3.getColumn().setResizable(true); + col3.getColumn().setWidth(150); + + treeViewer.setContentProvider(new VarContentProvider()); + treeViewer.setLabelProvider(varLabelProvider); + treeViewer.setInput(null); + } + + private static class InvContentProvider extends SimpleContentProvider { + public Object convert(final Object element) { + final Boolean result; + if (element != null && element instanceof State) { + final State state = (State) element; + result = state.isInitialized() ? Boolean.valueOf(state + .isInvariantPreserved()) : null; + } else { + result = null; + } + return result; + } + } + + private static class StateErrorProvider extends SimpleContentProvider { + public Object convert(final Object element) { + final Boolean result; + if (element != null && element instanceof State) { + final State state = (State) element; + result = Boolean.valueOf(!state.hasStateBasedErrors()); + } else { + result = null; + } + return result; + } + } + + private static class TimeoutContentProvider extends SimpleContentProvider { + public Object convert(final Object element) { + final Boolean result; + if (element != null && element instanceof State) { + final State state = (State) element; + result = state.isTimeoutOccured() ? Boolean.FALSE : null; + } else { + result = null; + } + return result; + } + } + + private static class ModelChangeContentProvider extends + SimpleContentProvider { + public Object convert(final Object element) { + return !Animator.getAnimator().isDirty(); + } + } + + private static class ResetAnimationListener implements MouseListener { + public void mouseDoubleClick(final MouseEvent event) { + Animator animator = Animator.getAnimator(); + LanguageDependendAnimationPart ldp = animator + .getLanguageDependendPart(); + if (ldp != null) { + try { + ldp.reload(animator); + } catch (ProBException e) { + e.notifyUserOnce(); + } + } + } + + public void mouseDown(final MouseEvent arg0) { + } + + public void mouseUp(final MouseEvent arg0) { + } + + } + + private static class ErrorViewDoubleClick implements MouseListener { + public void mouseDoubleClick(final MouseEvent event) { + IWorkbenchPage wpage = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage(); + try { + wpage.showView(StateErrorView.VIEWID); + } catch (PartInitException e) { + Logger.notifyUser(StateViewStrings.errorShowEventerrors, e); + } + } + + public void mouseDown(final MouseEvent arg0) { + } + + public void mouseUp(final MouseEvent arg0) { + } + } + + public void setDuplicateVariableFilter(final boolean filterState) { + final ViewerFilter[] filters = filterState ? new ViewerFilter[] { DUP_FILTER } + : new ViewerFilter[0]; + treeViewer.setFilters(filters); + refreshTreeView(); + } + + private void refreshTreeView() { + final Runnable refresh = new Runnable() { + public void run() { + treeViewer.refresh(); + } + }; + Display.getDefault().asyncExec(refresh); + } + + private static class ShowMultipleVarsFilter extends ViewerFilter { + @Override + public boolean select(final Viewer viewer, final Object parent, + final Object element) { + if (element instanceof StateTreeSection) + return ((StateTreeSection) element).isMainSectionOfVariable(); + else if (element instanceof StateTreeVariable) + return ((StateTreeVariable) element).isInMainSection(); + else + return true; + } + } + + public void addUserDefinedExpression( + final EvaluationElement userDefinedElement) { + this.expressionSection.addChild(userDefinedElement); + this.topEvaluationElements.add(userDefinedElement); + refreshTreeView(); + } +} diff --git a/de.prob.ui/src/de/prob/ui/stateview/StateViewStrings.java b/de.prob.ui/src/de/prob/ui/stateview/StateViewStrings.java new file mode 100644 index 0000000000000000000000000000000000000000..02af68618dd55b0016557da78b0b8ed952ed5faf --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/stateview/StateViewStrings.java @@ -0,0 +1,49 @@ +/** + * + */ +package de.prob.ui.stateview; + +import org.eclipse.osgi.util.NLS; + +/** + * Natural Language Strings for the state view + * + * @author plagge + */ +public class StateViewStrings extends NLS { + public static String signalInvariantTooltip; + public static String signalInvariantGood; + public static String signalInvariantBad; + + public static String signalEventerrorTooltip; + public static String signalEventerrorGood; + public static String signalEventerrorBad; + + public static String signalModelmodifiedTooltip; + public static String signalModelmodifiedBad; + + public static String signalTimeoutTooltip; + public static String signalTimeoutBad; + + public static String columnHeaderName; + public static String columnHeaderCurrentvalue; + public static String columnHeaderPreviousvalue; + + public static String errorShowEventerrors; + + public static String menuShowMultipleVariables; + + public static String menuEnterNewFormula; + public static String dialogTitleEnterNewFormula; + public static String dialogMessageEnterNewFormula; + public static String dialogSyntaxError; + + public static String formulasSectionLabel; + + public static String menuReloadAnimation; + + static { + final Class<StateViewStrings> clazz = StateViewStrings.class; + initializeMessages(clazz.getName(), clazz); + } +} diff --git a/de.prob.ui/src/de/prob/ui/stateview/StateViewStrings.properties b/de.prob.ui/src/de/prob/ui/stateview/StateViewStrings.properties new file mode 100644 index 0000000000000000000000000000000000000000..abb04c4fe88155e3921ffc0a04586f6dd2e9c00b --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/stateview/StateViewStrings.properties @@ -0,0 +1,30 @@ +signalInvariantTooltip=This area signals whether the invariant is violated or not +signalInvariantGood=invariant ok +signalInvariantBad=invariant violated! + +signalEventerrorTooltip=This area signals if an error occurred in an event +signalEventerrorGood=no event errors detected +signalEventerrorBad=event errors detected! + +signalModelmodifiedTooltip=This area signals whether the model has been changed. Doubleclick to reload it +signalModelmodifiedBad=The model was modified! + +signalTimeoutTooltip=This area signals whether a timeout occurred or not +signalTimeoutBad=a timeout occurred! + +columnHeaderName=Name +columnHeaderCurrentvalue=Value +columnHeaderPreviousvalue=Previous value + +errorShowEventerrors=An exception was raised when trying to show the state error view + +menuShowMultipleVariables=Show multiple occurrences of variables + +menuEnterNewFormula=Add a new formula... +dialogTitleEnterNewFormula=New formula +dialogMessageEnterNewFormula=Please enter a predicate or expression that will be added to the state view +dialogSyntaxError=Syntax error! + +formulasSectionLabel=Formulas + +menuReloadAnimation=Reload animation diff --git a/de.prob.ui/src/de/prob/ui/stateview/ToggleShowDuplicatesHandler.java b/de.prob.ui/src/de/prob/ui/stateview/ToggleShowDuplicatesHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..4501f95e0ec3bdb07e8a53c3275840abaf2ae79b --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/stateview/ToggleShowDuplicatesHandler.java @@ -0,0 +1,76 @@ +/** + * + */ +package de.prob.ui.stateview; + +import java.util.Map; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.Command; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.IHandler; +import org.eclipse.core.commands.State; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.commands.ICommandService; +import org.eclipse.ui.commands.IElementUpdater; +import org.eclipse.ui.menus.UIElement; +import org.eclipse.ui.services.IServiceLocator; + +/** + * This handler controls the behavior of the filter for duplicate variables in + * the state view. + * + * @author plagge + */ +public class ToggleShowDuplicatesHandler extends AbstractHandler implements + IHandler, IElementUpdater { + private static final String COMMAND_ID = "de.prob.ui.stateview.toggleShowDuplicates"; + private static final String STATE_ID = "de.prob.ui.stateview.duplicateFilterState"; + + public Object execute(final ExecutionEvent event) throws ExecutionException { + final State state = event.getCommand().getState(STATE_ID); + if (state != null) { + final boolean newFilterValue = toggleState(state); + setFilter(newFilterValue); + } else + throw new ExecutionException("Command state " + STATE_ID + + " not found"); + return null; + } + + private void setFilter(final boolean newFilterValue) + throws ExecutionException { + final IWorkbenchPage page = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage(); + final StateViewPart view = (StateViewPart) page + .findView(StateViewPart.STATE_VIEW_ID); + if (view != null) { + view.setDuplicateVariableFilter(newFilterValue); + } else + throw new ExecutionException("View " + StateViewPart.STATE_VIEW_ID + + " not found"); + } + + private boolean toggleState(final State state) { + final Boolean filterSet = (Boolean) state.getValue(); + state.setValue(!filterSet); + return !filterSet; + } + + public void updateElement(final UIElement element, + @SuppressWarnings("rawtypes") final Map parameters) { + final State state = getCurrentState(element.getServiceLocator()); + final Boolean filterSet = (Boolean) state.getValue(); + element.setChecked(filterSet); + } + + public static State getCurrentState(final IServiceLocator locator) { + final ICommandService service = (ICommandService) locator + .getService(ICommandService.class); + final Command command = service.getCommand(COMMAND_ID); + final State state = command.getState(STATE_ID); + return state; + } +} diff --git a/de.prob.ui/src/de/prob/ui/stateview/VarContentProvider.java b/de.prob.ui/src/de/prob/ui/stateview/VarContentProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..b633e150b496d0020fe9c59e01ef31354781beec --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/stateview/VarContentProvider.java @@ -0,0 +1,78 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +/** + * + */ +package de.prob.ui.stateview; + +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; + +import de.prob.ui.stateview.statetree.StateTreeElement; +import de.prob.ui.stateview.statetree.StaticStateElement; + +/** + * This class is the ContentProvider for the main tree in the StateView. + * + * Its input is an array of {@link StateTreeElement}s. + * + * @author plagge + */ +class VarContentProvider implements ITreeContentProvider { + public VarContentProvider() { + } + + public Object[] getChildren(final Object parentElement) { + StateTreeElement ste = toTreeElement(parentElement); + StaticStateElement[] children; + if (ste == null) { + children = new StaticStateElement[0]; + } else { + children = ste.getChildren(); + } + return children; + } + + public Object getParent(final Object element) { + StateTreeElement ste = toTreeElement(element); + return ste != null ? ste.getParent() : null; + } + + public boolean hasChildren(final Object element) { + StateTreeElement ste = toTreeElement(element); + return ste != null && ste.hasChildren(); + } + + private static StateTreeElement toTreeElement(final Object object) { + final StateTreeElement ste; + if (object != null && object instanceof StateTreeElement) { + ste = (StateTreeElement) object; + } else { + ste = null; + } + return ste; + } + + public Object[] getElements(final Object inputElement) { + final StateTreeElement[] elements; + if (inputElement != null && inputElement instanceof StateTreeElement[]) { + elements = (StateTreeElement[]) inputElement; + } else { + elements = null; + } + return elements; + } + + public void dispose() { + + } + + public void inputChanged(final Viewer viewer, final Object oldInput, + final Object newInput) { + } + +} diff --git a/de.prob.ui/src/de/prob/ui/stateview/VarLabelProvider.java b/de.prob.ui/src/de/prob/ui/stateview/VarLabelProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..ebf2b3a1b2bea22704dc1d54936159e7677cabdc --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/stateview/VarLabelProvider.java @@ -0,0 +1,150 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +/** + * + */ +package de.prob.ui.stateview; + +import static de.prob.ui.ProbUiPlugin.CHANGE_STAR; + +import org.eclipse.jface.resource.FontRegistry; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.viewers.BaseLabelProvider; +import org.eclipse.jface.viewers.ITableColorProvider; +import org.eclipse.jface.viewers.ITableFontProvider; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; + +import de.prob.core.domainobjects.State; +import de.prob.ui.ProbUiPlugin; +import de.prob.ui.stateview.statetree.StaticStateElement; + +/** + * This LabelProvider maps a {@link StaticStateElement} to its label, current + * value or previous value. Depending on its properties color and font is also + * chosen. + * + * An instance of {@link VarLabelProvider} has a state of its own, a current + * state and a last state. This is needed to map {@link StaticStateElement}s to + * their respective value without altering the tree structure. + * + * @author plagge + */ +public class VarLabelProvider extends BaseLabelProvider implements + ITableLabelProvider, ITableColorProvider, ITableFontProvider { + + private static final String RODIN_FONT_KEY = "org.rodinp.keyboard.textFont"; + + private final StateLabelProvider slProvider = new StateLabelProvider(); + + private final Color gray = Display.getCurrent().getSystemColor( + SWT.COLOR_GRAY); + + private State currentState, lastState; + + public void setStates(final State currentState, final State lastState) { + this.currentState = currentState; + this.lastState = lastState; + } + + public Image getColumnImage(final Object element, final int columnIndex) { + final Image image; + if (isApplicable(element)) { + if (columnIndex == 0) { + image = hasChanged(element) ? ProbUiPlugin.getDefault() + .getImageRegistry().get(CHANGE_STAR) : null; + } else { + State state = getState(columnIndex); + image = state == null ? null : slProvider.getImage(state, + (StaticStateElement) element); + } + } else { + image = null; + } + return image; + } + + public String getColumnText(final Object element, final int columnIndex) { + final String result; + if (isApplicable(element)) { + StaticStateElement sse = (StaticStateElement) element; + if (columnIndex == 0) { + result = sse.getLabel(); + } else { + State state = getState(columnIndex); + result = state == null ? null : slProvider.getText(state, sse); + } + } else { + result = null; + } + return result; + } + + public Color getBackground(final Object element, final int column) { + final Color color; + if (isApplicable(element)) { + final State state = getState(column); + color = state == null ? null : slProvider.getBackground(state, + (StaticStateElement) element); + } else { + color = null; + } + return color; + } + + public Color getForeground(final Object element, final int column) { + final Color color; + if (isApplicable(element)) { + final State state = getState(column == 0 ? 1 : column); + color = state == null ? gray : slProvider.getForeground(state, + (StaticStateElement) element); + } else { + color = null; + } + return color; + } + + public Font getFont(final Object element, final int column) { + final Font font; + final FontRegistry fontRegistry = JFaceResources.getFontRegistry(); + if (isApplicable(element) && hasChanged(element)) { + font = fontRegistry.getBold(RODIN_FONT_KEY); + } else { + font = fontRegistry.get(RODIN_FONT_KEY); + } + return font; + } + + private boolean hasChanged(final Object element) { + return ((StaticStateElement) element).hasChanged(currentState, + lastState); + } + + private boolean isApplicable(final Object element) { + return element != null && element instanceof StaticStateElement; + } + + private State getState(final int column) { + final State state; + switch (column) { + case 1: + state = currentState; + break; + case 2: + state = lastState; + break; + default: + state = null; + break; + } + return state; + } +} diff --git a/de.prob.ui/src/de/prob/ui/stateview/statetree/AbstractStateTreeElement.java b/de.prob.ui/src/de/prob/ui/stateview/statetree/AbstractStateTreeElement.java new file mode 100644 index 0000000000000000000000000000000000000000..5b183e0cf2affdb7364f7a2de8e400856355ded3 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/stateview/statetree/AbstractStateTreeElement.java @@ -0,0 +1,22 @@ +/** + * + */ +package de.prob.ui.stateview.statetree; + + +/** + * @author plagge + * + */ +public abstract class AbstractStateTreeElement implements StateTreeElement { + private final StaticStateElement parent; + + public AbstractStateTreeElement(final StaticStateElement parent) { + this.parent = parent; + } + + public StaticStateElement getParent() { + return parent; + } + +} diff --git a/de.prob.ui/src/de/prob/ui/stateview/statetree/EStateTreeElementProperty.java b/de.prob.ui/src/de/prob/ui/stateview/statetree/EStateTreeElementProperty.java new file mode 100644 index 0000000000000000000000000000000000000000..7017ddbb94bcb8c1d93728aa87d347688227ca66 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/stateview/statetree/EStateTreeElementProperty.java @@ -0,0 +1,5 @@ +package de.prob.ui.stateview.statetree; + +public enum EStateTreeElementProperty { + TRUE, FALSE, NONBOOLEAN, ERROR, INACTIVE +} diff --git a/de.prob.ui/src/de/prob/ui/stateview/statetree/StateDependendElement.java b/de.prob.ui/src/de/prob/ui/stateview/statetree/StateDependendElement.java new file mode 100644 index 0000000000000000000000000000000000000000..e2fc62fd0c733c27ba596e1d06a75da9d3758047 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/stateview/statetree/StateDependendElement.java @@ -0,0 +1,37 @@ +/** + * + */ +package de.prob.ui.stateview.statetree; + +import de.prob.core.domainobjects.State; + +/** + * This interface describes objects that can be displayed in a view that depends + * somehow on states, namely the state view and the history view. + * + * @author plagge + */ +public class StateDependendElement { + private final State state; + private final String value; + private final EStateTreeElementProperty property; + + public StateDependendElement(final State state, final String value, + final EStateTreeElementProperty property) { + this.state = state; + this.value = value; + this.property = property; + } + + public State getState() { + return state; + } + + public String getValue() { + return value; + } + + public EStateTreeElementProperty getProperty() { + return property; + } +} diff --git a/de.prob.ui/src/de/prob/ui/stateview/statetree/StateTreeElement.java b/de.prob.ui/src/de/prob/ui/stateview/statetree/StateTreeElement.java new file mode 100644 index 0000000000000000000000000000000000000000..5e5b781c745c436b99a0de181027fb2cd5735578 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/stateview/statetree/StateTreeElement.java @@ -0,0 +1,21 @@ +/** + * + */ +package de.prob.ui.stateview.statetree; + +/** + * Describes a static property of states that can have sub-property, e.g. a + * formula with it sub-formulas. + * + * @author plagge + */ +public interface StateTreeElement extends StaticStateElement { + public static final StateTreeElement[] EMPTY_ARRAY = new StateTreeElement[0]; + + StaticStateElement getParent(); + + boolean hasChildren(); + + StaticStateElement[] getChildren(); + +} diff --git a/de.prob.ui/src/de/prob/ui/stateview/statetree/StateTreeExpression.java b/de.prob.ui/src/de/prob/ui/stateview/statetree/StateTreeExpression.java new file mode 100644 index 0000000000000000000000000000000000000000..b5e5d24d74eaf0d774c4b014b0d4f1a48ff654bd --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/stateview/statetree/StateTreeExpression.java @@ -0,0 +1,125 @@ +/** + * + */ +package de.prob.ui.stateview.statetree; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.apache.commons.lang.ObjectUtils; + +import de.prob.core.command.EvaluationGetValuesCommand; +import de.prob.core.command.EvaluationGetValuesCommand.EvaluationResult; +import de.prob.core.domainobjects.EvaluationElement; +import de.prob.core.domainobjects.EvaluationStateElement; +import de.prob.core.domainobjects.State; +import de.prob.exceptions.ProBException; + +/** + * @author plagge + * + */ +public class StateTreeExpression extends AbstractStateTreeElement { + private final EvaluationElement staticElement; + private List<StateTreeElement> children = null; + + public StateTreeExpression(final StaticStateElement parent, + final EvaluationElement staticElement) { + super(parent); + this.staticElement = staticElement; + + } + + public StaticStateElement[] getChildren() { + checkForChildren(); + return children.toArray(StateTreeElement.EMPTY_ARRAY); + } + + private void checkForChildren() { + if (children == null) { + try { + EvaluationElement[] staticChildren = staticElement + .getChildren(); + children = new ArrayList<StateTreeElement>( + staticChildren.length); + for (EvaluationElement sChild : staticChildren) { + final StateTreeExpression dChild = new StateTreeExpression( + this, sChild); + children.add(dChild); + } + } catch (ProBException e) { + e.notifyUserOnce(); + children = Collections.emptyList(); + } + } + } + + public String getLabel() { + try { + return staticElement.getLabel(); + } catch (ProBException e) { + e.notifyUserOnce(); + return null; + } + } + + public boolean hasChildren() { + checkForChildren(); + return !children.isEmpty(); + } + + public boolean hasChanged(final State current, final State last) { + final String curval, lastval; + try { + curval = getResultString(current); + lastval = getResultString(last); + } catch (ProBException e) { + e.notifyUserOnce(); + return false; + } + return !ObjectUtils.equals(curval, lastval); + } + + private String getResultString(final State state) throws ProBException { + final EvaluationStateElement dyn = EvaluationGetValuesCommand + .getSingleValueCached(state, staticElement); + final EvaluationResult res = dyn == null ? null : dyn.getResult(); + return res == null ? null : res.getText(); + } + + public EvaluationElement getStaticElement() { + return staticElement; + } + + public StateDependendElement getValue(final State state) { + StateDependendElement sd; + try { + EvaluationStateElement dynamicElement = EvaluationGetValuesCommand + .getSingleValueCached(state, staticElement); + EStateTreeElementProperty property = EStateTreeElementProperty.INACTIVE; + String value = "?"; + if (dynamicElement != null) { + final EvaluationResult result = dynamicElement.getResult(); + if (result.isActive()) { + if (result.hasError()) { + property = EStateTreeElementProperty.ERROR; + } else if (result.isPredicate()) { + property = result.isPredicateTrue() ? EStateTreeElementProperty.TRUE + : EStateTreeElementProperty.FALSE; + } else { + property = EStateTreeElementProperty.NONBOOLEAN; + } + } + value = result.getText(); + } + sd = new StateDependendElement(state, value, property); + } catch (ProBException e) { + e.notifyUserOnce(); + sd = new StateDependendElement(state, "(internal error)", + EStateTreeElementProperty.ERROR); + } + return sd; + } + +} diff --git a/de.prob.ui/src/de/prob/ui/stateview/statetree/StateTreeExpressionSection.java b/de.prob.ui/src/de/prob/ui/stateview/statetree/StateTreeExpressionSection.java new file mode 100644 index 0000000000000000000000000000000000000000..10286c0b789987eda00cfb3bb72a60f57257bb79 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/stateview/statetree/StateTreeExpressionSection.java @@ -0,0 +1,64 @@ +/** + * + */ +package de.prob.ui.stateview.statetree; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import de.prob.core.domainobjects.EvaluationElement; +import de.prob.core.domainobjects.State; + +/** + * @author plagge + * + */ +public class StateTreeExpressionSection extends AbstractStateTreeElement { + private final String label; + private final List<StateTreeElement> children; + + public StateTreeExpressionSection(final String label, + final Collection<EvaluationElement> children) { + this(null, label, children); + } + + public StateTreeExpressionSection(final StaticStateElement parent, + final String label, final Collection<EvaluationElement> children) { + super(parent); + this.label = label; + this.children = new ArrayList<StateTreeElement>(children.size()); + for (final EvaluationElement elem : children) { + StateTreeElement child = new StateTreeExpression(this, elem); + this.children.add(child); + } + } + + public StaticStateElement[] getChildren() { + return children.toArray(StateTreeElement.EMPTY_ARRAY); + } + + public String getLabel() { + return label; + } + + public boolean hasChildren() { + return !children.isEmpty(); + } + + public boolean hasChanged(State current, State last) { + return false; + } + + public void addChild(final EvaluationElement staticElement) { + final StateTreeExpression child = new StateTreeExpression(this, + staticElement); + this.children.add(child); + } + + public StateDependendElement getValue(final State state) { + return new StateDependendElement(state, null, + EStateTreeElementProperty.NONBOOLEAN); + } + +} diff --git a/de.prob.ui/src/de/prob/ui/stateview/statetree/StateTreeSection.java b/de.prob.ui/src/de/prob/ui/stateview/statetree/StateTreeSection.java new file mode 100644 index 0000000000000000000000000000000000000000..c86dfbb816d0b3ba9216589c8eb8ea70633d0bdc --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/stateview/statetree/StateTreeSection.java @@ -0,0 +1,68 @@ +/** + * + */ +package de.prob.ui.stateview.statetree; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import de.prob.core.domainobjects.MachineDescription; +import de.prob.core.domainobjects.State; + +/** + * @author plagge + * + */ +public class StateTreeSection extends AbstractStateTreeElement { + private final String section; + private final List<StateTreeElement> children; + private final boolean isMainSectionOfVariable; + + public StateTreeSection(final String section, final MachineDescription md) { + super(null); + this.section = section; + Collection<String> varnames = md.getIdentifiersOfSection(section); + List<StateTreeElement> children = new ArrayList<StateTreeElement>(); + boolean isMainSectionOfVariable = false; + for (final String varname : varnames) { + final String mainSection = md.getSectionOfIdentifier(varname); + final boolean isInMainSection = section.equals(mainSection); + children.add(new StateTreeVariable(this, varname, isInMainSection)); + isMainSectionOfVariable |= isInMainSection; + } + this.children = children; + this.isMainSectionOfVariable = isMainSectionOfVariable; + } + + public StaticStateElement[] getChildren() { + return children.toArray(StateTreeVariable.EMPTY_ARRAY); + } + + public String getLabel() { + return section; + } + + public boolean hasChildren() { + return !children.isEmpty(); + } + + public boolean isMainSectionOfVariable() { + return isMainSectionOfVariable; + } + + public boolean hasChanged(final State current, final State last) { + for (final StateTreeElement child : children) { + if (child.hasChanged(current, last)) + return true; + } + return false; + } + + public StateDependendElement getValue(final State state) { + return new StateDependendElement(state, null, + hasChildren() ? EStateTreeElementProperty.NONBOOLEAN + : EStateTreeElementProperty.INACTIVE); + } + +} diff --git a/de.prob.ui/src/de/prob/ui/stateview/statetree/StateTreeVariable.java b/de.prob.ui/src/de/prob/ui/stateview/statetree/StateTreeVariable.java new file mode 100644 index 0000000000000000000000000000000000000000..ee019d7036c51b812dbba92911f21b209cd125d3 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/stateview/statetree/StateTreeVariable.java @@ -0,0 +1,74 @@ +/** + * + */ +package de.prob.ui.stateview.statetree; + +import org.apache.commons.lang.ObjectUtils; + +import de.prob.core.domainobjects.State; +import de.prob.core.domainobjects.Variable; + +/** + * Represents the property of the value of a specific variable. + * + * @author plagge + */ +public class StateTreeVariable extends AbstractStateTreeElement { + public static final StateTreeVariable[] EMPTY_ARRAY = new StateTreeVariable[0]; + + private final String name; + private final boolean isInMainSection; + + public StateTreeVariable(final StaticStateElement parent, + final String name, final boolean isInMainSection) { + super(parent); + this.name = name; + this.isInMainSection = isInMainSection; + } + + public StaticStateElement[] getChildren() { + return StateTreeElement.EMPTY_ARRAY; + } + + public String getLabel() { + return name; + } + + public boolean hasChildren() { + return false; + } + + public boolean isInMainSection() { + return isInMainSection; + } + + public boolean hasChanged(final State current, final State last) { + final String curVal = getValueOfVar(current); + final String lastVal = getValueOfVar(last); + return !ObjectUtils.equals(curVal, lastVal); + } + + private String getValueOfVar(final State state) { + final String result; + if (state != null) { + final Variable variable = state.getValues().get(name); + result = variable == null ? null : variable.getValue(); + } else { + result = null; + } + return result; + } + + public StateDependendElement getValue(final State state) { + final Variable variable = state.getValues().get(name); + final StateDependendElement element; + if (variable != null) { + element = new StateDependendElement(state, variable.getValue(), + EStateTreeElementProperty.NONBOOLEAN); + } else { + element = null; + } + return element; + } + +} diff --git a/de.prob.ui/src/de/prob/ui/stateview/statetree/StaticStateElement.java b/de.prob.ui/src/de/prob/ui/stateview/statetree/StaticStateElement.java new file mode 100644 index 0000000000000000000000000000000000000000..55964315996e62ab8d7cad7169dd3cf13a2659a4 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/stateview/statetree/StaticStateElement.java @@ -0,0 +1,36 @@ +package de.prob.ui.stateview.statetree; + +import de.prob.core.domainobjects.State; + +/** + * This interface is for objects that describe what information about a state + * possibly exists. Note that the objects are independent of a concrete state. + * + * @author plagge + */ +public interface StaticStateElement { + /** + * Returns the user-readable label for the property + * + * @return the label + */ + String getLabel(); + + /** + * Computes the value for a specific state + * + * @param state + * the state, never <code>null</code> + * @return a description of the specific property of the state + */ + StateDependendElement getValue(State state); + + /** + * @param current + * a state, may be <code>null</code> + * @param last + * a state, may be <code>null</code> + * @return if the property has changed between last and current + */ + boolean hasChanged(State current, State last); +} \ No newline at end of file diff --git a/de.prob.ui/src/de/prob/ui/ticket/Attachment.java b/de.prob.ui/src/de/prob/ui/ticket/Attachment.java new file mode 100644 index 0000000000000000000000000000000000000000..6a394a01dce7099d305096e865bf509d25a25559 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ticket/Attachment.java @@ -0,0 +1,79 @@ +package de.prob.ui.ticket; + +import java.io.ByteArrayOutputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; + +public class Attachment { + + int ticketId; + String filename; + IPath filepath; + String description; + byte[] data; + + public int getTicketId() { + return ticketId; + } + + public void setTicketId(int ticketId) { + this.ticketId = ticketId; + } + + public String getFilename() { + return filename; + } + + public void setFilename(String filename) { + this.filename = filename; + } + + public IPath getFilepath() { + return filepath; + } + + public String getDescription() { + return this.description; + } + + public void setDescription(String description) { + this.description = description; + } + + public byte[] getData() { + byte[] res = new byte[data.length]; + System.arraycopy(data, 0, res, 0, data.length); + return res; + } + + + public Attachment(String filepath, String description) throws IOException { + this.ticketId = 0; + this.filename = "untitled"; + this.filepath = new Path(filepath); + this.description = description; + InputStream in = new FileInputStream(filepath); + this.data = readData(in); + } + + private byte[] readData(InputStream in) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + try { + byte[] buffer = new byte[512]; + while (true) { + int count = in.read(buffer); + if (count == -1) { + return out.toByteArray(); + } + out.write(buffer, 0, count); + } + } finally { + in.close(); + } + } + +} diff --git a/de.prob.ui/src/de/prob/ui/ticket/BugReportWizard.java b/de.prob.ui/src/de/prob/ui/ticket/BugReportWizard.java new file mode 100644 index 0000000000000000000000000000000000000000..53d54e105b5c2b090c11294742e0c616bd0dd477 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ticket/BugReportWizard.java @@ -0,0 +1,272 @@ +package de.prob.ui.ticket; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Calendar; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import org.apache.xmlrpc.XmlRpcException; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.ui.internal.ConfigurationInfo; +import org.osgi.framework.Bundle; +import org.osgi.service.prefs.BackingStoreException; +import org.osgi.service.prefs.Preferences; + +import de.prob.core.Animator; +import de.prob.logging.Logger; +import de.prob.ui.ProbUiPlugin; + +@SuppressWarnings("restriction") +public class BugReportWizard extends Wizard { + + private WizardPage1 page1; + // private WizardPage2 page2; + private WizardPage3 page3; + + private String email = ""; + private String summary = ""; + private Boolean addTrace = true; + private String description = ""; + + private static final Preferences TICKET_PREFS = Platform + .getPreferencesService().getRootNode().node(InstanceScope.SCOPE) + .node("prob_ticket_preferences"); + + public BugReportWizard() { + super(); + setNeedsProgressMonitor(true); + this.email = TICKET_PREFS.get("email", ""); + } + + public BugReportWizard(final String summary, final Boolean addTrace, + final String description) { + super(); + setNeedsProgressMonitor(true); + + this.email = TICKET_PREFS.get("email", ""); + this.summary = summary; + this.addTrace = addTrace; + this.description = description; + } + + @Override + public void addPages() { + page1 = new WizardPage1(email, summary, description, addTrace, true); + // page2 = new WizardPage2(description); + page3 = new WizardPage3(); + addPage(page1); + // addPage(page2); + addPage(page3); + + } + + @Override + public boolean performFinish() { + + TICKET_PREFS.put("email", page1.getEmail()); + try { + TICKET_PREFS.flush(); + } catch (BackingStoreException e) { + Logger.notifyUserWithoutBugreport( + "Problem while storing preferences. " + + e.getLocalizedMessage(), e); + } + + Ticket ticket = new Ticket(page1.getEmail(), page1.getSummary(), "", + page1.getDetailedDescription(), page1.isSensitive()); + + for (Attachment a : page3.getAttachments()) { + ticket.addAttachment(a); + } + + if (page1.isAddTrace()) { + addTraceFileToTicket(ticket); + addInstallationDetailsToTicket(ticket); + } + + try { + ticket.send(); + } catch (XmlRpcException e) { + Logger.notifyUserWithoutBugreport("Error sending bug report", e); + } + + return true; + } + + private void addInstallationDetailsToTicket(final Ticket ticket) { + // Installation Details + try { + File[] installationDetailsFiles = new File[] { fetchPlugIns(), + fetchConfiguration(), fetchErrorLog() }; + File zipFile; + zipFile = File.createTempFile("InstallationDetails", ".tmp"); + compressFiles(installationDetailsFiles, zipFile); + + Attachment a = new Attachment(zipFile.getAbsolutePath().toString(), + "installation details"); + a.setFilename("InstallationDetails.zip"); + ticket.addAttachment(a); + + } catch (IOException e) { + Logger.notifyUserWithoutBugreport( + "Error adding installation details", e); + } + } + + private void addTraceFileToTicket(final Ticket ticket) { + // Trace File + if (Animator.getAnimator().isMachineLoaded()) { + try { + File tmpFile = File.createTempFile("ProBTrace", ".tmp"); + tmpFile.deleteOnExit(); + + String data = Animator.getAnimator().getTrace() + .getTraceAsString(); + String fileName = tmpFile.getAbsoluteFile().toString(); + + OutputStreamWriter writer; + writer = new OutputStreamWriter(new FileOutputStream(fileName)); + BufferedWriter out = new BufferedWriter(writer); + out.write(data, 0, data.length()); + out.close(); + + Attachment a = new Attachment(tmpFile.getAbsolutePath() + .toString(), "current trace"); + a.setFilename("ProBTraceFile.txt"); + ticket.addAttachment(a); + + } catch (IOException e) { + Logger.notifyUserWithoutBugreport("Error adding trace file", e); + } + } + } + + private File fetchErrorLog() { + // Error Log + String filename = Platform.getLogFileLocation().toOSString(); + + try { + File errorFile = File.createTempFile("ErrorLog", ".txt"); + errorFile.deleteOnExit(); + + BufferedReader input = new BufferedReader(new FileReader(filename)); + OutputStreamWriter writer = new OutputStreamWriter( + new FileOutputStream(errorFile)); + BufferedWriter output = new BufferedWriter(writer); + + String line; + boolean doCopy = false; + String today = String.format("%1$tY-%1$tm-%1$td", + Calendar.getInstance()); // current Date similar to + // YYYY-MM-DD + + while ((line = input.readLine()) != null) { + if (doCopy || line.startsWith("!SESSION " + today)) { + doCopy = true; + output.write(line); + output.newLine(); + } + } + + input.close(); + output.close(); + + return errorFile; + + } catch (IOException e) { + Logger.notifyUserWithoutBugreport("Error while fetching Error Log", + e); + } + return null; + } + + private File fetchConfiguration() { + // Configuration + String summary = ""; + try { + summary = ConfigurationInfo.getSystemSummary(); + } catch (Exception e) { + StringBuffer sb = new StringBuffer( + "Exception while getting System Summary.\n"); + StringWriter sw = new StringWriter(); + e.printStackTrace(new PrintWriter(sw)); + sb.append(sw.toString()); + summary = sb.toString(); + } + try { + File configFile = File.createTempFile("Configuration", ".txt"); + configFile.deleteOnExit(); + + PrintWriter out = new PrintWriter(configFile); + out.print(summary); + out.close(); + + return configFile; + + } catch (IOException e) { + Logger.notifyUserWithoutBugreport( + "Error while fetching Configuration", e); + } + return null; + } + + private File fetchPlugIns() { + // Plug-ins + try { + File plugInsFile = File.createTempFile("PlugIns", ".txt"); + plugInsFile.deleteOnExit(); + + OutputStreamWriter writer; + writer = new OutputStreamWriter(new FileOutputStream(plugInsFile)); + BufferedWriter output = new BufferedWriter(writer); + + for (Bundle b : ProbUiPlugin.getDefault().getInstalledBundles()) { + output.write(b.toString()); + output.newLine(); + } + + output.close(); + return plugInsFile; + + } catch (IOException e) { + Logger.notifyUserWithoutBugreport("Error while fetching Plug-ins", + e); + } + return null; + } + + private void compressFiles(final File[] inputFiles, final File zipFile) { + try { + byte[] buf = new byte[4096]; + ZipOutputStream out = new ZipOutputStream(new FileOutputStream( + zipFile)); + for (int i = 0; i < inputFiles.length; i++) { + File inFile = inputFiles[i]; + FileInputStream inStream = new FileInputStream(inFile); + out.putNextEntry(new ZipEntry(inFile.getName())); + int len; + while ((len = inStream.read(buf)) > 0) { + out.write(buf, 0, len); + } + inStream.close(); + } + out.close(); + + } catch (IOException e) { + Logger.notifyUserWithoutBugreport("Error while compressing Files", + e); + } + } + +} diff --git a/de.prob.ui/src/de/prob/ui/ticket/ErrorTicketDialog.java b/de.prob.ui/src/de/prob/ui/ticket/ErrorTicketDialog.java new file mode 100644 index 0000000000000000000000000000000000000000..115afc8e6f588b45867b70f0ef5d7d10b7c0b54a --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ticket/ErrorTicketDialog.java @@ -0,0 +1,101 @@ +package de.prob.ui.ticket; + +import java.io.PrintWriter; +import java.io.StringWriter; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.handlers.HandlerUtil; + +public class ErrorTicketDialog extends ErrorDialog { + + private static final int OPEN_BUGREPORT_ID = IDialogConstants.CLIENT_ID + 1; + private static final String OPEN_BUGREPORT_LABEL = "Submit Bugreport"; + + private final IStatus status; + private final boolean bugreport; + + public ErrorTicketDialog(final Shell parentShell, final String dialogTitle, + final String message, final IStatus status, final int displayMask, + final boolean bugreport) { + super(parentShell, dialogTitle, message, status, displayMask); + this.status = status; + this.bugreport = bugreport; + } + + public static int openError(final Shell parentShell, final String title, + final String message, final IStatus status, final boolean bugreport) { + ErrorTicketDialog dialog = new ErrorTicketDialog(parentShell, title, + message, status, IStatus.OK | IStatus.INFO | IStatus.WARNING + | IStatus.ERROR, bugreport); + return dialog.open(); + } + + @Override + protected void createButtonsForButtonBar(final Composite parent) { + // create Button to open the BugReport-Wizard + if (bugreport) + createButton(parent, OPEN_BUGREPORT_ID, OPEN_BUGREPORT_LABEL, false); + // create OK and Details buttons + createButton(parent, IDialogConstants.OK_ID, + IDialogConstants.IGNORE_LABEL, true); + // createDetailsButton(parent); + } + + @Override + protected void buttonPressed(final int id) { + if (id == IDialogConstants.DETAILS_ID) { + // was the details button pressed? + // toggleDetailsArea(); + } else if (id == OPEN_BUGREPORT_ID) { + openBugReportWizard(); + super.buttonPressed(IDialogConstants.OK_ID); + } else { + super.buttonPressed(id); + } + } + + private void openBugReportWizard() { + + StringBuffer sb = new StringBuffer(); + sb.append(status.getMessage()); + + printOperatingSystemInfo(sb); + printStackTrace(sb, status.getException()); + + BugReportWizard wizard = new BugReportWizard("ProB internal error", + true, sb.toString()); + WizardDialog dialog = new WizardDialog( + HandlerUtil.getActiveShell(new ExecutionEvent()), wizard); + dialog.setPageSize(400, 300); + dialog.open(); + } + + private void printStackTrace(final StringBuffer sb, + final Throwable exception) { + if (exception != null) { + sb.append("\n\n"); + StringWriter sw = new StringWriter(); + exception.printStackTrace(new PrintWriter(sw)); + sb.append(sw.toString()); + } + } + + private void printOperatingSystemInfo(final StringBuffer sb) { + sb.append("\n\n"); + sb.append("Java Version: "); + sb.append(System.getProperty("java.version")); + sb.append("\nOS: "); + sb.append(System.getProperty("os.name")); + sb.append("\nArchitecture: "); + sb.append(System.getProperty("os.arch")); + sb.append("\nOS-Version: "); + sb.append(System.getProperty("os.version")); + } + +} diff --git a/de.prob.ui/src/de/prob/ui/ticket/LogView.java b/de.prob.ui/src/de/prob/ui/ticket/LogView.java new file mode 100644 index 0000000000000000000000000000000000000000..dd46ac764ed84884f284153e754aaa7fdba6e796 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ticket/LogView.java @@ -0,0 +1,42 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.ui.ticket; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.part.ViewPart; + +public class LogView extends ViewPart { + + private static LogView instance = new LogView(); + private Text text; + + @Override + public void createPartControl(final Composite parent) { + text = new Text(parent, SWT.WRAP | SWT.MULTI); + } + + public static void writeToLog(final String s) { + if (instance != null) { + instance.write(s); + } + } + + private synchronized void write(final String s) { + if (text != null) { + text.append(s); + text.append("\n"); + } + } + + @Override + public void setFocus() { + + } + +} diff --git a/de.prob.ui/src/de/prob/ui/ticket/ProBLogListener.java b/de.prob.ui/src/de/prob/ui/ticket/ProBLogListener.java new file mode 100644 index 0000000000000000000000000000000000000000..c0c749c27d1de128f1aea516cb4270c0450fbc49 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ticket/ProBLogListener.java @@ -0,0 +1,47 @@ +/** + * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, + * Heinrich Heine Universitaet Duesseldorf + * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) + * */ + +package de.prob.ui.ticket; + +import org.eclipse.core.runtime.ILogListener; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.swt.widgets.Display; + +import de.prob.logging.Logger; + +public final class ProBLogListener implements ILogListener { + + private static final Display display = Display.getDefault(); + + public ProBLogListener() { + } + + public void logging(final IStatus status, final String plugin) { + if (display == null || display.isDisposed()) { + return; + } + + final int code = status.getCode(); + + if (code == Logger.BUGREPORT || code == Logger.NOBUGREPORT) { + final boolean bugreport = code == Logger.BUGREPORT; + display.asyncExec(new Runnable() { + public void run() { + // Notice: ErrorTICKETDialog to provide Bugreport-Button + ErrorTicketDialog.openError(display.getActiveShell(), + "Error", "An error occured.", status, bugreport); + } + }); + } + + display.asyncExec(new Runnable() { + public void run() { + LogView.writeToLog(status.getMessage()); + } + }); + + } +} diff --git a/de.prob.ui/src/de/prob/ui/ticket/ShowWizard.java b/de.prob.ui/src/de/prob/ui/ticket/ShowWizard.java new file mode 100644 index 0000000000000000000000000000000000000000..36b5aa909148b370d4da94d0e2a4de3a78f802a2 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ticket/ShowWizard.java @@ -0,0 +1,19 @@ +package de.prob.ui.ticket; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.ui.handlers.HandlerUtil; + +public class ShowWizard extends AbstractHandler{ + + public Object execute(ExecutionEvent arg0) throws ExecutionException { + + BugReportWizard wizard = new BugReportWizard(); + WizardDialog dialog = new WizardDialog(HandlerUtil.getActiveShell(arg0), wizard); + dialog.open(); + return null; + } + +} diff --git a/de.prob.ui/src/de/prob/ui/ticket/SubmitBugreportCommand.java b/de.prob.ui/src/de/prob/ui/ticket/SubmitBugreportCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..3cb0e178981fefcb9f2a61985cf4b4637e13f59a --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ticket/SubmitBugreportCommand.java @@ -0,0 +1,24 @@ +package de.prob.ui.ticket; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.IHandler; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.handlers.HandlerUtil; + +public class SubmitBugreportCommand extends AbstractHandler implements IHandler { + + public Object execute(final ExecutionEvent event) throws ExecutionException { + + IWorkbenchWindow window = HandlerUtil + .getActiveWorkbenchWindowChecked(event); + + BugReportWizard wizard = new BugReportWizard(); + WizardDialog dialog = new WizardDialog(window.getShell(), wizard); + dialog.open(); + return null; + } + +} diff --git a/de.prob.ui/src/de/prob/ui/ticket/Ticket.java b/de.prob.ui/src/de/prob/ui/ticket/Ticket.java new file mode 100644 index 0000000000000000000000000000000000000000..bdaee11d4e93b3b821b80265f0b142de13ddefa0 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ticket/Ticket.java @@ -0,0 +1,140 @@ +package de.prob.ui.ticket; + +import java.io.ByteArrayOutputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.List; + +import org.apache.xmlrpc.XmlRpcException; +import org.apache.xmlrpc.client.XmlRpcClient; +import org.apache.xmlrpc.client.XmlRpcClientConfigImpl; + +public class Ticket { + + private static final String ADDRESS = "http://cobra.cs.uni-duesseldorf.de/trac/xmlrpc"; + XmlRpcClient client = new XmlRpcClient(); + XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl(); + + int id; + String summary; + String type; + String description; + String reporter; + String priority; + String component; + String version; + String keywords; + String cc; + List<Attachment> attachments; + String sensitive; + + public Ticket(String reporter, String summary, String cc, + String description, Boolean sensitive) { + + this.sensitive = sensitive ? "1" : "0"; + this.id = 0; + this.summary = summary; + this.type = "defect"; + this.description = description; + this.reporter = reporter; + this.priority = "major"; + this.component = "Eclipse Plugin"; + this.version = ""; // get current version!? + this.keywords = "user discovered bug"; + this.cc = cc; + this.attachments = new ArrayList<Attachment>(); + + // Configuration + try { + this.config.setServerURL(new URL(ADDRESS)); + // this.config.setBasicUserName(USER_NAME); + // this.config.setBasicPassword(PASSWORD); + this.config.setConnectionTimeout(60 * 1000); + this.config.setReplyTimeout(3 * 60 * 1000); + + this.client.setConfig(this.config); + + } catch (MalformedURLException e) { + e.printStackTrace(); + } + } + + public void addAttachment(Attachment a) { + this.attachments.add(a); + } + + public void send() throws XmlRpcException { + + // "ticket.create" + String methodName = "ticket.create"; + + Hashtable<String, Object> attributes = new Hashtable<String, Object>(); + attributes.put("reporter", this.reporter); + attributes.put("type", this.type); + attributes.put("priority", this.priority); + attributes.put("component", this.component); + attributes.put("version", this.version); + attributes.put("keywords", this.keywords); + attributes.put("sensitive", this.sensitive); + attributes.put("cc", this.cc); + + Object[] params = new Object[] { this.summary, this.description, + attributes, true }; + // "true" means notify user by e-mail to affirm ticket's creation + + Integer ticketID; + ticketID = (Integer) this.client.execute(methodName, params); + this.id = ticketID.intValue(); + + // "ticket.putAttachment" + String methodName2 = "ticket.putAttachment"; + + for (Attachment a : this.attachments) { + // put single attachment to the ticket created even + String filename = a.getFilename(); + String path = a.getFilepath().toOSString(); + String attachmentDescription = a.getDescription(); + InputStream in; + + try { + in = new FileInputStream(path); + byte[] data; + data = readData(in); // -> IOException + Object[] params2 = new Object[] { this.id, filename, + attachmentDescription, data, true }; + String result; + result = (String) this.client.execute(methodName2, params2); + System.out.println("put Attachment " + result + + " to ticket ID " + this.id + "."); + } catch (XmlRpcException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + } + + } + + private byte[] readData(InputStream in) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + try { + byte[] buffer = new byte[512]; + while (true) { + int count = in.read(buffer); + if (count == -1) { + return out.toByteArray(); + } + out.write(buffer, 0, count); + } + } finally { + in.close(); + } + } + +} diff --git a/de.prob.ui/src/de/prob/ui/ticket/WizardPage1.java b/de.prob.ui/src/de/prob/ui/ticket/WizardPage1.java new file mode 100644 index 0000000000000000000000000000000000000000..57e2a9bea8cb2ea270383fc549f15be8e7030958 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ticket/WizardPage1.java @@ -0,0 +1,200 @@ +package de.prob.ui.ticket; + +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; + +public class WizardPage1 extends WizardPage { + private Composite container; + private Text textEmail; + private Text textSummary; + private Text textDescription; + private Button buttonPrivacy; + private Button buttonAddTrace; + private Boolean addTrace = true; + private Boolean privacy = false; + private String email = ""; + private String summary = ""; + private String description = ""; + + public WizardPage1(final String email, final String summary, + final String description, final Boolean addTrace, boolean sensitive) { + super("First Page"); + this.privacy = sensitive; + setTitle("Submit Bugreport"); + setDescription("Summary"); + + this.email = email; + this.summary = summary; + this.description = description; + this.addTrace = addTrace; + } + + public void createControl(final Composite parent) { + container = new Composite(parent, SWT.NULL); + GridLayout layout = new GridLayout(); + container.setLayout(layout); + layout.numColumns = 2; + + // Your Email: + Label labelEmail = new Label(container, SWT.NULL); + labelEmail.setText("Your email address:"); + textEmail = new Text(container, SWT.BORDER | SWT.SINGLE); + textEmail.setText(this.email); + textEmail.addKeyListener(new KeyListener() { + public void keyPressed(final KeyEvent e) { + } + + public void keyReleased(final KeyEvent e) { + setPageComplete(checkPageComplete()); + } + }); + + // Short Summary: + Label labelSummary = new Label(container, SWT.NULL); + labelSummary.setText("Short summary:"); + textSummary = new Text(container, SWT.BORDER | SWT.SINGLE); + textSummary.setText(this.summary); + textSummary.addKeyListener(new KeyListener() { + public void keyPressed(final KeyEvent e) { + } + + public void keyReleased(final KeyEvent e) { + setPageComplete(checkPageComplete()); + } + }); + + // Full Description: + Label labelDescription = new Label(container, SWT.NULL); + labelDescription.setText("Full description:"); + Label labelDummy = new Label(container, SWT.NULL); + labelDummy.setText(""); + textDescription = new Text(container, SWT.BORDER | SWT.MULTI | SWT.WRAP); + textDescription.setText(this.description); + + // Add trace: + Label labelAddTrace = new Label(container, SWT.NONE); + labelAddTrace.setText("Add debugging information:"); + buttonAddTrace = new Button(container, SWT.CHECK); + buttonAddTrace.setSelection(this.addTrace); + + buttonAddTrace.addSelectionListener(new SelectionListener() { + public void widgetDefaultSelected(final SelectionEvent arg0) { + } + + public void widgetSelected(final SelectionEvent arg0) { + addTrace = buttonAddTrace.getSelection(); + } + }); + + // Private: + Label labelPrivacy = new Label(container, SWT.NONE); + labelPrivacy.setText("Private:"); + buttonPrivacy = new Button(container, SWT.CHECK); + buttonPrivacy.setSelection(this.privacy); + + buttonPrivacy.addSelectionListener(new SelectionListener() { + public void widgetDefaultSelected(final SelectionEvent arg0) { + } + + public void widgetSelected(final SelectionEvent arg0) { + privacy = buttonPrivacy.getSelection(); + } + }); + + // Resize Text-Fields + GridData gd = new GridData(GridData.FILL_HORIZONTAL); + textEmail.setLayoutData(gd); + textSummary.setLayoutData(gd); + + gd = new GridData(GridData.FILL_BOTH); + gd.horizontalSpan = 2; + textDescription.setLayoutData(gd); + + // Required to avoid a system-error + setControl(container); + + setPageComplete(checkPageComplete()); + } + + @Override + /* + * Override setVisible(boolean visible)-Method of DialogPage to be enabled + * to set focus at will + */ + public void setVisible(final boolean visible) { + container.setVisible(visible); + + // Set Focus + if (!validateEmail(this.getEmail())) { + textEmail.setFocus(); + } else { + if (this.getSummary().equals("")) { + textSummary.setFocus(); + } else { + textDescription.setFocus(); + } + } + } + + private boolean checkPageComplete() { + Boolean emailValid = validateEmail(this.getEmail()); + Boolean summaryFilled = !textSummary.getText().equals(""); + + if (emailValid && summaryFilled) { + setErrorMessage(null); + return true; + } else { + if (!emailValid) { + setErrorMessage("Please enter a valid email address."); + return false; + } + if (!summaryFilled) { + setErrorMessage("Please enter a short summary of the bug."); + return false; + } + return false; + } + } + + private Boolean validateEmail(final String email) { + String regex = "[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?"; + Boolean emailValid = email.matches(regex); + return emailValid; + } + + public String getEmail() { + return textEmail.getText(); + } + + public String getSummary() { + return textSummary.getText(); + } + + public String getDetailedDescription() { + return textDescription.getText(); + } + + public Boolean isAddTrace() { + return addTrace; + } + + public Boolean isSensitive() { + return privacy; + } + + // private IConfigurationElement[] loadElements() { + // IExtensionPoint point = Platform.getExtensionRegistry() + // .getExtensionPoint("org.eclipse.ui", "installationPages"); //$NON-NLS-1$ //$NON-NLS-2$ + // return point.getConfigurationElements(); + // } +} diff --git a/de.prob.ui/src/de/prob/ui/ticket/WizardPage3.java b/de.prob.ui/src/de/prob/ui/ticket/WizardPage3.java new file mode 100644 index 0000000000000000000000000000000000000000..ffbf9509c8a6b08c63a7f49152b0a4f841193430 --- /dev/null +++ b/de.prob.ui/src/de/prob/ui/ticket/WizardPage3.java @@ -0,0 +1,241 @@ +package de.prob.ui.ticket; + +import java.io.IOException; +import java.util.ArrayList; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.TableEditor; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.swt.widgets.Text; + +public class WizardPage3 extends WizardPage { + private Composite container; + private Button buttonAdd; + private Button buttonDelete; + private Table tableAttachments; + private int columns; + + public WizardPage3() { + super("Third Page"); + setTitle("Submit Bugreport"); + setDescription("Add Attachments to Bugreport"); + } + + public void createControl(Composite parent) { + container = new Composite(parent, SWT.NULL); + GridLayout containerLayout = new GridLayout(); + containerLayout.numColumns = 2; + container.setLayout(containerLayout); + + // Files: + Label labelFiles = new Label(container, SWT.NULL); + labelFiles.setText("Files:"); + + tableAttachments = new Table(container, SWT.BORDER | SWT.MULTI + | SWT.FULL_SELECTION); + tableAttachments.setHeaderVisible(true); + String[] titles = { "Name", "Description" }; + columns = titles.length; + for (int i = 0; i < columns; i++) { + TableColumn column = new TableColumn(tableAttachments, SWT.NONE); + column.setText(titles[i]); // Header-Caption + switch (i) { + case 0: + column.setWidth(200); + break; + case 1: + column.setWidth(387); + } + } + + // Description: + + final TableEditor editor = new TableEditor(tableAttachments); + // The editor must have the same size as the cell and must + // not be any smaller than 50 pixels. + editor.horizontalAlignment = SWT.LEFT; + editor.grabHorizontal = true; + editor.minimumWidth = 50; + // editing the second column + final int EDITABLECOLUMN = 1; + + tableAttachments.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + + // Clean up any previous editor control + Control oldEditor = editor.getEditor(); + if (oldEditor != null) + oldEditor.dispose(); + + // Identify the selected row + TableItem item = (TableItem) e.item; + if (item == null) + return; + + // The control that will be the editor must be a child of the + // Table + Text newEditor = new Text(tableAttachments, SWT.NONE); + newEditor.setText(item.getText(EDITABLECOLUMN)); + newEditor.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent me) { + Text text = (Text) editor.getEditor(); + editor.getItem() + .setText(EDITABLECOLUMN, text.getText()); + Attachment a = (Attachment) editor.getItem().getData(); + a.setDescription(text.getText()); + } + }); + newEditor.selectAll(); + newEditor.setFocus(); + editor.setEditor(newEditor, item, EDITABLECOLUMN); + } + }); + + // Add file: + buttonAdd = new Button(container, SWT.PUSH); + buttonAdd.setText("Add file ..."); + buttonAdd.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + + IPath path = Platform.getLocation(); + + FileDialog dialog = new FileDialog(container.getShell(), + SWT.MULTI); + + dialog.setText("Add Attachment Files"); + dialog.setFilterPath(path.toOSString()); + dialog.setFilterNames(new String[] { "All Files", "Text Files", + "Image Files" }); + dialog.setFilterExtensions(new String[] { "*", + "*.txt;*.pdf;*.doc;*.docx", + "*.gif;*.png;*.jpg;*.jpeg;*.bmp;*.wmf;*.tiff" }); + + if (dialog.open() != null) { + String[] fileNames = dialog.getFileNames(); + IPath filterPath = new Path(dialog.getFilterPath()); + addAttachmentFiles(filterPath, fileNames); + } + } + }); + + // Delete attachment: + buttonDelete = new Button(container, SWT.PUSH); + buttonDelete.setText("Delete attachment"); + buttonDelete.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + // delete from displayed Table + tableAttachments.remove(tableAttachments.getSelectionIndices()); + } + }); + + GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true); + layoutData.grabExcessHorizontalSpace = true; + layoutData.grabExcessVerticalSpace = true; + layoutData.horizontalSpan = 2; + tableAttachments.setLayoutData(layoutData); + + // Required to avoid an error in the system + setControl(container); + + // to enable "Finish"-button not until this page was shown + setPageComplete(false); + } + + @Override + /* + * Override setVisible(boolean visible)-Method of DialogPage to be enabled + * to set focus at will + */ + public void setVisible(boolean visible) { + container.setVisible(visible); + + // Set Focus + buttonAdd.setFocus(); + + // now that this wizard page has been shown, the "Finish"-button may be + // enabled + setPageComplete(true); + } + + /** + * If a duplicate filename is chosen, an iterative number will be appended + * to the original filename. Thus the user can differ them in the Wizard + * Page shown. + * + * @param path + * @param fileNames + */ + protected void addAttachmentFiles(IPath path, String[] fileNames) { + // Examples: + // path: /Users/Marc/Downloads + // name: motogp.bmp + // filePath: /Users/Marc/Downloads/motogp.bmp + + for (String name : fileNames) { + IPath filePath = path.append(name); + String uniqueFileName = createUniqueFileName(name); + Attachment a; + try { + a = new Attachment(filePath.toOSString(), ""); + a.setFilename(uniqueFileName); + + TableItem item = new TableItem(tableAttachments, SWT.NONE); + item.setText(0, uniqueFileName); + item.setText(1, ""); + item.setData(a); + } catch (IOException e) { + e.printStackTrace(); + } + } + + } + + private String createUniqueFileName(String name) { + + StringBuilder uniqueName = new StringBuilder(name); + int counter = 1; + + for (TableItem item : this.tableAttachments.getItems()) { + if (item.getText(0).equals(name)) { + counter++; + } + } + + if (counter > 1) { + uniqueName.insert(uniqueName.lastIndexOf("."), "(" + counter + ")"); + } + + return uniqueName.toString(); + } + + public ArrayList<Attachment> getAttachments() { + ArrayList<Attachment> attachments = new ArrayList<Attachment>(); + + for (int i = 0; i < tableAttachments.getItemCount(); i++) { + attachments.add((Attachment) tableAttachments.getItem(i).getData()); + } + + return attachments; + } + +} diff --git a/de.prob.update_site/.project b/de.prob.update_site/.project new file mode 100644 index 0000000000000000000000000000000000000000..ddd7b57afddd1eeecaa7f00f6877ce31828b1ef8 --- /dev/null +++ b/de.prob.update_site/.project @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>de.prob.update_site</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.pde.FeatureBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.FeatureNature</nature> + </natures> +</projectDescription> diff --git a/de.prob.update_site/buckminster.properties b/de.prob.update_site/buckminster.properties new file mode 100644 index 0000000000000000000000000000000000000000..9d7bcbcf75396f1b2d3760e840fc257420f9ed75 --- /dev/null +++ b/de.prob.update_site/buckminster.properties @@ -0,0 +1,6 @@ +# Where all the output should go +buckminster.output.root=${user.home}/prob_updatesite +# Where the temp files should go +buckminster.temp.root=/tmp/prob_updatesite.tmp +# How .qualifier in versions should be replaced +qualifier.replacement.*=generator:lastRevision \ No newline at end of file diff --git a/de.prob.update_site/build.properties b/de.prob.update_site/build.properties new file mode 100644 index 0000000000000000000000000000000000000000..77674ccfa39d732d3f4bbedaf4be95c66b56f0fc --- /dev/null +++ b/de.prob.update_site/build.properties @@ -0,0 +1,4 @@ +bin.includes = feature.xml +category.id.de.prob.category=ProB for Rodin2 +category.members.de.prob.category=de.prob2.feature +category.description.de.prob.category=ProB Animator and Modelchecker \ No newline at end of file diff --git a/de.prob.update_site/feature.xml b/de.prob.update_site/feature.xml new file mode 100644 index 0000000000000000000000000000000000000000..2888f307eeda7dde8f80037215e1262aace973ec --- /dev/null +++ b/de.prob.update_site/feature.xml @@ -0,0 +1,235 @@ +<?xml version="1.0" encoding="UTF-8"?> +<feature + id="de.prob.update_site" + label="Update_site" + version="1.0.2"> + + <description url="http://www.stups.uni-duesseldorf.de/ProB"> + ProB is an animator and model checker for the B-Method. It allows +fully automatic animation of many B specifications, and can be +used to systematically check a specification for errors. +Part of the research and development was conducted within the +EPSRC funded projects ABCD and iMoc, and within the EU funded +project Rodin. +Development is continued under the EU funded project Deploy and +the DFG project Gepavas. +ProB has been successfully used on various industrial specifications +and is now being used within Siemens. + </description> + + <copyright> + (C) 2000-2011 Michael Leuschel (and many others) All rights reserved. + </copyright> + + <license url="http://www.eclipse.org/org/documents/epl-v10.html"> + ProB can be used freely for commercial, non-commercial and academic +use under the Eclipse Public Licence v. 1.0. (below) +For availability of commercial support, please contact the author +(http://www.stups.uni-duesseldorf.de/~leuschel). +Use of ProB's nauty library for symmetry reduction implies further +restrictions (no applications with nontrivial military significance, +see http://cs.anu.edu.au/~bdm/nauty/). +--- +Eclipse Public License - v. 1.0 +THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS +ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR +DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE +OF THIS AGREEMENT. +1. DEFINITIONS +"Contribution" means: +a) in the case of the initial Contributor, the initial code and +documentation distributed under this Agreement, and +b) in the case of each subsequent Contributor: +i) changes to the Program, and +ii) additions to the Program; +where such changes and/or additions to the Program originate +from and are distributed by that particular Contributor. A Contribution +'originates' from a Contributor if it was added to the Program +by such Contributor itself or anyone acting on such Contributor's +behalf. Contributions do not include additions to the Program +which: (i) are separate modules of software distributed in conjunction +with the Program under their own license agreement, and (ii) +are not derivative works of the Program. +"Contributor" means any person or entity that distributes the +Program. +"Licensed Patents" mean patent claims licensable by a Contributor +which are necessarily infringed by the use or sale of its Contribution +alone or when combined with the Program. +"Program" means the Contributions distributed in accordance with +this Agreement. +"Recipient" means anyone who receives the Program under this +Agreement, including all Contributors. +2. GRANT OF RIGHTS +a) Subject to the terms of this Agreement, each Contributor hereby +grants Recipient a non-exclusive, worldwide, royalty-free copyright +license to reproduce, prepare derivative works of, publicly display, +publicly perform, distribute and sublicense the Contribution +of such Contributor, if any, and such derivative works, in source +code and object code form. +b) Subject to the terms of this Agreement, each Contributor hereby +grants Recipient a non-exclusive, worldwide, royalty-free patent +license under Licensed Patents to make, use, sell, offer to sell, +import and otherwise transfer the Contribution of such Contributor, +if any, in source code and object code form. This patent license +shall apply to the combination of the Contribution and the Program +if, at the time the Contribution is added by the Contributor, +such addition of the Contribution causes such combination to +be covered by the Licensed Patents. The patent license shall +not apply to any other combinations which include the Contribution. +No hardware per se is licensed hereunder. +c) Recipient understands that although each Contributor grants +the licenses to its Contributions set forth herein, no assurances +are provided by any Contributor that the Program does not infringe +the patent or other intellectual property rights of any other +entity. Each Contributor disclaims any liability to Recipient +for claims brought by any other entity based on infringement +of intellectual property rights or otherwise. As a condition +to exercising the rights and licenses granted hereunder, each +Recipient hereby assumes sole responsibility to secure any other +intellectual property rights needed, if any. For example, if +a third party patent license is required to allow Recipient to +distribute the Program, it is Recipient's responsibility to acquire +that license before distributing the Program. +d) Each Contributor represents that to its knowledge it has sufficient +copyright rights in its Contribution, if any, to grant the copyright +license set forth in this Agreement. +3. REQUIREMENTS +A Contributor may choose to distribute the Program in object +code form under its own license agreement, provided that: +a) it complies with the terms and conditions of this Agreement; +and +b) its license agreement: +i) effectively disclaims on behalf of all Contributors all warranties +and conditions, express and implied, including warranties or +conditions of title and non-infringement, and implied warranties +or conditions of merchantability and fitness for a particular +purpose; +ii) effectively excludes on behalf of all Contributors all liability +for damages, including direct, indirect, special, incidental +and consequential damages, such as lost profits; +iii) states that any provisions which differ from this Agreement +are offered by that Contributor alone and not by any other party; +and +iv) states that source code for the Program is available from +such Contributor, and informs licensees how to obtain it in a +reasonable manner on or through a medium customarily used for +software exchange. +When the Program is made available in source code form: +a) it must be made available under this Agreement; and +b) a copy of this Agreement must be included with each copy of +the Program. +Contributors may not remove or alter any copyright notices contained +within the Program. +Each Contributor must identify itself as the originator of its +Contribution, if any, in a manner that reasonably allows subsequent +Recipients to identify the originator of the Contribution. +4. COMMERCIAL DISTRIBUTION +Commercial distributors of software may accept certain responsibilities +with respect to end users, business partners and the like. While +this license is intended to facilitate the commercial use of +the Program, the Contributor who includes the Program in a commercial +product offering should do so in a manner which does not create +potential liability for other Contributors. Therefore, if a Contributor +includes the Program in a commercial product offering, such Contributor +("Commercial Contributor") hereby agrees to defend and indemnify +every other Contributor ("Indemnified Contributor") against any +losses, damages and costs (collectively "Losses") arising from +claims, lawsuits and other legal actions brought by a third party +against the Indemnified Contributor to the extent caused by the +acts or omissions of such Commercial Contributor in connection +with its distribution of the Program in a commercial product +offering. The obligations in this section do not apply to any +claims or Losses relating to any actual or alleged intellectual +property infringement. In order to qualify, an Indemnified Contributor +must: a) promptly notify the Commercial Contributor in writing +of such claim, and b) allow the Commercial Contributor to control, +and cooperate with the Commercial Contributor in, the defense +and any related settlement negotiations. The Indemnified Contributor +may participate in any such claim at its own expense. +For example, a Contributor might include the Program in a commercial +product offering, Product X. That Contributor is then a Commercial +Contributor. If that Commercial Contributor then makes performance +claims, or offers warranties related to Product X, those performance +claims and warranties are such Commercial Contributor's responsibility +alone. Under this section, the Commercial Contributor would have +to defend claims against the other Contributors related to those +performance claims and warranties, and if a court requires any +other Contributor to pay any damages as a result, the Commercial +Contributor must pay those damages. +5. NO WARRANTY +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM +IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS +OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, +ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY +OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely +responsible for determining the appropriateness of using and +distributing the Program and assumes all risks associated with +its exercise of rights under this Agreement , including but not +limited to the risks and costs of program errors, compliance +with applicable laws, damage to or loss of data, programs or +equipment, and unavailability or interruption of operations. +6. DISCLAIMER OF LIABILITY +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT +NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE +OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGES. +7. GENERAL +If any provision of this Agreement is invalid or unenforceable +under applicable law, it shall not affect the validity or enforceability +of the remainder of the terms of this Agreement, and without +further action by the parties hereto, such provision shall be +reformed to the minimum extent necessary to make such provision +valid and enforceable. +If Recipient institutes patent litigation against any entity +(including a cross-claim or counterclaim in a lawsuit) alleging +that the Program itself (excluding combinations of the Program +with other software or hardware) infringes such Recipient's patent(s), +then such Recipient's rights granted under Section 2(b) shall +terminate as of the date such litigation is filed. +All Recipient's rights under this Agreement shall terminate if +it fails to comply with any of the material terms or conditions +of this Agreement and does not cure such failure in a reasonable +period of time after becoming aware of such noncompliance. If +all Recipient's rights under this Agreement terminate, Recipient +agrees to cease use and distribution of the Program as soon as +reasonably practicable. However, Recipient's obligations under +this Agreement and any licenses granted by Recipient relating +to the Program shall continue and survive. +Everyone is permitted to copy and distribute copies of this Agreement, +but in order to avoid inconsistency the Agreement is copyrighted +and may only be modified in the following manner. The Agreement +Steward reserves the right to publish new versions (including +revisions) of this Agreement from time to time. No one other +than the Agreement Steward has the right to modify this Agreement. +The Eclipse Foundation is the initial Agreement Steward. The +Eclipse Foundation may assign the responsibility to serve as +the Agreement Steward to a suitable separate entity. Each new +version of the Agreement will be given a distinguishing version +number. The Program (including Contributions) may always be distributed +subject to the version of the Agreement under which it was received. +In addition, after a new version of the Agreement is published, +Contributor may elect to distribute the Program (including its +Contributions) under the new version. Except as expressly stated +in Sections 2(a) and 2(b) above, Recipient receives no rights +or licenses to the intellectual property of any Contributor under +this Agreement, whether expressly, by implication, estoppel or +otherwise. All rights in the Program not expressly granted under +this Agreement are reserved. +This Agreement is governed by the laws of the State of New York +and the intellectual property laws of the United States of America. +No party to this Agreement will bring a legal action under this +Agreement more than one year after the cause of action arose. +Each party waives its rights to a jury trial in any resulting +litigation. + </license> + + <includes + id="de.prob2.feature" + version="0.0.0"/> + +</feature> diff --git a/de.prob2.feature/.project b/de.prob2.feature/.project new file mode 100644 index 0000000000000000000000000000000000000000..c8a53cbb4c5c20015575f87a893128db72115371 --- /dev/null +++ b/de.prob2.feature/.project @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>de.prob2.feature</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.pde.FeatureBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.FeatureNature</nature> + </natures> +</projectDescription> diff --git a/de.prob2.feature/build.properties b/de.prob2.feature/build.properties new file mode 100644 index 0000000000000000000000000000000000000000..64f93a9f0b7328eb563aa5ad6cec7f828020e124 --- /dev/null +++ b/de.prob2.feature/build.properties @@ -0,0 +1 @@ +bin.includes = feature.xml diff --git a/de.prob2.feature/feature.xml b/de.prob2.feature/feature.xml new file mode 100644 index 0000000000000000000000000000000000000000..81d4f462c012aba6b636f36baa64edbfa935d4ce --- /dev/null +++ b/de.prob2.feature/feature.xml @@ -0,0 +1,288 @@ +<?xml version="1.0" encoding="UTF-8"?> +<feature + id="de.prob2.feature" + label="ProB for Rodin2" + version="2.2.6" + provider-name="HHU Düsseldorf STUPS Group"> + + <description url="http://www.stups.uni-duesseldorf.de/ProB"> + ProB is an animator and model checker for the B-Method. It allows fully automatic animation of many B specifications, and can be used to systematically check a specification for errors. +Part of the research and development was conducted within the EPSRC funded projects ABCD and iMoc, and within the EU funded project Rodin. +Development is continued under the EU funded project Deploy and the DFG project Gepavas. +ProB has been successfully used on various industrial specifications and is now being used within Siemens. + </description> + + <copyright> + (C) 2000-2011 Michael Leuschel (and many others) All rights reserved. + </copyright> + + <license url="http://www.eclipse.org/org/documents/epl-v10.html"> + ProB can be used freely for commercial, non-commercial and academic +use under the Eclipse Public Licence v. 1.0. (below) +For availability of commercial support, please contact the author +(http://www.stups.uni-duesseldorf.de/~leuschel). +Use of ProB's nauty library for symmetry reduction implies further +restrictions (no applications with nontrivial military significance, +see http://cs.anu.edu.au/~bdm/nauty/). +--- +Eclipse Public License - v. 1.0 +THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS +ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR +DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE +OF THIS AGREEMENT. +1. DEFINITIONS +"Contribution" means: +a) in the case of the initial Contributor, the initial code and +documentation distributed under this Agreement, and +b) in the case of each subsequent Contributor: +i) changes to the Program, and +ii) additions to the Program; +where such changes and/or additions to the Program originate +from and are distributed by that particular Contributor. A Contribution +'originates' from a Contributor if it was added to the Program +by such Contributor itself or anyone acting on such Contributor's +behalf. Contributions do not include additions to the Program +which: (i) are separate modules of software distributed in conjunction +with the Program under their own license agreement, and (ii) +are not derivative works of the Program. +"Contributor" means any person or entity that distributes the +Program. +"Licensed Patents" mean patent claims licensable by a Contributor +which are necessarily infringed by the use or sale of its Contribution +alone or when combined with the Program. +"Program" means the Contributions distributed in accordance with +this Agreement. +"Recipient" means anyone who receives the Program under this +Agreement, including all Contributors. +2. GRANT OF RIGHTS +a) Subject to the terms of this Agreement, each Contributor hereby +grants Recipient a non-exclusive, worldwide, royalty-free copyright +license to reproduce, prepare derivative works of, publicly display, +publicly perform, distribute and sublicense the Contribution +of such Contributor, if any, and such derivative works, in source +code and object code form. +b) Subject to the terms of this Agreement, each Contributor hereby +grants Recipient a non-exclusive, worldwide, royalty-free patent +license under Licensed Patents to make, use, sell, offer to sell, +import and otherwise transfer the Contribution of such Contributor, +if any, in source code and object code form. This patent license +shall apply to the combination of the Contribution and the Program +if, at the time the Contribution is added by the Contributor, +such addition of the Contribution causes such combination to +be covered by the Licensed Patents. The patent license shall +not apply to any other combinations which include the Contribution. +No hardware per se is licensed hereunder. +c) Recipient understands that although each Contributor grants +the licenses to its Contributions set forth herein, no assurances +are provided by any Contributor that the Program does not infringe +the patent or other intellectual property rights of any other +entity. Each Contributor disclaims any liability to Recipient +for claims brought by any other entity based on infringement +of intellectual property rights or otherwise. As a condition +to exercising the rights and licenses granted hereunder, each +Recipient hereby assumes sole responsibility to secure any other +intellectual property rights needed, if any. For example, if +a third party patent license is required to allow Recipient to +distribute the Program, it is Recipient's responsibility to acquire +that license before distributing the Program. +d) Each Contributor represents that to its knowledge it has sufficient +copyright rights in its Contribution, if any, to grant the copyright +license set forth in this Agreement. +3. REQUIREMENTS +A Contributor may choose to distribute the Program in object +code form under its own license agreement, provided that: +a) it complies with the terms and conditions of this Agreement; +and +b) its license agreement: +i) effectively disclaims on behalf of all Contributors all warranties +and conditions, express and implied, including warranties or +conditions of title and non-infringement, and implied warranties +or conditions of merchantability and fitness for a particular +purpose; +ii) effectively excludes on behalf of all Contributors all liability +for damages, including direct, indirect, special, incidental +and consequential damages, such as lost profits; +iii) states that any provisions which differ from this Agreement +are offered by that Contributor alone and not by any other party; +and +iv) states that source code for the Program is available from +such Contributor, and informs licensees how to obtain it in a +reasonable manner on or through a medium customarily used for +software exchange. +When the Program is made available in source code form: +a) it must be made available under this Agreement; and +b) a copy of this Agreement must be included with each copy of +the Program. +Contributors may not remove or alter any copyright notices contained +within the Program. +Each Contributor must identify itself as the originator of its +Contribution, if any, in a manner that reasonably allows subsequent +Recipients to identify the originator of the Contribution. +4. COMMERCIAL DISTRIBUTION +Commercial distributors of software may accept certain responsibilities +with respect to end users, business partners and the like. While +this license is intended to facilitate the commercial use of +the Program, the Contributor who includes the Program in a commercial +product offering should do so in a manner which does not create +potential liability for other Contributors. Therefore, if a Contributor +includes the Program in a commercial product offering, such Contributor +("Commercial Contributor") hereby agrees to defend and indemnify +every other Contributor ("Indemnified Contributor") against any +losses, damages and costs (collectively "Losses") arising from +claims, lawsuits and other legal actions brought by a third party +against the Indemnified Contributor to the extent caused by the +acts or omissions of such Commercial Contributor in connection +with its distribution of the Program in a commercial product +offering. The obligations in this section do not apply to any +claims or Losses relating to any actual or alleged intellectual +property infringement. In order to qualify, an Indemnified Contributor +must: a) promptly notify the Commercial Contributor in writing +of such claim, and b) allow the Commercial Contributor to control, +and cooperate with the Commercial Contributor in, the defense +and any related settlement negotiations. The Indemnified Contributor +may participate in any such claim at its own expense. +For example, a Contributor might include the Program in a commercial +product offering, Product X. That Contributor is then a Commercial +Contributor. If that Commercial Contributor then makes performance +claims, or offers warranties related to Product X, those performance +claims and warranties are such Commercial Contributor's responsibility +alone. Under this section, the Commercial Contributor would have +to defend claims against the other Contributors related to those +performance claims and warranties, and if a court requires any +other Contributor to pay any damages as a result, the Commercial +Contributor must pay those damages. +5. NO WARRANTY +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM +IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS +OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, +ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY +OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely +responsible for determining the appropriateness of using and +distributing the Program and assumes all risks associated with +its exercise of rights under this Agreement , including but not +limited to the risks and costs of program errors, compliance +with applicable laws, damage to or loss of data, programs or +equipment, and unavailability or interruption of operations. +6. DISCLAIMER OF LIABILITY +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT +NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE +OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGES. +7. GENERAL +If any provision of this Agreement is invalid or unenforceable +under applicable law, it shall not affect the validity or enforceability +of the remainder of the terms of this Agreement, and without +further action by the parties hereto, such provision shall be +reformed to the minimum extent necessary to make such provision +valid and enforceable. +If Recipient institutes patent litigation against any entity +(including a cross-claim or counterclaim in a lawsuit) alleging +that the Program itself (excluding combinations of the Program +with other software or hardware) infringes such Recipient's patent(s), +then such Recipient's rights granted under Section 2(b) shall +terminate as of the date such litigation is filed. +All Recipient's rights under this Agreement shall terminate if +it fails to comply with any of the material terms or conditions +of this Agreement and does not cure such failure in a reasonable +period of time after becoming aware of such noncompliance. If +all Recipient's rights under this Agreement terminate, Recipient +agrees to cease use and distribution of the Program as soon as +reasonably practicable. However, Recipient's obligations under +this Agreement and any licenses granted by Recipient relating +to the Program shall continue and survive. +Everyone is permitted to copy and distribute copies of this Agreement, +but in order to avoid inconsistency the Agreement is copyrighted +and may only be modified in the following manner. The Agreement +Steward reserves the right to publish new versions (including +revisions) of this Agreement from time to time. No one other +than the Agreement Steward has the right to modify this Agreement. +The Eclipse Foundation is the initial Agreement Steward. The +Eclipse Foundation may assign the responsibility to serve as +the Agreement Steward to a suitable separate entity. Each new +version of the Agreement will be given a distinguishing version +number. The Program (including Contributions) may always be distributed +subject to the version of the Agreement under which it was received. +In addition, after a new version of the Agreement is published, +Contributor may elect to distribute the Program (including its +Contributions) under the new version. Except as expressly stated +in Sections 2(a) and 2(b) above, Recipient receives no rights +or licenses to the intellectual property of any Contributor under +this Agreement, whether expressly, by implication, estoppel or +otherwise. All rights in the Program not expressly granted under +this Agreement are reserved. +This Agreement is governed by the laws of the State of New York +and the intellectual property laws of the United States of America. +No party to this Agreement will bring a legal action under this +Agreement more than one year after the cause of action arose. +Each party waives its rights to a jury trial in any resulting +litigation. + </license> + + <requires> + <import plugin="fr.systerel.explorer" version="1.3.2" match="equivalent"/> + <import plugin="org.eclipse.ui.navigator" version="3.4.0" match="compatible"/> + <import plugin="org.eclipse.core.databinding" version="1.2.0" match="compatible"/> + <import plugin="org.eclipse.jface.databinding" version="1.2.1" match="compatible"/> + <import plugin="org.eclipse.core.databinding.beans" version="1.1.1" match="compatible"/> + <import plugin="org.eclipse.ui.views.properties.tabbed" version="3.4.1" match="compatible"/> + <import plugin="de.prob.ui" version="7.1.0" match="equivalent"/> + <import plugin="de.prob.core" version="9.1.0" match="equivalent"/> + <import plugin="org.eclipse.core.databinding.property" version="1.2.0" match="compatible"/> + <import plugin="org.eclipse.ui" version="3.5.0" match="compatible"/> + <import plugin="org.eclipse.core.runtime" version="3.5.0" match="compatible"/> + <import plugin="org.eclipse.jface.text" version="3.5.0" match="compatible"/> + <import plugin="org.eclipse.ui.editors" version="3.5.0" match="compatible"/> + <import plugin="org.eclipse.ui.views" version="3.4.1" match="compatible"/> + <import plugin="org.rodinp.core" version="1.3.1"/> + <import plugin="org.eclipse.gef" version="3.5.0" match="compatible"/> + <import plugin="org.eclipse.ui.ide" version="3.5.0" match="compatible"/> + <import plugin="org.eventb.core" version="2.1.0"/> + <import plugin="org.rodinp.keyboard" version="1.1.0" match="equivalent"/> + <import plugin="org.eclipse.jface" version="3.6.0" match="greaterOrEqual"/> + <import plugin="org.eclipse.ui" version="3.6.0" match="greaterOrEqual"/> + <import plugin="org.eclipse.core.resources" version="3.5.0" match="compatible"/> + <import plugin="org.eclipse.core.expressions" version="3.4.101" match="compatible"/> + </requires> + + <plugin + id="de.bmotionstudio.gef.editor" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="de.prob.core" + download-size="0" + install-size="0" + version="0.0.0"/> + + <plugin + id="de.prob.plugin" + download-size="0" + install-size="0" + version="0.0.0" + fragment="true" + unpack="false"/> + + <plugin + id="de.prob.ui" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="de.bmotionstudio.rodin" + download-size="0" + install-size="0" + version="0.0.0" + fragment="true" + unpack="false"/> + +</feature>