DZone
Java Zone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
  • Refcardz
  • Trend Reports
  • Webinars
  • Zones
  • |
    • Agile
    • AI
    • Big Data
    • Cloud
    • Database
    • DevOps
    • Integration
    • IoT
    • Java
    • Microservices
    • Open Source
    • Performance
    • Security
    • Web Dev
DZone > Java Zone > Some Reporting tricks with class-transformations

Some Reporting tricks with class-transformations

Taha Siddiqi user avatar by
Taha Siddiqi
·
Feb. 09, 12 · Java Zone · Interview
Like (0)
Save
Tweet
3.10K Views

Join the DZone community and get the full member experience.

Join For Free

Every time I used to see some duplication of code, I used to move that code to a new method. With Tapestry, you begin to think differently. Now every time I see duplication, my first thought is “Can I create a worker for it”.

In my current project, I am using a few new ones. So I thought why not share them with you.

@ReportException

My onSuccess methods usually are of the form

@InjectComponent
private Form form

@OnEvent(EventConstants.SUCCESS)
void success()
{
   try
   {
      do_my_stuff();
   }catch(MyException ex)
   {
      form.recordError(ex.getMessage());
   }
}

Here is how I wanted my code to look.

@ReportException
@OnEvent(EventConstants.SUCCESS)
void success()
{
   do_my_stuff();
}

So for implementation, we first need an annotation

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ReportException
{
}

and then a worker

public class ReportExceptionWorker implements ComponentClassTransformWorker2
{
    private Environment environment;

    public ReportExceptionWorker(Environment environment)
    {
        this.environment = environment;
    }

    @Override
    public void transform(PlasticClass plasticClass, TransformationSupport support,
        MutableComponentModel model)
    {
        for(PlasticMethod method : plasticClass.getMethodsWithAnnotation(ReportException.class))
        {
            method.addAdvice(new ReportExceptionAdvice());
        }
    }

    private class ReportExceptionAdvice implements MethodAdvice
    {
        @Override
        public void advise(MethodInvocation invocation)
        {
            ValidationTracker tracker = environment.peek(ValidationTracker.class);

            if(tracker != null)
            {
                try
                {
                    invocation.proceed();
                } catch(MyException ex)
                {
                    tracker.recordError(ex.getMessage());
                    ex.printStackTrace();
                }
            }
        }
    }
}

Here the advice gets the ValidationTracker from the Environment service and does the exception handling and reporting for us.

Finally the contribution in Module.

public static void contributeComponentClassTransformWorker(
        OrderedConfiguration<ComponentClassTransformWorker2> configuration)
    {
        configuration.addInstance("ReportExceptionWorker",
            ReportExceptionWorker.class);
    }

@ReportExceptionAsAlert

Another close use case is when you have an ajax call which may result in an exception but you just want to show the user a simple alert with the message.

The annotation

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ReportExceptionAsAlert
{
}


The Worker

public class ReportExceptionAsAlertWorker implements ComponentClassTransformWorker2
{

    private final AjaxResponseRenderer ajaxResponseRenderer;

    private final Request request;

    public ReportExceptionAsAlertWorker(
        AjaxResponseRenderer ajaxResponseRenderer,
        Request request)
    {
        this.ajaxResponseRenderer = ajaxResponseRenderer;
        this.request = request;
    }

    @Override
    public void transform(PlasticClass plasticClass, TransformationSupport support,
        MutableComponentModel model)
    {
        for(PlasticMethod method : plasticClass.getMethodsWithAnnotation(
            ReportExceptionAsAlert.class))
        {
            method.addAdvice(new ReportExceptionAsAlertAdvice());
        }
    }

    private class ReportExceptionAsAlertAdvice implements MethodAdvice
    {
        @Override
        public void advise(MethodInvocation invocation)
        {

            if(request.isXHR())
            {
                try
                {
                    invocation.proceed();
                } catch(final MyException ex)
                {
                    ajaxResponseRenderer.addCallback(new JavaScriptCallback()
                    {

                        @Override
                        public void run(JavaScriptSupport javascriptSupport)
                        {
                            javascriptSupport.addScript("alert('%s');", ex.getMessage());
                        }

                    });
                    ex.printStackTrace();
                }
            }
        }
    }
}

 

From http://tawus.wordpress.com/2012/02/03/some-reporting-tricks-with-class-transformations/

Use case Annotation Form (document) Advice (programming) Implementation

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Understand Source Code — Deep Into the Codebase, Locally and in Production
  • Legacy Modernization and Hybrid Cloud with Kafka in Healthcare
  • A Simple Guide to Rust Data Types
  • 8 Must-Have Project Reports You Can Use Today

Comments

Java Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • MVB Program
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends:

DZone.com is powered by 

AnswerHub logo