Monday, 14 October 2013

JetBrains IntelliJ IDEA > Features > Code/Context Highlighting and Code Folding

No one have ever understood the problems and challenges faced by Developers, better than JetBrains. The day, I was introduced to this amazingly genius IDE, back in 2004, I fell for it. And, with every passing day, or should I say every passing release, JetBrains keep on raising the bar to a level where no one can possibly reach it.

So impressed with this IDE, I though about writing each of those intelligent features that saves me from a lot of stress and waste of time and efforts. But, honestly, every time I failed to figure out where to start and which ones to blog first. So, now, just 2 minutes ago, while I was coding Bootstrap prototype interface for one of the projects that I’m working on, I was amazed to see how intelligently it is aiding and assisting me to do my work efficiently with as least stress as possible.

The Bootstrap prototype file I’m working on is a Plain HTML file, and there are around ~300 lines of code. See the snapshot below, shows how efficiently IntelliJ IDEA has highlighted the area where I’m working at:

JetBrains IntelliJ IDEA IDE (Click to open enlarge image in a new window)

  1. Notice breadcrumbs at the top of editor window
  2. Notice a thin stripe at the left hand side buffer of editor window
  3. Notice the highlighted line of code within the editor where my caret is
  4. Notice the highlighted tags hierarchy within the editor
  5. And finally notice, how all of the above are synced with beautiful colors to track each item of current context individually

Wow!

Well, that’s not all. This file you are looking at is a ~300 line file, notice how I saved my self from additional stress of looking at un-related code, by (6) folding/collapsing literally any part of the code I wished to.

Genius! isn’t it?

And finally Winking smile, for those who are thinking that I’ve spent a fortune to have that jewel under my belt, have a look at this:

JetBrains IntelliJ IDEA Community Edition

Happy Coding Smile

Saturday, 5 October 2013

Apache Maven Tips: Add/Append Copyright and License Header to your Project’s Source Code Artifacts using Maven License Plugin

apache-mavenEvery project requires proper copyrights and license information header to be added/appended at the top of each of the project’s source code artifacts. There is a very useful plugin for Apache Maven, called Maven License Plugin that helps you easily add/append such copyrights and license information.

First create a copyrights and license header file, for example:

${project}

Copyright (c) ${year}, ${founder}

This project includes software developed by ${founder}
${website}

Licensed under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at:

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.

Note the highlighted “parameters” enclosed within special notation “${ }”. We will define the values for these parameters when we will configure Maven License Plugin in our project’s POM file, as show below:

<plugin>
    <groupId>com.mycila.maven-license-plugin</groupId>
    <artifactId>maven-license-plugin</artifactId>
    <version>1.10.b1</version>
    <configuration>
        <header>src/license/LicenseHeader.txt</header>
        <properties>
            <project>${project.name}</project>
            <founder>${project.organization.name}</founder>
            <year>${project.inceptionYear}</year>
            <website>${founder-website}</website>

        </properties>
        <includes>
            <include>src/main/java/**</include>
            <include>src/test/java/**</include>

        </includes>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>format</goal>
            </goals>
            <phase>process-sources</phase>
        </execution>
    </executions>
    <dependencies>
        <dependency>
            <groupId>com.mycila</groupId>
            <artifactId>licenses</artifactId>
            <version>1</version>
        </dependency>
    </dependencies>
</plugin>

  1. Under the configuration tag, notice the <header/> element where we’ve mentioned the path to our copyrights and license header file.
  2. Similarly, the <properties/> element under <header/> is the place where you can define parameters and their values to be replaced by the parameter place holders as show in the header file above.
  3. The <includes/> element is the place where you can configure which files should the plugin attempt to add/append the copyright and license information. You can use wild cards as shown above.

Following is an example of Source Code file after processed by Maven License Plugin:

/**
* Apache Maven Tips: Add/Append Copyright and License Header to your Project’s Source Code Artifacts using Maven License Plugin
* - http://codeoftheday.blogspot.com/2013/10/apache-maven-tips-addappend-copyright.html
*/
/**
* Project MI+
*
* Copyright (c) 2013, Syed Muhammad Humayun - smhumayun@gmail.com
*
* This project includes software developed by Syed Muhammad Humayun - smhumayun@gmail.com
* http://www.smhumayun.com
*
* Licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.smhumayun.mi_plus;
...

Thursday, 3 October 2013

Apache Maven Tips: Customizing Maven Site generation via Site Descriptor (Site.xml), Maven Site Plugin and Velocity Template

apache-mavenThere are two kind of customizations you can do with Maven Site generation:

(1) Configuring the Site Descriptor (Simple) – This is a higher level customization, where you can change or configure certain sections/areas of the site layout including the navigation/menu. Read more on Maven website.

(2) Custom Velocity Template (Complex) – This is a low level customization, where you have full control over the generated html content. However it is more complex than the first one because you need to have an understanding of Apache Velocity templating language.

To begin with, add Maven Site Plugin configuration under the <build/> tag of your POM:

<plugin>
    <artifactId>maven-site-plugin</artifactId>
    <version>3.3</version>
    <configuration>
        <templateFile>${basedir}/src/site/maven-site-template.vm</templateFile>
    </configuration>

</plugin>

Recommended way to develop/design a custom maven site template, is to start with the default template provided by maven itself, and then change it to your desired layout.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- Generated by Apache Maven Doxia Site Renderer#if( $doxiaSiteRendererVersion ) $doxiaSiteRendererVersion#end at $dateFormat.format( $currentDate ) -->
#macro ( link $href $name $target $img $position $alt $border $width $height $title )
#set ( $linkTitle = ' title="' + $name + '"' )
#if( $target )
#set ( $linkTarget = ' target="' + $target + '"' )
#else
#set ( $linkTarget = "" )
#end
#if ( $href.toLowerCase().startsWith("http:/") || $href.toLowerCase().startsWith("https:/") ||
$href.toLowerCase().startsWith("ftp:/") || $href.toLowerCase().startsWith("mailto:") ||
$href.toLowerCase().startsWith("file:/") || ($href.toLowerCase().indexOf("://") != -1) )
#set ( $linkClass = ' class="externalLink"' )
#else
#set ( $linkClass = "" )
#end
#if ( $img )
#if ( $position == "left" )
<a href="$href"$linkClass$linkTarget$linkTitle>#image($img $alt $border $width $height $title)$name</a>
#else
<a href="$href"$linkClass$linkTarget$linkTitle>$name #image($img $alt $border $width $height $title)</a>
#end
#else
<a href="$href"$linkClass$linkTarget$linkTitle>$name</a>
#end
#end
##
#macro ( image $img $alt $border $width $height $title )
#if( $img )
#if ( ! ( $img.toLowerCase().startsWith("http:/") || $img.toLowerCase().startsWith("https:/") ||
$img.toLowerCase().startsWith("ftp:/") || $img.toLowerCase().startsWith("mailto:") ||
$img.toLowerCase().startsWith("file:/") || ($img.toLowerCase().indexOf("://") != -1) ) )
#set ( $imgSrc = $PathTool.calculateLink( $img, $relativePath ) )
#set ( $imgSrc = $imgSrc.replaceAll( '\\', '/' ) )
#set ( $imgSrc = ' src="' + $imgSrc + '"' )
#else
#set ( $imgSrc = ' src="' + $img + '"' )
#end
#if( $alt )
#set ( $imgAlt = ' alt="' + $alt + '"' )
#else
#set ( $imgAlt = ' alt=""' )
#end
#if( $border )
#set ( $imgBorder = ' border="' + $border + '"' )
#else
#set ( $imgBorder = "" )
#end
#if( $width )
#set ( $imgWidth = ' width="' + $width + '"' )
#else
#set ( $imgWidth = "" )
#end
#if( $height )
#set ( $imgHeight = ' height="' + $height + '"' )
#else
#set ( $imgHeight = "" )
#end
#if( $title )
#set ( $imgTitle = ' title="' + $title + '"' )
#else
#set ( $imgTitle = "" )
#end
<img class="imageLink"$imgSrc$imgAlt$imgBorder$imgWidth$imgHeight$imgTitle/>
#end
#end
#macro ( banner $banner $id )
#if ( $banner )
#if( $banner.href )
#set ( $hrf = $banner.href )
#if ( ! ( $hrf.toLowerCase().startsWith("http:/") || $hrf.toLowerCase().startsWith("https:/") ||
$hrf.toLowerCase().startsWith("ftp:/") || $hrf.toLowerCase().startsWith("mailto:") ||
$hrf.toLowerCase().startsWith("file:/") || ($hrf.toLowerCase().indexOf("://") != -1) ) )
#set ( $hrf = $PathTool.calculateLink( $hrf, $relativePath ) )
#set ( $hrf = $hrf.replaceAll( '\\', '/' ) )
#if ( ( $hrf == '' ) )
#set ( $hrf = './' )
#end
#end
<a href="$hrf" id="$id"#if( $banner.alt ) title="$banner.alt"#end>
#else
<div id="$id">
#end
##
#if( $banner.src )
#set ( $src = $banner.src )
#if ( ! ( $src.toLowerCase().startsWith("http:/") || $src.toLowerCase().startsWith("https:/") ||
$src.toLowerCase().startsWith("ftp:/") || $src.toLowerCase().startsWith("mailto:") ||
$src.toLowerCase().startsWith("file:/") || ($src.toLowerCase().indexOf("://") != -1) ) )
#set ( $src = $PathTool.calculateLink( $src, $relativePath ) )
#set ( $src = $src.replaceAll( '\\', '/' ) )
#end
#if ( $banner.alt )
#set ( $alt = $banner.alt )
#else
#set ( $alt = $banner.name )
#end
<img src="$src" alt="$alt"#if( $banner.title ) title="$banner.title"#end />
#else
$banner.name
#end
##
#if( $banner.href )
</a>
#else
</div>
#end
#end
#end
##
#macro ( links $links )
#set ( $counter = 0 )
#foreach( $item in $links )
#set ( $counter = $counter + 1 )
#set ( $currentItemHref = $PathTool.calculateLink( $item.href, $relativePath ) )
#set ( $currentItemHref = $currentItemHref.replaceAll( '\\', '/' ) )
#link( $currentItemHref $item.name $item.target $item.img $item.position $item.alt $item.border $item.width $item.height $item.title )
#if ( $links.size() > $counter )
|
#end
#end
#end
##
#macro ( breadcrumbs $breadcrumbs )
#foreach( $item in $breadcrumbs )
#set ( $currentItemHref = $PathTool.calculateLink( $item.href, $relativePath ) )
#set ( $currentItemHref = $currentItemHref.replaceAll( '\\', '/' ) )
#if ( ( $currentItemHref == '' ) )
#set ( $currentItemHref = './' )
#end
##
#link( $currentItemHref $item.name $item.target $item.img $item.position $item.alt $item.border $item.width $item.height $item.title )
&gt;
#end
$shortTitle
#end
##
#macro ( displayTree $display $item )
#if ( $item && $item.items && $item.items.size() > 0 )
#foreach( $subitem in $item.items )
#set ( $subitemHref = $PathTool.calculateLink( $subitem.href, $relativePath ) )
#set ( $subitemHref = $subitemHref.replaceAll( '\\', '/' ) )
##
#if ( $alignedFileName == $subitemHref )
#set ( $display = true )
#end
##
#displayTree( $display $subitem )
#end
#end
#end
##
#macro ( menuItem $item )
#set ( $collapse = "none" )
#set ( $currentItemHref = $PathTool.calculateLink( $item.href, $relativePath ) )
#set ( $currentItemHref = $currentItemHref.replaceAll( '\\', '/' ) )
##
#if ( $item && $item.items && $item.items.size() > 0 )
#if ( $item.collapse == false )
#set ( $collapse = "expanded" )
#else
## By default collapsed
#set ( $collapse = "collapsed" )
#end
##
#set ( $display = false )
#displayTree( $display $item )
##
#if ( $alignedFileName == $currentItemHref || $display )
#set ( $collapse = "expanded" )
#end
#end
<li class="$collapse">
#if ( $item.img )
#if ( $item.position == "left" )
#if ( $alignedFileName == $currentItemHref )
<strong>#image($item.img $item.alt $item.border $item.width $item.height $item.title) $item.name</strong>
#else
#link($currentItemHref $item.name $item.target $item.img $item.position $item.alt $item.border $item.width $item.height $item.title)
#end
#else
#if ( $alignedFileName == $currentItemHref )
<strong>$item.name #image($item.img $item.alt $item.border $item.width $item.height $item.title)</strong>
#else
#link($currentItemHref $item.name $item.target $item.img $item.position $item.alt $item.border $item.width $item.height $item.title)
#end
#end
#else
#if ( $alignedFileName == $currentItemHref )
<strong>$item.name</strong>
#else
#link( $currentItemHref $item.name $item.target $item.img $item.position $item.alt $item.border $item.width $item.height $item.title )
#end
#end
#if ( $item && $item.items && $item.items.size() > 0 )
#if ( $collapse == "expanded" )
<ul>
#foreach( $subitem in $item.items )
#menuItem( $subitem )
#end
</ul>
#end
#end
</li>
#end
##
#macro ( mainMenu $menus )
#foreach( $menu in $menus )
#if ( $menu.name )
#if ( $menu.img )
#if( $menu.position )
#set ( $position = $menu.position )
#else
#set ( $position = "left" )
#end
##
#if ( ! ( $menu.img.toLowerCase().startsWith("http:/") || $menu.img.toLowerCase().startsWith("https:/") ||
$menu.img.toLowerCase().startsWith("ftp:/") || $menu.img.toLowerCase().startsWith("mailto:") ||
$menu.img.toLowerCase().startsWith("file:/") || ($menu.img.toLowerCase().indexOf("://") != -1) ) )
#set ( $src = $PathTool.calculateLink( $menu.img, $relativePath ) )
#set ( $src = $src.replaceAll( '\\', '/' ) )
#set ( $src = ' src="' + $src + '"' )
#else
#set ( $src = ' src="' + $menu.img + '"' )
#end
##
#if( $menu.alt )
#set ( $alt = ' alt="' + $menu.alt + '"' )
#else
#set ( $alt = ' alt="' + $menu.name + '"' )
#end
##
#if( $menu.border )
#set ( $border = ' border="' + $menu.border + '"' )
#else
#set ( $border = ' border="0"' )
#end
##
#if( $menu.width )
#set ( $width = ' width="' + $menu.width + '"' )
#else
#set ( $width = "" )
#end
#if( $menu.height )
#set ( $height = ' height="' + $menu.height + '"' )
#else
#set ( $height = "" )
#end
#if( $menu.title )
#set ( $title = ' title="' + $menu.title + '"' )
#else
#set ( $title = "" )
#end
##
#set ( $img = '<img class="imageLink"' + $src + $alt + $border + $width + $height + $title + "/>" )
##
#if ( $position == "left" )
<h5>$img $menu.name</h5>
#else
<h5>$menu.name $img</h5>
#end
#else
<h5>$menu.name</h5>
#end
#end
#if ( $menu.items && $menu.items.size() > 0 )
<ul>
#foreach( $item in $menu.items )
#menuItem( $item )
#end
</ul>
#end
#end
#end
##
#macro ( copyright )
#if ( $project )
#if ( ${project.organization} && ${project.organization.name} )
#set ( $period = "" )
#else
#set ( $period = "." )
#end
##
#set ( $currentYear = ${currentDate.year} + 1900 )
##
#if ( ${project.inceptionYear} && ( ${project.inceptionYear} != ${currentYear.toString()} ) )
${project.inceptionYear}-${currentYear}${period}
#else
${currentYear}${period}
#end
##
#if ( ${project.organization} )
#if ( ${project.organization.name} && ${project.organization.url} )
<a href="$project.organization.url">${project.organization.name}</a>.
#elseif ( ${project.organization.name} )
${project.organization.name}.
#end
#end
#end
#end
##
#macro ( publishDate $position $decorationPublishDate $version )
#if ( $decorationPublishDate && $decorationPublishDate.format )
#set ( $format = $decorationPublishDate.format )
#else
#set ( $format = "yyyy-MM-dd" )
#end
##
$dateFormat.applyPattern( $format )
##
#if ( $publishDate )
#set ( $dateValue = $dateFormat.format( $publishDate ) )
#elseif ( $decoration.custom.getChild( 'publishDate' ) )
#set ( $dateValue = $decoration.custom.getChild( 'publishDate' ).getValue() )
#else
#set ( $dateValue = $dateFormat.format( $currentDate ) )
#end
##
#if ( $decorationPublishDate && $decorationPublishDate.position )
#set ( $datePosition = $decorationPublishDate.position )
#else
#set ( $datePosition = "left" )
#end
##
#if ( $version )
#if ( $version.position )
#set ( $versionPosition = $version.position )
#else
#set ( $versionPosition = "left" )
#end
#else
#set ( $version = "" )
#set ( $versionPosition = "left" )
#end
##
#set ( $breadcrumbs = $decoration.body.breadcrumbs )
#set ( $links = $decoration.body.links )
#if ( $datePosition.equalsIgnoreCase( "right" ) && $links && $links.size() > 0 )
#set ( $prefix = "&nbsp;|" )
#else
#set ( $prefix = "" )
#end
##
#if ( $datePosition.equalsIgnoreCase( $position ) )
#if ( ( $datePosition.equalsIgnoreCase( "right" ) ) || ( $datePosition.equalsIgnoreCase( "bottom" ) ) )
$prefix <span id="publishDate">$i18n.getString( "site-renderer", $locale, "template.lastpublished" ): $dateValue</span>
#if ( $versionPosition.equalsIgnoreCase( $position ) )
&nbsp;| <span id="projectVersion">$i18n.getString( "site-renderer", $locale, "template.version" ): ${project.version}</span>
#end
#elseif ( ( $datePosition.equalsIgnoreCase( "navigation-bottom" ) ) || ( $datePosition.equalsIgnoreCase( "navigation-top" ) ) )
<div id="lastPublished">
<span id="publishDate">$i18n.getString( "site-renderer", $locale, "template.lastpublished" ): $dateValue</span>
#if ( $versionPosition.equalsIgnoreCase( $position ) )
&nbsp;| <span id="projectVersion">$i18n.getString( "site-renderer", $locale, "template.version" ): ${project.version}</span>
#end
</div>
#elseif ( $datePosition.equalsIgnoreCase("left") )
<div class="xleft">
<span id="publishDate">$i18n.getString( "site-renderer", $locale, "template.lastpublished" ): $dateValue</span>
#if ( $versionPosition.equalsIgnoreCase( $position ) )
&nbsp;| <span id="projectVersion">$i18n.getString( "site-renderer", $locale, "template.version" ): ${project.version}</span>
#end
#if ( $breadcrumbs && $breadcrumbs.size() > 0 )
| #breadcrumbs( $breadcrumbs )
#end
</div>
#end
#elseif ( $versionPosition.equalsIgnoreCase( $position ) )
#if ( ( $versionPosition.equalsIgnoreCase( "right" ) ) || ( $versionPosition.equalsIgnoreCase( "bottom" ) ) )
$prefix <span id="projectVersion">$i18n.getString( "site-renderer", $locale, "template.version" ): ${project.version}</span>
#elseif ( ( $versionPosition.equalsIgnoreCase( "navigation-bottom" ) ) || ( $versionPosition.equalsIgnoreCase( "navigation-top" ) ) )
<div id="lastPublished">
<span id="projectVersion">$i18n.getString( "site-renderer", $locale, "template.version" ): ${project.version}</span>
</div>
#elseif ( $versionPosition.equalsIgnoreCase("left") )
<div class="xleft">
<span id="projectVersion">$i18n.getString( "site-renderer", $locale, "template.version" ): ${project.version}</span>
#if ( $breadcrumbs && $breadcrumbs.size() > 0 )
| #breadcrumbs( $breadcrumbs )
#end
</div>
#end
#elseif ( $position.equalsIgnoreCase( "left" ) )
#if ( $breadcrumbs && $breadcrumbs.size() > 0 )
<div class="xleft">
#breadcrumbs( $breadcrumbs )
</div>
#end
#end
#end
##
#macro ( poweredByLogo $poweredBy )
#if( $poweredBy )
#foreach ($item in $poweredBy)
#if( $item.href )
#set ( $href = $PathTool.calculateLink( $item.href, $relativePath ) )
#set ( $href = $href.replaceAll( '\\', '/' ) )
#else
#set ( $href="http://maven.apache.org/" )
#end
##
#if( $item.name )
#set ( $name = $item.name )
#else
#set ( $name = $i18n.getString( "site-renderer", $locale, "template.builtby" ) )
#set ( $name = "${name} Maven" )
#end
##
#if( $item.img )
#set ( $img = $item.img )
#else
#set ( $img = "images/logos/maven-feather.png" )
#end
##
#if ( ! ( $img.toLowerCase().startsWith("http:/") || $img.toLowerCase().startsWith("https:/") ||
$img.toLowerCase().startsWith("ftp:/") || $img.toLowerCase().startsWith("mailto:") ||
$img.toLowerCase().startsWith("file:/") || ($img.toLowerCase().indexOf("://") != -1) ) )
#set ( $img = $PathTool.calculateLink( $img, $relativePath ) )
#set ( $img = $img.replaceAll( '\\', '/' ) )
#end
##
#if( $item.alt )
#set ( $alt = ' alt="' + $item.alt + '"' )
#else
#set ( $alt = ' alt="' + $name + '"' )
#end
##
#if( $item.border )
#set ( $border = ' border="' + $item.border + '"' )
#else
#set ( $border = "" )
#end
##
#if( $item.width )
#set ( $width = ' width="' + $item.width + '"' )
#else
#set ( $width = "" )
#end
#if( $item.height )
#set ( $height = ' height="' + $item.height + '"' )
#else
#set ( $height = "" )
#end
#if( $item.title )
#set ( $title = ' title="' + $item.title + '"' )
#else
#set ( $title = "" )
#end
##
<a href="$href" title="$name" class="poweredBy">
<img class="poweredBy" $alt src="$img" $border $width $height $title />
</a>
#end
#if( $poweredBy.isEmpty() )
<a href="http://maven.apache.org/" title="$i18n.getString( "site-renderer", $locale, "template.builtby" ) Maven" class="poweredBy">
<img class="poweredBy" alt="$i18n.getString( "site-renderer", $locale, "template.builtby" ) Maven" src="$relativePath/images/logos/maven-feather.png" />
</a>
#end
#else
<a href="http://maven.apache.org/" title="$i18n.getString( "site-renderer", $locale, "template.builtby" ) Maven" class="poweredBy">
<img class="poweredBy" alt="$i18n.getString( "site-renderer", $locale, "template.builtby" ) Maven" src="$relativePath/images/logos/maven-feather.png" />
</a>
#end
#end
##
#macro ( googleAnalytics $accountId )
#if( $accountId && $accountId != "" )
<!-- Google Analytics -->
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', '$accountId']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
#end
#end
##
<html xmlns="http://www.w3.org/1999/xhtml"#if ( $locale ) xml:lang="$locale.language" lang="$locale.language"#end>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=${outputEncoding}" />
<title>$title</title>
<style type="text/css" media="all">
@import url("$relativePath/css/maven-base.css");
@import url("$relativePath/css/maven-theme.css");
@import url("$relativePath/css/site.css");
</style>
<link rel="stylesheet" href="$relativePath/css/print.css" type="text/css" media="print" />
#foreach( $author in $authors )
<meta name="author" content="$author" />
#end
#if ( $dateCreation )
<meta name="Date-Creation-yyyymmdd" content="$dateCreation" />
#end
#if ( $dateRevision )
<meta name="Date-Revision-yyyymmdd" content="$dateRevision" />
#end
#if ( $locale )
<meta http-equiv="Content-Language" content="$locale.language" />
#end
#if ( $decoration.body.head )
#foreach( $item in $decoration.body.head.getChildren() )
## Workaround for DOXIA-150 due to a non-desired behaviour in p-u
## @see org.codehaus.plexus.util.xml.Xpp3Dom#toString()
## @see org.codehaus.plexus.util.xml.Xpp3Dom#toUnescapedString()
#set ( $documentHeader = '<?xml version="1.0" encoding="UTF-8"?>' )
#if ( $item.name == "script" )
$StringUtils.replace( $item.toUnescapedString(), $documentHeader, "" )
#else
$StringUtils.replace( $item.toString(), $documentHeader, "" )
#end
#end
#end
$headContent
#googleAnalytics( $decoration.googleAnalyticsAccountId )
</head>
<body class="composite">
<div id="banner">
#banner( $decoration.bannerLeft "bannerLeft" )
#banner( $decoration.bannerRight "bannerRight" )
<div class="clear">
<hr/>
</div>
</div>
<div id="breadcrumbs">
#publishDate( "left" $decoration.publishDate $decoration.version )
<div class="xright">#links( $decoration.body.links )#publishDate( "right" $decoration.publishDate $decoration.version )</div>
<div class="clear">
<hr/>
</div>
</div>
<div id="leftColumn">
<div id="navcolumn">
#publishDate( "navigation-top" $decoration.publishDate $decoration.version )
#mainMenu( $decoration.body.menus )
#poweredByLogo( $decoration.poweredBy )
#publishDate( "navigation-bottom" $decoration.publishDate $decoration.version )
</div>
</div>
<div id="bodyColumn">
<div id="contentBox">
$bodyContent
</div>
</div>
<div class="clear">
<hr/>
</div>
<div id="footer">
<div class="xright">
#if($decoration.body.footer)
$decoration.body.footer
#else
Copyright &#169;#copyright()All Rights Reserved.#publishDate( "bottom" $decoration.publishDate $decoration.version )
#end
</div>
<div class="clear">
<hr/>
</div>
</div>
</body>
</html>

Tuesday, 1 October 2013

Apache Maven Tips: How to add/include or remove/exclude files as Resources and Test Resources

apache-mavenApache Maven’s Standard Directory Layout contains specific folders for application wide Resources and TestResources, they are:

src/main/resources
src/test/resources

What if you want to add or include more files as Resources or TestResources? a typical example is the use of standard README, LICENSE and NOTICE files, which by convention should reside at the very root of the project, like this:

./README
./LICENSE
./NOTICE
./src/...

In such situations, you can add or include files by adding a configuration similar to the following, under the <build/> section of your POM:

<build>
    <resources>
        <resource>
            <directory>${project.basedir}</directory>
            <includes>
                <include>README*</include>
                <include>LICENSE*</include>
                <include>NOTICE*</include>
            </includes>
        </resource>
    </resources>
    <testResources>
        <testResource>
            <directory>${project.basedir}</directory>
            <includes>
                <include>README*</include>
                <include>LICENSE*</include>
                <include>NOTICE*</include>
            </includes>
        </testResource>
    </testResources>

Similarly, you can remove or exclude files by adding a configuration similar to the following, under the <build/> section of your POM:

<build>
    <resources>
        <resource>
            <directory>${project.basedir}/src/main/resources</directory>
            <excludes>
                <exclude>SomeFile.toExclude</exclude>
            </excludes>
        </resource>
    </resources>
    <testResources>
        <testResource>
            <directory>${project.basedir}/src/test/resources</directory>
            <excludes>
                <exclude>SomeFile.toExclude</exclude>
            </excludes>
        </testResource>
    </testResources>

Wednesday, 25 September 2013

How to Flag a Post or a Discussion in a LinkedIn Group as a Promotion or a Job using Scribe and Java

As a sequel to my earlier post, Programmatically Posting to LinkedIn Groups via LinkedIn REST API and using Scribe-Java OAuth Library, in this post I will demonstrate how you can Flag a Post or a Discussion in a LinkedIn Group as a Promotion or a Job using Scribe and Java.

Flag Post or Discussion in LinkedIn Group as Promotion or Job

Consider the output of our example program in my previous post:

# Code Of The Day - Programmatically Posting to LinkedIn Groups via LinkedIn REST API and using Scribe-Java OAuth Library
# http://codeoftheday.blogspot.com/2013/07/programmatically-posting-to-linkedin.html
response.getBody() =
response.getMessage() = Created
response.getCode() = 201
response.getHeaders():
null = HTTP/1.1 201 Created
Date = Thu, 18 Jul 2013 18:46:12 GMT
Vary = Accept-Encoding
Content-Length = 0
Location = http://api.linkedin.com/v1/posts/g-5046253-S-259167773
x-li-request-id = 7R09I1AUHX
X-LI-R2-W-IC-2 = com.linkedin.container.dsc=1
Server = Apache-Coyote/1.1

Notice the following header and its value:

Location = http://api.linkedin.com/v1/posts/g-5046253-S-259167773

This URL contains the post id of the published post and it is the very last part of the URL “g-5046253-S-259167773”.

So, what we will do now is the extend the same program/example and will try to extract the “Location” header value and then extract the “post-id” from that value:

//http://api.linkedin.com/v1/posts/g-5046253-S-276447044
String preUrl = "http://api.linkedin.com/v1/posts/";
String url = response.getHeader("Location").substring(preUrl.length());
url = preUrl + url + "/category/code";

Once you have the target URL, you can now proceed with the HTTP PUT request, using the url as a LinkedIn REST API end point.

OAuthRequest request = new OAuthRequest(Verb.PUT, url);
request.addHeader("Content-Type", "text/xml");

Now, if you want to Flag your Post or Discussion as a Promotion, you should add following XML stanza as the pay load to this request:

request.addPayload("<code>promotion</code>");

OR, if you want to Flag your Post or Discussion as a Job, you should add following XML stanza as the pay load to this request:

request.addPayload("<code>job</code>");

And, finally send the request to LinkedIn REST API server:

signOAuthRequest(request);
response = request.send();

/**
* Code Of The Day - How to Flag a Post or a Discussion in a LinkedIn Group as a Promotion or a Job using Scribe and Java
* - http://codeoftheday.blogspot.com/2013/09/how-to-flag-post-or-discussion-in.html
*/
package smhumayun.codeoftheday.linkedin.group;
import org.scribe.builder.ServiceBuilder;
import org.scribe.builder.api.LinkedInApi;
import org.scribe.model.OAuthRequest;
import org.scribe.model.Response;
import org.scribe.model.Token;
import org.scribe.model.Verb;
import org.scribe.oauth.OAuthService;
/**
* This class demonstrate how you can Post Content to LinkedIn Groups using Scribe-Java OAuth API
*
* User: smhumayun
* Date: 9/25/13
* Time: 1:03 PM
*/
public class PostToLinkedInGroupWithFlaggingExample {
private static OAuthService oAuthService;
/**
* Main Method
*
* @param args arguments
*/
public static void main(String[] args) {
//Instantiating the oAuth Service of Scribe-Java API
oAuthService = new ServiceBuilder()
//LinkedIn Provider with Scopes support
.provider(LinkedInApi.withScopes(
//'rw_groups' is to retrieve and post group discussions as authenticated user
"rw_groups"
))
//API Key
.apiKey("XXXXXXXXXXXX")
//API Secret
.apiSecret("XXXXXXXXXXXXXXXX")
//build it!
.build();
//Instantiating oAuth Request of type POST and with LinkedIn Group Discussion Post - REST API End Point URL
OAuthRequest postGroupDiscussionRequest = new OAuthRequest(Verb.POST, "http://api.linkedin.com/v1/groups/5046253/posts");
//Preparing XML payload to Share Content on LinkedIn Group
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> \n" +
"<post>\n" +
"<title>" +
//title of the post
"New Job Post!" +
"</title>\n" +
"<summary>" +
//summary of the post
"A new job post has been shared recently by Syed Muhammad Humayun on H-1B Work Visa USA" +
"</summary>\n" +
"<content>\n" +
"<submitted-url>" +
//url of the content
"http://h1b-work-visa-usa.blogspot.com/2013/07/h-1b-transfer-jobs-java-tech-lead-il.html" +
"</submitted-url>\n" +
"<submitted-image-url>" +
//image url of the content (if any)
"http://lh4.ggpht.com/-X2DLlJm6hyg/Uec5z_tRxxI/AAAAAAAAEP8/E3gVAGKIYPs/h-1b%252520transfer%252520green%252520card%252520processing%252520jobs%25255B4%25255D.png?imgmax=800" +
"</submitted-image-url>\n" +
"<title>" +
//title of the content
"H-1B Transfer Jobs - Java Tech Lead - IL - (Sponsor Green Card)" +
"</title>\n" +
"<description>" +
//description of the content
"Provides application development and support to partner in the planning, delivery and/or support of business processes utilizing information technology and business practices for strategic business units. Work is of medium to high complexity and moderate to high in risk. Has expanded contact with responsibility to varied and multiple departments and functional operations, and actively participates in strategic business relationships. Serves as a key team member which may include being on multiple teams and/or team lead. Participates in the review and formation of processes. May plan work and schedules for others for project related work. Impact of decision-making is medium to high risk and impact. Serves as a consultant or expert and actively shares knowledge across workgroups. Applies information analyses to optimize the integration of major strategic business processes. Designs and implements complex changes impacting several processes with minimal direction. Primarily performs as an individual contributor, but may supervise a small work team (6 or fewer members). Duties: Lead the Identification, analysis and selection of complex information technology and business practices to support strategic business process/plans. Participates as required to design, develop, test and integrate applications of high complexity. Lead in the implementation of information technology and business processes of high complexity. Supports, evaluates, and continuously improves information technology and business processes to maintain alignment with business plans of medium-high complexity and medium-high risk. Leads the development and may manage a project plan and schedule for a given functional area. Acquires solid foundation of project management. Engages in expanded contact with varied and multiple departments and functional operations; actively participating in strategic business relationships and/or issues." +
"</description>\n" +
"</content>\n" +
"</post>\n";
//set the content type header to text/xml - this is the type of content you are sending as payload
postGroupDiscussionRequest.addHeader("Content-Type", "text/xml");
//add xml payload to request
postGroupDiscussionRequest.addPayload(xml);
//sign oAuth request
signOAuthRequest(postGroupDiscussionRequest);
//send the request
Response response = postGroupDiscussionRequest.send();
//print the response from server
System.out.println("response.getBody() = " + response.getBody());
System.out.println("response.getMessage() = " + response.getMessage());
System.out.println("response.getCode() = " + response.getCode());
System.out.println("response.getHeaders():");
for(String headerKey : response.getHeaders().keySet())
System.out.println("\t" + headerKey + " = " + response.getHeader(headerKey));
//http://api.linkedin.com/v1/posts/g-5046253-S-276447044
String preUrl = "http://api.linkedin.com/v1/posts/";
String url = response.getHeader("Location").substring(preUrl.length());
url = preUrl + url + "/category/code";
System.out.println("url = " + url);
OAuthRequest request = new OAuthRequest(Verb.PUT, url);
request.addHeader("Content-Type", "text/xml");
request.addPayload("<code>job</code>");
signOAuthRequest(request);
response = request.send();
//print the response from server
System.out.println("response.getBody() = " + response.getBody());
System.out.println("response.getMessage() = " + response.getMessage());
System.out.println("response.getCode() = " + response.getCode());
System.out.println("response.getHeaders():");
for(String headerKey : response.getHeaders().keySet())
System.out.println("\t" + headerKey + " = " + response.getHeader(headerKey));
}
/**
* Sign given oAuthRequest with oAuth Service
*
* @param oAuthRequest oAuthRequest
*/
public static void signOAuthRequest (OAuthRequest oAuthRequest)
{
//sign your request with oAuth Service
oAuthService.signRequest(
new Token(
//OAuth Token
"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
//OAuth Token Secret
, "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
), oAuthRequest);
}
}

When you run this updated program, you will see an output similar to the following on your console:

# Code Of The Day - How to Flag a Post or a Discussion in a LinkedIn Group as a Promotion or a Job using Scribe and Java
# - http://codeoftheday.blogspot.com/2013/09/how-to-flag-post-or-discussion-in.html
response.getBody() =
response.getMessage() = Created
response.getCode() = 201
response.getHeaders():
null = HTTP/1.1 201 Created
Age = 2
X-LI-UUID = 8CfT2IcuJxNQvy+ELCsAAA==
Date = Wed, 25 Sep 2013 15:29:31 GMT
Vary = Accept-Encoding
Content-Length = 0
X-Li-Fabric = PROD-ELA4
Location = http://api.linkedin.com/v1/posts/g-5046253-S-276449994
x-li-request-id = N3JMYKSBLB
X-Li-Pop = PROD-ELA4
Connection = keep-alive
Server = Apache-Coyote/1.1
url = http://api.linkedin.com/v1/posts/g-5046253-S-276449994/category/code
response.getBody() =
response.getMessage() = No Content
response.getCode() = 204
response.getHeaders():
null = HTTP/1.1 204 No Content
Age = 0
X-LI-UUID = yM8OSoguJxNQOBCwhSsAAA==
Date = Wed, 25 Sep 2013 15:29:33 GMT
X-Li-Fabric = PROD-ELA4
x-li-request-id = CT86R1S8EV
X-Li-Pop = PROD-ELA4
Connection = close
Server = Apache-Coyote/1.1

The Code 204 is fine, in our case as it complains about “No Content”. Your Post or Discussion on a LinkedIn Group has been Flagged as a Promotion or a Job.

Tuesday, 24 September 2013

Share a Post on Facebook Page using Scribe and Java

As a second Part of my earlier post, I will now demonstrate how you can Share a Post on a Facebook Page using Scribe and Java.

The pre-requisites/setup is the same as mentioned in the first part. i.e.

  • Create a Facebook App and get App ID & App Secret
  • Initialize Scribe’s OAuthService using above information
  • Get Short Lived Access Tokens and then exchange it a Long Lived Access Token – Note that these tokens are the Facebook App’s Tokens

    Token accessToken;

    //facebook app's short-lived access token
    //accessToken = getFbAppShortLivedAccessToken(oAuthService);
    //accessToken = new Token("CAAF3yH4PHBkBAO4mTp8sgngVkNgQxAebc1xt4O64qeOqlzxiI7vyJpM8Ml7VAIKROHPJB5IgDEgi0ShfWIkrnuMirmEm0UjuYFSrRlaURj9YWEWWKLrBQN5vrjFkid4JPMMYsewEcODKe73dp3LYA2JeHld8ZAJc1EkLZCr3HNdYLprSJF", "");

    //facebook app's long-lived access token
    //accessToken = getFbAppLongLivedAccessToken(oAuthService, accessToken);
    accessToken = new Token("CAAF3yH4PHBkBAKUwtBB5SAEreaLN2uVDRI48Q5LhAEHn2kUKaCyDcUO1y8ZBobqFccBx7QDdIWDd4gKJcQpZCYMAIy7P5KIKRBrvzuliJpjUJW18QUU3ijk4NMqROZAPmmrHqf24PufYNK9R26vRn9X7suDtuSze3eKvh5zSrZADZAkZCZARHan9ZAyWZBZBKvhWUZD", "");

  • You will also have to get the Short and Long Lived Access Tokens for the Facebook Page, on to which you want to share a post

    Token pageAccessToken;

    //facebook page's short-lived access token
    //pageAccessToken = getFbPageShortLivedAccessToken(oAuthService, accessToken);
    //pageAccessToken = new Token("CAAF3yH4PHBkBAMzY4Tyi5nyzhckF2DZC0V3ZBWjd5orLwZCw2Xv6lZBhCxsB29HCwPKdF8iMPgqmdurK9ZB2vmL7wPHlrWxagZA329QZBrnwkswZAMPZCDTvL5xcfCAvmZCTQXe6kS5ZAbUIELd1TeqB0pbjmkYh6w6kTNxtvRCSnAtDWOLMeP7qvpPMFXP21JFzToZD", "");

    //facebook page's long-lived access token
    //pageAccessToken = getFbPageLongLivedAccessToken(oAuthService, pageAccessToken);
    pageAccessToken = new Token("CAAF3yH4PHBkBAOSP9vZA0ZA876psVlRIfl1kQ4wdZBRm6M2nCx6Ru9eurBGzcx1zfLtBDZC2EFnGSNWuukwLpmgVHil57oXiZBLYRoWl0h8DcE8XSpAGvcxOumJrZBHZAEEFjZA1jrDVZCJu8ZBLZBQUqwKll0Ngy4EZCiglCYGSTj9NbOkuyX8S6vQl", "");

Finally:

OAuthRequest request = new OAuthRequest(Verb.POST, "https://graph.facebook.com/" + FB_PAGE_NAME + "/feed");
SimpleDateFormat sdf = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z");
String message = "test message - " + sdf.format(new Date());
request.addBodyParameter("message", message);
String link = "
http://codeoftheday.blogspot.com/";
request.addBodyParameter("link", link);
request.addBodyParameter(ACCESS_TOKEN, pageAccessToken.getToken());
oAuthService.signRequest(accessToken, request);
Response response = request.send();

Note that we have used accessToken, Facebook App’s Access Token, to sign the request as usual. And, we are passing the pageAccessToken, Facebook Page’s Access Token, as a parameter of our request. This will ensure the Facebook Page Impersonation, such that the Facebook Page’s name and icon will be displayed as the Sharer. If you don’t pass pageAccessToken as a parameter than the Facebook App’s name and icon will be displayed as the Sharer.

/**
* Share a Post on Facebook Page using Scribe and Java - http://codeoftheday.blogspot.com/2013/09/share-post-on-facebook-page-using.html
*/
package com.smhumayun.codeoftheday.PostToFacebookPageUsingScribeExample;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import org.scribe.builder.ServiceBuilder;
import org.scribe.builder.api.FacebookApi;
import org.scribe.model.*;
import org.scribe.oauth.OAuthService;
import java.lang.reflect.Type;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.Scanner;
public class PostToFacebookPageUsingScribeExample {
private static String FB_APP_KEY = "012345678901234";
private static String FB_APP_SECRET = "01234567890123456789012345678901";
private static String FB_PAGE_NAME = "H1bWorkVisaUsa";
private static String ACCESS_TOKEN = "access_token";
private static String FB_GRAPH_API = "https://graph.facebook.com/";
private static OAuthService getOAuthService()
{
return new ServiceBuilder()
.provider(FacebookApi.class)
.apiKey(FB_APP_KEY)
.apiSecret(FB_APP_SECRET)
.callback("http://www.smhumayun.com/")
.scope("publish_stream")
.build();
}
@SuppressWarnings("UnusedDeclaration")
private static Token getFbAppShortLivedAccessToken(OAuthService oAuthService)
{
Token fbAppShortLivedAccessToken;
System.out.println("Fetching the Authorization URL...");
String authorizationUrl = oAuthService.getAuthorizationUrl(null);
System.out.println("Got the Authorization URL!");
System.out.println("Now go and authorize this program here:");
System.out.println(authorizationUrl);
//open authorizationUrl in your browser and the you will be redirected to your call back url containing 'code'
//something like this: http://www.smhumayun.com/?code=AQBAFNRNKyxjaSf1....ONXVc#_=_
//copy only the value of 'code' and paste it on the console of this program as an input
System.out.println("And paste the authorization code here");
System.out.print(">>");
Verifier verifier = new Verifier(new Scanner(System.in).nextLine());
System.out.println();
// Trade the Request Token and Verfier for the Access Token
System.out.println("Trading the Request Token for an Access Token...");
fbAppShortLivedAccessToken = oAuthService.getAccessToken(null, verifier);
System.out.println("Got the Access Token!");
System.out.println("Facebook App's Short-Lived Access Token = " + fbAppShortLivedAccessToken.getToken());
System.out.println();
return fbAppShortLivedAccessToken;
}
@SuppressWarnings("UnusedDeclaration")
private static Token getFbAppLongLivedAccessToken(OAuthService oAuthService, Token fbAppShortLivedAccessToken)
{
return getLongLivedAccessToken("Facebook App", oAuthService, fbAppShortLivedAccessToken);
}
private static Token getLongLivedAccessToken(String tokenName, OAuthService oAuthService, Token shortLivedAccessToken)
{
return getAccessToken(tokenName + "'s Long-Lived Access Token"
, FB_GRAPH_API + "oauth/" + ACCESS_TOKEN + "?grant_type=fb_exchange_token"
+ "&client_id=" + FB_APP_KEY + "&client_secret=" + FB_APP_SECRET
+ "&fb_exchange_token=" + shortLivedAccessToken.getToken()
, oAuthService, shortLivedAccessToken);
}
private static Token getAccessToken(String tokenName, String url, OAuthService oAuthService, Token accessToken)
{
Token newAccessToken;
System.out.println("Getting the " + tokenName + "...");
OAuthRequest request = new OAuthRequest(Verb.GET, url);
oAuthService.signRequest(accessToken, request);
newAccessToken = new Token(extractAccessToken(request.send()), "");
System.out.println(tokenName + " = " + newAccessToken.getToken());
System.out.println();
return newAccessToken;
}
private static String extractAccessToken (Response response)
{
if(response != null)
{
System.out.println("response.getBody() = " + response.getBody());
String responseBody = response.getBody();
if(responseBody != null && responseBody.contains(ACCESS_TOKEN))
{
if(responseBody.contains(ACCESS_TOKEN + "="))
return responseBody.split("=")[1].trim();
else
return getValueFrom(response, ACCESS_TOKEN);
}
}
return null;
}
private static String getValueFrom (Response response, String key)
{
//determining the generic type of map
Type typeOfMap = new TypeToken<Map<String, String>>() {}.getType();
//desrialize json to map
Map<String, String> responseMap = new GsonBuilder().create().fromJson(response.getBody(), typeOfMap);
return responseMap.get(key).trim();
}
@SuppressWarnings("UnusedDeclaration")
private static Token getFbPageShortLivedAccessToken(OAuthService oAuthService, Token accessToken)
{
return getAccessToken("Facebook Page {" + FB_PAGE_NAME + "}'s Short-Lived Access Token"
, FB_GRAPH_API + FB_PAGE_NAME + "?fields=" + ACCESS_TOKEN
, oAuthService, accessToken);
}
@SuppressWarnings("UnusedDeclaration")
private static Token getFbPageLongLivedAccessToken(OAuthService oAuthService, Token fbPageShortLivedAccessToken)
{
return getLongLivedAccessToken("Facebook Page {" + FB_PAGE_NAME + "}", oAuthService, fbPageShortLivedAccessToken);
}
private static void postOnFacebookPage(OAuthService oAuthService, Token accessToken, Token pageAccessToken)
{
OAuthRequest request = new OAuthRequest(Verb.POST, "https://graph.facebook.com/" + FB_PAGE_NAME + "/feed");
SimpleDateFormat sdf = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z");
String message = "test message - " + sdf.format(new Date());
request.addBodyParameter("message", message);
String link = "http://codeoftheday.blogspot.com/";
request.addBodyParameter("link", link);
request.addBodyParameter(ACCESS_TOKEN, pageAccessToken.getToken());
oAuthService.signRequest(accessToken, request);
Response response = request.send();
System.out.println(response.getCode());
String responseBody = response.getBody();
System.out.println(responseBody);
}
public static void main(String[] args)
{
OAuthService oAuthService = getOAuthService();
Token accessToken;
//facebook app's short-lived access token
//accessToken = getFbAppShortLivedAccessToken(oAuthService);
//accessToken = new Token("CAAF3yH4...dYLprSJF", "");
//facebook app's long-lived access token
//accessToken = getFbAppLongLivedAccessToken(oAuthService, accessToken);
accessToken = new Token("CAAF3yH4...WUZD", "");
Token pageAccessToken;
//facebook page's short-lived access token
//pageAccessToken = getFbPageShortLivedAccessToken(oAuthService, accessToken);
//pageAccessToken = new Token("CAAF3yH4...ToZD", "");
//facebook page's long-lived access token
//pageAccessToken = getFbPageLongLivedAccessToken(oAuthService, pageAccessToken);
pageAccessToken = new Token("CAAF3yH4...6vQl", "");
postOnFacebookPage(oAuthService, accessToken, pageAccessToken);
}
}

Thursday, 12 September 2013

Share Post on Facebook Wall or Timeline using Scribe and Java

In this post, I will demonstrate how you can share post on your Facebook Wall or Timeline using Scribe OAuth API and Java.

As a pre-requisite, log into your Facebook account and go to Facebook Developer Apps section. If this is the first time you will have to register (no forms to fill, just a click of a button; more of a permission grant).

Create a new app, just fill the “Basic” information.

new facebook app

Once you click on “Save Changes”, your new app will be created and a unique “App ID” and “App Secret” will be assigned to your app. YOU SHOULD NOT SHARE THIS WITH ANY ONE and KEEP IT SAFE AND SECURE.

Besides, you will need these (ID & Secret) to make calls to Facebook servers via Graph API.

private static String FB_APP_KEY = "012345678901234";
private static String FB_APP_SECRET = "0123456789abcdef0123456789abcdef";

First thing to do is to initialize Scribe’s OAuthService, so that we can sign our requests to be sent to Facebook servers.

new ServiceBuilder()
        .provider(FacebookApi.class)
        .apiKey(FB_APP_KEY)
        .apiSecret(FB_APP_SECRET)
        .callback("
http://www.smhumayun.com/”)
        .build();

The call back URL used above is the same which we provided as a “Site URL” during our Facebook App creation. With one very important difference, the trailing forward slash “/”. No matter, if you have provided that trailing forward slash in your app’s “Site URL” or not, you MUST always append a forward slash “/” in your callback code. This might seems insane to you, but trust me, a lot of developers have banged their heads against the wall for this minor detail Smile

Next you’ll have to fetch the Short-Lived Access Token (typically expires in an hour or two).

String authorizationUrl = oAuthService.getAuthorizationUrl(null);
System.out.println(authorizationUrl);
System.out.println("And paste the authorization code here");
System.out.print(">>");
Verifier verifier = new Verifier(new Scanner(System.in).nextLine());
fbAppShortLivedAccessToken = oAuthService.getAccessToken(null, verifier);

The above code will print an Authorzation URL on console, you should copy that URL and open it in a browser and it will redirect to the same “callback” URL (we used above). The redirected URL will contain a ‘code’ query string parameter, copy the value of ‘code’ param and paste it on the console.

If this is a one time test, than you are good with Short-Lived Access Token, but if you want to make it part of a program, you need to exchange it with a Long-Lived Access Token (typically expires in 60 days).

OAuthRequest request = new OAuthRequest(Verb.GET
        , "
https://graph.facebook.com/oauth/access_token?grant_type=fb_exchange_token"
        + "&client_id=" + FB_APP_KEY + "&client_secret=" + FB_APP_SECRET
        + "&fb_exchange_token=" + fbAppShortLivedAccessToken.getToken());
oAuthService.signRequest(fbAppShortLivedAccessToken, request);
Response response = request.send();

In order to get the Long-Lived Access Token, you have to send the Short-Lived Access Token to Facebook server with an exchange token request with “grant_type” as “fb_exchange_token”. Note, we use the same Short-Lived Access Token to sign this request.

As response to this request, you will get the Long-Lived Access Token, which you can safe/persist and re-use thereafter.

Finally:

OAuthRequest request = new OAuthRequest(Verb.POST, "https://graph.facebook.com/me/feed");
SimpleDateFormat sdf = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z");
String message = "test message - " + sdf.format(new Date());
request.addBodyParameter("message", message);
String link = "
http://codeoftheday.blogspot.com/”;
request.addBodyParameter("link", link);
oAuthService.signRequest(accessToken, request);

You will create a new request to post a ‘message’ and a ‘link’ to your Facebook Wall or Timeline.

If all goes well, and the message/link were posted successfully, you will receive an “id” of the newly created post.

/**
* Share Post on Facebook Wall or Timeline using Scribe and Java
* http://codeoftheday.blogspot.com/2013/09/share-post-on-facebook-wall-or-timeline.html
*/
package com.smhumayun.codeoftheday.facebook;
import org.scribe.builder.ServiceBuilder;
import org.scribe.builder.api.FacebookApi;
import org.scribe.model.*;
import org.scribe.oauth.OAuthService;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
public class SharePostOnFacebookWallTimelineUsingScribe {
private static String FB_APP_KEY = "012345678901234";
private static String FB_APP_SECRET = "0123456789abcdef0123456789abcdef";
private static OAuthService getOAuthService()
{
return new ServiceBuilder()
.provider(FacebookApi.class)
.apiKey(FB_APP_KEY)
.apiSecret(FB_APP_SECRET)
.callback("http://www.smhumayun.com/")
.build();
}
@SuppressWarnings("UnusedDeclaration")
private static Token getFbAppShortLivedAccessToken(OAuthService oAuthService)
{
Token fbAppShortLivedAccessToken;
System.out.println("Fetching the Authorization URL...");
String authorizationUrl = oAuthService.getAuthorizationUrl(null);
System.out.println("Got the Authorization URL!");
System.out.println("Now go and authorize this program here:");
System.out.println(authorizationUrl);
System.out.println("And paste the authorization code here");
System.out.print(">>");
Verifier verifier = new Verifier(new Scanner(System.in).nextLine());
System.out.println();
// Trade the Request Token and Verfier for the Access Token
System.out.println("Trading the Request Token for an Access Token...");
fbAppShortLivedAccessToken = oAuthService.getAccessToken(null, verifier);
System.out.println("Got the Access Token!");
System.out.println("(if your curious it looks like this: " + fbAppShortLivedAccessToken + " )");
System.out.println();
return fbAppShortLivedAccessToken;
}
@SuppressWarnings("UnusedDeclaration")
private static Token getFbAppLongLivedAccessToken(OAuthService oAuthService, Token fbAppShortLivedAccessToken)
{
Token fbAppLongLivedAccessToken = null;
System.out.println("Getting the Long-Lived User Access Token...");
OAuthRequest request = new OAuthRequest(Verb.GET
, "https://graph.facebook.com/oauth/access_token?grant_type=fb_exchange_token"
+ "&client_id=" + FB_APP_KEY + "&client_secret=" + FB_APP_SECRET
+ "&fb_exchange_token=" + fbAppShortLivedAccessToken.getToken());
oAuthService.signRequest(fbAppShortLivedAccessToken, request);
Response response = request.send();
if(response != null)
{
System.out.println("response.getBody() = " + response.getBody());
String responseBody = response.getBody();
if(responseBody != null && responseBody.contains("access_token="))
{
System.out.println("Old FB App Access Token = " + fbAppShortLivedAccessToken.getToken());
fbAppLongLivedAccessToken = new Token(responseBody.split("=")[1].trim(), "");
System.out.println("New FB App Access Token = " + fbAppLongLivedAccessToken.getToken());
}
}
return fbAppLongLivedAccessToken;
}
private static void postOnFacebookWallTimeline (OAuthService oAuthService, Token accessToken)
{
OAuthRequest request = new OAuthRequest(Verb.POST, "https://graph.facebook.com/me/feed");
SimpleDateFormat sdf = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z");
String message = "test message - " + sdf.format(new Date());
request.addBodyParameter("message", message);
String link = "http://codeoftheday.blogspot.com/";
request.addBodyParameter("link", link);
oAuthService.signRequest(accessToken, request);
Response response = request.send();
System.out.println(response.getCode());
String responseBody = response.getBody();
System.out.println(responseBody);
}
public static void main(String[] args)
{
OAuthService oAuthService = getOAuthService();
Token accessToken;
//facebook app's short-lived access token
//accessToken = getFbAppShortLivedAccessToken(oAuthService);
//accessToken = new Token("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", "");
//facebook app's long-lived access token
//accessToken = getFbAppLongLivedAccessToken(oAuthService, accessToken);
accessToken = new Token("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", "");
postOnFacebookWallTimeline(oAuthService, accessToken);
}
}

Tuesday, 10 September 2013

Making Java’s Multiple Interface Inheritance more “adaptable”

If there's one feature that I like about Multiple Inheritance, that would be "adaptability". When a child is inherited from multiple parent, child will automatically "adapts" to all the changes made in all the parents, from then and onwards. No explicit changes in child is required, in order to keep it "compatible" or "in-sync" with the parents.

How is it different in Java? in Java, the concept of Multiple Inheritance is further split up into Multiple Interface Inheritance and Multiple Implementation Inheritance specifically. Java supports the former and relinquish the later.

Consider a typical example of TypeC inheriting from TypeA and TypeB. In Java, the closest you can come to Multiple Implementation Inheritance (functionally) is as follows:

public interface TypeA { 
void methodA();
}
public interface TypeB { 
void methodB();
}
//multiple interface inheritance
public interface TypeC extends TypeA, TypeB {
void methodA();
}

public class TypeAImpl implements TypeA {

@override
public void methodA() {
System.out.println("method A");
}
}

public class TypeBImpl implements TypeB {
@override
public void methodB() {
System.out.println("method B");
}
}

public class TypeCImpl implements TypeC (

//object composition
private TypeAImpl delegateAImpl;
private TypeBImpl delegateBImpl;

@override
public void methodA() {
//method delegation
delegateAImpl.methodA();
}
@override
public void methodB() {


//method delegation
delegateBImpl.methodB();
}
@override
public void methodC() {
System.out.println("method C");
}
}

 


Problem? lack of "adaptability"


In our example above, we try to emulate Multiple Implementation Inheritance as closely as possible using:


  • Multiple Interface Inheritance
  • Object Composition
  • Method Delegation

However, contrary to the Multiple Implementation Inheritance, the child still, will not "adapts" to any of the following changes made to the parents. Even worst, these changes will break the child:


  • Add a new method - if we declare a new methodA2 in TypeA and define its implementation in TypeAImpl. TypeC will instantly adapts to the change in TypeA due to multiple interface inheritance. And, because TypeCImpl implements TypeC, it will also adapts to the newly declared methodA2 in TypeA. And so, TypeCImpl will break instantly because it either needs (a). the implementation of methodA2 to be defined OR (b). to change its type from a concrete class to an abstract class.
  • Update the signature of an existing method - if we change signature of methodB in TypeB from "void methodB()" to "void methodB(int b)" and similarly change its implementation in TypeBImpl. TypeC will instantly adapts to the change in TypeB due to multiple interface inheritance. And, because TypeCImpl implements TypeC, it will also adapts to the recently changed methodB in TypeB. And so, TypeCImpl will break instantly because it either needs (a). the implementation of "void methodB(int b)" to be defined OR (b). to change its type from a concrete class to an abstract class. Also, note that the methodB implementation in TypeCImpl will now start complaining about the erroneous code "delegateBImpl.methodB()" because such a method does not exists in TypeBImpl any more.
  • Remove an existing method - if we remove methodB declaration in TypeB and implementation in TypeBImpl. TypeC will instantly adapts to the change in TypeB due to multiple interface inheritance. And, because TypeCImpl implements TypeC, it will also adapts to the recent removal of methodB in TypeB and TypeBImpl. And so, TypeCImpl will break instantly because the methodB implementation in TypeCImpl will now start complaining about the erroneous code "delegateBImpl.methodB()" because such a method does not exists in TypeBImpl any more.

All of the changes above require mandatory changes in child as well and this sucks big time! any change to any one of the parent components, will "force" a ripple effect of mandatory changes to all of the child components down the hierarchy and if you don't do that, it'll break them apart.

Let me raise the bar a little more, assume if, TypeA and TypeB belongs to publicly published APIs, ApiTypeA-1.0.jar and ApiTypeB-1.0.jar. And then one or more of the changes mentioned above is made to those APIs in their next releases, ApiTypeA-2.0.jar and ApiTypeB-2.0.jar respectively. Now, if you don't want the changes, that's fine, you can keep pointing to the older version 1.0 of the dependencies and there won't be any issues. But, most likely in a real world scenario, at some point you need the upgrade to newer versions of the dependencies. But, you can not do that, until and unless you have the necessary resources to make appropriate changes in your code otherwise it will break your code.

Think of those cases specifically, where only additions are being made to relatively newer component(s) in order to add more functionality to make them feature rich. Additional methods/features, with out any changes or removals to existing ones, should not have any impact, the transition should be seamless, but this is not the case as shown above.

So, to make Multiple Interface Inheritance more "adaptable" and to bring it (functionally) one step closer to Multiple Implementation Inheritance with out the negatives of the later, becomes the motivation of Project MI+.

Friday, 6 September 2013

Project MI+ | Multiple Inheritance in Java like never before!

 

project mi  logo

Project MI+ add multiple inheritance support to your java classes, so they can (functionally) "extend" (read inherit) from multiple parent classes.

Project MI+ is an open source project published under Apache Public License version 2.0.

Suppose we want to inherit our Child class from two parent classes: (1) ParentOne and (2) ParentTwo.

public class ParentOne {
public void parentOneMethod() {
System.out.println("parent one method");
}
}

public class ParentTwo {
public void parentTwoMethod() {
System.out.println("parent two method");
}
}

First we will 'extract' interfaces from the parent classes mentioned above. [Project MI+ promotes the use of classic design principle 'Program to Interface']

public interface ParentOne {
void parentOneMethod();
}

public interface ParentTwo {
public void parentTwoMethod();
}

public class ParentOneImpl implements ParentOne {
public void parentOneMethod() {
System.out.println("parent one method");
}
}

public class ParentTwoImpl implements ParentTwo {
public void parentTwoMethod() {
System.out.println("parent two method");
}
}

Now we can simply:


  1. Create a Child interface,
  2. Extend it from parent interfaces,
  3. Add "Multiple Inheritance Support" by annotating the Child interface with MISupport (JavaDoc | Source Code) annotation.
import com.smhumayun.mi_plus.MISupport;

@MISupport(parentClasses = {ParentOneImpl.class, ParentTwoImpl.class})
public interface Child extends ParentOne, ParentTwo {
}

For multiple inheritance to work, you should always create new instances of MISupport (JavaDoc | Source Code) annotated classes (only) via MIFactory (JavaDoc | Source Code) instead of directly instantiating them using java's new keyword and a constructor.

import com.smhumayun.mi_plus.MIFactory;

...
MIFactory miFactory = new MIFactory();
Child child = miFactory.newInstance(Child.class);
child.parentOneMethod();
child.parentTwoMethod();
...

The child now refers to an object which (functionally) inherits methods from all the parent classes.

Click here to read more about Project MI+

Monday, 29 July 2013

No-Arguments Default Constructor and Nested Classes (Non-Static Inner Class, Local Class, Anonymous Class)

Last week, I was working with different type of nested classes and found an interesting fact (which I overlooked up-till now) regarding no-arguments default constructor in some of the nested classes.

Before, I illustrate the example, as a refresher, lets briefly look how many types of Nested Classes are supported in Java.

Types of Nested Classes supported in Java:

  1. Static Nested Class – a static class nested inside another class
  2. Non-Static Nested Class – also called Inner Class – a non static class nested inside another class. Besides that, there are two other, special kinds of Inner Classes:
    1. Local Class – a named Inner Class
    2. Anonymous Class – an un-named Inner Class

Consider following class, in which I tried to create all different sorts of test cases regarding nested classes. Although I don’t wanted to add any extra code to illustrate these cases, but in order to gain “access” to certain members, I had to open doors here and there, please ignore them.

/**
* No-Arguments Default Constructor and Nested Classes (Non-Static Inner Class, Local Class, Anonymous Class)
* http://codeoftheday.blogspot.com/2013/07/no-arguments-default-constructor-and.html
*/
package com.smhumayun.codeoftheday.NestedClassesExample;
interface AnInterface {}
public class TopLevelClass {
static class StaticClassInsideTopLevelClass {}
class NonStaticClassInsideTopLevelClass {}
AnInterface anonymousClassObj1 = new AnInterface() {};
static {
class ClassInsideStaticBlock {}
AnInterface anonymousClassObj2 = new AnInterface() {}; //anonymous class
/*Ignore*/ classInsideStaticBlock = ClassInsideStaticBlock.class;
/*Ignore*/ anonymousClassInsideStaticBlock = anonymousClassObj2.getClass();
}
static void staticMethod () {
class ClassInsideStaticMethod {}
AnInterface anonymousClassObj3 = new AnInterface() {}; //anonymous class
/*Ignore*/ classInsideStaticMethod = ClassInsideStaticMethod.class;
/*Ignore*/ anonymousClassInsideStaticMethod = anonymousClassObj3.getClass();
}
/*Ignore*/ static { staticMethod(); }
void nonStaticMethod () {
class ClassInsideNonStaticMethod {}
AnInterface anonymousClassObj4 = new AnInterface() {}; //anonymous class
/*Ignore*/ classInsideNonStaticMethod = ClassInsideNonStaticMethod.class;
/*Ignore*/ anonymousClassInsideNonStaticMethod = anonymousClassObj4.getClass();
}
/*Ignore*/ static { new TopLevelClass().nonStaticMethod(); }
/*Ignore*/ public static Class classInsideStaticBlock;
/*Ignore*/ public static Class anonymousClassInsideStaticBlock;
/*Ignore*/ public static Class classInsideStaticMethod;
/*Ignore*/ public static Class anonymousClassInsideStaticMethod;
/*Ignore*/ public static Class classInsideNonStaticMethod;
/*Ignore*/ public static Class anonymousClassInsideNonStaticMethod;
}

And then I create following Test Runner sort-of a class which basically access different nested test classes created inside the top level class above and to display their information for our analysis.

/**
* No-Arguments Default Constructor and Nested Classes (Non-Static Inner Class, Local Class, Anonymous Class)
* http://codeoftheday.blogspot.com/2013/07/no-arguments-default-constructor-and.html
*/
package com.smhumayun.codeoftheday.NestedClassesExample;
import java.lang.reflect.Constructor;
import static com.smhumayun.codeoftheday.NestedClassesExample.TopLevelClass.*;
public class Test {
public static void main(String[] args) {
displayClassInfo("Top Level Class", TopLevelClass.class);
displayClassInfo("Static Nested Class", StaticClassInsideTopLevelClass.class);
displayClassInfo("Inner Class or Non Static Nested Class", TopLevelClass.NonStaticClassInsideTopLevelClass.class);
displayClassInfo("Anonymous Class inside Top Level Class", new TopLevelClass().anonymousClassObj1.getClass());
displayClassInfo("Class inside static block", classInsideStaticBlock);
displayClassInfo("Anonymous Class inside static block", anonymousClassInsideStaticBlock);
displayClassInfo("Class inside static method", classInsideStaticMethod);
displayClassInfo("Anonymous Class inside static method", anonymousClassInsideStaticMethod);
displayClassInfo("Class inside non static method", classInsideNonStaticMethod);
displayClassInfo("Anonymous Class inside non static method", anonymousClassInsideNonStaticMethod);
}
static void displayClassInfo (String classInfo, Class clazz) {
StringBuilder sb = new StringBuilder("\n").append(classInfo)
.append("\n\t").append(clazz.getName()).append(" [ ")
.append(clazz.isMemberClass() ? "Member Class " : "")
.append(clazz.isLocalClass() ? "Local Class " : "")
.append(clazz.isAnonymousClass() ? "Anonymous Class " : "")
.append(clazz.isSynthetic() ? "Synthetic Class " : "")
.append("]")
.append(clazz.getDeclaringClass() != null ? "\n\tDeclared by class - " + clazz.getDeclaringClass().getSimpleName() : "")
.append(clazz.getEnclosingClass() != null ? "\n\tEnclosed in class - " + clazz.getEnclosingClass().getSimpleName() : "")
.append(clazz.getEnclosingConstructor() != null ? "\n\tEnclosed in constructor - " + clazz.getEnclosingConstructor().toGenericString() : "")
.append(clazz.getEnclosingMethod() != null ? "\n\tEnclosed in method - " + clazz.getEnclosingMethod().toGenericString() : "")
.append("\n\tConstructors:")
;
Constructor<?>[] constructors = clazz.getDeclaredConstructors();
for (Constructor<?> constructor : constructors) {
sb.append("\n\t\t").append(constructor.toGenericString());
}
System.out.println(sb);
}
}

When you run the Test class, following output will be displayed on your console:

# No-Arguments Default Constructor and Nested Classes (Non-Static Inner Class, Local Class, Anonymous Class)
# http://codeoftheday.blogspot.com/2013/07/no-arguments-default-constructor-and.html
Top Level Class
com.smhumayun.codeoftheday.NestedClassesExample.TopLevelClass [ ]
Constructors:
public com.smhumayun.codeoftheday.NestedClassesExample.TopLevelClass()
Static Nested Class
com.smhumayun.codeoftheday.NestedClassesExample.TopLevelClass$StaticClassInsideTopLevelClass [ Member Class ]
Declared by class - TopLevelClass
Enclosed in class - TopLevelClass
Constructors:
com.smhumayun.codeoftheday.NestedClassesExample.TopLevelClass$StaticClassInsideTopLevelClass()
Inner Class or Non Static Nested Class
com.smhumayun.codeoftheday.NestedClassesExample.TopLevelClass$NonStaticClassInsideTopLevelClass [ Member Class ]
Declared by class - TopLevelClass
Enclosed in class - TopLevelClass
Constructors:
com.smhumayun.codeoftheday.NestedClassesExample.TopLevelClass$NonStaticClassInsideTopLevelClass(com.smhumayun.codeoftheday.NestedClassesExample.TopLevelClass)
Anonymous Class inside Top Level Class
com.smhumayun.codeoftheday.NestedClassesExample.TopLevelClass$1 [ Anonymous Class ]
Enclosed in class - TopLevelClass
Constructors:
com.smhumayun.codeoftheday.NestedClassesExample.TopLevelClass$1(com.smhumayun.codeoftheday.NestedClassesExample.TopLevelClass)
Class inside static block
com.smhumayun.codeoftheday.NestedClassesExample.TopLevelClass$1ClassInsideStaticBlock [ Local Class ]
Enclosed in class - TopLevelClass
Constructors:
com.smhumayun.codeoftheday.NestedClassesExample.TopLevelClass$1ClassInsideStaticBlock()
Anonymous Class inside static block
com.smhumayun.codeoftheday.NestedClassesExample.TopLevelClass$2 [ Anonymous Class ]
Enclosed in class - TopLevelClass
Constructors:
com.smhumayun.codeoftheday.NestedClassesExample.TopLevelClass$2()
Class inside static method
com.smhumayun.codeoftheday.NestedClassesExample.TopLevelClass$1ClassInsideStaticMethod [ Local Class ]
Enclosed in class - TopLevelClass
Enclosed in method - static void com.smhumayun.codeoftheday.NestedClassesExample.TopLevelClass.staticMethod()
Constructors:
com.smhumayun.codeoftheday.NestedClassesExample.TopLevelClass$1ClassInsideStaticMethod()
Anonymous Class inside static method
com.smhumayun.codeoftheday.NestedClassesExample.TopLevelClass$3 [ Anonymous Class ]
Enclosed in class - TopLevelClass
Enclosed in method - static void com.smhumayun.codeoftheday.NestedClassesExample.TopLevelClass.staticMethod()
Constructors:
com.smhumayun.codeoftheday.NestedClassesExample.TopLevelClass$3()
Class inside non static method
com.smhumayun.codeoftheday.NestedClassesExample.TopLevelClass$1ClassInsideNonStaticMethod [ Local Class ]
Enclosed in class - TopLevelClass
Enclosed in method - void com.smhumayun.codeoftheday.NestedClassesExample.TopLevelClass.nonStaticMethod()
Constructors:
com.smhumayun.codeoftheday.NestedClassesExample.TopLevelClass$1ClassInsideNonStaticMethod(com.smhumayun.codeoftheday.NestedClassesExample.TopLevelClass)
Anonymous Class inside non static method
com.smhumayun.codeoftheday.NestedClassesExample.TopLevelClass$4 [ Anonymous Class ]
Enclosed in class - TopLevelClass
Enclosed in method - void com.smhumayun.codeoftheday.NestedClassesExample.TopLevelClass.nonStaticMethod()
Constructors:
com.smhumayun.codeoftheday.NestedClassesExample.TopLevelClass$4(com.smhumayun.codeoftheday.NestedClassesExample.TopLevelClass)

Note following interesting observations:

  1. All nested classes, regardless of their type mentioned above, are mechanically generated by the compiler and hence a “$” in their fully qualified names. [Java Language Specification 3.8]
  2. Among all nested classes, static nested class is the only one that “retains” its constructor’s original signatures in the original form. All the other nested classes “looses” their constructor’s original signatures.
  3. For all the nested classes, other than the static nested class, following is true:
    1. If your nested class has no constructors defined, then don’t expect the default no-argument constructor to be available in these classes.
    2. If you nested class has one or more constructors defined, then don’t expect them to “retain” their original constructor signatures after compilation or at runtime.
    3. Why? because, java compiler, when compiles these nested classes, it “adds” an additional parameter at the very first (0 – zero) index of ALL constructors of a nested class. This additional parameter is actually the enclosing object’s reference. [Java Language Specification 8.1.3]

Now, if you refer to your Java Bean definition:

JavaBeans are are classes that are (1) serializable, (2) have a 0-argument constructor, and (3) allow access to properties using getter and setter methods.

So, by definition, all your non-static inner classes, local classes and anonymous classes disqualifies as JavaBeans.

Thursday, 25 July 2013

Emulating Multiple Inheritance in Java using ‘Program To Interface’ Design Principle, Object Composition and Method Delegation

In this post I will demonstrate the use of ‘Program To Interface’ Design Principle and Object Composition, to emulate Multiple Inheritance in Java. For a refresher on these topics, there’s a very informative post on Artima Developer where Erich Gamma, co-author of the landmark book, Design Patterns, talks with Bill Venners about two design principles: program to an interface, not an implementation, and favor object composition over class inheritance.

For our example, consider different type of Employment Roles available in a typical Software Consulting Firm. To simplify things a bit, assume there are 4 roles; Developer, Tester, Architect and Project Manager. All of these are Employee(s) of the Software Consulting Form i.e. the employer.

Thinking in Object Oriented, you can easily depict that Employee is the Base or Parent Class and Developer, Tester, Architect and ProjectManager are Derived or Child Classes.

v1

/**
* Emulating Multiple Inheritance in Java using ‘Program To Interface’ Design Principle, Object Composition and Method Delegation
* http://codeoftheday.blogspot.com/2013/07/emulating-multiple-inheritance-in-java.html
*/
package smhumayun.codeoftheday.MultipleInheritanceExample;
public class Employee {...}
public class Architect extends Employee {...}
public class Developer extends Employee {...}
public class ProjectManager extends Employee {...}
public class Tester extends Employee {...}

This is the simple example of (Single) Inheritance in Java i.e. all the five classes are inheriting a single Parent Class. All the five? yes Employee is inheriting from Object class following the rules of Java Language Specification that if a class is not inherited from any other class then by default it will be inherited from the Object class.

Now, in real world, this happens quite often and specially in a Software Consulting Firm that a person can “perform” the roles of more than one types. For example, given the circumstances and the skill sets:

  • A senior technical-management resource can perform the roles of Project Manager, Architect and Developer.
  • A senior technical resource can perform the roles of Architect and Developer.
  • Project Manager, Architect and Developer can wear the cap of Tester anytime during the project lifecycle.
  • So on and so forth

To simplify, let us consider one of the above cases, where we wanted to have a new “role”, which we call “ADP” and this role has the responsibilities of Architect, Developer and Project Manager combined. See the picture below:

v1

/**
* Emulating Multiple Inheritance in Java using ‘Program To Interface’ Design Principle, Object Composition and Method Delegation
* http://codeoftheday.blogspot.com/2013/07/emulating-multiple-inheritance-in-java.html
*/
package smhumayun.codeoftheday.MultipleInheritanceExample;
public class ADP extends Architect {...}
//Multiple Inheritance not allowed:
//public class ADP extends Architect, Developer, ProjectManager {...}

The Software Design depicted above is what we want to achieve, but because multiple inheritance is not supported in Java, we will try “emulate” Multiple Inheritance to allow “ADP” to inherit from Architect, Developer and ProjectManager classes.

java interface classJava allows us to emulate the behavior of Multiple Inheritance through the use of Interfaces. Java Interfaces are a good way to separate the contract from its actual implementation and which ever the class “implements” the interface will enter into a binding contract to provide implementation of all the methods “declared” in that particular interface, otherwise declares itself as an “abstract” class – an incomplete, non instantiable class.

While a Class in Java can not “extends”/inherit from more than one Classes, it can “implements”/inherit more than one Interfaces. If we can split the contract (method declarations) from the actual implementation (method definitions) of all of our classes above, we would be in a good position to at-least inherit/implement contracts from multiple interfaces – this is also referred to as “Multiple Interface Inheritance”.

/**
* Emulating Multiple Inheritance in Java using ‘Program To Interface’ Design Principle, Object Composition and Method Delegation
* http://codeoftheday.blogspot.com/2013/07/emulating-multiple-inheritance-in-java.html
*/
package smhumayun.codeoftheday.MultipleInheritanceExample;
public interface Employee {
int getEmployeeId();
void setEmployeeId(int employeeId);
}
//-----------------------------------------------------------
package smhumayun.codeoftheday.MultipleInheritanceExample;
public class EmployeeImpl implements Employee {
private int employeeId;
@Override
public int getEmployeeId() {
return employeeId;
}
@Override
public void setEmployeeId(int employeeId) {
this.employeeId = employeeId;
}
}

The Software Design depicted below now shows each of our classes are now split up into a set of Interface and a corresponding Implementation Class.

v3

Note that Interfaces alone, now form the same hierarchy as show in the first picture above. Similarly implementation Classes alone, form the same hierarchy as shown in the first picture above.

Now, let us make changes to our Software Design to accommodate the ADP Class introduced in second picture above.

v4

/**
* Emulating Multiple Inheritance in Java using ‘Program To Interface’ Design Principle, Object Composition and Method Delegation
* http://codeoftheday.blogspot.com/2013/07/emulating-multiple-inheritance-in-java.html
*/
package smhumayun.codeoftheday.MultipleInheritanceExample;
public interface ADP extends Employee, Architect, Developer, ProjectManager {
}
//----------------------------------------------------------------------------
package smhumayun.codeoftheday.MultipleInheritanceExample;
public class ADPImpl implements ADP {
@Override
public void design() { /*implementation?*/ }
@Override
public void develop() { /*implementation?*/ }
@Override
public void manage() { /*implementation?*/ }
@Override
public int getEmployeeId() { /*implementation?*/ return 0; }
@Override
public void setEmployeeId(int employeeId) { /*implementation?*/ }
}

Notice how ADP (now an Interface) “extends”/inherits from more than one Parent Interfaces (Emlpoyee, Architect, Developer & ProjectManager). This is very nice as far as Multiple Interface Inheritance is concerned. Our target Interface i.e. ADP now have the method declarations of all the four other Interfaces and following is possible as far ADP Interface alone is concern:

ADP refAdp;
...
refAdp.getEmploeeId();
refAdp.setEmployeeId(1);
refAdp.design();
refAdp.develop();
refAdp.manage();

The last unresolved issue now is the Multiple Implementation Inheritance i.e. support for a Class to inherit from more than one Classes. For that we will use Object Composition and Delegation principles of OOP.

Now, our ADPImpl class have to fulfill the contracts of 4 additional Interfaces (besides its very own ADP Interface) – Employee, Architect, Developer and ProjectManager. Note that all of the methods declared in each of the Interfaces have their matching implementation already available in corresponding Implementation classes. And, our intent here is to re-use that implementation rather copy-paste or duplicate the code. Once way to re-use implementation is to inherit the class that contains the required implementation, but java allows us to inherit implementations from only one class.

Question: Which one of these 4 classes (Employee, Architect, Developer, ProjectManager) is the best candidate for Implementation Inheritance for ADP class and why?

Answer: Employee class, because person with ADP role (or any other role) “is an” Employee first. A person who is not an Employee can not work as an Architect, Developer, ADP, etc..

So let us now extend/inherit our ADPImpl class from EmployeeImpl class.

v5

/**
* Emulating Multiple Inheritance in Java using ‘Program To Interface’ Design Principle, Object Composition and Method Delegation
* http://codeoftheday.blogspot.com/2013/07/emulating-multiple-inheritance-in-java.html
*/
package smhumayun.codeoftheday.MultipleInheritanceExample;
public class ADPImpl extends EmployeeImpl implements ADP {
@Override
public void design() { /*implementation?*/ }
@Override
public void develop() { /*implementation?*/ }
@Override
public void manage() { /*implementation?*/ }
}

One down! 3 more to go Smile

We have now exhaust the Implementation Inheritance option and can not use it any more for ADPImpl class, so lets move on to Object Composition.

Object composition is a tightly coupled form of association and it requires ownership of the composed object. So much that the Composed Object may not exists without the existence of Container Object, and if a Container object dies than the Composed object should be disposed off as well. This form of relationship is also called “has a” relationship.

{Do note that there’s another loosely coupled form of association available and is called “Aggregation”}

ADP “is an” Employee and ADP “has an” Architect role – make sense?

Look at the picture above, ADPImpl is still complaining us to provide the implementation for design(), develop() and manage() methods which are declared in Architect, Developer and ProjectManager Interfaces. We already have the implementation of these methods in implementation classes ArchitectImpl, DeveloperImpl and ProjectManagerImpl respectively.

We will now use the Object Composition and Method Delegation to try to re-use the implementations rather than copy-pasting or duplicating the logic/code.

v6

/**
* Emulating Multiple Inheritance in Java using ‘Program To Interface’ Design Principle, Object Composition and Method Delegation
* http://codeoftheday.blogspot.com/2013/07/emulating-multiple-inheritance-in-java.html
*/
package smhumayun.codeoftheday.MultipleInheritanceExample;
public class ADPImpl extends EmployeeImpl implements ADP {
private ArchitectImpl architectImplDelegate;
private DeveloperImpl developerImplDelegate;
private ProjectManagerImpl projectManagerImplDelegate;
@Override
public void design() { architectImplDelegate.design(); }
@Override
public void develop() { developerImplDelegate.develop(); }
@Override
public void manage() { projectManagerImplDelegate.manage(); }
}

DOWNLOAD COMPLETE SOURCE FROM HERE

UPDATE: I’ve published an open source project “Project MI+” which will helps you in (functionally) inherit from multiple classes, saving you from writing a lot of boiler late code. Importantly, it uses all of the above mentioned concepts to achieve that, plus a of couple more to come even closer.

Using Project MI+, you can re-write ADP interface as follows:

package smhumayun.codeoftheday.MultipleInheritanceExample;

@MISupport(parentClasses={EmployeeImpl.class, ArchitectImpl.class, DeveloperImpl.class, ProjectManagerImpl.class})
public interface ADP extends Employee, Architect, Developer, ProjectManager {
}

You won’t need ADPImpl now and can instantiate ADP objects using Project MI+’s factory as follows:

ADP adp = miFactory.newInstance(ADP.class);
adp.getEmployeeId();
adp.design();
adp.develop();
adp.manage();

Tuesday, 23 July 2013

Quick and Easy Integration of Google URL Shortener API in your Java Applications using Scribe-Java and GSon

This post is about a quick and easy integration of Google’s URL Shortener Service/API in your Java Applications using popular APIs like Scribe-Java and Google’s GSon.

The good part about this integration is that you don’t need to do additional steps to register your application with the Service APIs, because in this case, the Google’s URL Shortener Service can be accessed “anonymously”, with out having the need to register the application and performing the authentication and authorization steps.

google url shortener - goo.gl.com

First Download:

Create a new project in IDE of your choice and add above downloaded JAR files to your project’s build/class path.

GoogleUrlShortenerApiIntegrationUsingScribeExample.java:

/**
* Quick and Easy Integration of Google URL Shortener API in your Java Applications using Scribe-Java and GSon
* http://codeoftheday.blogspot.com/2013/07/quick-and-easy-integration-of-google.html
*/
package smhumayun.codeoftheday.google.urlshortener;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import org.scribe.builder.ServiceBuilder;
import org.scribe.builder.api.GoogleApi;
import org.scribe.model.OAuthRequest;
import org.scribe.model.Response;
import org.scribe.model.Verb;
import org.scribe.oauth.OAuthService;
import java.lang.reflect.Type;
import java.util.Map;
/**
* This class demonstrate quick and Easy Integration of Google URL Shortener API in your Java Applications
* using Scribe-Java and GSon APIs
*
* User: smhumayun
* Date: 7/23/13
* Time: 5:27 PM
*/
public class GoogleUrlShortenerApiIntegrationUsingScribeAndGsonExample {
/**
* Main Method
*
* @param args arguments
*/
public static void main(String[] args) {
//Instantiating the oAuth Service of Scribe-Java API
OAuthService oAuthService = new ServiceBuilder()
//Google Api Provider - Google's URL Shortener API is part of Google Platform APIs
.provider(GoogleApi.class)
/*
Using "anonymous" as API Key & Secret because Google's URL Shortener service
does not necessarily requires App identification and/or User Information Access
*/
.apiKey("anonymous")
.apiSecret("anonymous")
//OAuth 2.0 scope for the Google URL Shortener API
.scope("https://www.googleapis.com/auth/urlshortener")
//build it!
.build();
//Instantiating oAuth Request of type POST and with Google URL Shortener API End Point URL
OAuthRequest oAuthRequest = new OAuthRequest(Verb.POST, "https://www.googleapis.com/urlshortener/v1/url");
//set the content type header to application/json - this is the type of content you are sending as payload
oAuthRequest.addHeader("Content-Type", "application/json");
//Preparing JSON payload to send url to Google URL Shortener
String json = "{\"longUrl\": \"http://h1b-work-visa-usa.blogspot.com/\"}";
//add xml payload to request
oAuthRequest.addPayload(json);
//send the request
Response response = oAuthRequest.send();
//print the response from server
System.out.println("response.getBody() = " + response.getBody());
//determining the generic type of map
Type typeOfMap = new TypeToken<Map<String, String>>() {}.getType();
//desrialize json to map
Map<String, String> responseMap = new GsonBuilder().create().fromJson(response.getBody(), typeOfMap);
//print id which is actually the shortened url
System.out.println("Shortened URL = " + responseMap.get("id"));
}
}

Compile and Run the project. You will notice an output similar to the one below in your IDE’s console:

# Quick and Easy Integration of Google URL Shortener API in your Java Applications using Scribe-Java and GSon
# http://codeoftheday.blogspot.com/2013/07/quick-and-easy-integration-of-google.html
response.getBody() = {
"kind": "urlshortener#url",
"id": "http://goo.gl/ePeF0j",
"longUrl": "http://h1b-work-visa-usa.blogspot.com/"
}
Shortened URL = http://goo.gl/ePeF0j

Copy the Shortened URL, open a browser of your choice and paste the Shortened URL into the browser’s Address Bar and press ENTER. You will notice how Google’s URL Shortener Service resolves your Shortened URL to your original (longer) URL.

Shortened URL:

google url shortener - shortened url

Original Longer URL resolved by Goo.gl:

google url shortener - original longer url

DOWNLOAD COMPLETE SOURCE FROM HERE

Monday, 22 July 2013

Maven, Struts2 Annotations and Tiles Integration Example via Convention / Codebehind / Zero Config plugin using Eclipse IDE

In this example, I will demonstrate how you can use Struts2 Annotations and Conventions alone to avoid XML Configuration. I will also integrate Struts2 Tiles Plugin, because I’ve seen a number of people struggling when it comes to Tiles integration with Struts2 Annotation and Convention based projects. Do note that Struts2 Convention Plugin has replaced the older Codebehind plugin and Zero Config Plugin.

The Struts2 Convention Plugin provides the following features:

  • Action location by package naming conventions
  • Result (JSP, FreeMarker, etc) location by naming conventions
  • Class name to URL naming convention
  • Package name to namespace convention
  • SEO compliant URLs (i.e. my-action rather than MyAction)
  • Action name overrides using annotations
  • Interceptor overrides using annotations
  • Namespace overrides using annotations
  • XWork package overrides using annotations
  • Default action and result handling (i.e. /products will try com.example.actions.Products as well as com.example.actions.products.Index)

The Convention Plugin should require no configuration to use. Many of the conventions can be controlled using configuration properties and many of the classes can be extended or overridden.

Ok, let’s start then.

Open Eclipse IDE and create a new Maven project.

eclipse new other project

eclipse new maven project

eclipse new maven project - create a simple maven project (skip archetype selection)

eclipse new maven project - configure project

Note that I’ve selected the “war” Packaging above.

From the eclipse IDE’s Project Explorer, double click on “pom.xml” file. It is your project’s Maven POM file and it should look like:

<!--
Maven, Struts2 Annotations and Tiles Integration Example via Convention / Codebhind / Zero Config plugin using Eclipse IDE
http://codeoftheday.blogspot.com/2013/07/maven-struts2-annotations-and-tiles.html
-->
<project
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>smhumayun.codeoftheday</groupId>
<artifactId>Struts2AnnotationAndTilesIntegrationExample</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>CodeOfTheDay.blogspot.com - Struts2 Annotation And Tiles Integration Example</name>
<description>http://codeoftheday.blogspot.com</description>
</project>

This is the bare bone maven pom file. Now, add following three dependencies to it:

  1. Struts2 Core
  2. Struts2 Convention Plugin
  3. Struts2 Tiles Plugin
<!--
Maven, Struts2 Annotations and Tiles Integration Example via Convention / Codebhind / Zero Config plugin using Eclipse IDE
http://codeoftheday.blogspot.com/2013/07/maven-struts2-annotations-and-tiles.html
-->
<dependencies>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>2.3.15.1</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-convention-plugin</artifactId>
<version>2.3.15.1</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-tiles-plugin</artifactId>
<version>2.3.15.1</version>
</dependency>
</dependencies>

maven directory structure

Now,

Create a package structure as you like. However, make sure the immediate parent package that contains your Struts2 Actions should be named either of the following (refer to directory structure image above):

  • action
  • actions
  • struts
  • struts2

Why? because by “Convention”, Struts2 will “scan” for Action(s) in package(s) that “exactly” matches the names mentioned above. Yes, you can do all sorts of overriding and customizations, but you have to do that using XML Configuration (file called Struts.xml), which we want to avoid in our example. So, we will stick to the “Conventions” Smile

Create a new Action class. Make sure you follow these “Conventions”:

  • Your Action class must suffix with “Action”
    • For example: MyAction, ListOfAction, DownloadAction, etc..
  • OR, your class must implements “com.opensymphony.xwork2.Action” interface

(refer to directory structure image above) I prefer first one because in that case I’m less coupled with the Struts2 API. Lesser the “invasion” by a framework, the better!

Also, for the very same reason, and to demonstrate the plain POJO integration concept by Struts2, I avoid extending my Action class with any of the Struts2 support classes (i.e. com.opensymphony.xwork2.ActionSupport).

/**
* Maven, Struts2 Annotations and Tiles Integration Example via Convention / Codebhind / Zero Config plugin using Eclipse IDE
* http://codeoftheday.blogspot.com/2013/07/maven-struts2-annotations-and-tiles.html
*/
package smhumayun.codeoftheday.struts2_annotations_and_tiles_integration_example.actions;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Result;
public class MainAction {
private String serverTime;
private static int totalVisits;
@Action(value="/showTime", results={@Result(name="success", location="showTime.tiles", type="tiles")})
public String showServerTime ()
{
serverTime = SimpleDateFormat.getDateTimeInstance().format(new Date(System.currentTimeMillis()));
System.out.println("serverTime = " + serverTime);
return "success";
}
@Action(value="/showVisits", results={@Result(name="success", location="showVisits.tiles", type="tiles")})
public String showTotalVisits ()
{
System.out.println("totalVisits = " + ++totalVisits);
return "success";
}
public String getServerTime() {
return serverTime;
}
public void setServerTime(String serverTime) {
this.serverTime = serverTime;
}
public int getTotalVisits() {
return totalVisits;
}
public void setTotalVisits(int totalVisits) {
MainAction.totalVisits = totalVisits;
}
}

Two important things to notice in the class above are:

  • @Result (…, type=”tiles”) – This is to instruct Struts2 that the result is of “Tiles” type and to enable or configure that type you will have to create a minimal Struts XML Configuration file called struts.xml, because this particular configuration can not be done using Struts2 Annotations:
    <!--
    Maven, Struts2 Annotations and Tiles Integration Example via Convention / Codebhind / Zero Config plugin using Eclipse IDE
    http://codeoftheday.blogspot.com/2013/07/maven-struts2-annotations-and-tiles.html
    -->
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
    <struts>
    <constant name="struts.convention.default.parent.package" value="codeoftheday.blogspot.com"/>
    <package name="codeoftheday.blogspot.com" extends="struts-default">
    <result-types>
    <result-type name="tiles" class="org.apache.struts2.views.tiles.TilesResult" />
    </result-types>
    </package>
    </struts>
  • @Result (…, location=”your-tile-definition-name”) – The location refers to one of the tiles defined in your tiles definition file.

Create (if not already created) a web.xml, Java Web Application Deployment Descriptor, under /src/main/webapp/WEB-INF/ and add following to it:

  1. Struts2 Standard Filer Mapping
  2. Tiles Configuration
  3. Tiles Listener
<!--
Maven, Struts2 Annotations and Tiles Integration Example via Convention / Codebhind / Zero Config plugin using Eclipse IDE
http://codeoftheday.blogspot.com/2013/07/maven-struts2-annotations-and-tiles.html
-->
<!-- Struts2 Standard Filer -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Tiles Configuration -->
<context-param>
<param-name>org.apache.tiles.impl.BasicTilesContainer.DEFINITIONS_CONFIG</param-name>
<param-value>/WEB-INF/tiles.xml</param-value>
</context-param>
<!-- Tiles Listener -->
<listener>
<listener-class>org.apache.struts2.tiles.StrutsTilesListener</listener-class>
</listener>

Create your tiles definition file and define all tiles definition:

<!--
Maven, Struts2 Annotations and Tiles Integration Example via Convention / Codebhind / Zero Config plugin using Eclipse IDE
http://codeoftheday.blogspot.com/2013/07/maven-struts2-annotations-and-tiles.html
-->
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
"http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
<tiles-definitions>
<definition name="baseLayout" template="/WEB-INF/content/tiles/BaseLayout.jsp">
<put-attribute name="title" value="" />
<put-attribute name="header" value="/WEB-INF/content/tiles/Header.jsp" />
<put-attribute name="body" value="" />
<put-attribute name="footer" value="/WEB-INF/content/tiles/Footer.jsp" />
</definition>
<definition name="showTime.tiles" extends="baseLayout">
<put-attribute name="title" value="Server Time" />
<put-attribute name="body" value="/WEB-INF/content/DisplayServerTime.jsp" />
</definition>
<definition name="showVisits.tiles" extends="baseLayout">
<put-attribute name="title" value="Total Visits" />
<put-attribute name="body" value="/WEB-INF/content/DisplayTotalVisits.jsp" />
</definition>
</tiles-definitions>

Create following JSP files:

BaseLayout.jsp:

<!--
Maven, Struts2 Annotations and Tiles Integration Example via Convention / Codebhind / Zero Config plugin using Eclipse IDE
http://codeoftheday.blogspot.com/2013/07/maven-struts2-annotations-and-tiles.html
-->
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Struts2 Annotations and Tiles Integration Example - <tiles:insertAttribute name="title" ignore="true" /></title>
</head>
<body>
<tiles:insertAttribute name="header" />
<tiles:insertAttribute name="body" />
<tiles:insertAttribute name="footer" />
</body>
</html>

Header.jsp:

<!--
Maven, Struts2 Annotations and Tiles Integration Example via Convention / Codebhind / Zero Config plugin using Eclipse IDE
http://codeoftheday.blogspot.com/2013/07/maven-struts2-annotations-and-tiles.html
-->
<center>
<h1>
Struts2 Annotations and Tiles Integration Example
<br><br>
<br><br>

Footer.jsp:

DisplayServerTime.jsp:

<!--
Maven, Struts2 Annotations and Tiles Integration Example via Convention / Codebhind / Zero Config plugin using Eclipse IDE
http://codeoftheday.blogspot.com/2013/07/maven-struts2-annotations-and-tiles.html
-->
Server Time
<br><br>
${serverTime}

DisplayTotalVisits.jsp:

<!--
Maven, Struts2 Annotations and Tiles Integration Example via Convention / Codebhind / Zero Config plugin using Eclipse IDE
http://codeoftheday.blogspot.com/2013/07/maven-struts2-annotations-and-tiles.html
-->
Total Visits
<br><br>
${totalVisits}

Finally, deploy the application on any Java Web Application Server, open your browser and go to URLs:

DOWNLOAD COMPLETE SOURCE CODE FROM HERE

Saturday, 20 July 2013

How to post a Tweet in Java using Twitter REST API and Twitter4J Library

In this post, I will demonstrate how you can post a Tweet in Java  using the Twitter REST API and an open source third party twitter integration library in java called Twitter4J.

To start with you need to have an active Twitter account.

Log into Twitter Developer Site using your Twitter credentials.

Go to My Applications section and click on “Create a new application”.

Fill out the mandatory fields – Name, Description and Website. Accept the Terms. Fill Captcha and Submit.

twitter developer apps new application

Once your application is created successfully, you will be redirected to the My Applications page.

Click on the application you’ve just created.

Under the “Details” tab and “OAuth Settings”, you will find the “Consumer Key” and “Consumer Secret”. IMPORTANT – You should never share Consumer Key and Consumer Secret with any one.

twitter developer apps details oauth settings

For this example, you need a minimum of Read and Write “Access level”.

Click on the “Settings” tab and under “Application Type”, select the radio button option “Read and Write” or “Read, Write and Access direct messages”; which ever you like and click on the “Update this Twitter application’s settings” button at the bottom.

Now, go back to “Details” tab, notice that your newly set “Access level” is now reflected under the “OAuth Settings”.

Finally, generate your Access Token (if not already generated) by clicking the button at the bottom of “Details” tab. Do note that the “Access level” shown under the “Your access token” should match the one shown under “OAuth Settings”. Should you change your “Access level” anytime in future, you can re-generate your Access Token by clicking the button “Recreate my access token”.

So now you are all set for the coding part. You have:

  1. Consumer Key
  2. Consumer Secret
  3. Access Token
  4. Access Token Secret

For this particular example we will use Twitter REST API v1.1 and while, we can build up the necessary structure from scratch to do OAuth authentication, access token and making the raw RESTful calls all by ourselves, but we prefer to not to do this and would rather the principle of not re-inventing the wheel again. We will use a very good and easy to use Twitter Library written in Java to do the heavy lifting and save us a lot of precious time and effort.

Twitter4J is an unofficial Java library for the Twitter API. With Twitter4J, you can easily integrate your Java application with the Twitter service.

Twitter4J is:

  • 100% Pure Java - works on any Java Platform version 5 or later
  • Android platform and Google App Engine ready
  • Zero dependency : No additional jars required
  • Built-in OAuth support
  • Out-of-the-box gzip support
  • 100% Twitter API 1.1 compatible

Download Twitter4J from its official website. Unzip the downloaded folder at some location on your machine. For this example you only need the code JAR available in the lib folder.

/**
* How to post a Tweet in Java using Twitter REST API and Twitter4J Library
* http://codeoftheday.blogspot.com/2013/07/how-to-post-tweet-in-java-using-twitter.html
*/
package smhumayun.codeoftheday.twitter;
import twitter4j.*;
import twitter4j.auth.AccessToken;
import java.io.IOException;
import java.net.URL;
import java.util.Arrays;
/**
* This class demonstrate how you can post a Tweet in Java using the Twitter REST API and an open source third party
* twitter integration library in java called Twitter4J
*
* User: smhumayun
* Date: 7/20/13
* Time: 9:26 AM
*/
public class TweetUsingTwitter4jExample {
public static void main(String[] args) throws IOException, TwitterException {
//Your Twitter App's Consumer Key
String consumerKey = "XXXXXXXXXXXXXXXXXXXXX";
//Your Twitter App's Consumer Secret
String consumerSecret = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
//Your Twitter Access Token
String accessToken = "XXXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
//Your Twitter Access Token Secret
String accessTokenSecret = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
//Instantiate a re-usable and thread-safe factory
TwitterFactory twitterFactory = new TwitterFactory();
//Instantiate a new Twitter instance
Twitter twitter = twitterFactory.getInstance();
//setup OAuth Consumer Credentials
twitter.setOAuthConsumer(consumerKey, consumerSecret);
//setup OAuth Access Token
twitter.setOAuthAccessToken(new AccessToken(accessToken, accessTokenSecret));
//Instantiate and initialize a new twitter status update
StatusUpdate statusUpdate = new StatusUpdate(
//your tweet or status message
"H-1B Transfer Jobs | Java Developer | Harrison, NY | 2 Years" +
" - http://h1b-work-visa-usa.blogspot.com/2013/07/h-1b-transfer-jobs-java-developer_19.html");
//attach any media, if you want to
statusUpdate.setMedia(
//title of media
"http://h1b-work-visa-usa.blogspot.com"
, new URL("http://lh6.ggpht.com/-NiYLR6SkOmc/Uen_M8CpB7I/AAAAAAAAEQ8/tO7fufmK0Zg/h-1b%252520transfer%252520jobs%25255B4%25255D.png?imgmax=800").openStream());
//tweet or update status
Status status = twitter.updateStatus(statusUpdate);
//response from twitter server
System.out.println("status.toString() = " + status.toString());
System.out.println("status.getInReplyToScreenName() = " + status.getInReplyToScreenName());
System.out.println("status.getSource() = " + status.getSource());
System.out.println("status.getText() = " + status.getText());
System.out.println("status.getContributors() = " + Arrays.toString(status.getContributors()));
System.out.println("status.getCreatedAt() = " + status.getCreatedAt());
System.out.println("status.getCurrentUserRetweetId() = " + status.getCurrentUserRetweetId());
System.out.println("status.getGeoLocation() = " + status.getGeoLocation());
System.out.println("status.getId() = " + status.getId());
System.out.println("status.getInReplyToStatusId() = " + status.getInReplyToStatusId());
System.out.println("status.getInReplyToUserId() = " + status.getInReplyToUserId());
System.out.println("status.getPlace() = " + status.getPlace());
System.out.println("status.getRetweetCount() = " + status.getRetweetCount());
System.out.println("status.getRetweetedStatus() = " + status.getRetweetedStatus());
System.out.println("status.getUser() = " + status.getUser());
System.out.println("status.getAccessLevel() = " + status.getAccessLevel());
System.out.println("status.getHashtagEntities() = " + Arrays.toString(status.getHashtagEntities()));
System.out.println("status.getMediaEntities() = " + Arrays.toString(status.getMediaEntities()));
if(status.getRateLimitStatus() != null)
{
System.out.println("status.getRateLimitStatus().getLimit() = " + status.getRateLimitStatus().getLimit());
System.out.println("status.getRateLimitStatus().getRemaining() = " + status.getRateLimitStatus().getRemaining());
System.out.println("status.getRateLimitStatus().getResetTimeInSeconds() = " + status.getRateLimitStatus().getResetTimeInSeconds());
System.out.println("status.getRateLimitStatus().getSecondsUntilReset() = " + status.getRateLimitStatus().getSecondsUntilReset());
System.out.println("status.getRateLimitStatus().getRemainingHits() = " + status.getRateLimitStatus().getRemainingHits());
}
System.out.println("status.getURLEntities() = " + Arrays.toString(status.getURLEntities()));
System.out.println("status.getUserMentionEntities() = " + Arrays.toString(status.getUserMentionEntities()));
}
}

Once you run the above example, you will notice an output similar to this one on your console:

status.toString() = StatusJSONImpl{createdAt=Sat Jul 20 11:47:10 EDT 2013...}
status.getInReplyToScreenName() = null
status.getSource() = <a href="http://codeoftheday.blogspot.com" rel="nofollow">SMH's Integration App</a>
status.getText() = H-1B Transfer Jobs | Java Developer | Harrison, NY | 2 Years - http://t.co/dYnQYMKBst http://t.co/y7RJyvaaqc
status.getContributors() = []
status.getCreatedAt() = Sat Jul 20 11:47:10 EDT 2013
status.getCurrentUserRetweetId() = -1
status.getGeoLocation() = null
status.getId() = XXXXXXXXXXXXXXXXXX
status.getInReplyToStatusId() = -1
status.getInReplyToUserId() = -1
status.getPlace() = null
status.getRetweetCount() = 0
status.getRetweetedStatus() = null
status.getUser() = UserJSONImpl{id=XXXXXXXX, name='S M Humayun', screenName='smhumayun'...}
status.getAccessLevel() = 3
status.getHashtagEntities() = []
status.getMediaEntities() = [MediaEntityJSONImpl{...}]
status.getURLEntities() = [URLEntityJSONImpl{url='http://t.co/dYnQYMKBst', expandedURL='http://h1b-work-visa-usa.blogspot.com/2013/07/h-1b-transfer-jobs-java-developer_19.html', displayURL='h1b-work-visa-usa.blogspot.com/2013/07/h-1b-t…'}]
status.getUserMentionEntities() = []

Also, notice a tweet similar to this one on your Twitter Timeline:

tweet using twitter rest api twitter4j java

Thursday, 18 July 2013

Programmatically Posting to LinkedIn Groups via LinkedIn REST API and using Scribe-Java OAuth Library

In this post, I will demonstrate how you can post to LinkedIn Groups programmatically via LinkedIn REST API and using Scribe-Java OAuth Library.

To start with, you need to have an active LinkedIn account. Plus, you need to create a new LinkedIn Developer Application from LinkedIn Developer Site. If you want help on this, please refer to my previous post in which I demonstrate how you can create a new LinkedIn Developer Application, set different Scope(s) and how you can get following:

  1. API Key
  2. API Secret
  3. OAuth Token
  4. OAuth Secret

Do note that, for this example, you need to have 'rw_groups' scope because it is required to retrieve and post group discussions as authenticated user. So make sure you have checked the relevant box against ‘rw_groups’.

A LinkedIn Group Post contains following elements:

  1. Post Title
  2. Post Summary
  3. Content URL
  4. Content Image URL
  5. Content Title
  6. Content Description

programmatically posting on linkedin groups

Here’s the code and inline explanation of what it does:

/**
* Code Of The Day - Programmatically Posting to LinkedIn Groups via LinkedIn REST API and using Scribe-Java OAuth Library
* http://codeoftheday.blogspot.com/2013/07/programmatically-posting-to-linkedin.html
*/
package smhumayun.codeoftheday.linkedin.group;
import org.scribe.builder.ServiceBuilder;
import org.scribe.builder.api.LinkedInApi;
import org.scribe.model.OAuthRequest;
import org.scribe.model.Response;
import org.scribe.model.Token;
import org.scribe.model.Verb;
import org.scribe.oauth.OAuthService;
/**
* This class demonstrate how you can Post Content to LinkedIn Groups using Scribe-Java OAuth API
*
* User: smhumayun
* Date: 7/18/13
* Time: 7:03 PM
*/
public class PostToLinkedInGroupExample {
private static OAuthService oAuthService;
/**
* Main Method
*
* @param args arguments
*/
public static void main(String[] args) {
//Instantiating the oAuth Service of Scribe-Java API
oAuthService = new ServiceBuilder()
//LinkedIn Provider with Scopes support
.provider(LinkedInApi.withScopes(
//'rw_groups' is to retrieve and post group discussions as authenticated user
"rw_groups"
))
//API Key
.apiKey("XXXXXXXXXXXX")
//API Secret
.apiSecret("XXXXXXXXXXXXXXXX")
//build it!
.build();
//Instantiating oAuth Request of type POST and with LinkedIn Group Discussion Post - REST API End Point URL
OAuthRequest postGroupDiscussionRequest = new OAuthRequest(Verb.POST, "http://api.linkedin.com/v1/groups/5046253/posts");
//Preparing XML payload to Share Content on LinkedIn Group
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> \n" +
"<post>\n" +
"<title>" +
//title of the post
"New Job Post!" +
"</title>\n" +
"<summary>" +
//summary of the post
"A new job post has been shared recently by Syed Muhammad Humayun on H-1B Work Visa USA" +
"</summary>\n" +
"<content>\n" +
"<submitted-url>" +
//url of the content
"http://h1b-work-visa-usa.blogspot.com/2013/07/h-1b-transfer-jobs-java-tech-lead-il.html" +
"</submitted-url>\n" +
"<submitted-image-url>" +
//image url of the content (if any)
"http://lh4.ggpht.com/-X2DLlJm6hyg/Uec5z_tRxxI/AAAAAAAAEP8/E3gVAGKIYPs/h-1b%252520transfer%252520green%252520card%252520processing%252520jobs%25255B4%25255D.png?imgmax=800" +
"</submitted-image-url>\n" +
"<title>" +
//title of the content
"H-1B Transfer Jobs - Java Tech Lead - IL - (Sponsor Green Card)" +
"</title>\n" +
"<description>" +
//description of the content
"Provides application development and support to partner in the planning, delivery and/or support of business processes utilizing information technology and business practices for strategic business units. Work is of medium to high complexity and moderate to high in risk. Has expanded contact with responsibility to varied and multiple departments and functional operations, and actively participates in strategic business relationships. Serves as a key team member which may include being on multiple teams and/or team lead. Participates in the review and formation of processes. May plan work and schedules for others for project related work. Impact of decision-making is medium to high risk and impact. Serves as a consultant or expert and actively shares knowledge across workgroups. Applies information analyses to optimize the integration of major strategic business processes. Designs and implements complex changes impacting several processes with minimal direction. Primarily performs as an individual contributor, but may supervise a small work team (6 or fewer members). Duties: Lead the Identification, analysis and selection of complex information technology and business practices to support strategic business process/plans. Participates as required to design, develop, test and integrate applications of high complexity. Lead in the implementation of information technology and business processes of high complexity. Supports, evaluates, and continuously improves information technology and business processes to maintain alignment with business plans of medium-high complexity and medium-high risk. Leads the development and may manage a project plan and schedule for a given functional area. Acquires solid foundation of project management. Engages in expanded contact with varied and multiple departments and functional operations; actively participating in strategic business relationships and/or issues." +
"</description>\n" +
"</content>\n" +
"</post>\n";
//set the content type header to text/xml - this is the type of content you are sending as payload
postGroupDiscussionRequest.addHeader("Content-Type", "text/xml");
//add xml payload to request
postGroupDiscussionRequest.addPayload(xml);
//sign oAuth request
signOAuthRequest(postGroupDiscussionRequest);
//send the request
Response response = postGroupDiscussionRequest.send();
//print the response from server
System.out.println("response.getBody() = " + response.getBody());
System.out.println("response.getMessage() = " + response.getMessage());
System.out.println("response.getCode() = " + response.getCode());
System.out.println("response.getHeaders():");
for(String headerKey : response.getHeaders().keySet())
System.out.println("\t" + headerKey + " = " + response.getHeader(headerKey));
}
/**
* Sign given oAuthRequest with oAuth Service
*
* @param oAuthRequest oAuthRequest
*/
public static void signOAuthRequest (OAuthRequest oAuthRequest)
{
//sign your request with oAuth Service
oAuthService.signRequest(
new Token(
//OAuth Token
"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
//OAuth Token Secret
, "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
), oAuthRequest);
}
}

Once your program ran successfully, you will see a response on your console, similar to following:

# Code Of The Day - Programmatically Posting to LinkedIn Groups via LinkedIn REST API and using Scribe-Java OAuth Library
# http://codeoftheday.blogspot.com/2013/07/programmatically-posting-to-linkedin.html
response.getBody() =
response.getMessage() = Created
response.getCode() = 201
response.getHeaders():
null = HTTP/1.1 201 Created
Date = Thu, 18 Jul 2013 18:46:12 GMT
Vary = Accept-Encoding
Content-Length = 0
Location = http://api.linkedin.com/v1/posts/g-5046253-S-259167773
x-li-request-id = 7R09I1AUHX
X-LI-R2-W-IC-2 = com.linkedin.container.dsc=1
Server = Apache-Coyote/1.1