Friday, September 23, 2011

Dojo Charts

Dojo comes with an amazing charting library, in the form of dojox.charting. You can create various 2D chart, 3D Chart, Pie, Animated Chart. Follow link : http://docs.dojocampus.org/dojox/charting/

Sample html code for Columns chart using dojo :
<html>   
    <head>
        <script src="http://ajax.googleapis.com/ajax/libs/dojo/1.6/dojo/dojo.xd.js" djConfig="parseOnLoad: true">
        </script>
        <script type="text/javascript">
            dojo.require("dojox.charting.Chart2D");
            dojo.addOnLoad(function() {
                var c = new dojox.charting.Chart2D("chartOne",{
                    title: "Revenue per year",
                    titlePos: "bottom",
                    titleGap: 5,
                    titleFont: "normal normal normal 15pt Arial",
                    titleFontColor: "orange"
                });

                c.addPlot("default",{type: "Columns", gap: 5, minBarSize: 3, maxBarSize: 20})
                .addAxis("x", {
                    fixLower: "major",
                    fixUpper: "minor",
                    labels: [{value: 1, text: "Item1"}, {value: 2, text: "Item2"},{value: 3, text: "Item3"}]})
                .addAxis("y", {
                    title: "Revenue ($ Million)",
                    vertical: true,
                    fixLower: "major",
                    fixUpper: "major",
                    includeZero: true})
                .addSeries("Series A",
                    [{y: 4, color: "red"},{y: 2, color: "green"},{y: 6, color: "blue"}]);
                c.render();
            });
        </script>
    </head>
    <body>
        <div id="chartOne" style="width: 400px; height: 240px; margin: 30px auto 0px auto;">
        </div>
    </body>
</html>

Thursday, September 15, 2011

AJAX proxy

AJAX proxy is required to connect several different target hosts and make cross domain calls. As browsers don't allow to send ajax request to different host other than origin server so, there is a need of intermediate server side handler to serve request.
In websphere either you can add Ajax proxy capability in your own project or you can use websphere default Global Ajax proxy.

The global proxy configuration of the portal is located in a separate enterprise application that is deployed during the portal installation. The corresponding enterprise application archive is named AJAX Proxy Configuration.ear. The file proxy-config.xml that represents the global configuration is located in the WAR file wp.config.proxy.war.
To update the global proxy configuration, redeploy the enterprise application archive that contains the modified proxy-config.xml file and restart it. You do not need to restart the entire portal server.
For security reasons the global proxy configuration does not define any specific access policies. In other words, by default, the proxy blocks each request unless you add access policies to "unlock" your trusted sites.

AJAX proxy configurations file (proxy-config.xml) allows you to create specific access policy to restrict the set of allowed HTTP operations
You can also configure AJAX proxy to support single sign-on, the configuration makes the proxy forward the respective LTPA and JSessionID cookies.

URL format to use proxy is
<protocol>://<portal-domain>/<proxyurl>/<protocol>/<host>%3a<port>/<url>?<query>
Examples
Refer to the following sample proxy URLs. They show how you can load a URL via the proxy depending on the context path mapping in the proxy configuration.
URL: http://www.ibm.com/developerworks/news/dw_dwtp.rss
Context path mapping (from proxy-config.xml): <mapping contextpath="/proxy" url="*"/>
Proxy URL: http://myportal.com:10040/wps/proxy/http/www.ibm.com/developerworks/news/dw_dwtp.rss

You can also specify timeout in proxy-config.xml, this will be applicable to each proxy:policy urls
i.e.
<proxy:meta-data>
<proxy:name>connection-timeout</proxy:name>
<proxy:value>600000</proxy:value>
</proxy:meta-data>

Proxy also support http basic authentication and you can also automate passing user/password using jquery
To support http basic authentication modify proxy-config.xml
<proxy:policy acf="none" url="http://<url>/*" basic-auth-support="true">
To pass user/password using jquery use this :
<script language="JavaScript">
$.ajax({
type: "GET",
cache: false,
dataType: "xml",
url: "http://localhost:10039/.MEMCREST/proxy/http/some.com/getresult",
username: 'username',
password: 'password',
success: function(data) {
var $xml = $(data);
//iterate $xml and generate html markup
},
error : function(jqXHR, textStatus, errorThrown) {
alert("error: "+textStatus);
}
});
</script>

Lets say you want to access youtube channel content inside your webpage, do the following :
1) Edit proxy-config.xml file add followling lines so that only url which start from http://www.youtube.com/user/* will be served from this proxy
<?xml version="1.0" encoding="UTF-8"?><proxy:proxy-rules xmlns:proxy="http://www.ibm.com/xmlns/prod/sw/ajax/proxy-config/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <proxy:mapping contextpath="/proxy" url="*"/>
    <proxy:policy acf="none" url="http://www.youtube.com/user/*">
        <proxy:actions>
            <proxy:method>GET</proxy:method>
            <proxy:method>POST</proxy:method>
        </proxy:actions>
    </proxy:policy>
</proxy:proxy-rules>
2) Call youtube url using proxy, I have used here Jquery ajax
<script src="http://code.jquery.com/jquery-latest.js"></script>
<div id="results"></div>
<script language="JavaScript">
    $.ajax({
         type: "GET",
         cache: false,
         url: "http://localhost:10039/.YouTubeChannel/proxy/http/www.youtube.com/user/BoxOffice", //Requesting to proxy to get response from youtube
         success: function(html) {
             $("#results").append(html);
        },
        error : function(jqXHR, textStatus, errorThrown) {
            alert("error: "+textStatus);
        }
   });
</script>

For More Info Visit IBM Infocenter link : http://publib.boulder.ibm.com/infocenter/wpdoc/v6r1/topic/com.ibm.wp.ent.doc_v6101/dev/ajax_proxy.html

Tuesday, September 13, 2011

Process RSS/ATOM Feed on client side through JavaScript

There are few opensource javascript library API available to parse feed data and it gives you result in dom xml or either in JSON format. Once you get the result iterate through feed items and generate you own html markup
1)  Google feed api (http://code.google.com/apis/feed/)- With the Feed API, you can download any public Atom, RSS, or Media RSS feed using only JavaScript, so you can easily mash up feeds with your content. This work for cross domain website.
There is cloud service hosted by google to test this api. http://code.google.com/apis/ajax/playground/#load_feed
Only limitation of google hosted api are you need to generate api key for you server hostname.

2) JQuery JFeed plugins (http://plugins.jquery.com/project/jFeed): 
jFeed is a generic RSS/ATOM feed parser.
jFeed currently parses RSS 0.91, 0.92, 1.0, 2.0 and Atom 1.0 feeds.
Download sample code from here - https://github.com/jfhovinne/jFeed

Other way of displaying feed data is, send ajax request to feed_url use Ajax proxy(http://absolutebrain.blogspot.com/2011/09/ajax-proxy.html) in case of feed_url is pointing to different server and iterate through xml dom elements to get desired element values.
Starting with 1.5 jQuery has built-in xml parsing capabilities, which makes it pretty easy to do this without plugins or 3rd party services.
Sample Code :
<script src="http://code.jquery.com/jquery-latest.js"></script>
<div id="results"></div>
<script language="JavaScript">
    $.ajax({
         type: "GET",
         cache: false,
         dataType: "xml",
         url: "http://localhost:10039/.YouTubeChannel/proxy/http/toi.timesofindia.indiatimes.com/rssfeedstopstories.cms", //Requesting to proxy to get response from timeofindia
         success: function(data) {
             var $xml = $(data);
            $xml.find("item").each(function() {
                $("#results").append($(this).find("title").text()+":"+$(this).find("pubDate").text()+"<br>");
            });
        },
        error : function(jqXHR, textStatus, errorThrown) {
            alert("error: "+textStatus);
        }
   });
</script>

Tuesday, August 16, 2011

JAX-WS send custom SOAP headers and Set endpoint

String endPointURL=”<ws_service_endpoint_url>”;
String userName=”uname”; //custom header for ws security
String password=”password”; //custom header for ws security
String systemId=”system_id”; //custom header to call WS
String correlationId=”corr_id”; //custom header to call ws
                 
//adding handler to add custom soap header
RetailAccountService serviceLocator=new RetailAccountService();
HeaderHandlerResolver handlerResolver = new HeaderHandlerResolver(userName,password,systemId,correlationId);
serviceLocator.setHandlerResolver(handlerResolver);
                 
//setting webservice endpoint
PncEnterpriseOffersV1RetailInterfacesPortType oppService=serviceLocator.getPncEnterpriseOffersV1RetailInterfacesPort();
BindingProvider bp = (BindingProvider)oppService;          bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endPointURL);
GetOpportunitiesByUserType oppUser=new GetOpportunitiesByUserType();
oppUser.setUser(userId);
GetOpportunitiesByUserResponseType oppRes=oppService.getOpportunitiesByUser(oppUser);






import java.util.ArrayList;
import java.util.List;

import javax.xml.ws.handler.Handler;
import javax.xml.ws.handler.HandlerResolver;
import javax.xml.ws.handler.PortInfo;

public class HeaderHandlerResolver implements HandlerResolver {
      private String userName;
      private String password;
      private String systemId;
      private String correlationId;

      public HeaderHandlerResolver(String userName, String password,
                  String systemId, String correlationId) {
            super();
            this.userName = userName;
            this.password = password;
            this.systemId = systemId;
            this.correlationId = correlationId;
      }

      public List<Handler> getHandlerChain(PortInfo portInfo) {
            List<Handler> handlerChain = new ArrayList<Handler>();
            HeaderHandler hh = new HeaderHandler(userName, password, systemId,
                        correlationId);
            handlerChain.add(hh);
            return handlerChain;
      }
}



import java.io.ByteArrayOutputStream;
import java.util.Set;

import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;

import org.apache.log4j.Logger;

public class HeaderHandler implements SOAPHandler<SOAPMessageContext> {
      private static Logger log = Logger.getLogger(HeaderHandler.class);
      private String userName;
      private String password;
      private String systemId;
      private String correlationId;

      public HeaderHandler(String userName, String password, String systemId, String correlationId) {
            super();
            this.userName = userName;
            this.password = password;
            this.systemId = systemId;
            this.correlationId = correlationId;
      }

      public boolean handleMessage(SOAPMessageContext smc) {
            // constructing custom soap header
            Boolean outboundProperty = (Boolean) smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

            if (outboundProperty.booleanValue()) {
                  SOAPMessage message = smc.getMessage();
                  try {
                        SOAPEnvelope envelope = smc.getMessage().getSOAPPart().getEnvelope();
                        SOAPHeader header = envelope.addHeader();

                        SOAPElement securityEle = header.addChildElement("Security", "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
                        SOAPElement usernameTokenEle = securityEle.addChildElement("UsernameToken", "wsse");
                        SOAPElement usernameEle = usernameTokenEle.addChildElement("Username", "wsse");
                        usernameEle.addTextNode(userName);
                        SOAPElement passwordEle = usernameTokenEle.addChildElement("Password", "wsse");
                        passwordEle.setAttribute("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
                        passwordEle.addTextNode(password);

                        SOAPElement systemContextEle = header.addChildElement("systemContext", "urn", "urn:pnc.common.utils.v1.context");
                        SOAPElement systemIdEle = systemContextEle.addChildElement("systemId");
                        systemIdEle.addTextNode(systemId);
                        SOAPElement correlationIdEle = systemContextEle.addChildElement("correlationId");
                        correlationIdEle.addTextNode(correlationId);

                        // Print out the outbound SOAP message to log
                        ByteArrayOutputStream soapReq = new ByteArrayOutputStream();
                        message.writeTo(soapReq);
                        log.debug("SOAP Request for Operation getOpportunitiesByUser " + new String(soapReq.toByteArray()));
                        soapReq.close();
                  } catch (Exception e) {
                        log.error(e.getMessage(), e);
                  }
            } else {
                  try {
                        // This handler does nothing with the response from the Web
                        // Service so we just log the SOAP message.
                        SOAPMessage message = smc.getMessage();
                        ByteArrayOutputStream soapRes = new ByteArrayOutputStream();
                        message.writeTo(soapRes);
                        log.debug("SOAP Response for Operation getOpportunitiesByUser " + new String(soapRes.toByteArray()));
                        soapRes.close();
                  } catch (Exception e) {
                        log.error(e.getMessage(), e);
                  }
            }

            return outboundProperty;
      }

      public Set getHeaders() {
            // throw new UnsupportedOperationException("Not supported yet.");
            return null;
      }

      public boolean handleFault(SOAPMessageContext context) {
            // throw new UnsupportedOperationException("Not supported yet.");
            return true;
      }

      public void close(MessageContext context) {
            // throw new UnsupportedOperationException("Not supported yet.");
      }
}