Categories
Enterprise Application Development

WaveMaker Prefabs – A Primer

What are Prefabs?
In WaveMaker Studio, you would have noticed this unassuming group of components that are stashed in the Design-Toolbox accordion and contains components like Youtube, Google-Maps and Fbpost under it.(Fig-1).  These group of widgets are called Prefabs.

But what are they?  What’s their purpose of existence? These are exactly the kind of questions that we will try to answer in this post.

At a very basic level,  Prefab is nothing but an application.  Like an application, you can develop, test and deploy these Prefabs independently.  User can stack up a group of Prefabs and build a new app.  Prefabs typically represent a small independent logical business need of the enterprise app (a micro app).  For example, an Event Management Prefab.


How are Prefabs structured?
Structurally a Prefab is like any other WaveMaker app containing a UI layer for presentation, a backend layer representing the business logic and a REST API layer between them for communication.  (see Fig-2)

For example, the Fbpost Prefab, provided by default in WaveMaker Studio,  has a UI layer, wherein it accepts inputs from the user to post a message into the user’s Facebook wall, passes on these user inputs through REST APIs to the backend business logic, which communicates with the Facebook server to post the message.

Prefabs fosters the concept of reuse

I have already explained on how Prefabs are just micro-applications that can represent an independent business logic like Event-Management.  But in explaining that one important point would have got lost, if not for this section on reuse.  This Event-Management Prefab once created can be re-used across any apps within an enterprise.  This concept of REUSE is a very powerful one and is often not given its due share of importance in an application building process.

Prefabs abstract API consumption complexity
Prefabs are essential tools in abstracting the complexity associated with API consumption and saving a lot of time.  Business developers in an enterprise usually find it difficult to understand the intricacies of the APIs because of the technical nature of its existence.  In the example above, instead of using a Fbpost Prefab, if the user had to directly work with the Facebook APIs, then that immediately increases the complexity associated with the task manifold.  API complexities range from understanding technologies like OAUTH for authentication to understanding the semantics associated with APIs itself.  But what if these complexities are abstracted and presented as simple intuitive UI components? …that is exactly what a Prefab does.  Of course, there is an one time effort in creating the Prefab itself, but WaveMaker envisions an app and Prefab marketplace where these common utility Prefabs can be just got out of the box and integrated into the app.

Prefabs to assemble your apps
Composable Enterprise, a concept where the applications are built based on the composition of decoupled services to achieve higher levels of agility, is a concept that is gaining prominence.  You can learn more about composable enterprise model in this blog written by Jonathan Murray, EVP and Chief Technology Officer of Warner Music Group.  WaveMaker uses a Prefab to ease the process of building composable apps.

In WaveMaker, Prefabs are used like any other UI widgets.  All that user has to do is to drag and drop these Prefabs onto the canvas.  Prefabs use their REST API layer to communicate with the parent app (see Fig-3).  Applications can be built as stackable layers of Prefabs.

And finally, when an application gets deployed, WaveMaker resolves all the Prefab dependencies of the app and deploys the app as one single component into a Docker  container as shown in Fig-4.

All the REST APIs in the Prefab can also be published for sharing and consumption by other apps.  This is similar to design and sharing of APIs in an app and is done using API Designer.  If you are interested you can read my earlier blog post that talks about the capabilities of the API designer in detail.

Prefabs to integrate 3rd party widgets
Prefabs are powerful tools for extending the capabilities of the WaveMaker Studio.  Whenever the developer feels that a particular widget, available externally,  is not available natively in the WaveMaker Studio library, he or she can immediately integrate that external 3rd party widget into WaveMaker Studio library using Prefabs.  Prefabs in a way extend the capabilities of the studio through this approach.  In one of my earlier blog, I had explained in detail on how you can integrate an external 3rd party Jquery widget.

Prefabs as Microservices [#]
Microservices (MSA) is a new (yet another!) software development architecture, which is gaining prominence.  In this approach, a bigger app is built as a composition of  small decoupled services, called Microservices, which typically represents an independent business need.  These micro-apps are connected together by APIs (primarily HTTP/REST APIs) to build a bigger app.  These Microservices also have technical characteristics that include independent testability, deployability and upgradeability. For a more detailed explanation of MSA, you can checkout Martin Fowler’s article on Microservices here.

By now you would have noticed that Prefabs perfectly fit into the definition of a Microservice as defined above, word for word. As WaveMaker takes its next step into the future to enable Microservice based apps, Prefabs will play a significant role to ease the process of creating and deploying MSA based apps.

Checkout the sample reference architecture (Fig-5) of an MSA app created using WaveMaker and Prefabs deployed into separate Docker containers in WaveMaker Cloud platform.

Prefabs ecosystem [#]
Prefab is a great utility for achieving modularity, reusability and abstracting complexity in WaveMaker,  but it’s not free lunch either.  There is a one time effort that is involved in creating a Prefab before the user and the enterprise can reap its benefits.  But to even reduce this one time creation step, a simple effective utility, which has revolutionized the way inwhich people consume services in this digital world, can be used.  This utility is called a MarketPlace or an AppStore.  Once an ecosystem of the commonly used Prefabs and apps is established, the consumption of these Prefabs will be as easy as discovering the Prefabs in the AppStore and integrating it into your app.

Checkout the below image that captures the overall prefabs usage succinctly.

Prefabs can be quite a powerful tool if used strategically and can make the concept of composable enterprise come true very easily.  Excited to try Prefabs? Create your WaveMaker app now!

Key
[#] – Planned for future releases

Categories
Enterprise Application Development

Import data from MS-Excel documents into WaveMaker

Microsoft Excel is the most widely used spreadsheet application around the globe and in this post we will see how to import data from an Excel file into a grid widget of WaveMaker Studio.  For reading the Excel file we will be using Apache POI libraries.

Scope of this blog

  1. We will be creating a Prefab to upload an Excel file and display it using the grid widget in an application.
  2. The Excel file is assumed to have a particular structure with heading in its top row as shown below.
  3. This post  covers only the basic Excel integration, restricted to the reading and displaying the spreadsheet data in a grid widget.  We use a Java service for reading the Excel file.
  4. By modifying the provided Java service, one can implement more complex Excel integration using Apache POI libraries and methods.

Steps involved in WaveMaker-Excel integrations:

  1. Download the latest version of Apache POI library from HERE.
  2. Create a new “Prefab” Project.  I call it ReadWriteExcel (though I just demonstrate only Excel reading 🙂 ).  I will have another post for exporting Excel documents in the future.
    1. Import the following jars into WaveMaker
      Note: The JAR names could be different depending on the POI release you had downloaded.  I had downloaded Apache POI 3.11.

      1. poi-3.11-20141221.jar
      2. poi-ooxml-3.11-20141221.jar
      3. poi-ooxml-schemas-3.11-20141221.jar
      4. commons-codec-1.9.jar  (in $POI_HOME/lib directory)
      5. xmlbeans-2.6.0.jar (in $POI_HOME/ooxml-lib directory)
    2. Create a Java Service (I call it XLSReaderWriter). This java service uses the APIs provided by the Apache POI libraries, reads the excel file and outputs the content as a JSON object.  The Java service code is given below..
      /*Copyright (c) 2015-2016 wavemaker-com All Rights Reserved.This software is the confidential and proprietary information of wavemaker-com You shall not disclose such Confidential Information and shall use it only in accordance with the terms of the source code license agreement you entered into with wavemaker-com*/
      
      package com.readwriteexcel.xlsxreaderwriter;
      
      import com.wavemaker.runtime.javaservice.JavaServiceSuperClass;
      import com.wavemaker.runtime.service.annotations.ExposeToClient;
      
      
      import java.io.InputStream; 
      import java.io.FileNotFoundException;
      import java.io.IOException; 
      import java.util.Iterator;
      import java.util.*; 
      
      import org.apache.poi.ss.usermodel.Cell;
      import org.apache.poi.ss.usermodel.Row;
      import org.apache.poi.ss.usermodel.Workbook;
      import org.apache.poi.ss.usermodel.Sheet;
      
      import org.json.JSONArray;
      import org.json.JSONObject;
      import org.json.JSONException;
      
      import org.springframework.beans.factory.annotation.Autowired;
      import com.wavemaker.runtime.server.upload.FileUploadDownload;
      import com.wavemaker.runtime.server.*;
      import org.apache.poi.ss.usermodel.WorkbookFactory;
      import com.wavemaker.runtime.*;
      import javax.servlet.http.*;
      
      /**
       * This is a client-facing service class.  All
       * public methods will be exposed to the client.  Their return
       * values and parameters will be passed to the client or taken
       * from the client, respectively.  This will be a singleton
       * instance, shared between all requests. 
       * 
       * To log, call the superclass method log(LOG_LEVEL, String) or log(LOG_LEVEL, String, Exception).
       * LOG_LEVEL is one of FATAL, ERROR, WARN, INFO and DEBUG to modify your log level.
       * For info on these levels, look for tomcat/log4j documentation
       */
      @ExposeToClient
      public class XLSXReaderWriter extends JavaServiceSuperClass {
          @Autowired
          FileUploadDownload fileUpload;
      
          /* Pass in one of FATAL, ERROR, WARN,  INFO and DEBUG to modify your log level;
           *  recommend changing this to FATAL or ERROR before deploying.  For info on these levels, look for tomcat/log4j documentation
           */
          public XLSXReaderWriter() {
             super(INFO);
          }
      
          public void readExcel(String fileName, HttpServletResponse response ) {
              String resultString = null;
              Workbook book = null;
              InputStream fis = null;
              try {
      
                  log(INFO, "inside readExcel"); 
                  
                  DownloadResponse dresponse = fileUpload.downloadFile(fileName,fileName);
                  fis = dresponse.getContents();
                  
                  book = WorkbookFactory.create(fis);
                  Sheet sheet = book.getSheetAt(0);
                  
      			// Start constructing JSON.
      			JSONObject json = new JSONObject();
      			
                  Iterator<Row> itr = sheet.iterator();
      
      			// Iterate through the rows.
      			JSONArray rows = new JSONArray();
      
                  // Iterating over Excel file in Java
      			int rowCount = 0;
      			ArrayList<String> headerList = new ArrayList<String>();
                  while (itr.hasNext()) {
                      Row row = itr.next();
      				JSONObject jRow = new JSONObject();
                      log(INFO, "inside row iterator");
      				// Iterate through the cells.
                      // Iterating over each column of Excel file
                      Iterator<Cell> cellIterator = row.cellIterator();
                      int cellCount = 0;
      				while (cellIterator.hasNext()) {
                          log(INFO, "inside cell iterator");
      
                          Cell cell = cellIterator.next();
                          JSONObject jCellObj = new JSONObject();
                          switch (cell.getCellType()) {
                          case Cell.CELL_TYPE_STRING:
      						if(rowCount == 0) 
      							headerList.add(cell.getStringCellValue());
      						else{
      							jRow.put((String)headerList.get(cellCount),cell.getStringCellValue()); 
      							log(INFO,cell.getStringCellValue() + "t");
      						}
                              break;
                          case Cell.CELL_TYPE_NUMERIC:
      						jRow.put((String)headerList.get(cellCount),cell.getNumericCellValue()); 
      						log(INFO,cell.getNumericCellValue() + "t");
                              break;
                          case Cell.CELL_TYPE_BOOLEAN:
      						jRow.put((String)headerList.get(cellCount),cell.getBooleanCellValue()); 
      						log(INFO,cell.getBooleanCellValue() + "t");
                              break;
                          default:
                              jRow.put((String)headerList.get(cellCount),""); 
          
                          }
      					cellCount++;
                      }
      				if(rowCount == 0) {
      					rowCount++;
      					continue;
      				}
      				rows.put( jRow );
                      
                  }
      	        // Get the JSON text.
      	        resultString = rows.toString();
      			response.setContentType("application/json");
      			response.getOutputStream().write(resultString.getBytes("UTF-8"));
      			response.getOutputStream().flush();
          
              } catch (FileNotFoundException fe) {
                  fe.printStackTrace();
                  log(ERROR, "The sample java service operation has failed", fe);
              } catch (IOException ie) {
                  ie.printStackTrace();
                  log(ERROR, "The sample java service operation has failed", ie);
              } catch (JSONException je) {
                  je.printStackTrace();
                  log(ERROR, "The sample java service operation has failed", je);
              } catch (Exception ex) {
                  ex.printStackTrace();
                  log(ERROR, "The sample java service operation has failed", ex);
              }finally{
                  try{
                      if(book != null){
                      book.close();
                      }
                      if(fis != null){
                        fis.close();
                      }
                      
                  }catch(IOException e){
                      //swallow this
                  }
              }
              
      		
          }    
      
      
      }
      
    3. Design UI to consume the JSON object from java service and show it as a grid.
      1. Use File upload widget to allow user to select the excel file.  I call it “Select File & Load Grid”
        Select the required upload directory.  The file will be saved in this directory in runtime.  You can checkout the uploaded file “Employee.xlsx” – in the /resources/uploads directory after using the file-upload widget in runtime.
      2. Edit the java service variable (XLSReaderWriterReadExcel) and bind the filename variable to the filename from the fileupload widget, as shown below. Also make sure to enable the “Auto Update” property for this variable
      3. Drag and drop a  grid and bind it to the Java service variable created from the previous step.(i.e. XLSReaderWriterReadExcel)
    4. This is a fully functional Prefab and can be tested like any other application. Go ahead, run the application, and test it.
    5. Export prefab as zip file, to use it in various applications.
  3. You can use this prefab in any other project by importing the prefab zip file into any project.  Try it out.
Categories
Enterprise Application Development

Integrating third-party UI widgets into Studio using Prefabs

A common request among WaveMaker Studio developers is to integrate third-party UI widgets inside WaveMaker Studio and make them available as drag-and-drop  components.  This task becomes especially challenging when we consider the fact that the WaveMaker Studio uses AngularJS technology for defining its widgets and the third-party widget may be using another technology like jQuery.  In this blog post, we will take a use case-based approach to see how a jQuery-based third-party widget is integrated with WaveMaker Studio.  For achieving this, we will leverage Studio’s very own superstar component  – Prefab – and demonstrate its power of customization.

Use case

Lets take Lightbox image viewer widget and see how users can integrate this widget into WaveMaker Studio using Prefabs.   This widget is jQuery-based and this link gives the details about how to use the Lightbox widget in general.

Steps to integrate Lightbox widget into WaveMaker Studio

The detailed steps to create this Prefab, export it and use it any WaveMaker Studio project are given below.

1.  Get the widget library source code: Download the Lightbox resource files from here and unzip it into a folder

/integrating-third-party-ui-widgets-using-prefabs/

2. Import the relevant js, css and image files into WaveMaker Studio.  In case of Lightbox widget, the details are given in the step-1 of “How to use” section in the Lightbox project home page.

The imported files can be seen under the folders js, css and image.

3. Set the Bindable Properties for the Prefab: Go to the newly introduced “Prefabs Properties” section under the project “Settings” and add references to the imported js under script section, css under the style section and an icon  file.  Add the bindable properties that are needed for this Prefab. In this example, we have added  “image” and “title” properties that represent the location and title of the image to be displayed.

These properties will appear in the properties panel of the Prefab, once it is drag and dropped into the WYSIWYG canvas.

Checkout the WaveMaker Prefabs documentation to get complete details about this new feature.

4. Design the Prefab UI: Drag and drop the “picture” widget to display the image thumbnail  and bind the “Hint” and “Source” attributes to the “title” and “image” properties respectively that you had defined in the previous step.

And finally, step-2 of “How to use” section of Lightbox documentation instructs the user to embed the images inside an anchor tag(<a>…</a>) & also add a “data-lightbox” attribute, to activate the widget.  In the Studio we can do this by adding the above details in the “Markup” section, as shown below.

5.  Export the Prefab using the Export menu item in Studio (see Fig-7).  Make sure you have tested the Prefab before you export it.

6. Import the Prefab and use it as any other component inside an app.  To demonstrate the Lightbox Prefab usage, lets  create a demo app called “ImageViewer” and import the Lightbox Prefab.  Once it is imported you can spot the LightboxPrefab in the Prefabs accordion section.

7. Perform the following customary steps in the Studio to integrate the LightboxPrefab:

a. Import the sample DB provided with WaveMaker Studio
b. Drag and drop a Live-List widget into the canvas and bind it to the dataset of “HRdbEmployeeData” live variable that got created automatically after import of sample DB.
c. Delete the  “panel1” created under the “listtemplate1”.
d. Drag and drop the lightbox prefab into the “listtemplate1” and bind the image “Source” property to “Variables.HrdbEmployeeData.dataSet.picurl” and the title to “Variables.HrdbEmployeeData.dataSet.firstName”

We are all set now.  Run the application and see how the Lightbox image viewer functionality executes successfully.

The above approach of using Prefabs can be applied successfully to integrate any third-party UI widgets into WaveMaker Studio instantly, providing the needed customization inside Studio.

Try it out with your widget of choice and let us know how it went.  Send your experience of integrating your custom widget to feedback@wavemaker.com.

References
Lightbox: lokesh dhakar projects – lightbox2

Karthick Viswanathan
Product & Customer-Success Manager