Showing posts with label Coding. Show all posts
Showing posts with label Coding. Show all posts

Friday, August 17, 2012

Spring MVC - Convention over Configuration w/o Confusion?

Convention over configuration is an essential feature of Spring MVC and it does save some unnecessary coding effort, but I have more than one case where it can get really messy debugging issues.
Here is a simple example: URL app/contact - worked before invoking list method as the only GET method w/o any method level mapping - catch all after the controller mapping.

Beginning 3.1 it will not & throws a 404. But app/contact/list works & will invoke this GET method (IRRESPECTIVE OF THE METHOD NAME), as long it is the only catch-all GET method.

So you could even name it as fooBar and the same URL will invoke it. If however you get confident that the catch-all GET method will always be called for the GET and the URL won't matter, you are right but then the RequestToViewNameMapping goes out the window for the desired view; instead it will look for foorBar.jsp
Something to watch out for!
@Controller
@RequestMapping("contact")
public class ContactController{

@RequestMapping(method = RequestMethod.GET)
 public List<contact> list() {
  logger.info("default method list");
  return contactService.list();
 }
}
Note the mapping generated for this method: INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/contact/*],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.util.List com.aj.recipes.web.ContactController.list()

Wednesday, August 15, 2012

Spring Converter/ConversionService Example

Spring MVC provides so many cool features to make the controller code as minimal as possible. Converter & the ConversionService is one such feature that will be invoked by the framework to carry out type conversions. I have been looking for a decent example & stackoverflow came to the rescue.

I want to add some more information to the solution. As per the Spring documentation here a URI template variable gets translated to the target object using the Converter/ConversionService. I tried to use a `@RequestParam("id") @ModelAttribute("contact") Contact contact`, but I was getting an `IllegalStateException: Neither BindingResult nor plain target object for bean name 'contact' available as request attribute` for not having the model object `contact` in my view edit.jsp. This can be easily resolved by declaring a `Model model` and `model.addAttribute(contact);`. However, there is an even better way; using the URI template variable. It's strange why `@RequestParam` did not work. DID NOT WORK
    @RequestMapping("edit") //Passing id as .. edit?id=1
 public String editWithConverter(@RequestParam("id") @ModelAttribute("contact") Contact contact){
  logger.info("edit with converter");
   return "contact/edit";
 }
WHAT WORKED
    @RequestMapping("edit/{contact}") //Passing id as .. edit/1
 public String editWithConverter(@PathVariable("contact") @ModelAttribute("contact") Contact contact){ // STS gave a warning for using {contact} without @PathVariable 
  logger.info("edit with converter");
   return "contact/edit";
 }

So what does this thing do
.. a link like `...edit/1` implicitly invokes the converter for String '1' to Contact of id '1' conversion, and brings this contact object to the view. No need for `@InitBinder` and since its a `Converter` registered with the `ConversionService` I can use this **anywhere I want - implicitly or explicitly**.

Converter:
public class StringToContactConverter implements Converter <String, Contact > {
 private static final Logger logger = LoggerFactory
   .getLogger(StringToContactConverter.class);
 @Autowired
 private ContactService contactService;
 public void setContactService(ContactService contactService) {
  this.contactService = contactService;
 }
 @Override
 public Contact convert(String id) {
  logger.info("Converting String to Contact");
  Contact contact = contactService.getContact(Long.parseLong(id));
  return contact;
 }
}
Configuration: servlet-context.xml
<annotation-driven conversion-service="conversionService"/>

<beans:bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean" >
<beans:property name="converters">
<beans:list>
<beans:bean class="com.aj.recipes.web.convert.StringToContactConverter">
</beans:bean></beans:list>
</beans:property>
</beans:bean>

Thursday, May 3, 2012

Javascript Constructor & Namespacing

Namespacing is an obvious requirement for any JS applications in the enterprise world - apps. with several functions & data sets. Keeping data/functions i.e., objects in the global namespace would otherwise require being very creative with var names.
The following code demonstrates how to create a name space as well as constructors for JS Objects.

var a = {};
a.b = {};
a.b.C = function(){
    console.log("Constructor called!!");
    this.value="a.b.C";
    this.toString = function(){return this.value};
}

//console.log(b) // ReferenceError: b is not defined
console.log(a.b) // Object { C=function()}

var aa = new a.b.C();
console.log("Value: " + aa.toString()); // Constructor called!! 
                                        // Value: a.b.C

Thursday, April 5, 2012

ToDo App - jQuery UI

I have been playing around with Jquery UI and finally got some time to create a stand alone app. It's a GTD like app, of my personal taste. I use it home/work for personal tasks management. It may eventually hit the Chrome store, but I need to iron out some more kinks. I used to use task on cygwin, see my blog on this, but it certainly lacks in UI.

Features Include:
  • Uses jStorage for local storage: So tasks are available even after browser restart.
  • Keyboard Shortcuts - q  and Q to either quickly add a task or a form driven interface. Quick Add (q) follows some cryptic format but lets users "quickly" add a task. e.g., Something important ^t @Work #Feb 5 !H
  • Today/Next/Someday - Tabs can be navigated using arrow keys. 
  • Sortable tasks - This is the jquery ui sortable; lets users drag the tasks based on the order in which they want to perform.
  • Completed Tasks get nicely stricken out for that sense of accomplishment :D
Few enhancements that are still in the making:
  • Allow drag-n-drop across panes.
  • In-place editing of tasks : description/context/due/priorities
  • Log of completed/deleted tasks
This app was inspired by the so many good GTD apps available on Chrome Store or Mac OS X & the iOS. 

Friday, March 23, 2012

Unix sed - Fun at Work - Its Friday!

In my constant pursuit of efficiency vis-a-vis laziness, I ended up writing this stream editor command. I needed to transform this long list of constants in java into an HTML select tag. This served as a perfect opportunity to use sed.
Input: This comes from my file.
public static final String SOME_CONSTANT_1 = "CST1";
public static final String SOME_CONSTANT_2 = "CST2";
Output:


Here is the magical command.
sed -e 's/[[:space:]]\{1,\}/ /g' \                                                    
-e 's/.*g[[:space:]]\(.*\);/\1/g' \                                                   
-e 's/\(.*\)[[:space:]]*=[[:space:]]*"\(.*\)"/<option value="\2">\1<\/option>/g' \ 
fileName
  • [1]: Replace multiple spaces/tabs [white spaces] in and around a line in a file with a single space.
  • [2]: Get rid of unnecessary text
  • [3]: Swap and format the output to HTML

Friday, March 16, 2012

Javascript Singleton Pattern

This is just a working example of the idea discussed here. I thought it would help to see the working behavior.
var QuickDialog = function(){
    var privateInit = function(){console.log("init")};
    return{
        init: privateInit
    };
}();

QuickDialog.init();
QuickDialog.privateInit();
This is the firebug output for the above code.

Javascript === vs ==

=== also looks at the type


var a = "1";
var b = 1;
console.log(a===b); //false
console.log(a==b); //true

Saturday, February 18, 2012

Spring MVC 3.1 - Cancel button

I was searching for a way to deal with cancel button that would not cause a form submit and subsequent unnecessary validation of the form backing bean.
I ended up with the following solution for the time being.

Controller:
@RequestMapping(value = "cancel"
 method = RequestMethod.GET)
public String cancelSaveContact() {
 return "redirect:list";
}
JSP:
<a href="<c:url value='/contact/cancel'/>">
 <input type="button" value="Cancel"/>


Update: Unless you don't need cancel to do anything specific for this page, you might as well just redirect to the previous page.

Thursday, January 19, 2012

Java Lessons [3]


3. Hibernate:
People have been forever zealous about jumping into new technologies, but still hanging on to obsolete ideas. Just noticed a code written for Hibernate, where HQL was formed appending several HQLs & then the parameters as well. I thought we were done with this, having identified security issues like SQL injections & the complete failure in utilizing any caching mechanism offered by Hibernate or event the database.
Use Criteria to handle these dynamic queries, at least it will be clean and secure. And Hibernate can even cache these internally, if not by the DB.

Java Lessons [2]


2. Program Flow: 
Noticed another archaic coding style, apparently when there were no methods, where a single call had a ton of if..else.. handling the same condition. Why not branch off at the first if..else..?
This should be obvious by now, but isn't.

Friday, March 25, 2011

Cygwin task - My office GTD

I extensively use Cygwin on Widows at home and at work. No no, I am not talking about Windex vs Cygwin. I am talking about the OS Windows :|
To some extent it has become indispensible to me. A nifty new tool that I installed on cygwin a few yrs ago has now become my primary GTD app @Work. I can manage all my office work using this tool. It's a very basic tool but it comes in handy.

You can find all the necessary help here

Wednesday, January 19, 2011

cygwin gcc undefined reference to `_WinMain@16'

I tried to write a simple HelloWorld.c program using cygwin gcc on a Windows XP machine and got this error: undefined reference to `_WinMain@16'

I am not trying to write any Windows GUI app and this error was surprising for a simple c program. Turns out I need to add a default method as mentioned here. I will try to find a better solution than this, but for now this will do ;)

So here is the final code now.

#include <stdio.h>

static int main();

int __declspec(nothrow) __stdcall WinMain(int a, int b, char* c, int d){

  main();

  return 0;

}

static int main(){

  printf("Hello C Again\n");

  return 0;

}

 

Thursday, November 11, 2010

IBM RAD/RSA 7 installation on Ubuntu 10.04 Linux

IBM Rational Application Developer 7 or Rational Software Architect 7.0 installation on Linux can be annoying at times. Here are the steps I followed to get this working and this time around it felt quite simple.
1. IBM Installation Manager 1.4.1: It will be best to get the latest version of the installation manager, so download and install it first. Choose the agent.installer.linux.gtk.x86_1.4.1.
2. Download and install the libstdc++5 lib from Debian site. I had saved libstdc++5_3.3.6-18_amd64.deb locally and used this one. I am not sure but it seems I needed the 64 bit version.
3. Replace the default shell sh from dash to bash; as described here. The command to use is 'sudo dpkg-reconfigure dash' and select 'no'.
This did it for me!

Update Jun 23, 12: I am now running Ubuntu 12.04 64bit version, trying to install the 1.5.2 version of the IM. However, I kept on getting this bash error - bash ./install: No such file or directory
The issue was not having 32bit lib files described here. So install 32 bit library files using
sudo apt-get install ia32-libs

It all works now!

Disclaimer: Again this is the assimilation of all the wisdom that is available over the net, with some of own tweaks

Thursday, October 28, 2010

MySQL WorkBench 5.2.29 CE - Windows MSI Installer Error

When installing MySQL WorkBench 5.2.29 CE using the Windows MSI installer (mysql-workbench-gpl-5.2.29-win32.msi), I got an error "Error: 25580 - cannot connect to windows firewall".  

I followed the instructions from MySQL Forums, and it fixed the installation error. The solution is to start the "Windows Firewall/Internet Connection Sharing" from windows services (Run>services.msc). If the service is disabled, right click and make the start type manual/automatic and then start it.

Disclaimer: I often run into issues either configuring/installing applications on Windows/Ubuntu Linux/Mac OS X. I will hence forth put all the solutions on this blog, so I can use these whenever I need them. I must humbly acknowledge that the credit to most or even all of them would go to all the developers who post their solutions on the net. I will obviously put a link to the original resource.

Friday, October 22, 2010

MySQL 5.5.6 on Mac OS X Snow Leopard 10.6 PreferencePane

PreferencePane for MySQL 5.5.6. seems to have broken "again" in mysql-5.5.6-rc-osx10.6-x86_6.

If you try to start MySQL server using the preference pane it fails. I tried to start it using '/usr/local/mysql/bin/mysqld start' and it still failed.

Here is the fix for the preference pane start and stop.
Edit '/usr/local/mysql/support-files/mysql.server'
Find line 'basedir=.' and replace it with 'basedir=/usr/local/mysql'
Here is the screenshot after the change:
After this, I was able to successfully execute the following commands:
sudo /usr/local/mysql/support-files/mysql.server start|stop 
SystemPreferences > PreferencePane > MySQL Start|Stop Server
This fix came from: http://bugs.mysql.com/bug.php?id=53232

Saturday, May 9, 2009

HelloWorld - Ajax, Struts

This is a simple HelloWorld example for Ajax & Struts. In this example, I have a rudimentary Ajax call to the server side Struts Action class.

JavaScript:

<SCRIPT language="javascript">
var xmlHttp;
function greet(name) {
xmlHttp = GetXmlHttpObject();
if (xmlHttp == null) {
alert("Critical Browser Error: Pls. close the browser & try again!");
return false;
}
// struts action call
var url = "sayHello.do";
url = url + "?name=" + name.value;
url = url + "&sid=" + Math.random();
xmlHttp.onreadystatechange = stateChanged;
xmlHttp.open("GET", url, true);
xmlHttp.send(null);
}

function stateChanged() {

if (xmlHttp.readyState == 4) {
if (xmlHttp.status == 200) {
var strutsResp = xmlHttp.responseText;
document.getElementById("strutsResp").innerHTML = strutsResp;
} else {
alert("Critical Browser Error: Pls. close the browser & try again!");
}
}
}

function GetXmlHttpObject() {
var xmlHttp = null;
try {
xmlHttp = new XMLHttpRequest();
} catch (e) {
try {
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
}
return xmlHttp;
}
</SCRIPT>


HTML Form:

<form><!-- onchange='greet(this);'-->
<p><LABEL for="name">Name: <input type="text" name="name"
size="10" id="name" onchange='greet(this);'/></LABEL>
<input type="button" id="ok" value="OK"/>
</p>
</form>


Struts Config:

<!--Note: the response is fully cooked - no mapping required! -->
<action-mappings>
<action path="/sayHello" type="com.aj.helloajax.actions.SayHelloAction">
</action>
</action-mappings>


Struts Action Class:

public class SayHelloAction extends Action {

public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {

String name = (String)request.getParameter("name");
response.setContentType("text/html");
PrintWriter out = response.getWriter();

out.print("<h2>Hello "+name+" !!</h2>");
out.flush();
response.flushBuffer();
//Note: the response is fully cooked - no mapping required!
return null;
}
}

Thursday, April 30, 2009

Expand Collapse - Client Side using style.visibility

This is the simplest version of implementing Expand/Collapse of table rows using Javascript.
Clicking + expands the table & - collapses the table rows to the header.




Its important to note that even the selections are preserved, between expand and collapse; clearly since only the display property is altered.
I am enclosing the bare bone version of the code here. I have used some CSS to make the tables above look presentable.
Refer http://w3schools.com/css/ for more details

<br /><script language="javascript"><br />var disp = true;<br />function toggleDisplay(){<br /> if(disp){<br />  disp = false;<br />  document.getElementById("state").innerHTML="-";<br />  document.getElementById("table").style.<br />visibility="collapse";<br /> }else{<br />  disp = true;<br />  document.getElementById("state").innerHTML="+";<br />  document.getElementById("table").style.<br />visibility="visible";<br /> }<br />}<br /></script><br /></pre><br /><pre class="brush: html; wrap-lines: true"><br /><br /><body><br /> <table cellpadding="0" cellspacing="1"><br /> <thead><br />  <tr><td><a href='javascript:toggleDisplay()'><div id="state">-</div></a></td><td>Names</td></tr><br /> </thead><br /> <tbody id="table"><br />  <tr><td><input type="checkbox" name="name1"/></td><td>Ajay1</td></tr><br />  <tr><td><input type="checkbox" name="name2"/></td><td>Ajay2</td></tr><br />  <tr><td><input type="checkbox" name="name3"/></td><td>Ajay3</td></tr><br /> </tbody><br /> </table><br />

Sunday, November 9, 2008

VIM Command Short list

Unix vim command short list or references:

CommandDescription
vi +[num] ~/dsk/2DO.txt : Position cursor on line "num" when file is opened




Note:
All these commands are written from the vi man page or other valuable posts made by geeks on the internet. I am mere compiling this list for my quick reference & if anybody else that may be interested.

Recurring RegEx short list


Regular Expression>>Matches
[0-9]\.>>1.

Eclipse: Ctrl+F, w/ Regular Expressions

Find {100 in "{100,"asas"}, {200,"asas"}}.." and replace the number 100 with a string "" to get
{"100","asas"}, {"200","asas"}

Find: \{([0-9]+) .. () marks a group
Replace: \{"\1"
  .. \1 identifies the 1st marked group.. so the number matched is retained when replaced.

Find: ^\(.*\)
Replace: <span id="time_stamp">$0</span>
e.g,:
(10:42:59 AM) ..
<span id="time_stamp">(10:42:49 AM)</span>

Find: (A{2})(B{2})
Replace: $1, $2
e.g,:
AABB ..
AA, BB

(\b[a-z]{4}?:)(\s.*?$)
<span id="name">$1</span><span id="chat">$2</span>
e.g,:
AJ: ahoy!! there!!
<span id="name">AJ:</span><span id="chat"> ahoy!! there!!</span>