Sunday, June 29, 2014

Django Recipe: Custom Url Dispatcher for views.

While refactoring our Django application I felt a need to make url.py less loaded and more readable.

The idea is to attach the information on view regarding the action it performs. This action name will be the part of the url while requesting the view. Views will be abstracted in a callable class extending 'BaseView' (similar to the one’s provided by Django). A 'dispatch' decorator will be applied on the new class view methods. 

Here is the sample HomeView of a feeds display application:

class HomeView(BaseView):

  @dispatch(request_type='GET', action='default')
  def getAllfeeds(self, request):
    template_file_path = 'templates/main.html'
    tmpl = os.path.join(os.path.dirname(__file__), template_file_path)
    return render_to_response(tmpl, {'feeds': Feed.objects.all()})

  @dispatch(request_type='POST', action='add')
  def addFeed(self, request):
    new_feed = Feed(title=request.POST.get('title'),
                    description=request.POST.get('description'))
    new_feed.save()
    return HttpResponse('Added Feed.')

Notice the dispatch decorator: param 'request_type' will be the http request method and ‘action’ will be a part of url while requesting a view.

And we’ll have single entry for all views within HomeView.
urlpatterns = patterns('',
    url(r'^(?P<action>\w{0,50})$', HomeView(), name='home')
)

A url for addfeed will be:
customapp.com/myapp/feeds/add

Using this approach I've noticed following benefits:

  • Views have become even more discrete. Otherwise we had multiple if..else or switch statements or  write multiple urls.py entries.
  • Views are more readable.
  • Urls.py is less loaded and hence more readable. 
  • Since I’ve a Base view class. This has provided me the power to implement pre and cleanup logic.

Here is the crux:

Dispatch decorator will save the request_type and action information inside each view method.

def dispatch(request_type, action):
  """Decorator to transform the view class methods to be treated 
     Django views.
  """
  def dispatcher(handler_to_call):
    def WrappedFunc(*args, **kwargs):
      return handler_to_call(*args, **kwargs)
    setattr(WrappedFunc, 'request_type', request_type)
    setattr(WrappedFunc, 'action', action)
    return WrappedFunc
  return dispatcher

‘BaseView’ is a callable class. At runtime we’ll inspect the members of the class and take out the member call relevant action and request type.

class BaseView(object):

  def __call__(self, request, *args, **kwargs):
    """Dispatch the url to relevant handler.

    Args:
      request: django.http.HttpRequest representing the request being handled.
      *args: args for method.
      **kwargs: keyword args for method.

    Returns:
      Returns response from the called handler.
      Returns HttpResponseNotFound when AttributeError or TypeError.
    """

    if not kwargs.get('action'):
      kwargs['action'] = 'default'

    callee = None;

    def is_view(member):
      return inspect.ismethod(member) and request.method.upper() == getattr(
         member, 'request_type', False) and kwargs['action'] == getattr(
         member, 'action', False)

    members = inspect.getmembers(self, predicate=is_view)

    for member_name, _ in members:
      callee = getattr(self, member_name)

    del kwargs['action']
    if not callee:
      return HttpResponseNotFound()
    else:
      return callee(request, **kwargs)

You can clone the Django app here: https://github.com/rohit0286/DjangoCustomURLDispatcherApp

Hope this helps.



Thursday, October 13, 2011

Building AspectJ aspects using Ant


To develop Aspects using AspectJ you can follow my Blog.
After implementing there comes the work of automating the build process. Since, we use Hudson for  build, it can be configured to run an Ant script.

Tuesday, October 11, 2011

Aspect Oriented Programming (AOP) using AspectJ

Cross cutting concerns is set of behaviours needed by the conceptual section s of the program. An example of the cross cutting concerns is Logging.
AOP separates the cross cutting concerns from the functional requirements hence increasing the modularity of the code and making it easier to maintain and decreasing the complexity.
AspectJ is the aspect oriented extension for the Java Programming Language.
Following are the terminologies used in AOP
1.        Aspect - General feature we want to apply globally to your application (ex. Logging , transaction Management)
2.       Advice - A chunk of code that is invoked during program execution
3.       Joinpoint - A single location in the code where an advice should be executed  
4.        Pointcut - A pointcut is a set of many joinpoints where an advice should be executed
5.        Targets/Target Objects - The objects you want to apply an aspect or set of aspects to
6.       Introduction - This is the ability to add methods to an object
Different Types of advices in AspectJ are:
1.       Before advice:  Before advice executes before the execution of the advised join point. The  syntax of this advice is  before(args) : pointcut_expression {}
2.       After advice:  After advice executes after the execution of a join point. The  syntax of this advice is  after(args) returning() : pointcut_expression {}
3.       Around advice:  Around advice surrounds join points i.e. it can execute before and after the join points execution. The syntax of this advice is  around(args) : pointcut_expression {}. Responsibility when using an around advice is calling   the join point by using the proceed() method.
4.       After Throwing: This advice will be called when an advised join point throws an exception. The  syntax of this advice is  after(args) throwing() : pointcut_expression {}
 Eclipse IDE provides the AspectJ development tools plugin (available in Eclipse MarketPlace) .

Wednesday, October 5, 2011

Xpath = JxPath


Quite often while implementing   SOAP based service we  need to  traverse   xpath.
So, my XSD looks like this;
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="myorg.xml.com" targetNamespace="myorg.xml.com">
<element name="employeeDetails">
<complexType >
<sequence>
<element name="employee" type="tns:Employee" minOccurs="1" maxOccurs="unbounded"/>
</sequence>
</complexType>
</element>

    <complexType name="Employee">
    <sequence>
    <element  name="employeeId" type="int" />
    <element name="employeeName" type="string" />
    <element name="department" type="tns:Department"/>
    <element name="EmployeeDesignation" type="tns:Designation"/>
    </sequence>
    </complexType>

    <complexType name="Department">
    <sequence>
    <element  name="departmentId" type="int" />
    <element name="departmentName" type="string" />
    </sequence>
    </complexType>
   
   <simpleType name="Designation">
    <restriction base="string">
    <enumeration value="Associate"/>
    <enumeration value="Software Engineer"/>
    <enumeration value="Senior Software Engineer"/>
    <enumeration value="Manager"/>
    <enumeration value="Executive"/>
   
    </restriction>
    </simpleType>
</schema>

And a sample XML:
<?xml version="1.0" encoding="UTF-8"?>
<tns:employeeDetails xmlns:tns="myorg.xml.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="myorg.xml.com Employee.xsd ">
  <employee>
    <employeeId>230</employeeId>
    <employeeName>Jim</employeeName>
    <department>
      <departmentId>1</departmentId>
      <departmentName>IT</departmentName>
    </department>
    <EmployeeDesignation>Associate</EmployeeDesignation>
  </employee>
 
  <employee>
    <employeeId>231</employeeId>
    <employeeName>Tim</employeeName>
    <department>
      <departmentId>12</departmentId>
      <departmentName>Admin</departmentName>
    </department>
    <EmployeeDesignation>Manager</EmployeeDesignation>
  </employee>
</tns:employeeDetails>

JXPath (http://commons.apache.org/jxpath/)  provides APIs for traversal of graphs of JavaBeans, DOM and other types of objects using the XPath syntax. Both child and attribute axis of a node is mapped to Java Beans Properties.

Monday, July 11, 2011

E-signature and Documentum.......way to go...

What is E- Signature?
An electronic signature is defined as an electronic sound (e.g., audio files of a person's voice), symbol (e.g., a graphic representation of a person in JPEG file), or process (e.g., a procedure that conveys assent), attached to or logically associated with a record, and executed or adopted by a person with the intent to sign the record. An electronic signature is easy to implement, since something as simple as a typed name can serve as one. E- Signatures are implemented in Documentum by TCS (trusted content Services)