This website uses cookies for visitor traffic analysis. By using the website, you agree with storing the cookies on your computer.More information

VisionX 2.4 u2 is out

We're happy to announce VisionX 2.4 Update Release 2. It's another milestone for us.

The new version is a bugfix release with some important features for all our customers. The top bug was a missing license check for our HTML5 implementation. With older versions it was possible to use our HTML5 application without valid license. This wasn't a hidden feature, it was a real bug. The new version has a clean license check and some of you will need a new license. This is no problem, simply contact us.

What's new?

  • Full-Screen mode

    Press F12 to maximize VisionX without frame border.

  • HTML5 Live preview options

    It supports "application per session", custom UI factory, custom Application setups, main, config and externalCss URL parameter.

  • VisionX is now http session ready

    It will be possible to use VisionX on server-side as backend for remote application development.

  • Fixed Copy/Paste for DnD fields

    It's now possible to Copy/Paste into field with DnD support.

  • Automatic UI tests

    VisionX now supports automatic UI tests with an optional AddOn. The mechanism isn't limited to our AddOn. It's also possible to create custom Modules/AddOns.

  • Tibero Database support

    VisionX has built-in support for Tibero Database (tested with version 6).

  • Auto-restart feature

    VisionX got a Preloader. This allows custom libraries without manually changing the classpath. The old classpath mechanism is still available, but we use the Preloader by default.

  • Action Editor with custom editor support

    It's now possible to add custom editors in the action editor via action.xml and/or a custom module.

  • GridLayout support

    It's now possible to use panels with GridLayout, if set in Source Code.

  • Custom vaadin widgetsets and themes

    It's now possible to create custom vaadin widgetsets, e.g. add an AddOn from the Vaadin Directory. It's super easy to create a custom theme and setting your custom css attributes.

  • Performance improvement

    We reduced the fetch calls during screen creation. This will improve performance with big tables and complex views.

  • New modules, AddOns and demo applications (optional)

    The VaadinAddon can be used to create a custom widgetset or theme. The AppTeste is an automatic UI test tool. There is a new demo application for testing Validators. The new reporting demo application will show all features of our reporting engine.

  • Configurable EPlug ports

    It's now possible to configure the EPlug communication ports via system properties.

  • Better Application signing

    Our signing mechanism now supports TSA Urls, Proxies, signing algorithms and much more.

  • Service module merging

    Newly created applications will automatically merge service modules. This is an important bugfix for e.g. the profiles module.

The new version is available in your download area or as Trial version.

VisionX Update Release for 2.4

We have awesome news for you. We'll release the 2nd update of VisionX 2.4 by the end of this week!

The update will come with some new features and many bugfixes. The most important feature is that all open source libraries were updated. You'll have access to new APIs and new feautres of all libraries. VisionX itself got some bugfixes regarding the visual designer. A great new feature is the support for AddOns with access to VisionX. It'll be possible to customize VisionX for your needs.

We also have some new AddOns and Demo Applications e.g. the VaadinAddOn which enables you to create your own vaadin widgetset/theme in seconds.

The 2.4 release of VisionX will be the last version with Vaadin 7 because we already work with Vaadin 8.1 in our development branches.

We'll also change the version number of VisionX with our next release. Instead of 2.5, it'll be 5.0.

Why?

Because VisionX is very mature and the version number 2 doesn't fit. The next release will be a major change because VisionX will contain Vaadin 8.1 and this library requires Java 8, so also our VisionX projects will require Java 8. This isn't a big change, because VisionX itself comes with Java 8. The difference is the project configuration for your IDE.

All planned changes shouldn't be a problem for you, because Java 9 is out and Java 8 is the Java version you should use for your projects. The Java version won't make any difference for our Oracle Forms users because our JVx library will be built with Java 6 - no changes for you.

Wordpress/Contact Form 7 post request to Java Servlet

This article is an upgraded version of Joomla/RSForms post request to Java Servlet.

The use case is the same: Calling a Java Servlet, after submitting a form. The servlet should read the form data and start e.g. the creation of a license file.

The form plugin Contact Form 7 is very popular for Wordpress. It's powerful and easy to use.

But sadly, it doesn't support custom php scripts, only custom Javascript calls. So it's possible to add custom javascript calls with predefined hooks. Not exactly what we want because Javascript functions run on client side and not in the same context as the php backend.

It wasn't possible to implement missing features without coding php, but it was not tricky.

What we did to call a Java Servlet?

1. Register a custom module

Modified wp-content/plugins/contact-form-7/settings.php

public static function load_modules() {
    ...
    self::load_module( 'submit' );
    self::load_module( 'text' );
    self::load_module( 'textarea' );
    self::load_module( 'hidden' );

    self::load_module( 'sibvisions' );
}

Added load_module('sibvisions');

2. Create the new module

Created wp-content/plugins/contact-form-7/modules/sibvisions.php

<?php
/**
 ** Module for SIB Visions.
 **/

add_action('wpcf7_submit', 'wpcf7_sibvisions_submit', 10, 2);

function wpcf7_sibvisions_submit($contactform, $result)
{
    if ($contactform->in_demo_mode() || $contactform->is_true('do_not_store'))
    {
        return;
    }

    $servletURL = $contactform->additional_setting('sib_servletURL');

    if (empty($servletURL[0]))
    {
        error_log('Servlet URL is not set in form!');
        return;
    }

    $cases = (array)apply_filters('wpcf7_sibvisions_submit_if',
                                  array('spam', 'mail_sent', 'mail_failed'));

    if (empty($result['status']) || ! in_array($result['status'], $cases ))
    {
        return;
    }

    $submission = WPCF7_Submission::get_instance();

    if (!$submission || ! $posted_data = $submission->get_posted_data())
    {
        return;
    }

    if (isset($posted_data['g-recaptcha-response']))
    {
        if (empty($posted_data['g-recaptcha-response']))
        {
            return;
        }
    }

    $fields_senseless = $contactform->scan_form_tags(
                                        array('feature' => 'do-not-store'));

    $exclude_names = array();

    foreach ( $fields_senseless as $tag )
    {
        $exclude_names[] = $tag['name'];
    }

    $exclude_names[] = 'g-recaptcha-response';

    foreach ($posted_data as $key => $value)
    {
        if ('_' == substr($key, 0, 1) || in_array($key, $exclude_names))
        {
            unset($posted_data[$key]);
        }
    }

    $url = str_replace('"', "", $servletURL[0]);
    $url = str_replace("'", "", $url);

    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
    //curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
    //curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);

    $data = array();

    foreach ($posted_data as $post => $value)
    {
        if (is_array($value))
        {
            foreach ($value as $post2 => $value2)
            {
                $data[] = $post.'[]='.urlencode($value2);
            }
        }
        else
        {
            $data[] = $post.'='.urlencode($value);
        }
    }

    curl_setopt($ch, CURLOPT_POSTFIELDS, implode('&', $data));
 
    $data = curl_exec($ch);

    if (curl_errno($ch))
    {
        wp_mail('noreply@sibvisions.com', 'Service error',
                'Call to service ('.$url.') failed with error ('.curl_error($ch).')');
    }
    else
    {
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE)
       
        if ($http_code != 200)
        {
            wp_mail('noreply@sibvisions.com', 'Service error',
                    'Call to service ('.$url.') failed with error ('.$data.')');
        }
    }
   
    curl_close($ch);
}

The script is based on module flamingo.php because it had all useful validations.

Be careful, because the script will be applied to all your forms. It's form independent.

3. Additional setting

The only thing you'll need is am additional setting (for your form):

sib_servletURL:'https://server/services/registration'

This setting configures the servlet to use for the form. If you don't configure a servlet, the module will do nothing!

DONE

The new module will forward all form data to the servlet. The servlet is the same as in our original article - no changes needed.

JVx Vaadin UI and Vaadin 8.1

Our JVx Vaadin UI is based on vaadin 7.7.9 right now. It works great but vaadin moves forward in big steps. The latest 8.1 release contains many new features and bugfixes. Not all fixes were backported to vaadin 7. This is bad but clear for us.

So we should switch to vaadin 8.1?

This isn't an easy task because vaadin 8 has some new APIs and vaadin moved some parts like FontAwesome to new AddOns. The ContextMenu AddOn was compatible up to vaadin 7, but 8 needs the new official ContextMenu AddOn. The data bindings will work with 8 but needs a compatibility layer.

But anyway, we decided to start the migration and will do everything step-by-step. The first task will do the update of all our vaadin projects to Java 8 and vaadin 8.1. The next step will do the integration of v7 compatibility layer and the following tasks will fix all other problems like ContextMenu, FontAwesome, changed APIs. It's a bigger project and we hopefully will be finished by the end of October.

This blog post is a notice for our vaadin UI users!

We'll keep you up to date :)

Full-Screen Mode for JVx applications

If you have a JVx application and want to use it without the frame border, it's not supported out-of-the-box. Sometimes it's very useful to have a full-screen application or to grab a screenshot without frame.

We now support this feature for Swing based applications but not in the official UI API. Here's a code snippet:

//F12 for toggling mode
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new KeyEventDispatcher()
{
      @Override
      public boolean dispatchKeyEvent(KeyEvent e)
      {
          if (e.getKeyCode() == KeyEvent.VK_F12)
          {
              if (ObjectCache.get("FULLSCREEN") == null)
              {
                  ObjectCache.put("FULLSCREEN", Boolean.TRUE, 500);
                 
                  SwingApplication app = (SwingApplication)getLauncher();
                  app.setFullScreen(!app.isFullScreen());
                 
                  return true;
              }
             
              return false;
          }
         
          return false;
      }
});

The trick with FULLSCREEN is necessary because the event fires sometimes more than once.

Simply press F12 key to toggle between Fullscreen/Frame mode.

Vaadin AddOn for VisionX

We have a new AddOn for all VisionX users. It's the Vaadin AddOn.

The new AddOn makes it possible to integrate Vaadin AddOns from the official Vaadin AddOn Directory. It makes the integration super simple because we solved the technical problems. The AddOn does all the hard work for you and after two button clicks, everything is done.

With our new AddOn, we introduced more new VisionX features. In the next update release, it will be possible to create AddOns which have access to VisionX itself. Use the internal DataBooks or the Designer, the WizardManager and all other APIs. It'll be possible to create your own VisionX based on VisionX!

Also new is the automatic restart feature. It's possible to restart VisionX after installing an AddOn or Module with a simple button click. This feature is the base for automatic VisionX updates. Currently, we don't update VisionX automatically, but we think it will be nice for one of the next versions.

Get an impression

Vaadin AddOn for VisionX

The AddOn is commercial and not included in VisionX. Contact our sales team to get more information!

DOAG 2017

Auch in diesem Jahr sind wir wieder auf der DOAG anzutreffen. Details zur Veranstaltung.

Neu ist, das wir mit 3 Vorträgen vertreten sind:

  • Transformation: Fachbereich & IT digitalisieren gemeinsam
  • Low Code Plattform – A Web & Mobile UI Live Coding Session
  • Pimp your Forms - Forms Modernisierung mit Java

Nähere Details zu den Vorträgen, sind demnächst im Vortragsprogramm zu finden.

GUI Testing with VisionX

A new AddOn for VisionX is coming :)

Our GUI testing tool

A first impression

Application tester

Application tester

The tool is a recorder for VisionX/JVx applications. It has an option to export created tests as JUnit tests which makes it easy for Software developers to integrate the GUI tests in their CI systems. It's a super easy tool with so much value for you!

The App Tester will be available in our solution store and will be an AddOn for VisionX.

If you are interested in details, leave a comment.

VisionX 2.4 update I is out

VisionX 2.4 update release I is out. The exact version number is 2.4.544.310.
It's a powerful update release becasue it contains latest versions of relevant opensource libraries and frameworks.

What's new?

  • Thumbnails

    If application contains a thumbnail, VisionX won't add a random thumbnail anymore.

  • HTML5 Theme

    It's now possible to change the HTML5 theme via web settings: Standard, Valo, Mobile

    Web settings

    Web settings

  • Live preview

    Live preview does now work if you apply external changes or if you change the source code in Eclipse (with installed EPlug).

  • GridLayout is now supported

    The GridLayout of JVx is now officially supported in VisionX' Designer.

  • Vaadin 7.7.9

    VisionX updates contains Vaadin 7.7.9.

  • Solution store update

    The solution store now shows available solutions based on your VisionX version.

  • New demo solutions

    We have awesome new demo applications for licensed users.

    Demo applications

    Demo applications

  • New Reporting demo

    The reporting demo is a complete documentation about VisionX reporting features and the reporting API.

    Reporting

    Reporting

    Report overview

    Report overview

  • Smaller bugfixes

All customers will find the new version in their download area!
The trial version was updated as well!

Alexa, shutter control

It's time for some words about my "shutter control" side project.

My house has electrical roller shutters with remote control units for every window. It was/is possible to close and open the shutters with these remote control units without any problems. But it wasn't possible to open/close them automatically because I don't own a central control unit. I'm not sure if such a central control unit is available for my "old" receiver modules?
Anyway, I'm a researcher and builder. So I built a central control unit based on a Raspberry Pi. I wrote about it in the past:

In the meantime, the project got a lux sensor to close the shutter if it's dark outside and it recognizes public holidays for later opening. It's not a good idea to open shutters on public holidays at 6 am :) The whole project is working very stable and it's so useful!

A few months ago, I heard about Google Home and Amazon Echo because both systems offer Voice control. I thought that voice control would be an awesome feature for my shutter control because sometimes it happens that my smartphone or remote control units are not at hand. And voice control is faster than using a smartphone or remote control. The only problem was that Google Home and Amazon Echo weren't available in Austria, not for German language and I didn't find any information about their APIs and whether if it's possible to develop addons. ... Sometimes you have to wait...

Things have changed in the meantime and both devices have APIs but only Amazon Echo is available for German language. I read some test reviews about both devices and Amazon is the pioneer. It supports more 3rd party devices than Home and looks proven. I had no preferences for Echo or Home, but Echo was available. The decision was simple :)

I made some simple tests with Echo because I tried to find out if it's really useful to have such a thing at home. And for sure, it is. It works really great and saves time :) It's great as replacement for standard radios or to stream your favourite music. It's also nice to listen to daily news or the weather forecast. A nice feature is the alarm clock!

But enough, it's a nice and useful device which simply works. The idea was voice control of my roller shutters.

Amazon Echo allows developers to create AddOns. Such AddOns are called Skills. It's not trivial but also not complex to create a custom Skill. The getting started is well documented and more documentation is available online. A developer forum exists and is active enough. It's really no problem to start but some pieces of the puzzle are unclear. I didn't find a detailed technical overview or didn't search long enough. It also was unclear where the Skills will be executed. I thought a skill is like an app and runs directly on the device... This was not the case.

Amazon Echo is a simple client and sends all requests to the amazon cloud. It handles responses but the brain is in the cloud. This means that all your services must be in the cloud. It's not a problem to host your own services in your own infrastrcuture but all your services have to be available via Internet. It's not possible to access a server in your Intranet directly. It's not possible to tweak with custom router configurations or custom dns records. Your services have to be available as cloud services. I found many solutions with service proxies or request forwarding but I didn't like this solutions because my home network is private.

But this was the only limitation and not really a problem because we have technologies like MQTT. I didn't use MQTT in the past but read a lot about it. The problem was that I didn't have a use-case for it. This was changed with Echo.

I played around with Mosquitto some hours and after TLS with and without user certificates were working, I was ready for connecting my shutter client. I don't write about my Mosquitto configuration here because there are so many good blog entries available in the wild.
It might be interesting that I use Eclipse paho as Java client library.

Ooh... and this utility class was really helpful. It made it possible to communicate secure to my Mosquitto broker. The class didn't support authentication without user certificate and it didn't read from InputStreams, but it was a good starting point. It also didn't work in with my Jetty application server. Here's a snippet of my code:

public static SSLSocketFactory getSocketFactory(Object pCACrt, Object pCrt,
                                Object pKey, String pPassword)
{
    try
    {
        // Load Certificate Authority (CA) certificate
        PEMParser reader = new PEMParser(createReader(pCACrt));
        X509CertificateHolder caCertHolder = (X509CertificateHolder)reader.readObject();
        reader.close();

        JcaX509CertificateConverter conv = new JcaX509CertificateConverter();
       
        X509Certificate caCert = conv.getCertificate((X509CertificateHolder)caCertHolder);
       
        // CA certificate is used to authenticate server
        KeyStore caKeyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        caKeyStore.load(null, null);
        caKeyStore.setCertificateEntry("ca-certificate", caCert);

        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
                                TrustManagerFactory.getDefaultAlgorithm());
        trustManagerFactory.init(caKeyStore);
       
        // Create SSL socket factory
        SSLContext context = SSLContext.getInstance("TLSv1.2");

        if (exists(pCrt))
        {
            // Load client certificate
            reader = new PEMParser(createReader(pCrt));
            X509CertificateHolder certHolder = (X509CertificateHolder)reader.readObject();
            reader.close();

            X509Certificate cert = conv.getCertificate(certHolder);

            // Load client private key
            reader = new PEMParser(createReader(pKey));
            Object keyObject = reader.readObject();
            reader.close();

            PEMDecryptorProvider provider = new JcePEMDecryptorProviderBuilder().
                                build(pPassword.toCharArray());
            JcaPEMKeyConverter keyConverter = new JcaPEMKeyConverter().setProvider("BC");

            KeyPair key;

            if (keyObject instanceof PEMEncryptedKeyPair)
            {
                key = keyConverter.getKeyPair(((PEMEncryptedKeyPair)keyObject).
                                decryptKeyPair(provider));
            }
            else
            {
                key = keyConverter.getKeyPair((PEMKeyPair)keyObject);
            }

            // Client key and certificates are sent to server so it can authenticate
            // the client
            KeyStore clientKeyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            clientKeyStore.load(null, null);
            clientKeyStore.setCertificateEntry("certificate", cert);
            clientKeyStore.setKeyEntry("private-key", key.getPrivate(),
                                pPassword.toCharArray(), new Certificate[] { cert });

            KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(
                                KeyManagerFactory.getDefaultAlgorithm());
            keyManagerFactory.init(clientKeyStore, pPassword.toCharArray());
           
            context.init(keyManagerFactory.getKeyManagers(),
                                trustManagerFactory.getTrustManagers(), null);
        }
        else
        {
            context.init(null, trustManagerFactory.getTrustManagers(), null);
        }

        return context.getSocketFactory();
    }
    catch (Exception e)
    {
        throw new RuntimeException(e);
    }
}

So, the communication via MQTT was configured and ready to use. The next step was the creation of a Skill. Echo supports using external services via https. The Skills-API comes with a special Servlet, the SpeechletServlet. You have to extend this servlet for every service. This creates boilerplate code because the servlet does nothing special. It usually configures the Speechlet. A Speechlet is more or less the main class for your service. So I decided to create a generic Servlet:

public class GenericServlet extends SpeechletServlet
{
    public void init(ServletConfig pConfig) throws ServletException
    {
        String sSpeechlet = pConfig.getInitParameter("speechlet");
       
        try
        {
            Class<?> clazz = Class.forName(sSpeechlet);
           
            Object obj = clazz.newInstance();
           
            if (obj instanceof Speechlet)
            {
                setSpeechlet((Speechlet)obj);
            }
            else
            {
                setSpeechlet((SpeechletV2)obj);
            }
        }
        catch (Exception e)
        {
            throw new ServletException("Can't init speechlet, e");
        }
       
        super.init(pConfig);
    }

}   // GenericServlet

Simple configuration in web.xml and no additional servlets needed:

<servlet>
    <servlet-name>ShutterService</servlet-name>
    <servlet-class>com.sibvisions.alexa.services.GenericServlet</servlet-class>

  <init-param>
    <param-name>speechlet</param-name>
    <param-value>com.sibvisions.alexa.services.shutter.ShutterSpeechlet</param-value>
  </init-param>
</servlet>

The Skill itself doesn't need source code. Amazon offers a web UI for the configuration and a simple test tool. The creation was straight forward and I simply followed an example from the Skills-API package. One tricky step was the certificate configuration, but Amazon supports self-signed certificates and wildcard certificates without problems. So, the Skill creation was done very fast because everything was done online without coding.

The custom service creation wasn't very difficult because the API is really simple and doesn't need more than implementing 4 interface methods:

@Override
public void onSessionStarted(SessionStartedRequest pRequest, Session pSession) throws SpeechletException
{
}

@Override
public void onSessionEnded(SessionEndedRequest pRequest, Session pSession) throws SpeechletException
{
}

@Override
public SpeechletResponse onIntent(IntentRequest pRequest, Session pSession) throws SpeechletException
{
    Intent intent = pRequest.getIntent();
   
    String intentName = (intent != null) ? intent.getName() : null;

    TranslationMap tmap = getTranslation(pRequest);
   
    if ("DownIntent".equals(intentName)
        || "UpIntent".equals(intentName)
        || "HaltIntent".equals(intentName))
    {
        String sText;

        try
        {
            if ("DownIntent".equals(intentName))
            {
                client.down();
               
                sText = "The shutters are moving down!";
            }
            else if ("UpIntent".equals(intentName))
            {
                client.up();
               
                sText = "The shutters are moving up!";
            }
            else
            {
                client.halt();
               
                sText = "The shutters are stopping!";
            }
        }
        catch (Exception e)
        {
            sText = "Shutter control not possible!";
        }
       
        sText = tmap.translate(sText);
       
        // Create the Simple card content.
        SimpleCard card = new SimpleCard();
        card.setTitle(tmap.translate("Shutter control"));
        card.setContent(sText);

        // Create the plain text output.
        PlainTextOutputSpeech speech = new PlainTextOutputSpeech();
        speech.setText(sText);

        return SpeechletResponse.newTellResponse(speech, card);
    }
    else
    {
        throw new SpeechletException(tmap.translate("Invalid intent!"));
    }
}

@Override
public SpeechletResponse onLaunch(LaunchRequest pRequest, Session pSession) throws SpeechletException
{
    TranslationMap tmap = getTranslation(pRequest);
   
    String sText = tmap.translate("Here we go!");
   
    // Create the Simple card content.
    SimpleCard card = new SimpleCard();
    card.setTitle(tmap.translate("Shutter control"));
    card.setContent(sText);

    // Create the plain text output.
    PlainTextOutputSpeech speech = new PlainTextOutputSpeech();
    speech.setText(sText);

    PlainTextOutputSpeech repromptSpeech = new PlainTextOutputSpeech();
    repromptSpeech.setText(tmap.translate("Tell me the direction!"));
   
    Reprompt reprompt = new Reprompt();
    reprompt.setOutputSpeech(repromptSpeech);

    return SpeechletResponse.newAskResponse(speech, reprompt, card);
}

It's also possible to use Amazons infrastructure for your services, but I have my own application server.

After some days, my roller shutters were controlled by Amazon Echo aka Alexa with voice commands. It was really cool and simple!

Here's a demonstration of the result (it's in German):

Alexa in action

I can only recommend this device!