Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
TomVanDoo
Active Contributor

I'm a sucker for any new technology. Even more so when it revolves around SAP. So lately, I've really been pampered with a bunch of new hot 'n sexy stuff. I kinda stumbled into the NetWeaver Cloud technology (NEO) and while I was looking into that, rui.nogueira 's blog also pointed me into SAPUI5's direction.

2 brand spankin' new technologies! I'm having a field trip here.

The first problem of course, is getting up to speed with both of these technologies. There are already some nice tutorials and blogs out there to get you started, but the finer tricks can only be figured out by getting your hands dirty.

First stop was CodeJam Huizen where the experts would be present, so I could get some inside info. After that, I was on my own.

Hobby project

Anytime you want to learn something new, you need a working project. Something you can get up and running pretty quickly, and extend later on to try out new stuff. I worked together with tim.guest in the past to create a mobile SCN Reader concept, which we got working, but a lot of functionality was missing and we were blocked on the lack of an SCN API. Stil, the concept was nice, so I decided to redo it, but this time using all SAP technology.

I uploaded the package to my google drive for now. I'll try to update it as I progress and discover more tips 'n tricks.

Backend transformation

Consuming information from SCN can be done via RSS feeds. jason.lax doesn't know it, but he gave me a tremendous help by creating a document on all of SCN's feeds. RSS data is a bit hard to consume in SAPUI5 (I'm pretty sure it's possible), but I thought it would be way nicer to create a proxy on NEO which would convert the XML into JSON. It fits in a lot better with the "Mobile First" idea. So I created a Servlet which holds a generic proxy to read in feed data and transform it into JSON. This also solves the possible problems with cross site scripting. Modern browsers do not allow you to consume services from a different domain, than the one the page you are visiting belongs to.

In the doGet, we insert following code:

        //create URL   
        try {
                  String address = request.getParameter("address");
                        URL url = new URL(address);
            // Read all the text returned by the server
            BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
            StringBuilder fullResponse = new StringBuilder();
            String str;
            while ((str = in.readLine()) != null) {
                // str is one line of text; readLine() strips the newline character(s)
                        fullResponse.append(str);            
            }
            in.close();
            JSONObject jsonObj = org.json.XML.toJSONObject(fullResponse.toString());
            response.getWriter().println( jsonObj.toString() );
        }
        catch (MalformedURLException e) {
                  response.getWriter().println(e);
        }
        catch (JSONException e){
                  response.getWriter().println(e);        
        }
        catch (IOException e) {
                  response.getWriter().println(e);              
        }

All the JSON statements come from the library found on JSON.Org and are included with the import statement:

import org.json.*;

Once you deploy the servlet, you can fetch JSON feeds by simply calling the servlet with the feed url as parameter (escaped of course)

ex: http://server.domain/scnReader/FeedMe?address=http:%2F%2Fscn.sap.com%2Fblogs%2Ffeeds%2Fposts

SAPUI5 Layout

In order to create a basic front-end layout, I based myself on the introduction blog to SAP UI5 and NEO. Afterwards I decided to rework it following the MVC principle. So far, nothing new, except for the fact that I really had a lot of work just getting through these basic steps.

I created a simple shell, with one workitem (Blogs) (see shell.view.js and shell.controller.js), which contained a BlogList view (which was nothing more but a table). (see bloglist.view.js)

The fun started when I had to connect the front-end to the back-end and consume the info coming from the FeedMe servlet. So in the bloglist controller, I had to bind a JSON model to my table. (see bloglist.controller.js)

    onInit : function() {
              var sServiceUrl = "/scnReader/FeedMe?address=http:%2F%2Fscn.sap.com%2Fblogs%2Ffeeds%2Fposts";
              if(!this.getView().getModel()){
                        var oModel = new sap.ui.model.json.JSONModel(sServiceUrl);
                        this.getView().setModel(oModel);
                        sap.ui.getCore().byId("tblBlogs").bindRows("rss/channel/item");
                 }
    },

In the OnInit, we create a new JSON model, which gets its info from our FeedMe servlet. The model is then bound to our view. The rows of the table in our view, can then be bound to the items in the JSON feed. Sounds easy enough, but the real trick is the path to feed's property. You have to use the forward slash as path separator. It's only thanks to steinermatt  that I figured this out.

If we would run this already, we would get a nice list of the last 15 blogs on SCN:

* The strange characters are caused by some blogs written in Chinese or at least, a language with none ASCII characters.

Obviously, the titles alone are not enough, so we want to be able to click through to the contents. In order to do so, we need a simple contents view that holds an HTML area and a back button. The back button requires a binding to an event handler so we can navigate back to the blog list later on. (See blogcontent.view.js and blogcontent.controller.js)

Navigation

If we want to be able to navigate from the list to the contents, then we need an event handler on "RowClick" which will determine for which blog, we want to show the contents, and transfer us to the next view. Coming from the WebDynpro world, I'm used to defining my navigation in a declarative way. Just binding outbound plugs to inbound plugs, and then firing the right plug when you want to navigate. In SAPUI5, I couldn't find any navigation API yet, so I decided to mimic the WebDynpro approach instead.

I created a navigation function, which takes in the target view, target plug, the view name (ID which you want it to be known by), the event parameters and maybe the model information. (if you want to pass that)

function navigate(viewName, targetView, targetPlug, oEvent, oModel){
          var oShell = sap.ui.getCore().byId("scnReaderShell");
          var oView = sap.ui.getCore().byId(viewName);
          var oCtrl = null;
//        instantiate the content view if it doesn't exist yet
          if (!oView) {
              oView = sap.ui.view({
                              type : sap.ui.core.mvc.ViewType.JS,
                              id : viewName,
                              viewName : targetView
              });
              if(oModel){
//                      bind it to the same model
                        oView.setModel(oModel );              
              }
          }
          if(oView != null){
                    oCtrl = oView.getController();
          }
          if(oCtrl != null){
//                  Navigate to the content view
                    oCtrl[targetPlug](oEvent);
          }
//       show the view
          oShell.setContent(oView,true);
          return oCtrl;
}

We bind the onRowSelect event of our bloglist table to an event handler in our bloglist controller, and fire our navigation to the contents. Notice how we pass the model information from our list to the contents view, because we need of course the information available in our feed.

    onRowSelect : function(oEvent) {
//            navigate to the contents of the blog, pass model along
              navigate("vwBlogcontent", "scnReader.view.blogcontent", "inBound", oEvent, this.oParent.getModel());
    },

In the contents controller, we then just have to retrieve the reference to the blog we wanted to read, and bind it's feed description to our HTML area

    inBound: function(oEvent ){
                    var oContext = oEvent.getParameter("rowContext");
                    var bindpath = oContext + "/description";
                    this.setContent(bindpath);
    },
    setContent: function(bindpath){
                    var id = "htmlBlog";
                    var model = this.oView.getModel();
                    var core = sap.ui.getCore();
                    if (core) var elem = core.byId(id);
                    if (elem){
                              elem.setContent( model.getProperty(bindpath) );
                    }    
    },

We also bind our back button to an event handler which will navigate to the list again.

    back: function(oEvent ){
//           Navigate back to the list, Don't change the model    
              navigate("vwBlogList", "scnReader.view.bloglist", "inBound", oEvent, null);
    }

The result will show us our blogcontents in a nice SAPUI5 formatting.

Up to now it's still pretty basic, and you still can't like nor rate blogs. I don't even know if this will ever be possible. The SCN team is pondering about exposing REST services for this end, so maybe that will come. Until that time, I'll just continue to expand my little learning project with comments, discussions etc...

The main things that I wanted to share here are:

  • JSON model binding
  • Navigation in SAPUI5
  • Feed transformation in NEO
4 Comments
Labels in this area